alpar@348: #include <iostream>
alpar@348: #include <vector>
alpar@348: #include <smart_graph.h>
alpar@348: 
alpar@348: using namespace hugo;
alpar@348: 
alpar@348: ///\todo This is only a static map!
alpar@348: ///
alpar@348: template<class GG>
alpar@348: class BoolIterEdgeMap
alpar@348: {
alpar@348: public:
alpar@348:   typedef GG Graph;
alpar@348:   typedef typename GG::Edge Edge;
alpar@348:   
alpar@348:   typedef Edge KeyType;
alpar@348:   typedef bool ValueType;
alpar@348:   
alpar@348:   friend class RefType;
alpar@348:   friend class FalseIterator;
alpar@348:   friend class TrueIterator;
alpar@348: 
alpar@348: private:
alpar@348:   Graph &G;
alpar@348:   typename Graph::EdgeMap<int> cref;
alpar@348:   std::vector<Edge> vals;
alpar@348:   int sep;           //map[e] is true <=> cref[e]>=sep
alpar@348:   
alpar@348:   bool isTrue(Edge e) {return cref[e]>=sep;}
alpar@348:   void swap(Edge e, int s) 
alpar@348:   {
alpar@348:     int ti=cref[e];
alpar@348:     Edge te=vals[s];
alpar@348:     cref[e]=s; vals[s]=e;
alpar@348:     cref[te]=ti; vals[ti]=te;
alpar@348:   }  
alpar@348: 
alpar@348:   void setTrue(Edge e) { if(cref[e]<sep) { sep--; swap(e,sep); } }
alpar@348:   void setFalse(Edge e) { if(cref[e]>=sep) { swap(e,sep); sep++; } }
alpar@348:   
alpar@348: public:
alpar@348:   class FalseIterator 
alpar@348:   {
alpar@348:     BoolIterEdgeMap &M;
alpar@348:     int i;
alpar@348:   public:
alpar@348:     FalseIterator(BoolIterEdgeMap &_M) : M(_M), i(0) { }
alpar@348:     FalseIterator &operator++() { ++i; return *this;}
alpar@348:     operator Edge() { return i<M.sep ? M.vals[i] : INVALID; }
alpar@348:     operator bool() { return i<M.sep; }
alpar@348:   };
alpar@348:   class TrueIterator 
alpar@348:   {
alpar@348:     BoolIterEdgeMap &M;
alpar@348:     int i;
alpar@348:   public:
alpar@348:     TrueIterator(BoolIterEdgeMap &_M) : M(_M), i(M.vals.size()-1) { }
alpar@348:     TrueIterator &operator++() { --i; return *this;}
alpar@348:     operator Edge() { return i>=M.sep ? M.vals[i] : INVALID; }
alpar@348:     operator bool() { return i>=M.sep; }
alpar@348:   };
alpar@348:   
alpar@348:   class RefType 
alpar@348:   {
alpar@348:     BoolIterEdgeMap &M;
alpar@348:     Edge e;
alpar@348:   public:
alpar@348:     RefType(BoolIterEdgeMap &_M,Edge _e) : M(_M), e(_e) { }
alpar@348:     
alpar@348:     operator ValueType() const 
alpar@348:     {
alpar@348:       return M.isTrue(e);
alpar@348:       
alpar@348:     }
alpar@348:     ValueType operator = (ValueType v) const
alpar@348:     {
alpar@348:       if(v) M.setTrue(e); 
alpar@348:       else M.setFalse(e);
alpar@348:       return v;
alpar@348:     }
alpar@348:   };
alpar@348:   
alpar@348: public:
alpar@348:   BoolIterEdgeMap(Graph &_G) : G(_G), cref(G)
alpar@348:   {
alpar@348:     sep=0;
alpar@348:     for(typename Graph::EdgeIt e(G);G.valid(e);G.next(e)) {
alpar@348:       cref[e]=sep;
alpar@348:       vals.push_back(e);
alpar@348:       sep++;
alpar@348:     }
alpar@348:   }
alpar@348:   RefType operator[] (Edge e) { return RefType(*this,e);}  
alpar@348: };
alpar@348: 
alpar@348: int main()
alpar@348: {
alpar@348:   typedef SmartGraph Graph;
alpar@348:   typedef Graph::NodeIt NodeIt;
alpar@348:   typedef Graph::OutEdgeIt OutEdgeIt;
alpar@348:   typedef Graph::EdgeIt EdgeIt;
alpar@348:   
alpar@348:   Graph G;
alpar@348: 
alpar@348:   for(int i=0;i<3;i++) G.addNode();
alpar@348: 
alpar@348:   for(NodeIt n(G);G.valid(n);G.next(n))
alpar@348:     for(NodeIt m(G);G.valid(m);G.next(m)) if(n!=m)
alpar@348:       G.addEdge(n,m);
alpar@348: 
alpar@348:   //for(OutEdgeIt e(G,NodeIt(G));G.valid(e);G.next(e))
alpar@348:     
alpar@348:   BoolIterEdgeMap<Graph> map(G);
alpar@348: 
alpar@348:   bool b=true;
alpar@348:   
alpar@348:   for(EdgeIt e(G);G.valid(e);G.next(e)) {map[e]=b;b=!b;}
alpar@348:   
alpar@348:   std::cout << true << '\n';
alpar@348: 
alpar@348:   for(EdgeIt e(G);G.valid(e);G.next(e))
alpar@348:     std::cout << G.id(G.tail(e)) << "->" << G.id(G.head(e))
alpar@348:       << ": " << map[e] << '\n';
alpar@348:   std::cout << "True Edges:\n";
alpar@348:   for(BoolIterEdgeMap<Graph>::TrueIterator i(map);i;++i)
alpar@348:     std::cout << G.id(G.tail(i)) << "->" << G.id(G.head(i)) << '\n';
alpar@348:   std::cout << "False Edges:\n";
alpar@348:   for(BoolIterEdgeMap<Graph>::FalseIterator i(map);i;++i)
alpar@348:     std::cout << G.id(G.tail(i)) << "->" << G.id(G.head(i)) << '\n';
alpar@348: }
alpar@348: