src/work/marci/merge_node_graph_wrapper.h
author marci
Sat, 20 Nov 2004 14:23:27 +0000
changeset 1014 aae850a2394d
parent 1009 8cb323dbae93
child 1016 18d009b23e42
permissions -rw-r--r--
Modifications for hugo 0.2
     1 /* -*- C++ -*-
     2  * src/lemon/merge_node_graph_wrapper.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Combinatorial Optimization Research Group, 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   /*! 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.
    47    */
    48   template <typename _Graph1, typename _Graph2, typename Enable=void>
    49   class MergeNodeGraphWrapperBase : 
    50     public P1<_Graph1>, public P2<_Graph2> {
    51   public:
    52     static void printNode() { std::cout << "node: generic" << std::endl; }
    53     typedef _Graph1 Graph1;
    54     typedef _Graph2 Graph2;
    55     typedef P1<_Graph1> Parent1;
    56     typedef P2<_Graph2> Parent2;
    57     typedef typename Parent1::Node Graph1Node;
    58     typedef typename Parent2::Node Graph2Node;
    59   protected:
    60     MergeNodeGraphWrapperBase() { }
    61   public:
    62     template <typename _Value> class NodeMap;
    63 
    64     class Node : public Graph1Node, public Graph2Node {
    65       friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
    66       template <typename _Value> friend class NodeMap;
    67     protected:
    68       bool backward; //true, iff backward
    69     public:
    70       Node() { }
    71       /// \todo =false is needed, or causes problems?
    72       /// If \c _backward is false, then we get an edge corresponding to the 
    73       /// original one, otherwise its oppositely directed pair is obtained.
    74       Node(const Graph1Node& n1, 
    75 	   const Graph2Node& n2, bool _backward) : 
    76 	Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
    77       Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
    78       bool operator==(const Node& v) const { 
    79 	if (backward) 
    80 	  return (v.backward && 
    81 		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
    82 	else 
    83 	  return (!v.backward && 
    84 		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
    85       } 
    86       bool operator!=(const Node& v) const { 
    87 	return !(*this==v);
    88       }
    89     };
    90 
    91     //typedef void Edge;
    92     class Edge { };
    93     
    94     void first(Node& i) const {
    95       Parent1::graph->first(*static_cast<Graph1Node*>(&i));
    96       i.backward=false;
    97       if (*static_cast<Graph1Node*>(&i)==INVALID) {
    98 	Parent2::graph->first(*static_cast<Graph2Node*>(&i));
    99 	i.backward=true;
   100       }
   101     }
   102     void next(Node& i) const {
   103       if (!(i.backward)) {
   104 	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
   105 	if (*static_cast<Graph1Node*>(&i)==INVALID) {
   106 	  Parent2::graph->first(*static_cast<Graph2Node*>(&i));
   107 	  i.backward=true;
   108 	}
   109       } else {
   110 	Parent2::graph->next(*static_cast<Graph2Node*>(&i));
   111       }
   112     }
   113 
   114     int id(const Node& n) const { 
   115       if (!n.backward) 
   116 	return this->Parent1::graph->id(n);
   117       else
   118 	return this->Parent2::graph->id(n);
   119     }
   120 
   121     template <typename _Value> 
   122     class NodeMap { 
   123     protected:
   124       typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
   125       typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
   126       ParentMap1 forward_map;
   127       ParentMap2 backward_map;
   128     public:
   129       typedef _Value Value;
   130       typedef Node Key;
   131       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
   132 	forward_map(*(gw.Parent1::graph)), 
   133 	backward_map(*(gw.Parent2::graph)) { }
   134       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
   135 	      const _Value& value) : 
   136 	forward_map(*(gw.Parent1::graph), value), 
   137 	backward_map(*(gw.Parent2::graph), value) { }
   138       _Value operator[](const Node& n) const {
   139 	if (!n.backward) 
   140 	  return forward_map[n];
   141 	else 
   142 	  return backward_map[n];
   143       }
   144       void set(const Node& n, const _Value& value) {
   145 	if (!n.backward) 
   146 	  forward_map.set(n, value);
   147 	else 
   148 	  backward_map.set(n, value);
   149       }
   150 //       using ParentMap1::operator[];
   151 //       using ParentMap2::operator[];
   152     };
   153 
   154   };
   155 
   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    */
   162   template <typename _Graph1, typename _Graph2>
   163   class MergeNodeGraphWrapperBase<
   164     _Graph1, _Graph2, typename boost::enable_if<
   165     boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   166     public P1<_Graph1>, public P2<_Graph2> {
   167   public:
   168     static void printNode() { std::cout << "node: same" << std::endl; }
   169     typedef _Graph1 Graph1;
   170     typedef _Graph2 Graph2;
   171     typedef P1<_Graph1> Parent1;
   172     typedef P2<_Graph2> Parent2;
   173     typedef typename Parent1::Node Graph1Node;
   174     typedef typename Parent2::Node Graph2Node;
   175   protected:
   176     MergeNodeGraphWrapperBase() { }
   177   public:
   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;
   204     class Edge { };
   205     
   206     void first(Node& i) const {
   207       Parent1::graph->first(*static_cast<Graph1Node*>(&i));
   208       i.backward=false;
   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    */
   276   template <typename _Graph1, typename _Graph2>
   277   class MergeNodeGraphWrapperBase<
   278     _Graph1, _Graph2, typename boost::enable_if<
   279     boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   280     public P1<_Graph1>, public P2<_Graph2> {
   281   public :
   282     static void printNode() { std::cout << "node: 2nd is derived" << std::endl; }
   283     typedef _Graph1 Graph1;
   284     typedef _Graph2 Graph2;
   285     typedef P1<_Graph1> Parent1;
   286     typedef P2<_Graph2> Parent2;
   287     typedef typename Parent1::Node Graph1Node;
   288     typedef typename Parent2::Node Graph2Node;
   289   protected:
   290     MergeNodeGraphWrapperBase() { }
   291   public:
   292     class Node { };
   293     class Edge { };
   294     void first() const;
   295     void next() const;
   296   };
   297 
   298   //not yet working
   299   template <typename _Graph1, typename _Graph2>
   300   class MergeNodeGraphWrapperBase<
   301     _Graph1, _Graph2, typename boost::enable_if<
   302     boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> : 
   303     public P1<_Graph1>, public P2<_Graph2> {
   304   public :
   305     static void printNode() { std::cout << "node: 1st is derived" << std::endl; }
   306     typedef _Graph1 Graph1;
   307     typedef _Graph2 Graph2;
   308     typedef P1<_Graph1> Parent1;
   309     typedef P2<_Graph2> Parent2;
   310     typedef typename Parent1::Node Graph1Node;
   311     typedef typename Parent2::Node Graph2Node;
   312   protected:
   313     MergeNodeGraphWrapperBase() { }
   314   public:
   315     class Node { };
   316     class Edge { };
   317     void first() const;
   318     void next() const;
   319   };
   320 
   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    */
   328   template <typename _Graph1, typename _Graph2>
   329   class MergeNodeGraphWrapper : public 
   330   IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
   331   public:
   332     typedef _Graph1 Graph1;
   333     typedef _Graph2 Graph2;
   334     typedef IterableGraphExtender<
   335       MergeNodeGraphWrapperBase<_Graph1, _Graph2> > Parent;
   336   protected:
   337     MergeNodeGraphWrapper() { }
   338   public:
   339     MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
   340       Parent::Parent1::setGraph(_graph1);
   341       Parent::Parent2::setGraph(_graph2);
   342     }
   343   };
   344 
   345 
   346   /*! A grah wrapper base class 
   347     for merging the node-sets and edge-sets of 
   348     two node-disjoint graphs 
   349     into one graph.
   350     Generic implementation for unrelated _Graph1::Edge and _Graph2::Edge.
   351    */
   352   template <typename _Graph1, typename _Graph2, typename Enable=void>
   353   class MergeEdgeGraphWrapperBase : 
   354     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
   355   public:
   356     static void printEdge() { std::cout << "edge: generic" << std::endl; }
   357     typedef _Graph1 Graph1;
   358     typedef _Graph2 Graph2;
   359     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
   360     typedef typename Parent::Parent1 Parent1;
   361     typedef typename Parent::Parent2 Parent2;
   362 //     typedef P1<_Graph1> Parent1;
   363 //     typedef P2<_Graph2> Parent2;
   364     typedef typename Parent1::Edge Graph1Edge;
   365     typedef typename Parent2::Edge Graph2Edge;
   366   protected:
   367     MergeEdgeGraphWrapperBase() { }
   368   public:
   369     template <typename _Value> class EdgeMap;
   370 
   371     typedef typename Parent::Node Node;
   372 
   373     class Edge : public Graph1Edge, public Graph2Edge {
   374       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
   375       template <typename _Value> friend class EdgeMap;
   376     protected:
   377       bool backward; //true, iff backward
   378     public:
   379       Edge() { }
   380       /// \todo =false is needed, or causes problems?
   381       /// If \c _backward is false, then we get an edge corresponding to the 
   382       /// original one, otherwise its oppositely directed pair is obtained.
   383       Edge(const Graph1Edge& n1, 
   384 	   const Graph2Edge& n2, bool _backward) : 
   385 	Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
   386       Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
   387       bool operator==(const Edge& v) const { 
   388 	if (backward) 
   389 	  return (v.backward && 
   390 		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
   391 	else 
   392 	  return (!v.backward && 
   393 		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
   394       } 
   395       bool operator!=(const Edge& v) const { 
   396 	return !(*this==v);
   397       }
   398     };
   399 
   400     using Parent::first;
   401     void first(Edge& i) const {
   402       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
   403       i.backward=false;
   404       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
   405 	Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
   406 	i.backward=true;
   407       }
   408     }
   409     void firstIn(Edge& i, const Node& n) const {
   410       Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
   411       i.backward=false;
   412       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
   413 	Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
   414 	i.backward=true;
   415       }
   416     }
   417     void firstOut(Edge& i, const Node& n) const {
   418       Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
   419       i.backward=false;
   420       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
   421 	Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
   422 	i.backward=true;
   423       }
   424     }
   425 
   426     using Parent::next;
   427     void next(Edge& i) const {
   428       if (!(i.backward)) {
   429 	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
   430 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
   431 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
   432 	  i.backward=true;
   433 	}
   434       } else {
   435 	Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
   436       }
   437     }
   438     void nextIn(Edge& i) const {
   439       if (!(i.backward)) {
   440 	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
   441 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
   442 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
   443 	  i.backward=true;
   444 	}
   445       } else {
   446 	Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
   447       }
   448     }
   449     void nextOut(Edge& i) const {
   450       if (!(i.backward)) {
   451 	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
   452 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
   453 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
   454 	  i.backward=true;
   455 	}
   456       } else {
   457 	Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
   458       }
   459     }
   460 
   461     Node source(const Edge& i) const {
   462       if (!(i.backward)) {
   463 	return 
   464 	  Node(Parent1::graph->source(i), INVALID, false);
   465       } else {
   466 	return 
   467 	  Node(INVALID, Parent2::graph->source(i), true);
   468       }
   469     }
   470 
   471     Node target(const Edge& i) const {
   472       if (!(i.backward)) {
   473 	return 
   474 	  Node(Parent1::graph->target(i), INVALID, false);
   475       } else {
   476 	return 
   477 	  Node(INVALID, Parent2::graph->target(i), true);
   478       }
   479     }
   480 
   481     using Parent::id;
   482     int id(const Edge& n) const { 
   483       if (!n.backward) 
   484 	return this->Parent1::graph->id(n);
   485       else
   486 	return this->Parent2::graph->id(n);
   487     }
   488 
   489     template <typename _Value> 
   490     class EdgeMap { 
   491     protected:
   492       typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
   493       typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
   494       ParentMap1 forward_map;
   495       ParentMap2 backward_map;
   496     public:
   497       typedef _Value Value;
   498       typedef Edge Key;
   499       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
   500 	forward_map(*(gw.Parent1::graph)), 
   501 	backward_map(*(gw.Parent2::graph)) { }
   502       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
   503 	      const _Value& value) : 
   504 	forward_map(*(gw.Parent1::graph), value), 
   505 	backward_map(*(gw.Parent2::graph), value) { }
   506       _Value operator[](const Edge& n) const {
   507 	if (!n.backward) 
   508 	  return forward_map[n];
   509 	else 
   510 	  return backward_map[n];
   511       }
   512       void set(const Edge& n, const _Value& value) {
   513 	if (!n.backward) 
   514 	  forward_map.set(n, value);
   515 	else 
   516 	  backward_map.set(n, value);
   517       }
   518 //       using ParentMap1::operator[];
   519 //       using ParentMap2::operator[];
   520     };
   521 
   522   };
   523 
   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    */
   708   template <typename _Graph1, typename _Graph2>
   709   class MergeEdgeGraphWrapper : public 
   710   IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
   711   public:
   712     typedef _Graph1 Graph1;
   713     typedef _Graph2 Graph2;
   714     typedef IterableGraphExtender<
   715       MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > Parent;
   716   protected:
   717     MergeEdgeGraphWrapper() { }
   718   public:
   719     MergeEdgeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
   720       Parent::Parent1::setGraph(_graph1);
   721       Parent::Parent2::setGraph(_graph2);
   722     }
   723   };
   724 
   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    */
   731   template <typename _Graph, typename _EdgeSetGraph>
   732   class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> {
   733   public:
   734     typedef GraphWrapperBase<_Graph> Parent; 
   735     typedef _Graph Graph;
   736     typedef _EdgeSetGraph EdgeSetGraph;
   737     typedef typename _Graph::Node Node;
   738     typedef typename _EdgeSetGraph::Node ENode;
   739   protected:
   740     EdgeSetGraph* edge_set_graph;
   741     typename Graph::NodeMap<ENode>* e_node;
   742     typename EdgeSetGraph::NodeMap<Node>* n_node;
   743     void setEdgeSetGraph(EdgeSetGraph& _edge_set_graph) { 
   744       edge_set_graph=&_edge_set_graph; 
   745     }
   746     /// For each node of \c Graph, this gives a node of \c EdgeSetGraph .
   747     void setNodeMap(typename EdgeSetGraph::NodeMap<Node>& _n_node) { 
   748       n_node=&_n_node; 
   749     }
   750     /// For each node of \c EdgeSetGraph, this gives a node of \c Graph .
   751     void setENodeMap(typename Graph::NodeMap<ENode>& _e_node) { 
   752       e_node=&_e_node; 
   753     }
   754   public:
   755     class Edge : public EdgeSetGraph::Edge {
   756       typedef typename EdgeSetGraph::Edge Parent;
   757     public:
   758       Edge() { }
   759       Edge(const Parent& e) : Parent(e) { }
   760       Edge(Invalid i) : Parent(i) { }
   761     };
   762 
   763     using Parent::first;
   764     void first(Edge &e) const { 
   765       edge_set_graph->first(e);
   766     }
   767     void firstOut(Edge& e, const Node& n) const {
   768 //       cout << e_node << endl;
   769 //       cout << n_node << endl;
   770       edge_set_graph->firstOut(e, (*e_node)[n]);
   771     }
   772     void firstIn(Edge& e, const Node& n) const {
   773       edge_set_graph->firstIn(e, (*e_node)[n]);
   774     }
   775 
   776     using Parent::next;
   777     void next(Edge &e) const { 
   778       edge_set_graph->next(e);
   779     }
   780     void nextOut(Edge& e) const {
   781       edge_set_graph->nextOut(e);
   782     }
   783     void nextIn(Edge& e) const {
   784       edge_set_graph->nextIn(e);
   785     }
   786 
   787     Node source(const Edge& e) const { 
   788       return (*n_node)[edge_set_graph->source(e)];
   789     }
   790     Node target(const Edge& e) const { 
   791       return (*n_node)[edge_set_graph->target(e)];
   792     }
   793 
   794     int edgeNum() const { return edge_set_graph->edgeNum(); }
   795 
   796     Edge addEdge(const Node& u, const Node& v) {
   797       return edge_set_graph->addEdge((*e_node)[u], (*e_node)[v]);
   798     }
   799 
   800     using Parent::erase;
   801     void erase(const Edge& i) const { edge_set_graph->erase(i); }
   802   
   803     void clear() const { Parent::clear(); edge_set_graph->clear(); }
   804 
   805     bool forward(const Edge& e) const { return edge_set_graph->forward(e); }
   806     bool backward(const Edge& e) const { return edge_set_graph->backward(e); }
   807 
   808     int id(const Node& e) const { return Parent::id(e); }
   809     int id(const Edge& e) const { return edge_set_graph->id(e); }
   810     
   811     Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); }
   812 
   813     template <typename _Value>
   814     class EdgeMap : public EdgeSetGraph::EdgeMap<_Value> {
   815     public:
   816       typedef typename EdgeSetGraph::EdgeMap<_Value> Parent; 
   817       typedef _Value Value;
   818       typedef Edge Key;
   819       EdgeMap(const NewEdgeSetGraphWrapperBase& gw) : 
   820 	Parent(*(gw.edge_set_graph)) { }
   821       EdgeMap(const NewEdgeSetGraphWrapperBase& gw, const _Value& _value) : 
   822 	Parent(*(gw.edge_set_graph), _value) { }
   823     };
   824 
   825   };
   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    */
   833   template <typename _Graph, typename _EdgeSetGraph>
   834   class NewEdgeSetGraphWrapper : 
   835     public IterableGraphExtender<
   836     NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > {
   837   public:
   838     typedef _Graph Graph;
   839     typedef _EdgeSetGraph EdgeSetGraph;
   840     typedef IterableGraphExtender<
   841       NewEdgeSetGraphWrapper<_Graph, _EdgeSetGraph> > Parent;
   842   protected:
   843     NewEdgeSetGraphWrapper() { }
   844   public:
   845     NewEdgeSetGraphWrapper(_Graph& _graph, 
   846 			   _EdgeSetGraph& _edge_set_graph, 
   847 			   typename _Graph::
   848 			   NodeMap<typename _EdgeSetGraph::Node>& _e_node, 
   849 			   typename _EdgeSetGraph::
   850 			   NodeMap<typename _Graph::Node>& _n_node) { 
   851       setGraph(_graph);
   852       setEdgeSetGraph(_edge_set_graph);
   853       setNodeMap(_n_node);
   854       setENodeMap(_e_node);
   855     }
   856   };
   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 
  1064 } //namespace lemon
  1065 
  1066 #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H