src/lemon/maps.h
author marci
Tue, 11 Jan 2005 17:16:29 +0000
changeset 1075 789bad021e2d
parent 1044 f97380557656
child 1076 67a115cdade4
permissions -rw-r--r--
:-}
alpar@906
     1
/* -*- C++ -*-
alpar@921
     2
 * src/lemon/maps.h - Part of LEMON, a generic C++ optimization library
alpar@906
     3
 *
alpar@906
     4
 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@906
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
alpar@906
     6
 *
alpar@906
     7
 * Permission to use, modify and distribute this software is granted
alpar@906
     8
 * provided that this copyright notice appears in all copies. For
alpar@906
     9
 * precise terms see the accompanying LICENSE file.
alpar@906
    10
 *
alpar@906
    11
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    12
 * express or implied, and with no claim as to its suitability for any
alpar@906
    13
 * purpose.
alpar@906
    14
 *
alpar@906
    15
 */
alpar@906
    16
alpar@921
    17
#ifndef LEMON_MAPS_H
alpar@921
    18
#define LEMON_MAPS_H
klao@286
    19
alpar@1041
    20
#include<math.h>
alpar@1041
    21
klao@286
    22
///\file
alpar@1041
    23
///\ingroup maps
klao@286
    24
///\brief Miscellaneous property maps
klao@286
    25
///
klao@959
    26
///\todo This file has the same name as the concept file in concept/,
klao@286
    27
/// and this is not easily detectable in docs...
klao@286
    28
klao@286
    29
#include <map>
klao@286
    30
alpar@921
    31
namespace lemon {
klao@286
    32
alpar@1041
    33
  /// \addtogroup maps
alpar@1041
    34
  /// @{
alpar@1041
    35
alpar@720
    36
  /// Base class of maps.
alpar@720
    37
alpar@805
    38
  /// Base class of maps.
alpar@805
    39
  /// It provides the necessary <tt>typedef</tt>s required by the map concept.
alpar@720
    40
  template<typename K, typename T>
alpar@720
    41
  class MapBase
alpar@720
    42
  {
alpar@720
    43
  public:
alpar@911
    44
    ///\e
alpar@987
    45
    typedef K Key;
alpar@911
    46
    ///\e
alpar@987
    47
    typedef T Value;
alpar@720
    48
  };
alpar@720
    49
alpar@805
    50
  /// Null map. (a.k.a. DoNothingMap)
klao@286
    51
klao@286
    52
  /// If you have to provide a map only for its type definitions,
alpar@805
    53
  /// or if you have to provide a writable map, but
alpar@805
    54
  /// data written to it will sent to <tt>/dev/null</tt>...
klao@286
    55
  template<typename K, typename T>
alpar@720
    56
  class NullMap : public MapBase<K,T>
klao@286
    57
  {
klao@286
    58
  public:
klao@286
    59
alpar@805
    60
    /// Gives back a default constructed element.
klao@286
    61
    T operator[](const K&) const { return T(); }
alpar@805
    62
    /// Absorbs the value.
klao@286
    63
    void set(const K&, const T&) {}
klao@286
    64
  };
klao@286
    65
klao@286
    66
klao@286
    67
  /// Constant map.
klao@286
    68
alpar@805
    69
  /// This is a readable map which assigns a specified value to each key.
alpar@805
    70
  /// In other aspects it is equivalent to the \ref NullMap.
alpar@805
    71
  /// \todo set could be used to set the value.
klao@286
    72
  template<typename K, typename T>
alpar@720
    73
  class ConstMap : public MapBase<K,T>
klao@286
    74
  {
klao@286
    75
    T v;
klao@286
    76
  public:
klao@286
    77
alpar@805
    78
    /// Default constructor
alpar@805
    79
alpar@805
    80
    /// The value of the map will be uninitialized. 
alpar@805
    81
    /// (More exactly it will be default constructed.)
klao@286
    82
    ConstMap() {}
alpar@911
    83
    ///\e
alpar@805
    84
alpar@805
    85
    /// \param _v The initial value of the map.
alpar@911
    86
    ///
klao@286
    87
    ConstMap(const T &_v) : v(_v) {}
klao@286
    88
klao@286
    89
    T operator[](const K&) const { return v; }
klao@286
    90
    void set(const K&, const T&) {}
klao@286
    91
klao@286
    92
    template<typename T1>
klao@286
    93
    struct rebind {
klao@286
    94
      typedef ConstMap<K,T1> other;
klao@286
    95
    };
klao@286
    96
klao@286
    97
    template<typename T1>
klao@286
    98
    ConstMap(const ConstMap<K,T1> &, const T &_v) : v(_v) {}
klao@286
    99
  };
klao@286
   100
marci@890
   101
  //to document later
marci@890
   102
  template<typename T, T v>
marci@890
   103
  struct Const { };
marci@890
   104
  //to document later
marci@890
   105
  template<typename K, typename V, V v>
marci@890
   106
  class ConstMap<K, Const<V, v> > : public MapBase<K, V>
marci@890
   107
  {
marci@890
   108
  public:
marci@890
   109
    ConstMap() { }
marci@890
   110
    V operator[](const K&) const { return v; }
marci@890
   111
    void set(const K&, const V&) { }
marci@890
   112
  };
klao@286
   113
klao@286
   114
  /// \c std::map wrapper
klao@286
   115
klao@286
   116
  /// This is essentially a wrapper for \c std::map. With addition that
alpar@987
   117
  /// you can specify a default value different from \c Value() .
klao@286
   118
  ///
klao@286
   119
  /// \todo Provide allocator parameter...
alpar@987
   120
  template <typename K, typename T, typename Compare = std::less<K> >
alpar@987
   121
  class StdMap : public std::map<K,T,Compare> {
alpar@987
   122
    typedef std::map<K,T,Compare> parent;
klao@286
   123
    T v;
klao@286
   124
    typedef typename parent::value_type PairType;
klao@286
   125
klao@286
   126
  public:
alpar@987
   127
    typedef K Key;
alpar@987
   128
    typedef T Value;
alpar@987
   129
    typedef T& Reference;
alpar@987
   130
    typedef const T& ConstReference;
klao@286
   131
klao@286
   132
klao@345
   133
    StdMap() : v() {}
klao@286
   134
    /// Constructor with specified default value
klao@286
   135
    StdMap(const T& _v) : v(_v) {}
klao@286
   136
klao@286
   137
    /// \brief Constructs the map from an appropriate std::map.
klao@286
   138
    ///
klao@286
   139
    /// \warning Inefficient: copies the content of \c m !
klao@286
   140
    StdMap(const parent &m) : parent(m) {}
klao@286
   141
    /// \brief Constructs the map from an appropriate std::map, and explicitly
klao@286
   142
    /// specifies a default value.
klao@286
   143
    ///
klao@286
   144
    /// \warning Inefficient: copies the content of \c m !
klao@286
   145
    StdMap(const parent &m, const T& _v) : parent(m), v(_v) {}
klao@286
   146
    
klao@286
   147
    template<typename T1, typename Comp1>
marci@389
   148
    StdMap(const StdMap<Key,T1,Comp1> &m, const T &_v) { 
marci@389
   149
      //FIXME; 
marci@389
   150
    }
klao@286
   151
alpar@987
   152
    Reference operator[](const Key &k) {
klao@346
   153
      return insert(PairType(k,v)).first -> second;
klao@286
   154
    }
alpar@987
   155
    ConstReference operator[](const Key &k) const {
marci@389
   156
      typename parent::iterator i = lower_bound(k);
beckerjc@391
   157
      if (i == parent::end() || parent::key_comp()(k, (*i).first))
klao@286
   158
	return v;
klao@286
   159
      return (*i).second;
klao@286
   160
    }
klao@345
   161
    void set(const Key &k, const T &t) {
klao@346
   162
      parent::operator[](k) = t;
klao@345
   163
    }
klao@286
   164
klao@286
   165
    /// Changes the default value of the map.
klao@286
   166
    /// \return Returns the previous default value.
klao@286
   167
    ///
alpar@805
   168
    /// \warning The value of some keys (which has already been queried, but
klao@286
   169
    /// the value has been unchanged from the default) may change!
klao@286
   170
    T setDefault(const T &_v) { T old=v; v=_v; return old; }
klao@286
   171
klao@286
   172
    template<typename T1>
klao@286
   173
    struct rebind {
klao@286
   174
      typedef StdMap<Key,T1,Compare> other;
klao@286
   175
    };
klao@286
   176
  };
alpar@1041
   177
alpar@1041
   178
alpar@1041
   179
  ///Sum of two maps
alpar@1041
   180
alpar@1041
   181
  ///This \ref concept::ReadMap "read only map" returns the sum of the two
alpar@1041
   182
  ///given maps. Its \c Key and \c Value will be inherited from \c M1.
alpar@1041
   183
  ///The \c Key and \c Value of M2 must be convertible to those of \c M1.
alpar@1041
   184
alpar@1041
   185
  template<class M1,class M2> 
alpar@1041
   186
  class AddMap
alpar@1041
   187
  {
alpar@1041
   188
    const M1 &m1;
alpar@1041
   189
    const M2 &m2;
alpar@1041
   190
  public:
alpar@1041
   191
    typedef typename M1::Key Key;
alpar@1041
   192
    typedef typename M1::Value Value;
alpar@1041
   193
alpar@1041
   194
    ///Constructor
alpar@1041
   195
alpar@1041
   196
    ///\e
alpar@1041
   197
    ///
alpar@1041
   198
    AddMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
alpar@1044
   199
    Value operator[](Key k) const {return m1[k]+m2[k];}
alpar@1041
   200
  };
alpar@1041
   201
  
alpar@1041
   202
  ///Returns an \ref AddMap class
alpar@1041
   203
alpar@1041
   204
  ///This function just returns an \ref AddMap class.
alpar@1041
   205
  ///\todo How to call these type of functions?
alpar@1041
   206
  ///
alpar@1041
   207
  ///\relates AddMap
alpar@1041
   208
  ///\todo Wrong scope in Doxygen when \c \\relates is used
alpar@1041
   209
  template<class M1,class M2> 
alpar@1041
   210
  inline AddMap<M1,M2> addMap(const M1 &m1,const M2 &m2) 
alpar@1041
   211
  {
alpar@1041
   212
    return AddMap<M1,M2>(m1,m2);
alpar@1041
   213
  }
alpar@1041
   214
alpar@1070
   215
  ///Shift a maps with a constant.
alpar@1070
   216
alpar@1070
   217
  ///This \ref concept::ReadMap "read only map" returns the sum of the
alpar@1070
   218
  ///given map and a constant value.
alpar@1070
   219
  ///Its \c Key and \c Value is inherited from \c M.
alpar@1070
   220
  ///
alpar@1070
   221
  ///Actually,
alpar@1070
   222
  ///\code
alpar@1070
   223
  ///  ShiftMap<X> sh(x,v);
alpar@1070
   224
  ///\endcode
alpar@1070
   225
  ///it is equivalent with
alpar@1070
   226
  ///\code
alpar@1070
   227
  ///  ConstMap<X::Key, X::Value> c_tmp(v);
alpar@1070
   228
  ///  AddMap<X, ConstMap<X::Key, X::Value> > sh(x,v);
alpar@1070
   229
  ///\endcode
alpar@1070
   230
  template<class M> 
alpar@1070
   231
  class ShiftMap
alpar@1070
   232
  {
alpar@1070
   233
    const M &m;
alpar@1070
   234
    typename M::Value v;
alpar@1070
   235
  public:
alpar@1070
   236
    typedef typename M::Key Key;
alpar@1070
   237
    typedef typename M::Value Value;
alpar@1070
   238
alpar@1070
   239
    ///Constructor
alpar@1070
   240
alpar@1070
   241
    ///Constructor
alpar@1070
   242
    ///\param _m is the undelying map
alpar@1070
   243
    ///\param _v is the shift value
alpar@1070
   244
    ShiftMap(const M &_m,const Value &_v ) : m(_m), v(_v) {};
alpar@1070
   245
    Value operator[](Key k) const {return m[k]+v;}
alpar@1070
   246
  };
alpar@1070
   247
  
alpar@1070
   248
  ///Returns an \ref ShiftMap class
alpar@1070
   249
alpar@1070
   250
  ///This function just returns an \ref ShiftMap class.
alpar@1070
   251
  ///\relates ShiftMap
alpar@1070
   252
  ///\todo A better name is required.
alpar@1070
   253
  template<class M> 
alpar@1070
   254
  inline ShiftMap<M> shiftMap(const M &m,const typename M::Value &v) 
alpar@1070
   255
  {
alpar@1070
   256
    return ShiftMap<M>(m,v);
alpar@1070
   257
  }
alpar@1070
   258
alpar@1041
   259
  ///Difference of two maps
alpar@1041
   260
alpar@1041
   261
  ///This \ref concept::ReadMap "read only map" returns the difference
alpar@1041
   262
  ///of the values returned by the two
alpar@1041
   263
  ///given maps. Its \c Key and \c Value will be inherited from \c M1.
alpar@1041
   264
  ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
alpar@1041
   265
alpar@1041
   266
  template<class M1,class M2> 
alpar@1041
   267
  class SubMap
alpar@1041
   268
  {
alpar@1041
   269
    const M1 &m1;
alpar@1041
   270
    const M2 &m2;
alpar@1041
   271
  public:
alpar@1041
   272
    typedef typename M1::Key Key;
alpar@1041
   273
    typedef typename M1::Value Value;
alpar@1041
   274
alpar@1041
   275
    ///Constructor
alpar@1041
   276
alpar@1041
   277
    ///\e
alpar@1041
   278
    ///
alpar@1041
   279
    SubMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
alpar@1044
   280
    Value operator[](Key k) const {return m1[k]-m2[k];}
alpar@1041
   281
  };
alpar@1041
   282
  
alpar@1041
   283
  ///Returns a \ref SubMap class
alpar@1041
   284
alpar@1041
   285
  ///This function just returns a \ref SubMap class.
alpar@1041
   286
  ///
alpar@1041
   287
  ///\relates SubMap
alpar@1041
   288
  template<class M1,class M2> 
alpar@1041
   289
  inline SubMap<M1,M2> subMap(const M1 &m1,const M2 &m2) 
alpar@1041
   290
  {
alpar@1041
   291
    return SubMap<M1,M2>(m1,m2);
alpar@1041
   292
  }
alpar@1041
   293
alpar@1041
   294
  ///Product of two maps
alpar@1041
   295
alpar@1041
   296
  ///This \ref concept::ReadMap "read only map" returns the product of the
alpar@1041
   297
  ///values returned by the two
alpar@1041
   298
  ///given
alpar@1041
   299
  ///maps. Its \c Key and \c Value will be inherited from \c M1.
alpar@1041
   300
  ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
alpar@1041
   301
alpar@1041
   302
  template<class M1,class M2> 
alpar@1041
   303
  class MulMap
alpar@1041
   304
  {
alpar@1041
   305
    const M1 &m1;
alpar@1041
   306
    const M2 &m2;
alpar@1041
   307
  public:
alpar@1041
   308
    typedef typename M1::Key Key;
alpar@1041
   309
    typedef typename M1::Value Value;
alpar@1041
   310
alpar@1041
   311
    ///Constructor
alpar@1041
   312
alpar@1041
   313
    ///\e
alpar@1041
   314
    ///
alpar@1041
   315
    MulMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
alpar@1044
   316
    Value operator[](Key k) const {return m1[k]*m2[k];}
alpar@1041
   317
  };
alpar@1041
   318
  
alpar@1041
   319
  ///Returns a \ref MulMap class
alpar@1041
   320
alpar@1041
   321
  ///This function just returns a \ref MulMap class.
alpar@1041
   322
  ///\relates MulMap
alpar@1041
   323
  template<class M1,class M2> 
alpar@1041
   324
  inline MulMap<M1,M2> mulMap(const M1 &m1,const M2 &m2) 
alpar@1041
   325
  {
alpar@1041
   326
    return MulMap<M1,M2>(m1,m2);
alpar@1041
   327
  }
alpar@1041
   328
 
alpar@1070
   329
  ///Scale a maps with a constant.
alpar@1070
   330
alpar@1070
   331
  ///This \ref concept::ReadMap "read only map" returns the value of the
alpar@1070
   332
  ///given map multipied with a constant value.
alpar@1070
   333
  ///Its \c Key and \c Value is inherited from \c M.
alpar@1070
   334
  ///
alpar@1070
   335
  ///Actually,
alpar@1070
   336
  ///\code
alpar@1070
   337
  ///  ScaleMap<X> sc(x,v);
alpar@1070
   338
  ///\endcode
alpar@1070
   339
  ///it is equivalent with
alpar@1070
   340
  ///\code
alpar@1070
   341
  ///  ConstMap<X::Key, X::Value> c_tmp(v);
alpar@1070
   342
  ///  MulMap<X, ConstMap<X::Key, X::Value> > sc(x,v);
alpar@1070
   343
  ///\endcode
alpar@1070
   344
  template<class M> 
alpar@1070
   345
  class ScaleMap
alpar@1070
   346
  {
alpar@1070
   347
    const M &m;
alpar@1070
   348
    typename M::Value v;
alpar@1070
   349
  public:
alpar@1070
   350
    typedef typename M::Key Key;
alpar@1070
   351
    typedef typename M::Value Value;
alpar@1070
   352
alpar@1070
   353
    ///Constructor
alpar@1070
   354
alpar@1070
   355
    ///Constructor
alpar@1070
   356
    ///\param _m is the undelying map
alpar@1070
   357
    ///\param _v is the scaling value
alpar@1070
   358
    ScaleMap(const M &_m,const Value &_v ) : m(_m), v(_v) {};
alpar@1070
   359
    Value operator[](Key k) const {return m[k]*v;}
alpar@1070
   360
  };
alpar@1070
   361
  
alpar@1070
   362
  ///Returns an \ref ScaleMap class
alpar@1070
   363
alpar@1070
   364
  ///This function just returns an \ref ScaleMap class.
alpar@1070
   365
  ///\relates ScaleMap
alpar@1070
   366
  ///\todo A better name is required.
alpar@1070
   367
  template<class M> 
alpar@1070
   368
  inline ScaleMap<M> scaleMap(const M &m,const typename M::Value &v) 
alpar@1070
   369
  {
alpar@1070
   370
    return ScaleMap<M>(m,v);
alpar@1070
   371
  }
alpar@1070
   372
alpar@1041
   373
  ///Quotient of two maps
alpar@1041
   374
alpar@1041
   375
  ///This \ref concept::ReadMap "read only map" returns the quotient of the
alpar@1041
   376
  ///values returned by the two
alpar@1041
   377
  ///given maps. Its \c Key and \c Value will be inherited from \c M1.
alpar@1041
   378
  ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
alpar@1041
   379
alpar@1041
   380
  template<class M1,class M2> 
alpar@1041
   381
  class DivMap
alpar@1041
   382
  {
alpar@1041
   383
    const M1 &m1;
alpar@1041
   384
    const M2 &m2;
alpar@1041
   385
  public:
alpar@1041
   386
    typedef typename M1::Key Key;
alpar@1041
   387
    typedef typename M1::Value Value;
alpar@1041
   388
alpar@1041
   389
    ///Constructor
alpar@1041
   390
alpar@1041
   391
    ///\e
alpar@1041
   392
    ///
alpar@1041
   393
    DivMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
alpar@1044
   394
    Value operator[](Key k) const {return m1[k]/m2[k];}
alpar@1041
   395
  };
alpar@1041
   396
  
alpar@1041
   397
  ///Returns a \ref DivMap class
alpar@1041
   398
alpar@1041
   399
  ///This function just returns a \ref DivMap class.
alpar@1041
   400
  ///\relates DivMap
alpar@1041
   401
  template<class M1,class M2> 
alpar@1041
   402
  inline DivMap<M1,M2> divMap(const M1 &m1,const M2 &m2) 
alpar@1041
   403
  {
alpar@1041
   404
    return DivMap<M1,M2>(m1,m2);
alpar@1041
   405
  }
alpar@1041
   406
  
alpar@1041
   407
  ///Composition of two maps
alpar@1041
   408
alpar@1041
   409
  ///This \ref concept::ReadMap "read only map" returns the composition of
alpar@1041
   410
  ///two
alpar@1041
   411
  ///given maps. That is to say, if \c m1 is of type \c M1 and \c m2 is
alpar@1041
   412
  ///of \c M2,
alpar@1041
   413
  ///then for
alpar@1041
   414
  ///\code
alpar@1041
   415
  ///  ComposeMap<M1,M2> cm(m1,m2);
alpar@1041
   416
  ///\endcode
alpar@1044
   417
  /// <tt>cm[x]</tt> will be equal to <tt>m1[m2[x]]</tt>
alpar@1041
   418
  ///
alpar@1041
   419
  ///Its \c Key is inherited from \c M2 and its \c Value is from
alpar@1041
   420
  ///\c M1.
alpar@1041
   421
  ///The \c M2::Value must be convertible to \c M1::Key.
alpar@1041
   422
  ///\todo Check the requirements.
alpar@1041
   423
alpar@1041
   424
  template<class M1,class M2> 
alpar@1041
   425
  class ComposeMap
alpar@1041
   426
  {
alpar@1041
   427
    const M1 &m1;
alpar@1041
   428
    const M2 &m2;
alpar@1041
   429
  public:
alpar@1041
   430
    typedef typename M2::Key Key;
alpar@1041
   431
    typedef typename M1::Value Value;
alpar@1041
   432
alpar@1041
   433
    ///Constructor
alpar@1041
   434
alpar@1041
   435
    ///\e
alpar@1041
   436
    ///
alpar@1041
   437
    ComposeMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
alpar@1044
   438
    Value operator[](Key k) const {return m1[m2[k]];}
alpar@1041
   439
  };
alpar@1041
   440
  
alpar@1041
   441
  ///Returns a \ref ComposeMap class
alpar@1041
   442
alpar@1041
   443
  ///This function just returns a \ref ComposeMap class.
alpar@1041
   444
  ///\relates ComposeMap
alpar@1041
   445
  template<class M1,class M2> 
alpar@1041
   446
  inline ComposeMap<M1,M2> composeMap(const M1 &m1,const M2 &m2) 
alpar@1041
   447
  {
alpar@1041
   448
    return ComposeMap<M1,M2>(m1,m2);
alpar@1041
   449
  }
alpar@1041
   450
alpar@1041
   451
  ///Negative value of a map
alpar@1041
   452
alpar@1041
   453
  ///This \ref concept::ReadMap "read only map" returns the negative
alpar@1041
   454
  ///value of the
alpar@1041
   455
  ///value returned by the
alpar@1041
   456
  ///given map. Its \c Key and \c Value will be inherited from \c M.
alpar@1041
   457
  ///The unary \c - operator must be defined for \c Value, of course.
alpar@1041
   458
alpar@1041
   459
  template<class M> 
alpar@1041
   460
  class NegMap
alpar@1041
   461
  {
alpar@1041
   462
    const M &m;
alpar@1041
   463
  public:
alpar@1041
   464
    typedef typename M::Key Key;
alpar@1041
   465
    typedef typename M::Value Value;
alpar@1041
   466
alpar@1041
   467
    ///Constructor
alpar@1041
   468
alpar@1041
   469
    ///\e
alpar@1041
   470
    ///
alpar@1041
   471
    NegMap(const M &_m) : m(_m) {};
alpar@1044
   472
    Value operator[](Key k) const {return -m[k];}
alpar@1041
   473
  };
alpar@1041
   474
  
alpar@1041
   475
  ///Returns a \ref NegMap class
alpar@1041
   476
alpar@1041
   477
  ///This function just returns a \ref NegMap class.
alpar@1041
   478
  ///\relates NegMap
alpar@1041
   479
  template<class M> 
alpar@1041
   480
  inline NegMap<M> negMap(const M &m) 
alpar@1041
   481
  {
alpar@1041
   482
    return NegMap<M>(m);
alpar@1041
   483
  }
alpar@1041
   484
alpar@1041
   485
alpar@1041
   486
  ///Absolute value of a map
alpar@1041
   487
alpar@1041
   488
  ///This \ref concept::ReadMap "read only map" returns the absolute value
alpar@1041
   489
  ///of the
alpar@1041
   490
  ///value returned by the
alpar@1044
   491
  ///given map. Its \c Key and \c Value will be inherited
alpar@1044
   492
  ///from <tt>M</tt>. <tt>Value</tt>
alpar@1044
   493
  ///must be comparable to <tt>0</tt> and the unary <tt>-</tt>
alpar@1044
   494
  ///operator must be defined for it, of course.
alpar@1044
   495
  ///
alpar@1044
   496
  ///\bug We need a unified way to handle the situation below:
alpar@1044
   497
  ///\code
alpar@1044
   498
  ///  struct _UnConvertible {};
alpar@1044
   499
  ///  template<class A> inline A t_abs(A a) {return _UnConvertible();}
alpar@1044
   500
  ///  template<> inline int t_abs<>(int n) {return abs(n);}
alpar@1044
   501
  ///  template<> inline long int t_abs<>(long int n) {return labs(n);}
alpar@1044
   502
  ///  template<> inline long long int t_abs<>(long long int n) {return ::llabs(n);}
alpar@1044
   503
  ///  template<> inline float t_abs<>(float n) {return fabsf(n);}
alpar@1044
   504
  ///  template<> inline double t_abs<>(double n) {return fabs(n);}
alpar@1044
   505
  ///  template<> inline long double t_abs<>(long double n) {return fabsl(n);}
alpar@1044
   506
  ///\endcode
alpar@1044
   507
  
alpar@1041
   508
alpar@1041
   509
  template<class M> 
alpar@1041
   510
  class AbsMap
alpar@1041
   511
  {
alpar@1041
   512
    const M &m;
alpar@1041
   513
  public:
alpar@1041
   514
    typedef typename M::Key Key;
alpar@1041
   515
    typedef typename M::Value Value;
alpar@1041
   516
alpar@1041
   517
    ///Constructor
alpar@1041
   518
alpar@1041
   519
    ///\e
alpar@1041
   520
    ///
alpar@1041
   521
    AbsMap(const M &_m) : m(_m) {};
alpar@1044
   522
    Value operator[](Key k) const {Value tmp=m[k]; return tmp>=0?tmp:-tmp;}
alpar@1041
   523
  };
alpar@1041
   524
  
alpar@1041
   525
  ///Returns a \ref AbsMap class
alpar@1041
   526
alpar@1041
   527
  ///This function just returns a \ref AbsMap class.
alpar@1041
   528
  ///\relates AbsMap
alpar@1041
   529
  template<class M> 
alpar@1041
   530
  inline AbsMap<M> absMap(const M &m) 
alpar@1041
   531
  {
alpar@1041
   532
    return AbsMap<M>(m);
alpar@1041
   533
  }
alpar@1041
   534
alpar@1041
   535
  /// @}
klao@286
   536
  
klao@286
   537
}
alpar@1041
   538
alpar@1041
   539
alpar@921
   540
#endif // LEMON_MAPS_H