src/work/marci/merge_node_graph_wrapper.h
changeset 1014 aae850a2394d
parent 1009 8cb323dbae93
child 1016 18d009b23e42
equal deleted inserted replaced
6:9744318aa587 7:86da8bcef4fc
    20 #include <lemon/invalid.h>
    20 #include <lemon/invalid.h>
    21 #include <lemon/maps.h>
    21 #include <lemon/maps.h>
    22 #include <lemon/map_defines.h>
    22 #include <lemon/map_defines.h>
    23 #include <lemon/graph_wrapper.h>
    23 #include <lemon/graph_wrapper.h>
    24 #include <iostream>
    24 #include <iostream>
       
    25 
    25 using std::cout;
    26 using std::cout;
    26 using std::endl;
    27 using std::endl;
    27 
    28 
    28 #include <boost/type_traits.hpp>
    29 #include <boost/type_traits.hpp>
    29 #include <boost/utility/enable_if.hpp>
    30 #include <boost/utility/enable_if.hpp>
    36 
    37 
    37   template <class _Graph2>
    38   template <class _Graph2>
    38   class P2 : public GraphWrapperBase<_Graph2> {
    39   class P2 : public GraphWrapperBase<_Graph2> {
    39   };
    40   };
    40 
    41 
    41   /*! A base class for merging the node-set of two node-disjoint graphs 
    42 
    42     into the node-set of one graph.
    43   /*! A graph wrapper base class 
       
    44     for merging the node-set of two node-disjoint graphs 
       
    45     into the node-set of one graph. 
       
    46     Generic implementation for unrelated _Graph1::Node and _Graph2::Node.
    43    */
    47    */
    44   template <typename _Graph1, typename _Graph2, typename Enable=void>
    48   template <typename _Graph1, typename _Graph2, typename Enable=void>
    45   class MergeNodeGraphWrapperBase : 
    49   class MergeNodeGraphWrapperBase : 
    46     public P1<_Graph1>, public P2<_Graph2> {
    50     public P1<_Graph1>, public P2<_Graph2> {
    47   public:
    51   public:
    48     void printNode() const { std::cout << "generic" << std::endl; }
    52     static void printNode() { std::cout << "node: generic" << std::endl; }
    49     typedef _Graph1 Graph1;
    53     typedef _Graph1 Graph1;
    50     typedef _Graph2 Graph2;
    54     typedef _Graph2 Graph2;
    51     typedef P1<_Graph1> Parent1;
    55     typedef P1<_Graph1> Parent1;
    52     typedef P2<_Graph2> Parent2;
    56     typedef P2<_Graph2> Parent2;
    53     typedef typename Parent1::Node Graph1Node;
    57     typedef typename Parent1::Node Graph1Node;
    57   public:
    61   public:
    58     template <typename _Value> class NodeMap;
    62     template <typename _Value> class NodeMap;
    59 
    63 
    60     class Node : public Graph1Node, public Graph2Node {
    64     class Node : public Graph1Node, public Graph2Node {
    61       friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
    65       friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
    62       template <typename Value> friend class NodeMap;
    66       template <typename _Value> friend class NodeMap;
    63     protected:
    67     protected:
    64       bool backward; //true, iff backward
    68       bool backward; //true, iff backward
    65     public:
    69     public:
    66       Node() { }
    70       Node() { }
    67       /// \todo =false is needed, or causes problems?
    71       /// \todo =false is needed, or causes problems?
    70       Node(const Graph1Node& n1, 
    74       Node(const Graph1Node& n1, 
    71 	   const Graph2Node& n2, bool _backward) : 
    75 	   const Graph2Node& n2, bool _backward) : 
    72 	Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
    76 	Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
    73       Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
    77       Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
    74       bool operator==(const Node& v) const { 
    78       bool operator==(const Node& v) const { 
    75 	return (this->backward==v.backward && 
    79 	if (backward) 
    76 		static_cast<Graph1Node>(*this)==
    80 	  return (v.backward && 
    77 		static_cast<Graph1Node>(v) && 
    81 		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
    78 		static_cast<Graph2Node>(*this)==
    82 	else 
    79 		static_cast<Graph2Node>(v));
    83 	  return (!v.backward && 
       
    84 		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
    80       } 
    85       } 
    81       bool operator!=(const Node& v) const { 
    86       bool operator!=(const Node& v) const { 
    82 	return (this->backward!=v.backward || 
    87 	return !(*this==v);
    83 		static_cast<Graph1Node>(*this)!=
       
    84 		static_cast<Graph1Node>(v) || 
       
    85 		static_cast<Graph2Node>(*this)!=
       
    86 		static_cast<Graph2Node>(v));
       
    87       }
    88       }
    88     };
    89     };
    89 
    90 
    90     //typedef void Edge;
    91     //typedef void Edge;
    91     class Edge { };
    92     class Edge { };
   116       else
   117       else
   117 	return this->Parent2::graph->id(n);
   118 	return this->Parent2::graph->id(n);
   118     }
   119     }
   119 
   120 
   120     template <typename _Value> 
   121     template <typename _Value> 
   121     class NodeMap : public Parent1::template NodeMap<_Value>, 
   122     class NodeMap { 
   122 		    public Parent2::template NodeMap<_Value> { 
   123     protected:
   123       typedef typename Parent1::template NodeMap<_Value> ParentMap1;
   124       typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
   124       typedef typename Parent2::template NodeMap<_Value> ParentMap2;
   125       typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
       
   126       ParentMap1 forward_map;
       
   127       ParentMap2 backward_map;
   125     public:
   128     public:
   126       typedef _Value Value;
   129       typedef _Value Value;
   127       typedef Node Key;
   130       typedef Node Key;
   128       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
   131       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
   129 	ParentMap1(gw), ParentMap2(gw) { }
   132 	forward_map(*(gw.Parent1::graph)), 
       
   133 	backward_map(*(gw.Parent2::graph)) { }
   130       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
   134       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
   131 	      const _Value& value) : 
   135 	      const _Value& value) : 
   132 	ParentMap1(gw, value), ParentMap2(gw, value) { }
   136 	forward_map(*(gw.Parent1::graph), value), 
       
   137 	backward_map(*(gw.Parent2::graph), value) { }
   133       _Value operator[](const Node& n) const {
   138       _Value operator[](const Node& n) const {
   134 	if (!n.backward) 
   139 	if (!n.backward) 
   135 	  return ParentMap1::operator[](n);
   140 	  return forward_map[n];
   136 	else 
   141 	else 
   137 	  return ParentMap2::operator[](n);
   142 	  return backward_map[n];
   138       }
   143       }
   139       void set(const Node& n, const _Value& value) {
   144       void set(const Node& n, const _Value& value) {
   140 	if (!n.backward) 
   145 	if (!n.backward) 
   141 	  ParentMap1::set(n, value);
   146 	  forward_map.set(n, value);
   142 	else 
   147 	else 
   143 	  ParentMap2::set(n, value);
   148 	  backward_map.set(n, value);
   144       }
   149       }
   145 //       using ParentMap1::operator[];
   150 //       using ParentMap1::operator[];
   146 //       using ParentMap2::operator[];
   151 //       using ParentMap2::operator[];
   147     };
   152     };
   148 
   153 
   149   };
   154   };
   150 
   155 
   151   //not yet working
   156 
       
   157   /*! A graph wrapper base class 
       
   158     for merging the node-set of two node-disjoint graphs 
       
   159     into the node-set of one graph. 
       
   160     Specialization for the case when _Graph1::Node are the same _Graph2::Node.
       
   161    */
   152   template <typename _Graph1, typename _Graph2>
   162   template <typename _Graph1, typename _Graph2>
   153   class MergeNodeGraphWrapperBase<
   163   class MergeNodeGraphWrapperBase<
   154     _Graph1, _Graph2, typename boost::enable_if<
   164     _Graph1, _Graph2, typename boost::enable_if<
   155     boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   165     boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   156     public P1<_Graph1>, public P2<_Graph2> {
   166     public P1<_Graph1>, public P2<_Graph2> {
   157   public :
   167   public:
   158     void printNode() const { std::cout << "same" << std::endl; }
   168     static void printNode() { std::cout << "node: same" << std::endl; }
   159     typedef _Graph1 Graph1;
   169     typedef _Graph1 Graph1;
   160     typedef _Graph2 Graph2;
   170     typedef _Graph2 Graph2;
   161     typedef P1<_Graph1> Parent1;
   171     typedef P1<_Graph1> Parent1;
   162     typedef P2<_Graph2> Parent2;
   172     typedef P2<_Graph2> Parent2;
   163     typedef typename Parent1::Node Graph1Node;
   173     typedef typename Parent1::Node Graph1Node;
   164     typedef typename Parent2::Node Graph2Node;
   174     typedef typename Parent2::Node Graph2Node;
   165   protected:
   175   protected:
   166     MergeNodeGraphWrapperBase() { }
   176     MergeNodeGraphWrapperBase() { }
   167   public:
   177   public:
   168     class Node { };
   178     template <typename _Value> class NodeMap;
       
   179 
       
   180     class Node : public Graph1Node {
       
   181       friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
       
   182       template <typename _Value> friend class NodeMap;
       
   183     protected:
       
   184       bool backward; //true, iff backward
       
   185     public:
       
   186       Node() { }
       
   187       /// \todo =false is needed, or causes problems?
       
   188       /// If \c _backward is false, then we get an edge corresponding to the 
       
   189       /// original one, otherwise its oppositely directed pair is obtained.
       
   190       Node(const Graph1Node& n1, 
       
   191 	   const Graph2Node& n2, bool _backward) : 
       
   192 	Graph1Node(!backward ? n1 : n2), backward(_backward) { }
       
   193       Node(Invalid i) : Graph1Node(i), backward(true) { }
       
   194       bool operator==(const Node& v) const { 
       
   195 	return (backward==v.backward && 
       
   196 		static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
       
   197       } 
       
   198       bool operator!=(const Node& v) const { 
       
   199 	return !(*this==v);
       
   200       }
       
   201     };
       
   202 
       
   203     //typedef void Edge;
   169     class Edge { };
   204     class Edge { };
   170     void first() const;
   205     
   171     void next() const;
   206     void first(Node& i) const {
   172   };
   207       Parent1::graph->first(*static_cast<Graph1Node*>(&i));
   173 
   208       i.backward=false;
   174   //not yet working
   209       if (*static_cast<Graph1Node*>(&i)==INVALID) {
       
   210 	Parent2::graph->first(*static_cast<Graph1Node*>(&i));
       
   211 	i.backward=true;
       
   212       }
       
   213     }
       
   214     void next(Node& i) const {
       
   215       if (!(i.backward)) {
       
   216 	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
       
   217 	if (*static_cast<Graph1Node*>(&i)==INVALID) {
       
   218 	  Parent2::graph->first(*static_cast<Graph1Node*>(&i));
       
   219 	  i.backward=true;
       
   220 	}
       
   221       } else {
       
   222 	Parent2::graph->next(*static_cast<Graph1Node*>(&i));
       
   223       }
       
   224     }
       
   225 
       
   226     int id(const Node& n) const { 
       
   227       if (!n.backward) 
       
   228 	return this->Parent1::graph->id(n);
       
   229       else
       
   230 	return this->Parent2::graph->id(n);
       
   231     }
       
   232 
       
   233     template <typename _Value> 
       
   234     class NodeMap { 
       
   235     protected:
       
   236       typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
       
   237       typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
       
   238       ParentMap1 forward_map;
       
   239       ParentMap2 backward_map;
       
   240     public:
       
   241       typedef _Value Value;
       
   242       typedef Node Key;
       
   243       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
   244 	forward_map(*(gw.Parent1::graph)), 
       
   245 	backward_map(*(gw.Parent2::graph)) { }
       
   246       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
   247 	      const _Value& value) : 
       
   248 	forward_map(*(gw.Parent1::graph), value), 
       
   249 	backward_map(*(gw.Parent2::graph), value) { }
       
   250       _Value operator[](const Node& n) const {
       
   251 	if (!n.backward) 
       
   252 	  return forward_map[n];
       
   253 	else 
       
   254 	  return backward_map[n];
       
   255       }
       
   256       void set(const Node& n, const _Value& value) {
       
   257 	if (!n.backward) 
       
   258 	  forward_map.set(n, value);
       
   259 	else 
       
   260 	  backward_map.set(n, value);
       
   261       }
       
   262 //       using ParentMap1::operator[];
       
   263 //       using ParentMap2::operator[];
       
   264     };
       
   265 
       
   266   };
       
   267 
       
   268 
       
   269   /*! A graph wrapper base class 
       
   270     for merging the node-set of two node-disjoint graphs 
       
   271     into the node-set of one graph. 
       
   272     Specialization for the case when 
       
   273     _Graph1::Node are base and derived _Graph2::Node.
       
   274     NOT YET IMPLEMENTED
       
   275    */
   175   template <typename _Graph1, typename _Graph2>
   276   template <typename _Graph1, typename _Graph2>
   176   class MergeNodeGraphWrapperBase<
   277   class MergeNodeGraphWrapperBase<
   177     _Graph1, _Graph2, typename boost::enable_if<
   278     _Graph1, _Graph2, typename boost::enable_if<
   178     boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   279     boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   179     public P1<_Graph1>, public P2<_Graph2> {
   280     public P1<_Graph1>, public P2<_Graph2> {
   180   public :
   281   public :
   181     void printNode() const { std::cout << "2. nagyobb" << std::endl; }
   282     static void printNode() { std::cout << "node: 2nd is derived" << std::endl; }
   182     typedef _Graph1 Graph1;
   283     typedef _Graph1 Graph1;
   183     typedef _Graph2 Graph2;
   284     typedef _Graph2 Graph2;
   184     typedef P1<_Graph1> Parent1;
   285     typedef P1<_Graph1> Parent1;
   185     typedef P2<_Graph2> Parent2;
   286     typedef P2<_Graph2> Parent2;
   186     typedef typename Parent1::Node Graph1Node;
   287     typedef typename Parent1::Node Graph1Node;
   199   class MergeNodeGraphWrapperBase<
   300   class MergeNodeGraphWrapperBase<
   200     _Graph1, _Graph2, typename boost::enable_if<
   301     _Graph1, _Graph2, typename boost::enable_if<
   201     boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> : 
   302     boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> : 
   202     public P1<_Graph1>, public P2<_Graph2> {
   303     public P1<_Graph1>, public P2<_Graph2> {
   203   public :
   304   public :
   204     void printNode() const { std::cout << "1. nagyobb" << std::endl; }
   305     static void printNode() { std::cout << "node: 1st is derived" << std::endl; }
   205     typedef _Graph1 Graph1;
   306     typedef _Graph1 Graph1;
   206     typedef _Graph2 Graph2;
   307     typedef _Graph2 Graph2;
   207     typedef P1<_Graph1> Parent1;
   308     typedef P1<_Graph1> Parent1;
   208     typedef P2<_Graph2> Parent2;
   309     typedef P2<_Graph2> Parent2;
   209     typedef typename Parent1::Node Graph1Node;
   310     typedef typename Parent1::Node Graph1Node;
   216     void first() const;
   317     void first() const;
   217     void next() const;
   318     void next() const;
   218   };
   319   };
   219 
   320 
   220 
   321 
       
   322   /*! A graph wrapper class 
       
   323     fors merging the node-set of two node-disjoint graphs 
       
   324     into one node-set. It does not satisfy 
       
   325     StaticGraph concept as it has no edge-set which 
       
   326     works together with the node-set.
       
   327    */
   221   template <typename _Graph1, typename _Graph2>
   328   template <typename _Graph1, typename _Graph2>
   222   class MergeNodeGraphWrapper : public 
   329   class MergeNodeGraphWrapper : public 
   223   IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
   330   IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
   224   public:
   331   public:
   225     typedef _Graph1 Graph1;
   332     typedef _Graph1 Graph1;
   234       Parent::Parent2::setGraph(_graph2);
   341       Parent::Parent2::setGraph(_graph2);
   235     }
   342     }
   236   };
   343   };
   237 
   344 
   238 
   345 
   239   /*! A base class for merging the node-sets and edge-sets of 
   346   /*! A grah wrapper base class 
       
   347     for merging the node-sets and edge-sets of 
   240     two node-disjoint graphs 
   348     two node-disjoint graphs 
   241     into one graph.
   349     into one graph.
       
   350     Generic implementation for unrelated _Graph1::Edge and _Graph2::Edge.
   242    */
   351    */
   243   template <typename _Graph1, typename _Graph2, typename Enable=void>
   352   template <typename _Graph1, typename _Graph2, typename Enable=void>
   244   class MergeEdgeGraphWrapperBase : 
   353   class MergeEdgeGraphWrapperBase : 
   245     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
   354     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
   246   public:
   355   public:
   247     void printEdge() const { std::cout << "generic" << std::endl; }
   356     static void printEdge() { std::cout << "edge: generic" << std::endl; }
   248     typedef _Graph1 Graph1;
   357     typedef _Graph1 Graph1;
   249     typedef _Graph2 Graph2;
   358     typedef _Graph2 Graph2;
   250     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
   359     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
   251     typedef typename Parent::Parent1 Parent1;
   360     typedef typename Parent::Parent1 Parent1;
   252     typedef typename Parent::Parent2 Parent2;
   361     typedef typename Parent::Parent2 Parent2;
   261 
   370 
   262     typedef typename Parent::Node Node;
   371     typedef typename Parent::Node Node;
   263 
   372 
   264     class Edge : public Graph1Edge, public Graph2Edge {
   373     class Edge : public Graph1Edge, public Graph2Edge {
   265       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
   374       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
   266       template <typename Value> friend class EdgeMap;
   375       template <typename _Value> friend class EdgeMap;
   267     protected:
   376     protected:
   268       bool backward; //true, iff backward
   377       bool backward; //true, iff backward
   269     public:
   378     public:
   270       Edge() { }
   379       Edge() { }
   271       /// \todo =false is needed, or causes problems?
   380       /// \todo =false is needed, or causes problems?
   274       Edge(const Graph1Edge& n1, 
   383       Edge(const Graph1Edge& n1, 
   275 	   const Graph2Edge& n2, bool _backward) : 
   384 	   const Graph2Edge& n2, bool _backward) : 
   276 	Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
   385 	Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
   277       Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
   386       Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
   278       bool operator==(const Edge& v) const { 
   387       bool operator==(const Edge& v) const { 
   279 	return (this->backward==v.backward && 
   388 	if (backward) 
   280 		static_cast<Graph1Edge>(*this)==
   389 	  return (v.backward && 
   281 		static_cast<Graph1Edge>(v) && 
   390 		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
   282 		static_cast<Graph2Edge>(*this)==
   391 	else 
   283 		static_cast<Graph2Edge>(v));
   392 	  return (!v.backward && 
       
   393 		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
   284       } 
   394       } 
   285       bool operator!=(const Edge& v) const { 
   395       bool operator!=(const Edge& v) const { 
   286 	return (this->backward!=v.backward || 
   396 	return !(*this==v);
   287 		static_cast<Graph1Edge>(*this)!=
       
   288 		static_cast<Graph1Edge>(v) || 
       
   289 		static_cast<Graph2Edge>(*this)!=
       
   290 		static_cast<Graph2Edge>(v));
       
   291       }
   397       }
   292     };
   398     };
   293 
   399 
   294     using Parent::first;
   400     using Parent::first;
   295     void first(Edge& i) const {
   401     void first(Edge& i) const {
   379       else
   485       else
   380 	return this->Parent2::graph->id(n);
   486 	return this->Parent2::graph->id(n);
   381     }
   487     }
   382 
   488 
   383     template <typename _Value> 
   489     template <typename _Value> 
   384     class EdgeMap : public Parent1::template EdgeMap<_Value>, 
   490     class EdgeMap { 
   385 		    public Parent2::template EdgeMap<_Value> { 
   491     protected:
   386       typedef typename Parent1::template EdgeMap<_Value> ParentMap1;
   492       typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
   387       typedef typename Parent2::template EdgeMap<_Value> ParentMap2;
   493       typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
       
   494       ParentMap1 forward_map;
       
   495       ParentMap2 backward_map;
   388     public:
   496     public:
   389       typedef _Value Value;
   497       typedef _Value Value;
   390       typedef Edge Key;
   498       typedef Edge Key;
   391       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
   499       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
   392 	ParentMap1(gw), ParentMap2(gw) { }
   500 	forward_map(*(gw.Parent1::graph)), 
       
   501 	backward_map(*(gw.Parent2::graph)) { }
   393       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
   502       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
   394 	      const _Value& value) : 
   503 	      const _Value& value) : 
   395 	ParentMap1(gw, value), ParentMap2(gw, value) { }
   504 	forward_map(*(gw.Parent1::graph), value), 
       
   505 	backward_map(*(gw.Parent2::graph), value) { }
   396       _Value operator[](const Edge& n) const {
   506       _Value operator[](const Edge& n) const {
   397 	if (!n.backward) 
   507 	if (!n.backward) 
   398 	  return ParentMap1::operator[](n);
   508 	  return forward_map[n];
   399 	else 
   509 	else 
   400 	  return ParentMap2::operator[](n);
   510 	  return backward_map[n];
   401       }
   511       }
   402       void set(const Edge& n, const _Value& value) {
   512       void set(const Edge& n, const _Value& value) {
   403 	if (!n.backward) 
   513 	if (!n.backward) 
   404 	  ParentMap1::set(n, value);
   514 	  forward_map.set(n, value);
   405 	else 
   515 	else 
   406 	  ParentMap2::set(n, value);
   516 	  backward_map.set(n, value);
   407       }
   517       }
   408 //       using ParentMap1::operator[];
   518 //       using ParentMap1::operator[];
   409 //       using ParentMap2::operator[];
   519 //       using ParentMap2::operator[];
   410     };
   520     };
   411 
   521 
   412   };
   522   };
   413 
   523 
   414 
   524 
       
   525   /*! A graph wrapper base class 
       
   526     for merging the node-sets and edge-sets of 
       
   527     two node-disjoint graphs 
       
   528     into one graph.
       
   529     Specialization for the case when _Graph1::Edge and _Graph2::Edge
       
   530     are the same.
       
   531    */
       
   532   template <typename _Graph1, typename _Graph2>
       
   533   class MergeEdgeGraphWrapperBase<
       
   534     _Graph1, _Graph2, typename boost::enable_if<
       
   535     boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
       
   536     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
       
   537   public:
       
   538     static void printEdge() { std::cout << "edge: same" << std::endl; }
       
   539     typedef _Graph1 Graph1;
       
   540     typedef _Graph2 Graph2;
       
   541     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
       
   542     typedef typename Parent::Parent1 Parent1;
       
   543     typedef typename Parent::Parent2 Parent2;
       
   544 //     typedef P1<_Graph1> Parent1;
       
   545 //     typedef P2<_Graph2> Parent2;
       
   546     typedef typename Parent1::Edge Graph1Edge;
       
   547     typedef typename Parent2::Edge Graph2Edge;
       
   548   protected:
       
   549     MergeEdgeGraphWrapperBase() { }
       
   550   public:
       
   551     template <typename _Value> class EdgeMap;
       
   552 
       
   553     typedef typename Parent::Node Node;
       
   554 
       
   555     class Edge : public Graph1Edge {
       
   556       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
       
   557       template <typename _Value> friend class EdgeMap;
       
   558     protected:
       
   559       bool backward; //true, iff backward
       
   560     public:
       
   561       Edge() { }
       
   562       /// \todo =false is needed, or causes problems?
       
   563       /// If \c _backward is false, then we get an edge corresponding to the 
       
   564       /// original one, otherwise its oppositely directed pair is obtained.
       
   565       Edge(const Graph1Edge& n1, 
       
   566 	   const Graph2Edge& n2, bool _backward) : 
       
   567 	Graph1Edge(!backward ? n1 : n2), backward(_backward) { }
       
   568       Edge(Invalid i) : Graph1Edge(i), backward(true) { }
       
   569       bool operator==(const Edge& v) const { 
       
   570 	return (backward==v.backward && 
       
   571 		static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
       
   572       }
       
   573       bool operator!=(const Edge& v) const { 
       
   574 	return !(*this==v);
       
   575       }
       
   576     };
       
   577 
       
   578     using Parent::first;
       
   579     void first(Edge& i) const {
       
   580       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
       
   581       i.backward=false;
       
   582       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   583 	Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
       
   584 	i.backward=true;
       
   585       }
       
   586     }
       
   587     void firstIn(Edge& i, const Node& n) const {
       
   588       Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
       
   589       i.backward=false;
       
   590       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   591 	Parent2::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
       
   592 	i.backward=true;
       
   593       }
       
   594     }
       
   595     void firstOut(Edge& i, const Node& n) const {
       
   596       Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
       
   597       i.backward=false;
       
   598       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   599 	Parent2::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
       
   600 	i.backward=true;
       
   601       }
       
   602     }
       
   603 
       
   604     using Parent::next;
       
   605     void next(Edge& i) const {
       
   606       if (!(i.backward)) {
       
   607 	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
       
   608 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   609 	  Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
       
   610 	  i.backward=true;
       
   611 	}
       
   612       } else {
       
   613 	Parent2::graph->next(*static_cast<Graph1Edge*>(&i));
       
   614       }
       
   615     }
       
   616     void nextIn(Edge& i) const {
       
   617       if (!(i.backward)) {
       
   618 	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
       
   619 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   620 	  Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
       
   621 	  i.backward=true;
       
   622 	}
       
   623       } else {
       
   624 	Parent2::graph->nextIn(*static_cast<Graph1Edge*>(&i));
       
   625       }
       
   626     }
       
   627     void nextOut(Edge& i) const {
       
   628       if (!(i.backward)) {
       
   629 	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
       
   630 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   631 	  Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
       
   632 	  i.backward=true;
       
   633 	}
       
   634       } else {
       
   635 	Parent2::graph->nextOut(*static_cast<Graph1Edge*>(&i));
       
   636       }
       
   637     }
       
   638 
       
   639     Node source(const Edge& i) const {
       
   640       if (!(i.backward)) {
       
   641 	return 
       
   642 	  Node(Parent1::graph->source(i), INVALID, false);
       
   643       } else {
       
   644 	return 
       
   645 	  Node(INVALID, Parent2::graph->source(i), true);
       
   646       }
       
   647     }
       
   648 
       
   649     Node target(const Edge& i) const {
       
   650       if (!(i.backward)) {
       
   651 	return 
       
   652 	  Node(Parent1::graph->target(i), INVALID, false);
       
   653       } else {
       
   654 	return 
       
   655 	  Node(INVALID, Parent2::graph->target(i), true);
       
   656       }
       
   657     }
       
   658 
       
   659     using Parent::id;
       
   660     int id(const Edge& n) const { 
       
   661       if (!n.backward) 
       
   662 	return this->Parent1::graph->id(n);
       
   663       else
       
   664 	return this->Parent2::graph->id(n);
       
   665     }
       
   666 
       
   667     template <typename _Value> 
       
   668     class EdgeMap { 
       
   669     protected:
       
   670       typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
       
   671       typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
       
   672       ParentMap1 forward_map;
       
   673       ParentMap2 backward_map;
       
   674     public:
       
   675       typedef _Value Value;
       
   676       typedef Edge Key;
       
   677       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
   678 	forward_map(*(gw.Parent1::graph)), 
       
   679 	backward_map(*(gw.Parent2::graph)) { }
       
   680       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
   681 	      const _Value& value) : 
       
   682 	forward_map(*(gw.Parent1::graph), value), 
       
   683 	backward_map(*(gw.Parent2::graph), value) { }
       
   684       _Value operator[](const Edge& n) const {
       
   685 	if (!n.backward) 
       
   686 	  return forward_map[n];
       
   687 	else 
       
   688 	  return backward_map[n];
       
   689       }
       
   690       void set(const Edge& n, const _Value& value) {
       
   691 	if (!n.backward) 
       
   692 	  forward_map.set(n, value);
       
   693 	else 
       
   694 	  backward_map.set(n, value);
       
   695       }
       
   696 //       using ParentMap1::operator[];
       
   697 //       using ParentMap2::operator[];
       
   698     };
       
   699 
       
   700   };
       
   701 
       
   702 
       
   703   /*! A graph wrapper class 
       
   704     for merging the node-sets and edge-sets of 
       
   705     two node-disjoint graphs 
       
   706     into one graph.
       
   707    */
   415   template <typename _Graph1, typename _Graph2>
   708   template <typename _Graph1, typename _Graph2>
   416   class MergeEdgeGraphWrapper : public 
   709   class MergeEdgeGraphWrapper : public 
   417   IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
   710   IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
   418   public:
   711   public:
   419     typedef _Graph1 Graph1;
   712     typedef _Graph1 Graph1;
   428       Parent::Parent2::setGraph(_graph2);
   721       Parent::Parent2::setGraph(_graph2);
   429     }
   722     }
   430   };
   723   };
   431 
   724 
   432   
   725   
       
   726   /*! A graph wrapper base class for the following functionality.
       
   727     If a bijection is given between the node-sets of two graphs, 
       
   728     then the second one can be considered as a new edge-set 
       
   729     over th first node-set. 
       
   730    */
   433   template <typename _Graph, typename _EdgeSetGraph>
   731   template <typename _Graph, typename _EdgeSetGraph>
   434   class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> {
   732   class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> {
   435   public:
   733   public:
   436     typedef GraphWrapperBase<_Graph> Parent; 
   734     typedef GraphWrapperBase<_Graph> Parent; 
   437     typedef _Graph Graph;
   735     typedef _Graph Graph;
   505     void clear() const { Parent::clear(); edge_set_graph->clear(); }
   803     void clear() const { Parent::clear(); edge_set_graph->clear(); }
   506 
   804 
   507     bool forward(const Edge& e) const { return edge_set_graph->forward(e); }
   805     bool forward(const Edge& e) const { return edge_set_graph->forward(e); }
   508     bool backward(const Edge& e) const { return edge_set_graph->backward(e); }
   806     bool backward(const Edge& e) const { return edge_set_graph->backward(e); }
   509 
   807 
   510     using Parent::id;
   808     int id(const Node& e) const { return Parent::id(e); }
   511     int id(const Edge& e) const { return edge_set_graph->id(e); }
   809     int id(const Edge& e) const { return edge_set_graph->id(e); }
   512     
   810     
   513     Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); }
   811     Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); }
   514 
   812 
   515     template <typename _Value>
   813     template <typename _Value>
   524 	Parent(*(gw.edge_set_graph), _value) { }
   822 	Parent(*(gw.edge_set_graph), _value) { }
   525     };
   823     };
   526 
   824 
   527   };
   825   };
   528 
   826 
       
   827 
       
   828   /*! A graph wrapper class for the following functionality.
       
   829     If a bijection is given between the node-sets of two graphs, 
       
   830     then the second one can be considered as a new edge-set 
       
   831     over th first node-set. 
       
   832    */
   529   template <typename _Graph, typename _EdgeSetGraph>
   833   template <typename _Graph, typename _EdgeSetGraph>
   530   class NewEdgeSetGraphWrapper : 
   834   class NewEdgeSetGraphWrapper : 
   531     public IterableGraphExtender<
   835     public IterableGraphExtender<
   532     NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > {
   836     NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > {
   533   public:
   837   public:
   549       setNodeMap(_n_node);
   853       setNodeMap(_n_node);
   550       setENodeMap(_e_node);
   854       setENodeMap(_e_node);
   551     }
   855     }
   552   };
   856   };
   553 
   857 
       
   858 
       
   859   /*! A graph wrapper base class 
       
   860     for merging graphs of type _Graph1 and _Graph2 
       
   861     which are given on the same node-set 
       
   862     (specially on the node-set of Graph1) 
       
   863     into one graph.
       
   864     In an other point of view, _Graph1 is extended with 
       
   865     the edge-set of _Graph2.
       
   866    */
       
   867   template <typename _Graph1, typename _Graph2, typename Enable=void>
       
   868   class AugmentingGraphWrapperBase : 
       
   869     public P1<_Graph1> {
       
   870   public:
       
   871     void printAugment() const { std::cout << "generic" << std::endl; }
       
   872     typedef _Graph1 Graph1;
       
   873     typedef _Graph2 Graph2;
       
   874     typedef P1<_Graph1> Parent1;
       
   875     typedef P2<_Graph2> Parent2;
       
   876     typedef typename Parent1::Edge Graph1Edge;
       
   877     typedef typename Parent2::Edge Graph2Edge;
       
   878   protected:
       
   879     AugmentingGraphWrapperBase() { }
       
   880     _Graph2* graph2;
       
   881     void setGraph2(_Graph2& _graph2) { graph2=&_graph2; }
       
   882   public:
       
   883     
       
   884     template <typename _Value> class EdgeMap;
       
   885 
       
   886     typedef typename Parent1::Node Node;
       
   887 
       
   888     class Edge : public Graph1Edge, public Graph2Edge {
       
   889       friend class AugmentingGraphWrapperBase<_Graph1, _Graph2>;
       
   890       template <typename _Value> friend class EdgeMap;
       
   891     protected:
       
   892       bool backward; //true, iff backward
       
   893     public:
       
   894       Edge() { }
       
   895       /// \todo =false is needed, or causes problems?
       
   896       /// If \c _backward is false, then we get an edge corresponding to the 
       
   897       /// original one, otherwise its oppositely directed pair is obtained.
       
   898       Edge(const Graph1Edge& n1, 
       
   899 	   const Graph2Edge& n2, bool _backward) : 
       
   900 	Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
       
   901       Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
       
   902       bool operator==(const Edge& v) const { 
       
   903 	if (backward) 
       
   904 	  return (v.backward && 
       
   905 		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
       
   906 	else 
       
   907 	  return (!v.backward && 
       
   908 		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
       
   909       } 
       
   910       bool operator!=(const Edge& v) const { 
       
   911 	return !(*this==v);
       
   912       }
       
   913     };
       
   914 
       
   915     using Parent1::first;
       
   916     void first(Edge& i) const {
       
   917       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
       
   918       i.backward=false;
       
   919       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   920 	graph2->first(*static_cast<Graph2Edge*>(&i));
       
   921 	i.backward=true;
       
   922       }
       
   923     }
       
   924     void firstIn(Edge& i, const Node& n) const {
       
   925       Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
       
   926       i.backward=false;
       
   927       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   928 	graph2->firstIn(*static_cast<Graph2Edge*>(&i), n);
       
   929 	i.backward=true;
       
   930       }
       
   931     }
       
   932     void firstOut(Edge& i, const Node& n) const {
       
   933       Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
       
   934       i.backward=false;
       
   935       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   936 	graph2->firstOut(*static_cast<Graph2Edge*>(&i), n);
       
   937 	i.backward=true;
       
   938       }
       
   939     }
       
   940 
       
   941     using Parent1::next;
       
   942     void next(Edge& i) const {
       
   943       if (!(i.backward)) {
       
   944 	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
       
   945 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   946 	  graph2->first(*static_cast<Graph2Edge*>(&i));
       
   947 	  i.backward=true;
       
   948 	}
       
   949       } else {
       
   950 	graph2->next(*static_cast<Graph2Edge*>(&i));
       
   951       }
       
   952     }
       
   953     void nextIn(Edge& i) const {
       
   954       if (!(i.backward)) {
       
   955 	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
       
   956 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   957 	  graph2->first(*static_cast<Graph2Edge*>(&i));
       
   958 	  i.backward=true;
       
   959 	}
       
   960       } else {
       
   961 	graph2->nextIn(*static_cast<Graph2Edge*>(&i));
       
   962       }
       
   963     }
       
   964     void nextOut(Edge& i) const {
       
   965       if (!(i.backward)) {
       
   966 	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
       
   967 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   968 	  graph2->first(*static_cast<Graph2Edge*>(&i));
       
   969 	  i.backward=true;
       
   970 	}
       
   971       } else {
       
   972 	graph2->nextOut(*static_cast<Graph2Edge*>(&i));
       
   973       }
       
   974     }
       
   975 
       
   976     Node source(const Edge& i) const {
       
   977       if (!(i.backward)) {
       
   978 	return Parent1::graph->source(i);
       
   979       } else {
       
   980 	return graph2->source(i);
       
   981       }
       
   982     }
       
   983 
       
   984     Node target(const Edge& i) const {
       
   985       if (!(i.backward)) {
       
   986 	return Parent1::graph->target(i);
       
   987       } else {
       
   988 	return graph2->target(i);
       
   989       }
       
   990     }
       
   991 
       
   992     int id(const Node& n) const {
       
   993       return Parent1::id(n);
       
   994     };
       
   995     int id(const Edge& n) const { 
       
   996       if (!n.backward) 
       
   997 	return this->Parent1::graph->id(n);
       
   998       else
       
   999 	return this->graph2->id(n);
       
  1000     }
       
  1001 
       
  1002     template <typename _Value> 
       
  1003     class EdgeMap { 
       
  1004     protected:
       
  1005       typedef typename _Graph1::template EdgeMap<_Value> ParentMap1;
       
  1006       typedef typename _Graph2::template EdgeMap<_Value> ParentMap2;
       
  1007       ParentMap1 forward_map;
       
  1008       ParentMap2 backward_map;
       
  1009     public:
       
  1010       typedef _Value Value;
       
  1011       typedef Edge Key;
       
  1012       EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
  1013 	forward_map(*(gw.Parent1::graph)), 
       
  1014 	backward_map(*(gw.graph2)) { }
       
  1015       EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
  1016 	      const _Value& value) : 
       
  1017 	forward_map(*(gw.Parent1::graph), value), 
       
  1018 	backward_map(*(gw.graph2), value) { }
       
  1019       _Value operator[](const Edge& n) const {
       
  1020 	if (!n.backward) 
       
  1021 	  return forward_map[n];
       
  1022 	else 
       
  1023 	  return backward_map[n];
       
  1024       }
       
  1025       void set(const Edge& n, const _Value& value) {
       
  1026 	if (!n.backward) 
       
  1027 	  forward_map.set(n, value);
       
  1028 	else 
       
  1029 	  backward_map.set(n, value);
       
  1030       }
       
  1031 //       using ParentMap1::operator[];
       
  1032 //       using ParentMap2::operator[];
       
  1033     };
       
  1034 
       
  1035   };
       
  1036 
       
  1037 
       
  1038   /*! A graph wrapper class 
       
  1039     for merging two graphs (of type _Graph1 and _Graph2)
       
  1040     with the same node-set 
       
  1041     (specially on the node-set of Graph1) 
       
  1042     into one graph. 
       
  1043     In an other point of view, _Graph1 is extended with 
       
  1044     the edge-set of _Graph2.
       
  1045    */  
       
  1046   template <typename _Graph1, typename _Graph2>
       
  1047   class AugmentingGraphWrapper : public 
       
  1048   IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> > {
       
  1049   public:
       
  1050     typedef 
       
  1051     IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> >
       
  1052     Parent;
       
  1053     typedef _Graph1 Graph1;
       
  1054     typedef _Graph2 Graph2;
       
  1055   protected:
       
  1056     AugmentingGraphWrapper() { }
       
  1057   public:
       
  1058     AugmentingGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
       
  1059       setGraph(_graph1); 
       
  1060       setGraph2(_graph2);
       
  1061     }
       
  1062   };
       
  1063 
   554 } //namespace lemon
  1064 } //namespace lemon
   555 
  1065 
   556 #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H
  1066 #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H