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