alpar@1677: /* -*- C++ -*-
alpar@1677:  * lemon/iterable_maps.h - Part of LEMON, a generic C++ optimization library
alpar@1677:  *
alpar@1677:  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1677:  * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@1677:  *
alpar@1677:  * Permission to use, modify and distribute this software is granted
alpar@1677:  * provided that this copyright notice appears in all copies. For
alpar@1677:  * precise terms see the accompanying LICENSE file.
alpar@1677:  *
alpar@1677:  * This software is provided "AS IS" with no warranty of any kind,
alpar@1677:  * express or implied, and with no claim as to its suitability for any
alpar@1677:  * purpose.
alpar@1677:  *
alpar@1677:  */
alpar@1677: 
alpar@1677: #include <vector>
alpar@1677: #include <limits>
alpar@1677: 
alpar@1677: ///\ingroup maps
alpar@1677: ///\file
alpar@1677: ///\brief Maps that makes it possible to iterate through the keys having
alpar@1677: ///a certain value
alpar@1677: ///
alpar@1677: ///
alpar@1677: 
alpar@1677: 
alpar@1677: namespace lemon {
alpar@1677:   
alpar@1677:   ///\todo This is only a static map!
alpar@1677:   ///\param BaseMap is an interger map.
alpar@1677:   template<class BaseMap>
alpar@1677:   class IterableBoolMap
alpar@1677:   {
alpar@1677:   public:
alpar@1677:   
alpar@1677:     typedef typename BaseMap::Key Key;
alpar@1677:     typedef bool Value;
alpar@1677:   
alpar@1677:     friend class RefType;
alpar@1677:     friend class FalseIt;
alpar@1677:     friend class TrueIt;
alpar@1677: 
alpar@1677:   private:
alpar@1677:     BaseMap &cref;
alpar@1677:     std::vector<Key> vals;
alpar@1677:     int sep;           //map[e] is true <=> cref[e]>=sep
alpar@1677:   
alpar@1677:     bool isTrue(Key k) {return cref[k]>=sep;}
alpar@1677:     void swap(Key k, int s) 
alpar@1677:     {
alpar@1677:       int ti=cref[k];
alpar@1677:       Key tk=vals[s];
alpar@1677:       cref[k]=s; vals[s]=k;
alpar@1677:       cref[tk]=ti; vals[ti]=tk;
alpar@1677:     }  
alpar@1677: 
alpar@1677:     void setTrue(Key k) { if(cref[k]<sep) { sep--; swap(k,sep); } }
alpar@1677:     void setFalse(Key k) { if(cref[k]>=sep) { swap(k,sep); sep++; } }
alpar@1677:   
alpar@1677:   public:
alpar@1677:     ///\e
alpar@1677:     void set(Key k,Value v) { if(v) setTrue(k); else setFalse(k);}
alpar@1677: 
alpar@1677:     ///\e
alpar@1677:     class FalseIt
alpar@1677:     {
alpar@1677:       const IterableBoolMap &M;
alpar@1677:       int i;
alpar@1677:     public:
alpar@1677:       explicit FalseIt(const IterableBoolMap &_M) : M(_M), i(0) { }
alpar@1677:       FalseIt(Invalid)
alpar@1677: 	: M(*((IterableBoolMap*)(0))), i(std::numeric_limits<int>::max()) { }
alpar@1677:       FalseIt &operator++() { ++i; return *this;}
alpar@1677:       operator Key() const { return i<M.sep ? M.vals[i] : INVALID; }
alpar@1677:       bool operator !=(Invalid) const { return i<M.sep; }
alpar@1677:       bool operator ==(Invalid) const { return i>=M.sep; }
alpar@1677:     };
alpar@1677:     ///\e
alpar@1677:     class TrueIt
alpar@1677:     {
alpar@1677:       const IterableBoolMap &M;
alpar@1677:       int i;
alpar@1677:     public:
alpar@1677:       explicit TrueIt(const IterableBoolMap &_M)
alpar@1677: 	: M(_M), i(M.vals.size()-1) { }
alpar@1677:       TrueIt(Invalid)
alpar@1677: 	: M(*((IterableBoolMap*)(0))), i(-1) { }
alpar@1677:       TrueIt &operator++() { --i; return *this;}
alpar@1677:       operator Key() const { return i>=M.sep ? M.vals[i] : INVALID; }
alpar@1677:       bool operator !=(Invalid) const { return i>=M.sep; }
alpar@1677:       bool operator ==(Invalid) const { return i<M.sep; }
alpar@1677:     };
alpar@1677:   
alpar@1677:     ///\e
alpar@1677:     class RefType
alpar@1677:     {
alpar@1677:       IterableBoolMap &M;
alpar@1677:       Key k;
alpar@1677:     public:
alpar@1677:       RefType(IterableBoolMap &_M,Key _k) : M(_M), k(_k) { }
alpar@1677:     
alpar@1677:       operator Value() const 
alpar@1677:       {
alpar@1677: 	return M.isTrue(k);
alpar@1677:       }
alpar@1677:       Value operator = (Value v) const { M.set(k,v); return v; }
alpar@1677:     };
alpar@1677:   
alpar@1677:   public:
alpar@1677:     explicit IterableBoolMap(BaseMap &_m,bool init=false) : cref(_m)
alpar@1677:     {
alpar@1677:       sep=0;
alpar@1677:       for(typename BaseMap::MapSet::iterator i=cref.mapSet().begin();
alpar@1677: 	  i!=cref.mapSet().end();
alpar@1677: 	  ++i) {
alpar@1677: 	i->second=sep;
alpar@1677: 	vals.push_back(i->first);
alpar@1677: 	sep++;
alpar@1677:       }
alpar@1677:       if(init) sep=0;
alpar@1677:     }
alpar@1677:     RefType operator[] (Key k) { return RefType(*this,k);}  
alpar@1677:     Value operator[] (Key k) const { return isTrue(k);}  
alpar@1677:   };
alpar@1677: 
alpar@1677: 
alpar@1677: 
alpar@1677: 
alpar@1677:   /// \addtogroup graph_maps
alpar@1677:   /// @{
alpar@1677: 
alpar@1677:   /// Iterable bool NodeMap
alpar@1677: 
alpar@1677:   /// This map can be used in the same way
alpar@1677:   /// as the standard NodeMap<bool> of the
alpar@1677:   /// given graph \c Graph. 
alpar@1677:   /// In addition, this class provides two iterators called \ref TrueIt
alpar@1677:   /// and \ref FalseIt to iterate through the "true" and "false" nodes.
alpar@1677:   template <class Graph>
alpar@1677:   class IterableBoolNodeMap
alpar@1677:   {
deba@1685:     typename Graph::template NodeMap<int> cmap;
alpar@1677:   
alpar@1677:   public:
alpar@1677:   
deba@1685:     typedef IterableBoolMap<typename Graph::template NodeMap<int> > BimType;
alpar@1677:     BimType imap;
alpar@1677: 
alpar@1677: 
alpar@1677:     typedef typename BimType::RefType RefType;
alpar@1677:     typedef typename Graph::Node Key;
alpar@1677:     typedef bool Value;
alpar@1677:   
alpar@1677:     friend class FalseIt;
alpar@1677:     friend class TrueIt;
alpar@1677:   
alpar@1677:     ///\e
alpar@1677:     IterableBoolNodeMap(const Graph &g,bool b=false) : cmap(g), imap(cmap,b) {}
alpar@1677: 
alpar@1677:   public:
alpar@1677:     ///\e
alpar@1677:     void set(Key k, bool v) { imap.set(k,v);}
alpar@1677: #ifdef DOXYGEN
alpar@1677:     ///\e
alpar@1677:     bool &operator[](Key k) { return imap[k];}  
alpar@1677:     ///\e
alpar@1677:     const bool &operator[](Key k) const { return imap[k];}  
alpar@1677: #else
alpar@1677:     Value operator[](Key k) const { return imap[k];}  
alpar@1677:     RefType operator[](Key k) { return imap[k];}  
alpar@1677: #endif
alpar@1677:     ///Iterator for the "false" nodes
alpar@1677:     class FalseIt : public BimType::FalseIt
alpar@1677:     {
alpar@1677:     public:
alpar@1677:       explicit FalseIt(const IterableBoolNodeMap &m)
alpar@1677: 	: BimType::FalseIt(m.imap) { }
alpar@1677:       FalseIt(Invalid i) : BimType::FalseIt(i) { }
alpar@1677:     };
alpar@1677:     ///Iterator for the "true" nodes
alpar@1677:     class TrueIt : public BimType::TrueIt
alpar@1677:     {
alpar@1677:     public:
alpar@1677:       explicit TrueIt(const IterableBoolNodeMap &m)
alpar@1677: 	: BimType::TrueIt(m.imap) { }
alpar@1677:       TrueIt(Invalid i) : BimType::TrueIt(i) { }
alpar@1677:     };  
alpar@1677:   };
alpar@1677: 
alpar@1677:   /// Iterable bool EdgeMap
alpar@1677: 
alpar@1677:   /// This map can be used in the same way
alpar@1677:   /// as the standard EdgeMap<bool> of the
alpar@1677:   /// given graph \c Graph. 
alpar@1677:   /// In addition, this class provides two iterators called \ref TrueIt
alpar@1677:   /// and \ref FalseIt to iterate through the "true" and "false" edges.
alpar@1677:   template <class Graph>
alpar@1677:   class IterableBoolEdgeMap
alpar@1677:   {
deba@1685:     typename Graph::template EdgeMap<int> cmap;
alpar@1677:   
alpar@1677:   public:
alpar@1677:   
deba@1685:     typedef IterableBoolMap<typename Graph::template EdgeMap<int> > BimType;
alpar@1677:     BimType imap;
alpar@1677: 
alpar@1677: 
alpar@1677:     typedef typename BimType::RefType RefType;
alpar@1677:     typedef typename Graph::Edge Key;
alpar@1677:     typedef bool Value;
alpar@1677:   
alpar@1677:     friend class FalseIt;
alpar@1677:     friend class TrueIt;
alpar@1677:   
alpar@1677:     ///\e
alpar@1677:     IterableBoolEdgeMap(const Graph &g,bool b=false) : cmap(g), imap(cmap,b) {}
alpar@1677: 
alpar@1677:   public:
alpar@1677:     ///\e
alpar@1677:     void set(Key k, bool v) { imap.set(k,v);}
alpar@1677: #ifdef DOXYGEN
alpar@1677:     ///\e
alpar@1677:     bool &operator[](Key k) { return imap[k];}  
alpar@1677:     ///\e
alpar@1677:     const bool &operator[](Key k) const { return imap[k];}  
alpar@1677: #else
alpar@1677:     Value operator[](Key k) const { return imap[k];}  
alpar@1677:     RefType operator[](Key k) { return imap[k];}  
alpar@1677: #endif
alpar@1677:     ///Iterator for the "false" edges
alpar@1677:     class FalseIt : public BimType::FalseIt
alpar@1677:     {
alpar@1677:     public:
alpar@1677:       explicit FalseIt(const IterableBoolEdgeMap &m)
alpar@1677: 	: BimType::FalseIt(m.imap) { }
alpar@1677:       FalseIt(Invalid i) : BimType::FalseIt(i) { }
alpar@1677:     };
alpar@1677:     ///Iterator for the "true" edges
alpar@1677:     class TrueIt : public BimType::TrueIt
alpar@1677:     {
alpar@1677:     public:
alpar@1677:       explicit TrueIt(const IterableBoolEdgeMap &m)
alpar@1677: 	: BimType::TrueIt(m.imap) { }
alpar@1677:       TrueIt(Invalid i) : BimType::TrueIt(i) { }
alpar@1677:     };  
alpar@1677:   };
alpar@1677: 
alpar@1677:   /// @}
alpar@1677: }