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 alpar@1677: #include 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 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 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) { 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::max()) { } alpar@1677: FalseIt &operator++() { ++i; return *this;} alpar@1677: operator Key() 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 isecond=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 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 alpar@1677: class IterableBoolNodeMap alpar@1677: { deba@1685: typename Graph::template NodeMap cmap; alpar@1677: alpar@1677: public: alpar@1677: deba@1685: typedef IterableBoolMap > 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 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 alpar@1677: class IterableBoolEdgeMap alpar@1677: { deba@1685: typename Graph::template EdgeMap cmap; alpar@1677: alpar@1677: public: alpar@1677: deba@1685: typedef IterableBoolMap > 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: }