src/work/marci/merge_node_graph_wrapper.h
changeset 1365 c280de819a73
parent 1164 80bb73097736
equal deleted inserted replaced
12:d9277ac7d96a -1:000000000000
     1 /* -*- C++ -*-
       
     2  * src/lemon/merge_node_graph_wrapper.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 #ifndef LEMON_MERGE_NODE_GRAPH_WRAPPER_H
       
    18 #define LEMON_MERGE_NODE_GRAPH_WRAPPER_H
       
    19 
       
    20 #include <lemon/invalid.h>
       
    21 #include <lemon/maps.h>
       
    22 #include <lemon/map_defines.h>
       
    23 #include <lemon/graph_wrapper.h>
       
    24 #include <iostream>
       
    25 
       
    26 using std::cout;
       
    27 using std::endl;
       
    28 
       
    29 #include <boost/type_traits.hpp>
       
    30 #include <boost/utility/enable_if.hpp>
       
    31 
       
    32 namespace lemon {
       
    33 
       
    34   template <class _Graph1>
       
    35   class P1 : public GraphWrapperBase<_Graph1> {
       
    36   };
       
    37 
       
    38   template <class _Graph2>
       
    39   class P2 : public GraphWrapperBase<_Graph2> {
       
    40   };
       
    41 
       
    42 
       
    43   template <typename _Graph1, typename _Graph2, typename Enable=void>
       
    44   class MergeNodeGraphWrapperBaseBase : 
       
    45     public P1<_Graph1>, public P2<_Graph2> {
       
    46   public:
       
    47     static void printNode() { std::cout << "node: generic" << std::endl; }
       
    48     typedef _Graph1 Graph1;
       
    49     typedef _Graph2 Graph2;
       
    50     typedef P1<_Graph1> Parent1;
       
    51     typedef P2<_Graph2> Parent2;
       
    52     typedef typename Parent1::Node Graph1Node;
       
    53     typedef typename Parent2::Node Graph2Node;
       
    54   protected:
       
    55     MergeNodeGraphWrapperBaseBase() { }
       
    56   public:
       
    57 
       
    58     class Node : public Graph1Node, public Graph2Node {
       
    59       friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>;
       
    60     protected:
       
    61       bool backward; //true, iff backward
       
    62     public:
       
    63       Node() { }
       
    64       /// \todo =false is needed, or causes problems?
       
    65       /// If \c _backward is false, then we get an edge corresponding to the 
       
    66       /// original one, otherwise its oppositely directed pair is obtained.
       
    67       Node(const Graph1Node& n1, 
       
    68 	   const Graph2Node& n2, bool _backward) : 
       
    69 	Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
       
    70       Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
       
    71       bool operator==(const Node& v) const { 
       
    72 	if (backward) 
       
    73 	  return (v.backward && 
       
    74 		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
       
    75 	else 
       
    76 	  return (!v.backward && 
       
    77 		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
       
    78       } 
       
    79       bool operator!=(const Node& v) const { 
       
    80 	return !(*this==v);
       
    81       }
       
    82     };
       
    83 
       
    84     static bool forward(const Node& n) { return !n.backward; }
       
    85     static bool backward(const Node& n) { return n.backward; }
       
    86     static void setForward(Node& n) { n.backward=false; }
       
    87     static void setBackward(Node& n) { n.backward=true; }    
       
    88   };
       
    89 
       
    90 
       
    91   template <typename _Graph1, typename _Graph2>
       
    92   class MergeNodeGraphWrapperBaseBase<
       
    93     _Graph1, _Graph2, typename boost::enable_if<
       
    94     boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
       
    95     public P1<_Graph1>, public P2<_Graph2> {
       
    96   public:
       
    97     static void printNode() { std::cout << "node: same" << std::endl; }
       
    98     typedef _Graph1 Graph1;
       
    99     typedef _Graph2 Graph2;
       
   100     typedef P1<_Graph1> Parent1;
       
   101     typedef P2<_Graph2> Parent2;
       
   102     typedef typename Parent1::Node Graph1Node;
       
   103     typedef typename Parent2::Node Graph2Node;
       
   104   protected:
       
   105     MergeNodeGraphWrapperBaseBase() { }
       
   106   public:
       
   107 
       
   108     class Node : public Graph1Node {
       
   109       friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>;
       
   110     protected:
       
   111       bool backward; //true, iff backward
       
   112     public:
       
   113       Node() { }
       
   114       /// \todo =false is needed, or causes problems?
       
   115       /// If \c _backward is false, then we get an edge corresponding to the 
       
   116       /// original one, otherwise its oppositely directed pair is obtained.
       
   117       Node(const Graph1Node& n1, 
       
   118 	   const Graph2Node& n2, bool _backward) : 
       
   119 	Graph1Node(!_backward ? n1 : n2), backward(_backward) { }
       
   120       Node(Invalid i) : Graph1Node(i), backward(true) { }
       
   121       bool operator==(const Node& v) const { 
       
   122 	return (backward==v.backward && 
       
   123 		static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
       
   124       } 
       
   125       bool operator!=(const Node& v) const { 
       
   126 	return !(*this==v);
       
   127       }
       
   128     };
       
   129 
       
   130     static bool forward(const Node& n) { return !n.backward; }
       
   131     static bool backward(const Node& n) { return n.backward; }
       
   132     static void setForward(Node& n) { n.backward=false; }
       
   133     static void setBackward(Node& n) { n.backward=true; }
       
   134   };
       
   135 
       
   136 
       
   137   template <typename _Graph1, typename _Graph2>
       
   138   class MergeNodeGraphWrapperBaseBase<
       
   139     _Graph1, _Graph2, typename boost::enable_if<
       
   140     boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
       
   141     public P1<_Graph1>, public P2<_Graph2> {
       
   142   public :
       
   143     static void printNode() { std::cout << "node: 2nd is derived" << std::endl; }
       
   144     typedef _Graph1 Graph1;
       
   145     typedef _Graph2 Graph2;
       
   146     typedef P1<_Graph1> Parent1;
       
   147     typedef P2<_Graph2> Parent2;
       
   148     typedef typename Parent1::Node Graph1Node;
       
   149     typedef typename Parent2::Node Graph2Node;
       
   150   protected:
       
   151     MergeNodeGraphWrapperBaseBase() { }
       
   152   public:
       
   153 
       
   154     class Node : public Graph2Node {
       
   155       friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>;
       
   156     protected:
       
   157       bool backward; //true, iff backward
       
   158     public:
       
   159       Node() { }
       
   160       /// \todo =false is needed, or causes problems?
       
   161       /// If \c _backward is false, then we get an edge corresponding to the 
       
   162       /// original one, otherwise its oppositely directed pair is obtained.
       
   163       Node(const Graph1Node& n1, 
       
   164 	   const Graph2Node& n2, bool _backward) : 
       
   165 	Graph2Node(n2), backward(_backward) { 
       
   166 	if (!backward) *this=n1;
       
   167       }
       
   168       Node(Invalid i) : Graph2Node(i), backward(true) { }
       
   169       bool operator==(const Node& v) const { 
       
   170 	if (backward) 
       
   171 	  return (v.backward && 
       
   172 		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
       
   173 	else 
       
   174 	  return (!v.backward && 
       
   175 		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
       
   176       } 
       
   177       bool operator!=(const Node& v) const { 
       
   178 	return !(*this==v);
       
   179       }
       
   180     };
       
   181 
       
   182     static bool forward(const Node& n) { return !n.backward; }
       
   183     static bool backward(const Node& n) { return n.backward; }
       
   184     static void setForward(Node& n) { n.backward=false; }
       
   185     static void setBackward(Node& n) { n.backward=true; }
       
   186   };
       
   187   
       
   188 
       
   189   template <typename _Graph1, typename _Graph2>
       
   190   class MergeNodeGraphWrapperBaseBase<
       
   191     _Graph1, _Graph2, typename boost::enable_if<
       
   192     boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> : 
       
   193     public P1<_Graph1>, public P2<_Graph2> {
       
   194   public :
       
   195     static void printNode() { std::cout << "node: 1st is derived" << std::endl; }
       
   196     typedef _Graph1 Graph1;
       
   197     typedef _Graph2 Graph2;
       
   198     typedef P1<_Graph1> Parent1;
       
   199     typedef P2<_Graph2> Parent2;
       
   200     typedef typename Parent1::Node Graph1Node;
       
   201     typedef typename Parent2::Node Graph2Node;
       
   202   protected:
       
   203     MergeNodeGraphWrapperBaseBase() { }
       
   204   public:
       
   205 
       
   206     class Node : public Graph1Node {
       
   207       friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>;
       
   208     protected:
       
   209       bool backward; //true, iff backward
       
   210     public:
       
   211       Node() { }
       
   212       /// \todo =false is needed, or causes problems?
       
   213       /// If \c _backward is false, then we get an edge corresponding to the 
       
   214       /// original one, otherwise its oppositely directed pair is obtained.
       
   215       Node(const Graph1Node& n1, 
       
   216 	   const Graph2Node& n2, bool _backward) : 
       
   217 	Graph1Node(n1), backward(_backward) { 
       
   218 	if (backward) *this=n2;
       
   219       }
       
   220       Node(Invalid i) : Graph1Node(i), backward(true) { }
       
   221       bool operator==(const Node& v) const { 
       
   222 	if (backward) 
       
   223 	  return (v.backward && 
       
   224 		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
       
   225 	else 
       
   226 	  return (!v.backward && 
       
   227 		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
       
   228       } 
       
   229       bool operator!=(const Node& v) const { 
       
   230 	return !(*this==v);
       
   231       }
       
   232     };
       
   233 
       
   234     static bool forward(const Node& n) { return !n.backward; }
       
   235     static bool backward(const Node& n) { return n.backward; }
       
   236     static void setForward(Node& n) { n.backward=false; }
       
   237     static void setBackward(Node& n) { n.backward=true; }
       
   238   };
       
   239 
       
   240 
       
   241   template <typename _Graph1, typename _Graph2>
       
   242   class MergeNodeGraphWrapperBase : 
       
   243     public MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2> {
       
   244   public:
       
   245     typedef MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2> Parent;
       
   246     typedef _Graph1 Graph1;
       
   247     typedef _Graph2 Graph2;
       
   248     typedef P1<_Graph1> Parent1;
       
   249     typedef P2<_Graph2> Parent2;
       
   250     typedef typename Parent1::Node Graph1Node;
       
   251     typedef typename Parent2::Node Graph2Node;
       
   252 
       
   253     typedef typename Parent::Node Node; 
       
   254     class Edge { };
       
   255     
       
   256     void first(Node& i) const {
       
   257       Parent1::graph->first(*static_cast<Graph1Node*>(&i));
       
   258       this->setForward(i);
       
   259       if (*static_cast<Graph1Node*>(&i)==INVALID) {
       
   260 	Parent2::graph->first(*static_cast<Graph2Node*>(&i));
       
   261 	this->setBackward(i);
       
   262       }
       
   263     }
       
   264     void next(Node& i) const {
       
   265       if (this->forward(i)) {
       
   266 	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
       
   267 	if (*static_cast<Graph1Node*>(&i)==INVALID) {
       
   268 	  Parent2::graph->first(*static_cast<Graph2Node*>(&i));
       
   269 	  this->setBackward(i);
       
   270 	}
       
   271       } else {
       
   272 	Parent2::graph->next(*static_cast<Graph2Node*>(&i));
       
   273       }
       
   274     }
       
   275 
       
   276     int id(const Node& n) const { 
       
   277       if (this->forward(n)) 
       
   278 	return this->Parent1::graph->id(n);
       
   279       else
       
   280 	return this->Parent2::graph->id(n);
       
   281     }
       
   282 
       
   283     template <typename _Value> 
       
   284     class NodeMap { 
       
   285     protected:
       
   286       typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
       
   287       typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
       
   288       ParentMap1 forward_map;
       
   289       ParentMap2 backward_map;
       
   290     public:
       
   291       typedef _Value Value;
       
   292       typedef Node Key;
       
   293       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
   294 	forward_map(*(gw.Parent1::graph)), 
       
   295 	backward_map(*(gw.Parent2::graph)) { }
       
   296       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
   297 	      const _Value& value) : 
       
   298 	forward_map(*(gw.Parent1::graph), value), 
       
   299 	backward_map(*(gw.Parent2::graph), value) { }
       
   300       _Value operator[](const Node& n) const {
       
   301 	if (Parent::forward(n)) 
       
   302 	  return forward_map[n];
       
   303 	else 
       
   304 	  return backward_map[n];
       
   305       }
       
   306       void set(const Node& n, const _Value& value) {
       
   307 	if (Parent::forward(n)) 
       
   308 	  forward_map.set(n, value);
       
   309 	else 
       
   310 	  backward_map.set(n, value);
       
   311       }
       
   312 //       using ParentMap1::operator[];
       
   313 //       using ParentMap2::operator[];
       
   314     };
       
   315 
       
   316   };
       
   317 
       
   318 
       
   319   /*! A graph wrapper class 
       
   320     for merging the node-set of two node-disjoint graphs 
       
   321     into the node-set of one graph. 
       
   322     Different implementations are according to the relation of 
       
   323     _Graph1::Node and _Graph2::Node. 
       
   324     If _Graph1::Node and _Graph2::Node are unrelated, then 
       
   325     MergeNodeGraphWrapper<_Graph1, _Graph2>::Node 
       
   326     is derived from both. 
       
   327     If _Graph1::Node and _Graph2::Node are the same type, then 
       
   328     MergeNodeGraphWrapper<_Graph1, _Graph2>::Node 
       
   329     is derived from _Graph1::Node. 
       
   330     If one of _Graph1::Node and _Graph2::Node 
       
   331     is derived from the other one, then 
       
   332     MergeNodeGraphWrapper<_Graph1, _Graph2>::Node 
       
   333     is derived from the derived type.
       
   334     It does not satisfy 
       
   335     StaticGraph concept as it has no edge-set which 
       
   336     works together with the node-set.
       
   337   */
       
   338   template <typename _Graph1, typename _Graph2>
       
   339   class MergeNodeGraphWrapper : public 
       
   340   IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
       
   341   public:
       
   342     typedef _Graph1 Graph1;
       
   343     typedef _Graph2 Graph2;
       
   344     typedef IterableGraphExtender<
       
   345       MergeNodeGraphWrapperBase<_Graph1, _Graph2> > Parent;
       
   346   protected:
       
   347     MergeNodeGraphWrapper() { }
       
   348   public:
       
   349     MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
       
   350       Parent::Parent1::setGraph(_graph1);
       
   351       Parent::Parent2::setGraph(_graph2);
       
   352     }
       
   353   };
       
   354 
       
   355 
       
   356   /*! A grah wrapper base class 
       
   357     for merging the node-sets and edge-sets of 
       
   358     two node-disjoint graphs 
       
   359     into one graph.
       
   360     Generic implementation for unrelated _Graph1::Edge and _Graph2::Edge.
       
   361    */
       
   362   template <typename _Graph1, typename _Graph2, typename Enable=void>
       
   363   class MergeEdgeGraphWrapperBaseBase : 
       
   364     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
       
   365   public:
       
   366     static void printEdge() { std::cout << "edge: generic" << std::endl; }
       
   367     typedef _Graph1 Graph1;
       
   368     typedef _Graph2 Graph2;
       
   369     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
       
   370     typedef typename Parent::Parent1 Parent1;
       
   371     typedef typename Parent::Parent2 Parent2;
       
   372 //     typedef P1<_Graph1> Parent1;
       
   373 //     typedef P2<_Graph2> Parent2;
       
   374     typedef typename Parent1::Edge Graph1Edge;
       
   375     typedef typename Parent2::Edge Graph2Edge;
       
   376   protected:
       
   377     MergeEdgeGraphWrapperBaseBase() { }
       
   378   public:
       
   379 
       
   380     class Edge : public Graph1Edge, public Graph2Edge {
       
   381       friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
       
   382     protected:
       
   383       bool backward; //true, iff backward
       
   384     public:
       
   385       Edge() { }
       
   386       /// \todo =false is needed, or causes problems?
       
   387       /// If \c _backward is false, then we get an edge corresponding to the 
       
   388       /// original one, otherwise its oppositely directed pair is obtained.
       
   389       Edge(const Graph1Edge& n1, 
       
   390 	   const Graph2Edge& n2, bool _backward) : 
       
   391 	Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
       
   392       Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
       
   393       bool operator==(const Edge& v) const { 
       
   394 	if (backward) 
       
   395 	  return (v.backward && 
       
   396 		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
       
   397 	else 
       
   398 	  return (!v.backward && 
       
   399 		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
       
   400       } 
       
   401       bool operator!=(const Edge& v) const { 
       
   402 	return !(*this==v);
       
   403       }
       
   404     };
       
   405 
       
   406     using Parent::forward;
       
   407     using Parent::backward;
       
   408     using Parent::setForward;
       
   409     using Parent::setBackward;
       
   410     static bool forward(const Edge& e) { return !e.backward; }
       
   411     static bool backward(const Edge& e) { return e.backward; }
       
   412     static void setForward(Edge& e) { e.backward=false; }
       
   413     static void setBackward(Edge& e) { e.backward=true; }
       
   414   };
       
   415 
       
   416 
       
   417 
       
   418   /*! A graph wrapper base class 
       
   419     for merging the node-sets and edge-sets of 
       
   420     two node-disjoint graphs 
       
   421     into one graph.
       
   422     Specialization for the case when _Graph1::Edge and _Graph2::Edge
       
   423     are the same.
       
   424    */
       
   425   template <typename _Graph1, typename _Graph2>
       
   426   class MergeEdgeGraphWrapperBaseBase<
       
   427     _Graph1, _Graph2, typename boost::enable_if<
       
   428     boost::is_same<typename _Graph1::Edge, typename _Graph2::Edge> >::type> : 
       
   429     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
       
   430   public:
       
   431     static void printEdge() { std::cout << "edge: same" << std::endl; }
       
   432     typedef _Graph1 Graph1;
       
   433     typedef _Graph2 Graph2;
       
   434     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
       
   435     typedef typename Parent::Parent1 Parent1;
       
   436     typedef typename Parent::Parent2 Parent2;
       
   437 //     typedef P1<_Graph1> Parent1;
       
   438 //     typedef P2<_Graph2> Parent2;
       
   439     typedef typename Parent1::Edge Graph1Edge;
       
   440     typedef typename Parent2::Edge Graph2Edge;
       
   441   protected:
       
   442     MergeEdgeGraphWrapperBaseBase() { }
       
   443   public:
       
   444 
       
   445     class Edge : public Graph1Edge {
       
   446       friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
       
   447     protected:
       
   448       bool backward; //true, iff backward
       
   449     public:
       
   450       Edge() { }
       
   451       /// \todo =false is needed, or causes problems?
       
   452       /// If \c _backward is false, then we get an edge corresponding to the 
       
   453       /// original one, otherwise its oppositely directed pair is obtained.
       
   454       Edge(const Graph1Edge& n1, 
       
   455 	   const Graph2Edge& n2, bool _backward) : 
       
   456 	Graph1Edge(!_backward ? n1 : n2), backward(_backward) { }
       
   457       Edge(Invalid i) : Graph1Edge(i), backward(true) { }
       
   458       bool operator==(const Edge& v) const { 
       
   459 	return (backward==v.backward && 
       
   460 		static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
       
   461       }
       
   462       bool operator!=(const Edge& v) const { 
       
   463 	return !(*this==v);
       
   464       }
       
   465     };
       
   466 
       
   467     using Parent::forward;
       
   468     using Parent::backward;
       
   469     using Parent::setForward;
       
   470     using Parent::setBackward;
       
   471     static bool forward(const Edge& e) { return !e.backward; }
       
   472     static bool backward(const Edge& e) { return e.backward; }
       
   473     static void setForward(Edge& e) { e.backward=false; }
       
   474     static void setBackward(Edge& e) { e.backward=true; }
       
   475   };
       
   476 
       
   477 
       
   478   /*! A grah wrapper base class 
       
   479     for merging the node-sets and edge-sets of 
       
   480     two node-disjoint graphs 
       
   481     into one graph. 
       
   482     Specialized implementation for the case 
       
   483     when _Graph1::Edge is a base class and _Graph2::Edge
       
   484     is derived from it.
       
   485    */
       
   486   template <typename _Graph1, typename _Graph2>
       
   487   class MergeEdgeGraphWrapperBaseBase<
       
   488     _Graph1, _Graph2, typename boost::enable_if<
       
   489     boost::is_base_and_derived<typename _Graph1::Edge, typename _Graph2::Edge> >::type> : 
       
   490     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
       
   491   public:
       
   492     static void printEdge() { std::cout << "edge: 2nd is derived" << std::endl; }
       
   493     typedef _Graph1 Graph1;
       
   494     typedef _Graph2 Graph2;
       
   495     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
       
   496     typedef typename Parent::Parent1 Parent1;
       
   497     typedef typename Parent::Parent2 Parent2;
       
   498 //     typedef P1<_Graph1> Parent1;
       
   499 //     typedef P2<_Graph2> Parent2;
       
   500     typedef typename Parent1::Edge Graph1Edge;
       
   501     typedef typename Parent2::Edge Graph2Edge;
       
   502   protected:
       
   503     MergeEdgeGraphWrapperBaseBase() { }
       
   504   public:
       
   505 
       
   506     class Edge : public Graph2Edge {
       
   507       friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
       
   508     protected:
       
   509       bool backward; //true, iff backward
       
   510     public:
       
   511       Edge() { }
       
   512       /// \todo =false is needed, or causes problems?
       
   513       /// If \c _backward is false, then we get an edge corresponding to the 
       
   514       /// original one, otherwise its oppositely directed pair is obtained.
       
   515       Edge(const Graph1Edge& n1, 
       
   516 	   const Graph2Edge& n2, bool _backward) : 
       
   517 	Graph2Edge(n2), backward(_backward) { 
       
   518 	if (!backward) *this=n1;
       
   519       }
       
   520       Edge(Invalid i) : Graph2Edge(i), backward(true) { }
       
   521       bool operator==(const Edge& v) const { 
       
   522 	if (backward) 
       
   523 	  return (v.backward && 
       
   524 		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
       
   525 	else 
       
   526 	  return (!v.backward && 
       
   527 		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
       
   528       } 
       
   529       bool operator!=(const Edge& v) const { 
       
   530 	return !(*this==v);
       
   531       }
       
   532     };
       
   533 
       
   534     using Parent::forward;
       
   535     using Parent::backward;
       
   536     using Parent::setForward;
       
   537     using Parent::setBackward;
       
   538     static bool forward(const Edge& e) { return !e.backward; }
       
   539     static bool backward(const Edge& e) { return e.backward; }
       
   540     static void setForward(Edge& e) { e.backward=false; }
       
   541     static void setBackward(Edge& e) { e.backward=true; }
       
   542   };
       
   543 
       
   544 
       
   545   /*! A grah wrapper base class 
       
   546     for merging the node-sets and edge-sets of 
       
   547     two node-disjoint graphs 
       
   548     into one graph. 
       
   549     Specialized implementation for the case 
       
   550     when _Graph1::Edge is derived from _Graph2::Edge.
       
   551    */
       
   552   template <typename _Graph1, typename _Graph2>
       
   553   class MergeEdgeGraphWrapperBaseBase<
       
   554     _Graph1, _Graph2, typename boost::enable_if<
       
   555     boost::is_base_and_derived<typename _Graph2::Edge, typename _Graph1::Edge> >::type> : 
       
   556     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
       
   557   public:
       
   558     static void printEdge() { std::cout << "edge: 1st is derived" << std::endl; }
       
   559     typedef _Graph1 Graph1;
       
   560     typedef _Graph2 Graph2;
       
   561     typedef MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2> Parent;
       
   562     typedef typename Parent::Parent1 Parent1;
       
   563     typedef typename Parent::Parent2 Parent2;
       
   564 //     typedef P1<_Graph1> Parent1;
       
   565 //     typedef P2<_Graph2> Parent2;
       
   566     typedef typename Parent1::Edge Graph1Edge;
       
   567     typedef typename Parent2::Edge Graph2Edge;
       
   568   protected:
       
   569     MergeEdgeGraphWrapperBaseBase() { }
       
   570   public:
       
   571 
       
   572     class Edge : public Graph1Edge {
       
   573       friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
       
   574     protected:
       
   575       bool backward; //true, iff backward
       
   576     public:
       
   577       Edge() { }
       
   578       /// \todo =false is needed, or causes problems?
       
   579       /// If \c _backward is false, then we get an edge corresponding to the 
       
   580       /// original one, otherwise its oppositely directed pair is obtained.
       
   581       Edge(const Graph1Edge& n1, 
       
   582 	   const Graph2Edge& n2, bool _backward) : 
       
   583 	Graph1Edge(n1), backward(_backward) { 
       
   584 	if (backward) *this=n2;
       
   585       }
       
   586       Edge(Invalid i) : Graph1Edge(i), backward(true) { }
       
   587       bool operator==(const Edge& v) const { 
       
   588 	if (backward) 
       
   589 	  return (v.backward && 
       
   590 		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
       
   591 	else 
       
   592 	  return (!v.backward && 
       
   593 		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
       
   594       } 
       
   595       bool operator!=(const Edge& v) const { 
       
   596 	return !(*this==v);
       
   597       }
       
   598     };
       
   599 
       
   600     using Parent::forward;
       
   601     using Parent::backward;
       
   602     using Parent::setForward;
       
   603     using Parent::setBackward;
       
   604     static bool forward(const Edge& e) { return !e.backward; }
       
   605     static bool backward(const Edge& e) { return e.backward; }
       
   606     static void setForward(Edge& e) { e.backward=false; }
       
   607     static void setBackward(Edge& e) { e.backward=true; }
       
   608   };
       
   609 
       
   610 
       
   611   template <typename _Graph1, typename _Graph2>
       
   612   class MergeEdgeGraphWrapperBase : 
       
   613     public MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2> {
       
   614   public:
       
   615     typedef MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2> Parent;
       
   616     typedef _Graph1 Graph1;
       
   617     typedef _Graph2 Graph2;
       
   618     typedef typename Parent::Parent1 Parent1;
       
   619     typedef typename Parent::Parent2 Parent2;
       
   620     typedef typename Parent1::Node Graph1Node;
       
   621     typedef typename Parent2::Node Graph2Node;
       
   622     typedef typename Parent1::Edge Graph1Edge;
       
   623     typedef typename Parent2::Edge Graph2Edge;
       
   624 
       
   625     typedef typename Parent::Node Node;
       
   626     typedef typename Parent::Edge Edge;
       
   627 
       
   628     using Parent::first;
       
   629     void first(Edge& i) const {
       
   630       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
       
   631       this->setForward(i);
       
   632       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   633 	Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
   634 	this->setBackward(i);
       
   635       }
       
   636     }
       
   637     void firstIn(Edge& i, const Node& n) const {
       
   638       if (forward(n)) {
       
   639 	Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
       
   640 	if (*static_cast<Graph1Edge*>(&i)==INVALID) 
       
   641 	  i=INVALID;
       
   642 	else
       
   643 	  this->setForward(i);
       
   644       } else {
       
   645 	Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
       
   646 	this->setBackward(i);
       
   647       }
       
   648     }
       
   649     void firstOut(Edge& i, const Node& n) const {
       
   650       if (forward(n)) {
       
   651 	Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
       
   652 	if (*static_cast<Graph1Edge*>(&i)==INVALID) 
       
   653 	  i=INVALID;
       
   654 	else
       
   655 	  this->setForward(i);
       
   656       } else {
       
   657 	Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
       
   658 	this->setBackward(i);
       
   659       }
       
   660     }
       
   661 
       
   662     using Parent::next;
       
   663     void next(Edge& i) const {
       
   664       if (forward(i)) {
       
   665 	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
       
   666 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   667 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
   668 	  this->setBackward(i);
       
   669 	}
       
   670       } else {
       
   671 	Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
       
   672       }
       
   673     }
       
   674     void nextIn(Edge& i) const {
       
   675       if (forward(i)) {
       
   676 	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
       
   677  	if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
       
   678       } else {
       
   679 	Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
       
   680       }
       
   681     }
       
   682     void nextOut(Edge& i) const {
       
   683       if (Parent::forward(i)) {
       
   684 	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
       
   685  	if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
       
   686       } else {
       
   687 	Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
       
   688       }
       
   689     }
       
   690 
       
   691     Node source(const Edge& i) const {
       
   692       if (forward(i)) {
       
   693 	return 
       
   694 	  Node(Parent1::graph->source(i), INVALID, false);
       
   695       } else {
       
   696 	return 
       
   697 	  Node(INVALID, Parent2::graph->source(i), true);
       
   698       }
       
   699     }
       
   700 
       
   701     Node target(const Edge& i) const {
       
   702       if (forward(i)) {
       
   703 	return 
       
   704 	  Node(Parent1::graph->target(i), INVALID, false);
       
   705       } else {
       
   706 	return 
       
   707 	  Node(INVALID, Parent2::graph->target(i), true);
       
   708       }
       
   709     }
       
   710 
       
   711     using Parent::id;
       
   712     int id(const Edge& n) const { 
       
   713       if (forward(n)) 
       
   714 	return this->Parent1::graph->id(n);
       
   715       else
       
   716 	return this->Parent2::graph->id(n);
       
   717     }
       
   718 
       
   719     template <typename _Value> 
       
   720     class EdgeMap { 
       
   721     protected:
       
   722       typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
       
   723       typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
       
   724       ParentMap1 forward_map;
       
   725       ParentMap2 backward_map;
       
   726     public:
       
   727       typedef _Value Value;
       
   728       typedef Edge Key;
       
   729       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
   730 	forward_map(*(gw.Parent1::graph)), 
       
   731 	backward_map(*(gw.Parent2::graph)) { }
       
   732       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
   733 	      const _Value& value) : 
       
   734 	forward_map(*(gw.Parent1::graph), value), 
       
   735 	backward_map(*(gw.Parent2::graph), value) { }
       
   736       _Value operator[](const Edge& n) const {
       
   737 	if (Parent::forward(n)) 
       
   738 	  return forward_map[n];
       
   739 	else 
       
   740 	  return backward_map[n];
       
   741       }
       
   742       void set(const Edge& n, const _Value& value) {
       
   743 	if (Parent::forward(n)) 
       
   744 	  forward_map.set(n, value);
       
   745 	else 
       
   746 	  backward_map.set(n, value);
       
   747       }
       
   748 //       using ParentMap1::operator[];
       
   749 //       using ParentMap2::operator[];
       
   750     };
       
   751 
       
   752   };
       
   753 
       
   754 
       
   755 
       
   756   /*! A graph wrapper class 
       
   757     for merging two node-disjoint graphs 
       
   758     into one graph. 
       
   759     Different implementations are according to the relation of 
       
   760     _Graph1::Edge and _Graph2::Edge. 
       
   761     If _Graph1::Edge and _Graph2::Edge are unrelated, then 
       
   762     MergeEdgeGraphWrapper<_Graph1, _Graph2>::Edge 
       
   763     is derived from both. 
       
   764     If _Graph1::Edge and _Graph2::Edge are the same type, then 
       
   765     MergeEdgeGraphWrapper<_Graph1, _Graph2>::Edge 
       
   766     is derived from _Graph1::Edge. 
       
   767     If one of _Graph1::Edge and _Graph2::Edge 
       
   768     is derived from the other one, then 
       
   769     MergeEdgeGraphWrapper<_Graph1, _Graph2>::Edge 
       
   770     is derived from the derived type.
       
   771     It does not satisfy 
       
   772   */
       
   773   template <typename _Graph1, typename _Graph2>
       
   774   class MergeEdgeGraphWrapper : public 
       
   775   IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
       
   776   public:
       
   777     typedef _Graph1 Graph1;
       
   778     typedef _Graph2 Graph2;
       
   779     typedef IterableGraphExtender<
       
   780       MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > Parent;
       
   781   protected:
       
   782     MergeEdgeGraphWrapper() { }
       
   783   public:
       
   784     MergeEdgeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
       
   785       Parent::Parent1::setGraph(_graph1);
       
   786       Parent::Parent2::setGraph(_graph2);
       
   787     }
       
   788   };
       
   789 
       
   790   
       
   791   /*! A graph wrapper base class for the following functionality.
       
   792     If a bijection is given between the node-sets of two graphs, 
       
   793     then the second one can be considered as a new edge-set 
       
   794     over th first node-set. 
       
   795    */
       
   796   template <typename _Graph, typename _EdgeSetGraph>
       
   797   class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> {
       
   798   public:
       
   799     typedef GraphWrapperBase<_Graph> Parent; 
       
   800     typedef _Graph Graph;
       
   801     typedef _EdgeSetGraph EdgeSetGraph;
       
   802     typedef typename _Graph::Node Node;
       
   803     typedef typename _EdgeSetGraph::Node ENode;
       
   804   protected:
       
   805     EdgeSetGraph* edge_set_graph;
       
   806     typename Graph::NodeMap<ENode>* e_node;
       
   807     typename EdgeSetGraph::NodeMap<Node>* n_node;
       
   808     void setEdgeSetGraph(EdgeSetGraph& _edge_set_graph) { 
       
   809       edge_set_graph=&_edge_set_graph; 
       
   810     }
       
   811     /// For each node of \c Graph, this gives a node of \c EdgeSetGraph .
       
   812     void setNodeMap(typename EdgeSetGraph::NodeMap<Node>& _n_node) { 
       
   813       n_node=&_n_node; 
       
   814     }
       
   815     /// For each node of \c EdgeSetGraph, this gives a node of \c Graph .
       
   816     void setENodeMap(typename Graph::NodeMap<ENode>& _e_node) { 
       
   817       e_node=&_e_node; 
       
   818     }
       
   819   public:
       
   820     class Edge : public EdgeSetGraph::Edge {
       
   821       typedef typename EdgeSetGraph::Edge Parent;
       
   822     public:
       
   823       Edge() { }
       
   824       Edge(const Parent& e) : Parent(e) { }
       
   825       Edge(Invalid i) : Parent(i) { }
       
   826     };
       
   827 
       
   828     using Parent::first;
       
   829     void first(Edge &e) const { 
       
   830       edge_set_graph->first(e);
       
   831     }
       
   832     void firstOut(Edge& e, const Node& n) const {
       
   833 //       cout << e_node << endl;
       
   834 //       cout << n_node << endl;
       
   835       edge_set_graph->firstOut(e, (*e_node)[n]);
       
   836     }
       
   837     void firstIn(Edge& e, const Node& n) const {
       
   838       edge_set_graph->firstIn(e, (*e_node)[n]);
       
   839     }
       
   840 
       
   841     using Parent::next;
       
   842     void next(Edge &e) const { 
       
   843       edge_set_graph->next(e);
       
   844     }
       
   845     void nextOut(Edge& e) const {
       
   846       edge_set_graph->nextOut(e);
       
   847     }
       
   848     void nextIn(Edge& e) const {
       
   849       edge_set_graph->nextIn(e);
       
   850     }
       
   851 
       
   852     Node source(const Edge& e) const { 
       
   853       return (*n_node)[edge_set_graph->source(e)];
       
   854     }
       
   855     Node target(const Edge& e) const { 
       
   856       return (*n_node)[edge_set_graph->target(e)];
       
   857     }
       
   858 
       
   859     int edgeNum() const { return edge_set_graph->edgeNum(); }
       
   860 
       
   861 //     NNode addOldNode() {
       
   862 //       return Parent::addNode();
       
   863 //     }
       
   864 
       
   865 //     ENode addNewNode() {
       
   866 //       return edge_set_graph->addNode();
       
   867 //     }
       
   868 
       
   869     Edge addEdge(const Node& u, const Node& v) {
       
   870       return edge_set_graph->addEdge((*e_node)[u], (*e_node)[v]);
       
   871     }
       
   872 
       
   873     using Parent::erase;
       
   874     void erase(const Edge& i) const { edge_set_graph->erase(i); }
       
   875   
       
   876     void clear() const { Parent::clear(); edge_set_graph->clear(); }
       
   877 
       
   878     bool forward(const Edge& e) const { return edge_set_graph->forward(e); }
       
   879     bool backward(const Edge& e) const { return edge_set_graph->backward(e); }
       
   880 
       
   881     int id(const Node& e) const { return Parent::id(e); }
       
   882     int id(const Edge& e) const { return edge_set_graph->id(e); }
       
   883     
       
   884     Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); }
       
   885 
       
   886     template <typename _Value>
       
   887     class EdgeMap : public EdgeSetGraph::EdgeMap<_Value> {
       
   888     public:
       
   889       typedef typename EdgeSetGraph::EdgeMap<_Value> Parent; 
       
   890       typedef _Value Value;
       
   891       typedef Edge Key;
       
   892       EdgeMap(const NewEdgeSetGraphWrapperBase& gw) : 
       
   893 	Parent(*(gw.edge_set_graph)) { }
       
   894       EdgeMap(const NewEdgeSetGraphWrapperBase& gw, const _Value& _value) : 
       
   895 	Parent(*(gw.edge_set_graph), _value) { }
       
   896     };
       
   897 
       
   898   };
       
   899 
       
   900 
       
   901   /*! A graph wrapper class for the following functionality.
       
   902     If a bijection is given between the node-sets of two graphs, 
       
   903     then the second one can be considered as a new edge-set 
       
   904     over th first node-set. 
       
   905    */
       
   906   template <typename _Graph, typename _EdgeSetGraph>
       
   907   class NewEdgeSetGraphWrapper : 
       
   908     public IterableGraphExtender<
       
   909     NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > {
       
   910   public:
       
   911     typedef _Graph Graph;
       
   912     typedef _EdgeSetGraph EdgeSetGraph;
       
   913     typedef IterableGraphExtender<
       
   914       NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > Parent;
       
   915   protected:
       
   916     NewEdgeSetGraphWrapper() { }
       
   917   public:
       
   918     NewEdgeSetGraphWrapper(_Graph& _graph, 
       
   919 			   _EdgeSetGraph& _edge_set_graph, 
       
   920 			   typename _Graph::
       
   921 			   NodeMap<typename _EdgeSetGraph::Node>& _e_node, 
       
   922 			   typename _EdgeSetGraph::
       
   923 			   NodeMap<typename _Graph::Node>& _n_node) { 
       
   924       setGraph(_graph);
       
   925       setEdgeSetGraph(_edge_set_graph);
       
   926       setNodeMap(_n_node);
       
   927       setENodeMap(_e_node);
       
   928     }
       
   929   };
       
   930 
       
   931   /*! A graph wrapper class for the following functionality.
       
   932     The same as NewEdgeSetGrapWrapper, but the bijection and the graph of 
       
   933     new edges is andled inthe class.
       
   934    */
       
   935   template <typename _Graph, typename _EdgeSetGraph>
       
   936   class NewEdgeSetGraphWrapper2 : 
       
   937     public IterableGraphExtender<
       
   938     NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > {
       
   939   public:
       
   940     typedef _Graph Graph;
       
   941     typedef _EdgeSetGraph EdgeSetGraph;
       
   942     typedef IterableGraphExtender<
       
   943       NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > Parent;
       
   944   protected:
       
   945     _EdgeSetGraph _edge_set_graph;
       
   946     typename Graph::template NodeMap<typename EdgeSetGraph::Node> _e_node;
       
   947     typename EdgeSetGraph::template NodeMap<typename Graph::Node> _n_node;
       
   948     NewEdgeSetGraphWrapper2() { }
       
   949   public:
       
   950     typedef typename Graph::Node Node;
       
   951     //    typedef typename Parent::Edge Edge;
       
   952 
       
   953     NewEdgeSetGraphWrapper2(_Graph& _graph) : 
       
   954       _edge_set_graph(), 
       
   955       _e_node(_graph), _n_node(_edge_set_graph) { 
       
   956       setGraph(_graph);
       
   957       setEdgeSetGraph(_edge_set_graph);
       
   958       setNodeMap(_n_node); setENodeMap(_e_node);
       
   959       Node n;
       
   960       for (this->first(n); n!=INVALID; this->next(n)) {
       
   961 	typename EdgeSetGraph::Node e=_edge_set_graph.addNode();
       
   962 	_e_node.set(n, e);
       
   963 	_n_node.set(e, n);
       
   964       }
       
   965     }
       
   966 
       
   967 //     Node addNode() {
       
   968 //       Node n=(*this).Parent::addNode();
       
   969 //       typename EdgeSetGraph::Node e=_edge_set_graph.addNode();
       
   970 //       _e_node.set(n, e);
       
   971 //       _n_node.set(e, n);
       
   972 //       return n;
       
   973 //     }
       
   974 
       
   975   };
       
   976 
       
   977   /*! A graph wrapper base class 
       
   978     for merging graphs of type _Graph1 and _Graph2 
       
   979     which are given on the same node-set 
       
   980     (specially on the node-set of Graph1) 
       
   981     into one graph.
       
   982     In an other point of view, _Graph1 is extended with 
       
   983     the edge-set of _Graph2.
       
   984     \warning we need specialize dimplementations
       
   985     \todo we need specialize dimplementations
       
   986     \bug we need specialize dimplementations
       
   987    */
       
   988   template <typename _Graph1, typename _Graph2, typename Enable=void>
       
   989   class AugmentingGraphWrapperBase : 
       
   990     public P1<_Graph1> {
       
   991   public:
       
   992     void printAugment() const { std::cout << "generic" << std::endl; }
       
   993     typedef _Graph1 Graph1;
       
   994     typedef _Graph2 Graph2;
       
   995     typedef P1<_Graph1> Parent1;
       
   996     typedef P2<_Graph2> Parent2;
       
   997     typedef typename Parent1::Edge Graph1Edge;
       
   998     typedef typename Parent2::Edge Graph2Edge;
       
   999   protected:
       
  1000     AugmentingGraphWrapperBase() { }
       
  1001     _Graph2* graph2;
       
  1002     void setGraph2(_Graph2& _graph2) { graph2=&_graph2; }
       
  1003   public:
       
  1004     
       
  1005     template <typename _Value> class EdgeMap;
       
  1006 
       
  1007     typedef typename Parent1::Node Node;
       
  1008 
       
  1009     class Edge : public Graph1Edge, public Graph2Edge {
       
  1010       friend class AugmentingGraphWrapperBase<_Graph1, _Graph2>;
       
  1011       template <typename _Value> friend class EdgeMap;
       
  1012     protected:
       
  1013       bool backward; //true, iff backward
       
  1014     public:
       
  1015       Edge() { }
       
  1016       /// \todo =false is needed, or causes problems?
       
  1017       /// If \c _backward is false, then we get an edge corresponding to the 
       
  1018       /// original one, otherwise its oppositely directed pair is obtained.
       
  1019       Edge(const Graph1Edge& n1, 
       
  1020 	   const Graph2Edge& n2, bool _backward) : 
       
  1021 	Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
       
  1022       Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
       
  1023       bool operator==(const Edge& v) const { 
       
  1024 	if (backward) 
       
  1025 	  return (v.backward && 
       
  1026 		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
       
  1027 	else 
       
  1028 	  return (!v.backward && 
       
  1029 		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
       
  1030       } 
       
  1031       bool operator!=(const Edge& v) const { 
       
  1032 	return !(*this==v);
       
  1033       }
       
  1034     };
       
  1035 
       
  1036     using Parent1::first;
       
  1037     void first(Edge& i) const {
       
  1038       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
       
  1039       i.backward=false;
       
  1040       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1041 	graph2->first(*static_cast<Graph2Edge*>(&i));
       
  1042 	i.backward=true;
       
  1043       }
       
  1044     }
       
  1045     void firstIn(Edge& i, const Node& n) const {
       
  1046       Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
       
  1047       i.backward=false;
       
  1048       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1049 	graph2->firstIn(*static_cast<Graph2Edge*>(&i), n);
       
  1050 	i.backward=true;
       
  1051       }
       
  1052     }
       
  1053     void firstOut(Edge& i, const Node& n) const {
       
  1054       Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
       
  1055       i.backward=false;
       
  1056       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1057 	graph2->firstOut(*static_cast<Graph2Edge*>(&i), n);
       
  1058 	i.backward=true;
       
  1059       }
       
  1060     }
       
  1061 
       
  1062     using Parent1::next;
       
  1063     void next(Edge& i) const {
       
  1064       if (!(i.backward)) {
       
  1065 	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
       
  1066 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1067 	  graph2->first(*static_cast<Graph2Edge*>(&i));
       
  1068 	  i.backward=true;
       
  1069 	}
       
  1070       } else {
       
  1071 	graph2->next(*static_cast<Graph2Edge*>(&i));
       
  1072       }
       
  1073     }
       
  1074     void nextIn(Edge& i) const {
       
  1075       if (!(i.backward)) {
       
  1076 	Node n=target(i);
       
  1077 	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
       
  1078 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1079 	  graph2->firstIn(*static_cast<Graph2Edge*>(&i), n);
       
  1080 	  i.backward=true;
       
  1081 	}
       
  1082       } else {
       
  1083 	graph2->nextIn(*static_cast<Graph2Edge*>(&i));
       
  1084       }
       
  1085     }
       
  1086     void nextOut(Edge& i) const {
       
  1087       if (!(i.backward)) {
       
  1088 	Node n=source(i);
       
  1089 	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
       
  1090 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1091 	  graph2->firstOut(*static_cast<Graph2Edge*>(&i), n);
       
  1092 	  i.backward=true;
       
  1093 	}
       
  1094       } else {
       
  1095 	graph2->nextOut(*static_cast<Graph2Edge*>(&i));
       
  1096       }
       
  1097     }
       
  1098 
       
  1099     Node source(const Edge& i) const {
       
  1100       if (!(i.backward)) {
       
  1101 	return Parent1::graph->source(i);
       
  1102       } else {
       
  1103 	return graph2->source(i);
       
  1104       }
       
  1105     }
       
  1106 
       
  1107     Node target(const Edge& i) const {
       
  1108       if (!(i.backward)) {
       
  1109 	return Parent1::graph->target(i);
       
  1110       } else {
       
  1111 	return graph2->target(i);
       
  1112       }
       
  1113     }
       
  1114 
       
  1115     int id(const Node& n) const {
       
  1116       return Parent1::id(n);
       
  1117     };
       
  1118     int id(const Edge& n) const { 
       
  1119       if (!n.backward) 
       
  1120 	return this->Parent1::graph->id(n);
       
  1121       else
       
  1122 	return this->graph2->id(n);
       
  1123     }
       
  1124 
       
  1125     template <typename _Value> 
       
  1126     class EdgeMap { 
       
  1127     protected:
       
  1128       typedef typename _Graph1::template EdgeMap<_Value> ParentMap1;
       
  1129       typedef typename _Graph2::template EdgeMap<_Value> ParentMap2;
       
  1130       ParentMap1 forward_map;
       
  1131       ParentMap2 backward_map;
       
  1132     public:
       
  1133       typedef _Value Value;
       
  1134       typedef Edge Key;
       
  1135       EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
  1136 	forward_map(*(gw.Parent1::graph)), 
       
  1137 	backward_map(*(gw.graph2)) { }
       
  1138       EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
  1139 	      const _Value& value) : 
       
  1140 	forward_map(*(gw.Parent1::graph), value), 
       
  1141 	backward_map(*(gw.graph2), value) { }
       
  1142       _Value operator[](const Edge& n) const {
       
  1143 	if (!n.backward) 
       
  1144 	  return forward_map[n];
       
  1145 	else 
       
  1146 	  return backward_map[n];
       
  1147       }
       
  1148       void set(const Edge& n, const _Value& value) {
       
  1149 	if (!n.backward) 
       
  1150 	  forward_map.set(n, value);
       
  1151 	else 
       
  1152 	  backward_map.set(n, value);
       
  1153       }
       
  1154 //       using ParentMap1::operator[];
       
  1155 //       using ParentMap2::operator[];
       
  1156     };
       
  1157 
       
  1158   };
       
  1159 
       
  1160 
       
  1161   /*! A graph wrapper class 
       
  1162     for merging two graphs (of type _Graph1 and _Graph2)
       
  1163     with the same node-set 
       
  1164     (specially on the node-set of Graph1) 
       
  1165     into one graph. 
       
  1166     In an other point of view, _Graph1 is extended with 
       
  1167     the edge-set of _Graph2.
       
  1168    */  
       
  1169   template <typename _Graph1, typename _Graph2>
       
  1170   class AugmentingGraphWrapper : public 
       
  1171   IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> > {
       
  1172   public:
       
  1173     typedef 
       
  1174     IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> >
       
  1175     Parent;
       
  1176     typedef _Graph1 Graph1;
       
  1177     typedef _Graph2 Graph2;
       
  1178   protected:
       
  1179     AugmentingGraphWrapper() { }
       
  1180   public:
       
  1181     AugmentingGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
       
  1182       setGraph(_graph1); 
       
  1183       setGraph2(_graph2);
       
  1184     }
       
  1185   };
       
  1186 
       
  1187 } //namespace lemon
       
  1188 
       
  1189 #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H