lemon/iterable_maps.h
author deba
Fri, 14 Oct 2005 10:48:34 +0000
changeset 1719 674182524bd9
parent 1677 a9f923a4d998
child 1752 dce1f28ac595
permissions -rw-r--r--
Traits moved to own file
Tag for reference maps
Possibility to handle proper the return type
of the operator[]() const -- value or reference
alpar@1677
     1
/* -*- C++ -*-
alpar@1677
     2
 * lemon/iterable_maps.h - Part of LEMON, a generic C++ optimization library
alpar@1677
     3
 *
alpar@1677
     4
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1677
     5
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@1677
     6
 *
alpar@1677
     7
 * Permission to use, modify and distribute this software is granted
alpar@1677
     8
 * provided that this copyright notice appears in all copies. For
alpar@1677
     9
 * precise terms see the accompanying LICENSE file.
alpar@1677
    10
 *
alpar@1677
    11
 * This software is provided "AS IS" with no warranty of any kind,
alpar@1677
    12
 * express or implied, and with no claim as to its suitability for any
alpar@1677
    13
 * purpose.
alpar@1677
    14
 *
alpar@1677
    15
 */
alpar@1677
    16
alpar@1677
    17
#include <vector>
alpar@1677
    18
#include <limits>
alpar@1677
    19
alpar@1677
    20
///\ingroup maps
alpar@1677
    21
///\file
alpar@1677
    22
///\brief Maps that makes it possible to iterate through the keys having
alpar@1677
    23
///a certain value
alpar@1677
    24
///
alpar@1677
    25
///
alpar@1677
    26
alpar@1677
    27
alpar@1677
    28
namespace lemon {
alpar@1677
    29
  
alpar@1677
    30
  ///\todo This is only a static map!
alpar@1677
    31
  ///\param BaseMap is an interger map.
alpar@1677
    32
  template<class BaseMap>
alpar@1677
    33
  class IterableBoolMap
alpar@1677
    34
  {
alpar@1677
    35
  public:
alpar@1677
    36
  
alpar@1677
    37
    typedef typename BaseMap::Key Key;
alpar@1677
    38
    typedef bool Value;
alpar@1677
    39
  
alpar@1677
    40
    friend class RefType;
alpar@1677
    41
    friend class FalseIt;
alpar@1677
    42
    friend class TrueIt;
alpar@1677
    43
alpar@1677
    44
  private:
alpar@1677
    45
    BaseMap &cref;
alpar@1677
    46
    std::vector<Key> vals;
alpar@1677
    47
    int sep;           //map[e] is true <=> cref[e]>=sep
alpar@1677
    48
  
alpar@1677
    49
    bool isTrue(Key k) {return cref[k]>=sep;}
alpar@1677
    50
    void swap(Key k, int s) 
alpar@1677
    51
    {
alpar@1677
    52
      int ti=cref[k];
alpar@1677
    53
      Key tk=vals[s];
alpar@1677
    54
      cref[k]=s; vals[s]=k;
alpar@1677
    55
      cref[tk]=ti; vals[ti]=tk;
alpar@1677
    56
    }  
alpar@1677
    57
alpar@1677
    58
    void setTrue(Key k) { if(cref[k]<sep) { sep--; swap(k,sep); } }
alpar@1677
    59
    void setFalse(Key k) { if(cref[k]>=sep) { swap(k,sep); sep++; } }
alpar@1677
    60
  
alpar@1677
    61
  public:
alpar@1677
    62
    ///\e
alpar@1677
    63
    void set(Key k,Value v) { if(v) setTrue(k); else setFalse(k);}
alpar@1677
    64
alpar@1677
    65
    ///\e
alpar@1677
    66
    class FalseIt
alpar@1677
    67
    {
alpar@1677
    68
      const IterableBoolMap &M;
alpar@1677
    69
      int i;
alpar@1677
    70
    public:
alpar@1677
    71
      explicit FalseIt(const IterableBoolMap &_M) : M(_M), i(0) { }
alpar@1677
    72
      FalseIt(Invalid)
alpar@1677
    73
	: M(*((IterableBoolMap*)(0))), i(std::numeric_limits<int>::max()) { }
alpar@1677
    74
      FalseIt &operator++() { ++i; return *this;}
alpar@1677
    75
      operator Key() const { return i<M.sep ? M.vals[i] : INVALID; }
alpar@1677
    76
      bool operator !=(Invalid) const { return i<M.sep; }
alpar@1677
    77
      bool operator ==(Invalid) const { return i>=M.sep; }
alpar@1677
    78
    };
alpar@1677
    79
    ///\e
alpar@1677
    80
    class TrueIt
alpar@1677
    81
    {
alpar@1677
    82
      const IterableBoolMap &M;
alpar@1677
    83
      int i;
alpar@1677
    84
    public:
alpar@1677
    85
      explicit TrueIt(const IterableBoolMap &_M)
alpar@1677
    86
	: M(_M), i(M.vals.size()-1) { }
alpar@1677
    87
      TrueIt(Invalid)
alpar@1677
    88
	: M(*((IterableBoolMap*)(0))), i(-1) { }
alpar@1677
    89
      TrueIt &operator++() { --i; return *this;}
alpar@1677
    90
      operator Key() const { return i>=M.sep ? M.vals[i] : INVALID; }
alpar@1677
    91
      bool operator !=(Invalid) const { return i>=M.sep; }
alpar@1677
    92
      bool operator ==(Invalid) const { return i<M.sep; }
alpar@1677
    93
    };
alpar@1677
    94
  
alpar@1677
    95
    ///\e
alpar@1677
    96
    class RefType
alpar@1677
    97
    {
alpar@1677
    98
      IterableBoolMap &M;
alpar@1677
    99
      Key k;
alpar@1677
   100
    public:
alpar@1677
   101
      RefType(IterableBoolMap &_M,Key _k) : M(_M), k(_k) { }
alpar@1677
   102
    
alpar@1677
   103
      operator Value() const 
alpar@1677
   104
      {
alpar@1677
   105
	return M.isTrue(k);
alpar@1677
   106
      }
alpar@1677
   107
      Value operator = (Value v) const { M.set(k,v); return v; }
alpar@1677
   108
    };
alpar@1677
   109
  
alpar@1677
   110
  public:
alpar@1677
   111
    explicit IterableBoolMap(BaseMap &_m,bool init=false) : cref(_m)
alpar@1677
   112
    {
alpar@1677
   113
      sep=0;
alpar@1677
   114
      for(typename BaseMap::MapSet::iterator i=cref.mapSet().begin();
alpar@1677
   115
	  i!=cref.mapSet().end();
alpar@1677
   116
	  ++i) {
alpar@1677
   117
	i->second=sep;
alpar@1677
   118
	vals.push_back(i->first);
alpar@1677
   119
	sep++;
alpar@1677
   120
      }
alpar@1677
   121
      if(init) sep=0;
alpar@1677
   122
    }
alpar@1677
   123
    RefType operator[] (Key k) { return RefType(*this,k);}  
alpar@1677
   124
    Value operator[] (Key k) const { return isTrue(k);}  
alpar@1677
   125
  };
alpar@1677
   126
alpar@1677
   127
alpar@1677
   128
alpar@1677
   129
alpar@1677
   130
  /// \addtogroup graph_maps
alpar@1677
   131
  /// @{
alpar@1677
   132
alpar@1677
   133
  /// Iterable bool NodeMap
alpar@1677
   134
alpar@1677
   135
  /// This map can be used in the same way
alpar@1677
   136
  /// as the standard NodeMap<bool> of the
alpar@1677
   137
  /// given graph \c Graph. 
alpar@1677
   138
  /// In addition, this class provides two iterators called \ref TrueIt
alpar@1677
   139
  /// and \ref FalseIt to iterate through the "true" and "false" nodes.
alpar@1677
   140
  template <class Graph>
alpar@1677
   141
  class IterableBoolNodeMap
alpar@1677
   142
  {
deba@1685
   143
    typename Graph::template NodeMap<int> cmap;
alpar@1677
   144
  
alpar@1677
   145
  public:
alpar@1677
   146
  
deba@1685
   147
    typedef IterableBoolMap<typename Graph::template NodeMap<int> > BimType;
alpar@1677
   148
    BimType imap;
alpar@1677
   149
alpar@1677
   150
alpar@1677
   151
    typedef typename BimType::RefType RefType;
alpar@1677
   152
    typedef typename Graph::Node Key;
alpar@1677
   153
    typedef bool Value;
alpar@1677
   154
  
alpar@1677
   155
    friend class FalseIt;
alpar@1677
   156
    friend class TrueIt;
alpar@1677
   157
  
alpar@1677
   158
    ///\e
alpar@1677
   159
    IterableBoolNodeMap(const Graph &g,bool b=false) : cmap(g), imap(cmap,b) {}
alpar@1677
   160
alpar@1677
   161
  public:
alpar@1677
   162
    ///\e
alpar@1677
   163
    void set(Key k, bool v) { imap.set(k,v);}
alpar@1677
   164
#ifdef DOXYGEN
alpar@1677
   165
    ///\e
alpar@1677
   166
    bool &operator[](Key k) { return imap[k];}  
alpar@1677
   167
    ///\e
alpar@1677
   168
    const bool &operator[](Key k) const { return imap[k];}  
alpar@1677
   169
#else
alpar@1677
   170
    Value operator[](Key k) const { return imap[k];}  
alpar@1677
   171
    RefType operator[](Key k) { return imap[k];}  
alpar@1677
   172
#endif
alpar@1677
   173
    ///Iterator for the "false" nodes
alpar@1677
   174
    class FalseIt : public BimType::FalseIt
alpar@1677
   175
    {
alpar@1677
   176
    public:
alpar@1677
   177
      explicit FalseIt(const IterableBoolNodeMap &m)
alpar@1677
   178
	: BimType::FalseIt(m.imap) { }
alpar@1677
   179
      FalseIt(Invalid i) : BimType::FalseIt(i) { }
alpar@1677
   180
    };
alpar@1677
   181
    ///Iterator for the "true" nodes
alpar@1677
   182
    class TrueIt : public BimType::TrueIt
alpar@1677
   183
    {
alpar@1677
   184
    public:
alpar@1677
   185
      explicit TrueIt(const IterableBoolNodeMap &m)
alpar@1677
   186
	: BimType::TrueIt(m.imap) { }
alpar@1677
   187
      TrueIt(Invalid i) : BimType::TrueIt(i) { }
alpar@1677
   188
    };  
alpar@1677
   189
  };
alpar@1677
   190
alpar@1677
   191
  /// Iterable bool EdgeMap
alpar@1677
   192
alpar@1677
   193
  /// This map can be used in the same way
alpar@1677
   194
  /// as the standard EdgeMap<bool> of the
alpar@1677
   195
  /// given graph \c Graph. 
alpar@1677
   196
  /// In addition, this class provides two iterators called \ref TrueIt
alpar@1677
   197
  /// and \ref FalseIt to iterate through the "true" and "false" edges.
alpar@1677
   198
  template <class Graph>
alpar@1677
   199
  class IterableBoolEdgeMap
alpar@1677
   200
  {
deba@1685
   201
    typename Graph::template EdgeMap<int> cmap;
alpar@1677
   202
  
alpar@1677
   203
  public:
alpar@1677
   204
  
deba@1685
   205
    typedef IterableBoolMap<typename Graph::template EdgeMap<int> > BimType;
alpar@1677
   206
    BimType imap;
alpar@1677
   207
alpar@1677
   208
alpar@1677
   209
    typedef typename BimType::RefType RefType;
alpar@1677
   210
    typedef typename Graph::Edge Key;
alpar@1677
   211
    typedef bool Value;
alpar@1677
   212
  
alpar@1677
   213
    friend class FalseIt;
alpar@1677
   214
    friend class TrueIt;
alpar@1677
   215
  
alpar@1677
   216
    ///\e
alpar@1677
   217
    IterableBoolEdgeMap(const Graph &g,bool b=false) : cmap(g), imap(cmap,b) {}
alpar@1677
   218
alpar@1677
   219
  public:
alpar@1677
   220
    ///\e
alpar@1677
   221
    void set(Key k, bool v) { imap.set(k,v);}
alpar@1677
   222
#ifdef DOXYGEN
alpar@1677
   223
    ///\e
alpar@1677
   224
    bool &operator[](Key k) { return imap[k];}  
alpar@1677
   225
    ///\e
alpar@1677
   226
    const bool &operator[](Key k) const { return imap[k];}  
alpar@1677
   227
#else
alpar@1677
   228
    Value operator[](Key k) const { return imap[k];}  
alpar@1677
   229
    RefType operator[](Key k) { return imap[k];}  
alpar@1677
   230
#endif
alpar@1677
   231
    ///Iterator for the "false" edges
alpar@1677
   232
    class FalseIt : public BimType::FalseIt
alpar@1677
   233
    {
alpar@1677
   234
    public:
alpar@1677
   235
      explicit FalseIt(const IterableBoolEdgeMap &m)
alpar@1677
   236
	: BimType::FalseIt(m.imap) { }
alpar@1677
   237
      FalseIt(Invalid i) : BimType::FalseIt(i) { }
alpar@1677
   238
    };
alpar@1677
   239
    ///Iterator for the "true" edges
alpar@1677
   240
    class TrueIt : public BimType::TrueIt
alpar@1677
   241
    {
alpar@1677
   242
    public:
alpar@1677
   243
      explicit TrueIt(const IterableBoolEdgeMap &m)
alpar@1677
   244
	: BimType::TrueIt(m.imap) { }
alpar@1677
   245
      TrueIt(Invalid i) : BimType::TrueIt(i) { }
alpar@1677
   246
    };  
alpar@1677
   247
  };
alpar@1677
   248
alpar@1677
   249
  /// @}
alpar@1677
   250
}