src/work/marci/merge_node_graph_wrapper.h
changeset 1021 fd1d073b6557
parent 1013 b3bdd856faf4
child 1025 3b1ad8bc21da
equal deleted inserted replaced
7:86da8bcef4fc 8:75b307ecac62
   268 
   268 
   269   /*! A graph wrapper base class 
   269   /*! A graph wrapper base class 
   270     for merging the node-set of two node-disjoint graphs 
   270     for merging the node-set of two node-disjoint graphs 
   271     into the node-set of one graph. 
   271     into the node-set of one graph. 
   272     Specialization for the case when 
   272     Specialization for the case when 
   273     _Graph1::Node are base and derived _Graph2::Node.
   273     _Graph1::Node is a base class and _Graph2::Node is derived from it.
   274     NOT YET IMPLEMENTED
       
   275    */
   274    */
   276   template <typename _Graph1, typename _Graph2>
   275   template <typename _Graph1, typename _Graph2>
   277   class MergeNodeGraphWrapperBase<
   276   class MergeNodeGraphWrapperBase<
   278     _Graph1, _Graph2, typename boost::enable_if<
   277     _Graph1, _Graph2, typename boost::enable_if<
   279     boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   278     boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   287     typedef typename Parent1::Node Graph1Node;
   286     typedef typename Parent1::Node Graph1Node;
   288     typedef typename Parent2::Node Graph2Node;
   287     typedef typename Parent2::Node Graph2Node;
   289   protected:
   288   protected:
   290     MergeNodeGraphWrapperBase() { }
   289     MergeNodeGraphWrapperBase() { }
   291   public:
   290   public:
   292     class Node { };
   291     template <typename _Value> class NodeMap;
       
   292 
       
   293     class Node : public Graph2Node {
       
   294       friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
       
   295       template <typename _Value> friend class NodeMap;
       
   296     protected:
       
   297       bool backward; //true, iff backward
       
   298     public:
       
   299       Node() { }
       
   300       /// \todo =false is needed, or causes problems?
       
   301       /// If \c _backward is false, then we get an edge corresponding to the 
       
   302       /// original one, otherwise its oppositely directed pair is obtained.
       
   303       Node(const Graph1Node& n1, 
       
   304 	   const Graph2Node& n2, bool _backward) : 
       
   305 	Graph2Node(n2), backward(_backward) { 
       
   306 	if (!backward) *this=n1;
       
   307       }
       
   308       Node(Invalid i) : Graph2Node(i), backward(true) { }
       
   309       bool operator==(const Node& v) const { 
       
   310 	if (backward) 
       
   311 	  return (v.backward && 
       
   312 		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
       
   313 	else 
       
   314 	  return (!v.backward && 
       
   315 		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
       
   316       } 
       
   317       bool operator!=(const Node& v) const { 
       
   318 	return !(*this==v);
       
   319       }
       
   320     };
       
   321 
       
   322     //typedef void Edge;
   293     class Edge { };
   323     class Edge { };
   294     void first() const;
   324     
   295     void next() const;
   325     void first(Node& i) const {
       
   326       Parent1::graph->first(*static_cast<Graph1Node*>(&i));
       
   327       i.backward=false;
       
   328       if (*static_cast<Graph1Node*>(&i)==INVALID) {
       
   329 	Parent2::graph->first(*static_cast<Graph2Node*>(&i));
       
   330 	i.backward=true;
       
   331       }
       
   332     }
       
   333     void next(Node& i) const {
       
   334       if (!(i.backward)) {
       
   335 	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
       
   336 	if (*static_cast<Graph1Node*>(&i)==INVALID) {
       
   337 	  Parent2::graph->first(*static_cast<Graph2Node*>(&i));
       
   338 	  i.backward=true;
       
   339 	}
       
   340       } else {
       
   341 	Parent2::graph->next(*static_cast<Graph2Node*>(&i));
       
   342       }
       
   343     }
       
   344 
       
   345     int id(const Node& n) const { 
       
   346       if (!n.backward) 
       
   347 	return this->Parent1::graph->id(n);
       
   348       else
       
   349 	return this->Parent2::graph->id(n);
       
   350     }
       
   351 
       
   352     template <typename _Value> 
       
   353     class NodeMap { 
       
   354     protected:
       
   355       typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
       
   356       typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
       
   357       ParentMap1 forward_map;
       
   358       ParentMap2 backward_map;
       
   359     public:
       
   360       typedef _Value Value;
       
   361       typedef Node Key;
       
   362       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
   363 	forward_map(*(gw.Parent1::graph)), 
       
   364 	backward_map(*(gw.Parent2::graph)) { }
       
   365       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
   366 	      const _Value& value) : 
       
   367 	forward_map(*(gw.Parent1::graph), value), 
       
   368 	backward_map(*(gw.Parent2::graph), value) { }
       
   369       _Value operator[](const Node& n) const {
       
   370 	if (!n.backward) 
       
   371 	  return forward_map[n];
       
   372 	else 
       
   373 	  return backward_map[n];
       
   374       }
       
   375       void set(const Node& n, const _Value& value) {
       
   376 	if (!n.backward) 
       
   377 	  forward_map.set(n, value);
       
   378 	else 
       
   379 	  backward_map.set(n, value);
       
   380       }
       
   381 //       using ParentMap1::operator[];
       
   382 //       using ParentMap2::operator[];
       
   383     };
       
   384 
   296   };
   385   };
   297 
   386 
   298   //not yet working
   387 
       
   388   /*! A graph wrapper base class 
       
   389     for merging the node-set of two node-disjoint graphs 
       
   390     into the node-set of one graph. 
       
   391     Specialized implementaton for the case when _Graph1::Node is derived 
       
   392     from _Graph2::Node.
       
   393    */
   299   template <typename _Graph1, typename _Graph2>
   394   template <typename _Graph1, typename _Graph2>
   300   class MergeNodeGraphWrapperBase<
   395   class MergeNodeGraphWrapperBase<
   301     _Graph1, _Graph2, typename boost::enable_if<
   396     _Graph1, _Graph2, typename boost::enable_if<
   302     boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> : 
   397     boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> : 
   303     public P1<_Graph1>, public P2<_Graph2> {
   398     public P1<_Graph1>, public P2<_Graph2> {
   310     typedef typename Parent1::Node Graph1Node;
   405     typedef typename Parent1::Node Graph1Node;
   311     typedef typename Parent2::Node Graph2Node;
   406     typedef typename Parent2::Node Graph2Node;
   312   protected:
   407   protected:
   313     MergeNodeGraphWrapperBase() { }
   408     MergeNodeGraphWrapperBase() { }
   314   public:
   409   public:
   315     class Node { };
   410     template <typename _Value> class NodeMap;
       
   411 
       
   412     class Node : public Graph1Node {
       
   413       friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
       
   414       template <typename _Value> friend class NodeMap;
       
   415     protected:
       
   416       bool backward; //true, iff backward
       
   417     public:
       
   418       Node() { }
       
   419       /// \todo =false is needed, or causes problems?
       
   420       /// If \c _backward is false, then we get an edge corresponding to the 
       
   421       /// original one, otherwise its oppositely directed pair is obtained.
       
   422       Node(const Graph1Node& n1, 
       
   423 	   const Graph2Node& n2, bool _backward) : 
       
   424 	Graph1Node(n1), backward(_backward) { 
       
   425 	if (backward) *this=n2;
       
   426       }
       
   427       Node(Invalid i) : Graph1Node(i), backward(true) { }
       
   428       bool operator==(const Node& v) const { 
       
   429 	if (backward) 
       
   430 	  return (v.backward && 
       
   431 		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
       
   432 	else 
       
   433 	  return (!v.backward && 
       
   434 		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
       
   435       } 
       
   436       bool operator!=(const Node& v) const { 
       
   437 	return !(*this==v);
       
   438       }
       
   439     };
       
   440 
       
   441     //typedef void Edge;
   316     class Edge { };
   442     class Edge { };
   317     void first() const;
   443     
   318     void next() const;
   444     void first(Node& i) const {
       
   445       Parent1::graph->first(*static_cast<Graph1Node*>(&i));
       
   446       i.backward=false;
       
   447       if (*static_cast<Graph1Node*>(&i)==INVALID) {
       
   448 	Parent2::graph->first(*static_cast<Graph2Node*>(&i));
       
   449 	i.backward=true;
       
   450       }
       
   451     }
       
   452     void next(Node& i) const {
       
   453       if (!(i.backward)) {
       
   454 	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
       
   455 	if (*static_cast<Graph1Node*>(&i)==INVALID) {
       
   456 	  Parent2::graph->first(*static_cast<Graph2Node*>(&i));
       
   457 	  i.backward=true;
       
   458 	}
       
   459       } else {
       
   460 	Parent2::graph->next(*static_cast<Graph2Node*>(&i));
       
   461       }
       
   462     }
       
   463 
       
   464     int id(const Node& n) const { 
       
   465       if (!n.backward) 
       
   466 	return this->Parent1::graph->id(n);
       
   467       else
       
   468 	return this->Parent2::graph->id(n);
       
   469     }
       
   470 
       
   471     template <typename _Value> 
       
   472     class NodeMap { 
       
   473     protected:
       
   474       typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
       
   475       typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
       
   476       ParentMap1 forward_map;
       
   477       ParentMap2 backward_map;
       
   478     public:
       
   479       typedef _Value Value;
       
   480       typedef Node Key;
       
   481       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
   482 	forward_map(*(gw.Parent1::graph)), 
       
   483 	backward_map(*(gw.Parent2::graph)) { }
       
   484       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
   485 	      const _Value& value) : 
       
   486 	forward_map(*(gw.Parent1::graph), value), 
       
   487 	backward_map(*(gw.Parent2::graph), value) { }
       
   488       _Value operator[](const Node& n) const {
       
   489 	if (!n.backward) 
       
   490 	  return forward_map[n];
       
   491 	else 
       
   492 	  return backward_map[n];
       
   493       }
       
   494       void set(const Node& n, const _Value& value) {
       
   495 	if (!n.backward) 
       
   496 	  forward_map.set(n, value);
       
   497 	else 
       
   498 	  backward_map.set(n, value);
       
   499       }
       
   500 //       using ParentMap1::operator[];
       
   501 //       using ParentMap2::operator[];
       
   502     };
       
   503 
   319   };
   504   };
   320 
   505 
   321 
   506 
   322   /*! A graph wrapper class 
   507   /*! A graph wrapper class 
   323     fors merging the node-set of two node-disjoint graphs 
   508     fors merging the node-set of two node-disjoint graphs 
   530     are the same.
   715     are the same.
   531    */
   716    */
   532   template <typename _Graph1, typename _Graph2>
   717   template <typename _Graph1, typename _Graph2>
   533   class MergeEdgeGraphWrapperBase<
   718   class MergeEdgeGraphWrapperBase<
   534     _Graph1, _Graph2, typename boost::enable_if<
   719     _Graph1, _Graph2, typename boost::enable_if<
   535     boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   720     boost::is_same<typename _Graph1::Edge, typename _Graph2::Edge> >::type> : 
   536     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
   721     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
   537   public:
   722   public:
   538     static void printEdge() { std::cout << "edge: same" << std::endl; }
   723     static void printEdge() { std::cout << "edge: same" << std::endl; }
   539     typedef _Graph1 Graph1;
   724     typedef _Graph1 Graph1;
   540     typedef _Graph2 Graph2;
   725     typedef _Graph2 Graph2;
   698     };
   883     };
   699 
   884 
   700   };
   885   };
   701 
   886 
   702 
   887 
       
   888   /*! A grah wrapper base class 
       
   889     for merging the node-sets and edge-sets of 
       
   890     two node-disjoint graphs 
       
   891     into one graph. 
       
   892     Specialized implementation for the case 
       
   893     when _Graph1::Edge is a base class and _Graph2::Edge
       
   894     is derived from it.
       
   895    */
       
   896   template <typename _Graph1, typename _Graph2>
       
   897   class MergeEdgeGraphWrapperBase<
       
   898     _Graph1, _Graph2, typename boost::enable_if<
       
   899     boost::is_base_and_derived<typename _Graph1::Edge, typename _Graph2::Edge> >::type> : 
       
   900     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
       
   901   public:
       
   902     static void printEdge() { std::cout << "edge: 2nd is derived" << std::endl; }
       
   903     typedef _Graph1 Graph1;
       
   904     typedef _Graph2 Graph2;
       
   905     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
       
   906     typedef typename Parent::Parent1 Parent1;
       
   907     typedef typename Parent::Parent2 Parent2;
       
   908 //     typedef P1<_Graph1> Parent1;
       
   909 //     typedef P2<_Graph2> Parent2;
       
   910     typedef typename Parent1::Edge Graph1Edge;
       
   911     typedef typename Parent2::Edge Graph2Edge;
       
   912   protected:
       
   913     MergeEdgeGraphWrapperBase() { }
       
   914   public:
       
   915     template <typename _Value> class EdgeMap;
       
   916 
       
   917     typedef typename Parent::Node Node;
       
   918 
       
   919     class Edge : public Graph2Edge {
       
   920       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
       
   921       template <typename _Value> friend class EdgeMap;
       
   922     protected:
       
   923       bool backward; //true, iff backward
       
   924     public:
       
   925       Edge() { }
       
   926       /// \todo =false is needed, or causes problems?
       
   927       /// If \c _backward is false, then we get an edge corresponding to the 
       
   928       /// original one, otherwise its oppositely directed pair is obtained.
       
   929       Edge(const Graph1Edge& n1, 
       
   930 	   const Graph2Edge& n2, bool _backward) : 
       
   931 	Graph2Edge(n2), backward(_backward) { 
       
   932 	if (!backward) *this=n1;
       
   933       }
       
   934       Edge(Invalid i) : Graph2Edge(i), backward(true) { }
       
   935       bool operator==(const Edge& v) const { 
       
   936 	if (backward) 
       
   937 	  return (v.backward && 
       
   938 		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
       
   939 	else 
       
   940 	  return (!v.backward && 
       
   941 		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
       
   942       } 
       
   943       bool operator!=(const Edge& v) const { 
       
   944 	return !(*this==v);
       
   945       }
       
   946     };
       
   947 
       
   948     using Parent::first;
       
   949     void first(Edge& i) const {
       
   950       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
       
   951       i.backward=false;
       
   952       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   953 	Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
   954 	i.backward=true;
       
   955       }
       
   956     }
       
   957     void firstIn(Edge& i, const Node& n) const {
       
   958       Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
       
   959       i.backward=false;
       
   960       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   961 	Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
       
   962 	i.backward=true;
       
   963       }
       
   964     }
       
   965     void firstOut(Edge& i, const Node& n) const {
       
   966       Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
       
   967       i.backward=false;
       
   968       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   969 	Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
       
   970 	i.backward=true;
       
   971       }
       
   972     }
       
   973 
       
   974     using Parent::next;
       
   975     void next(Edge& i) const {
       
   976       if (!(i.backward)) {
       
   977 	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
       
   978 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   979 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
   980 	  i.backward=true;
       
   981 	}
       
   982       } else {
       
   983 	Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
       
   984       }
       
   985     }
       
   986     void nextIn(Edge& i) const {
       
   987       if (!(i.backward)) {
       
   988 	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
       
   989 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   990 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
   991 	  i.backward=true;
       
   992 	}
       
   993       } else {
       
   994 	Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
       
   995       }
       
   996     }
       
   997     void nextOut(Edge& i) const {
       
   998       if (!(i.backward)) {
       
   999 	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
       
  1000 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1001 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
  1002 	  i.backward=true;
       
  1003 	}
       
  1004       } else {
       
  1005 	Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
       
  1006       }
       
  1007     }
       
  1008 
       
  1009     Node source(const Edge& i) const {
       
  1010       if (!(i.backward)) {
       
  1011 	return 
       
  1012 	  Node(Parent1::graph->source(i), INVALID, false);
       
  1013       } else {
       
  1014 	return 
       
  1015 	  Node(INVALID, Parent2::graph->source(i), true);
       
  1016       }
       
  1017     }
       
  1018 
       
  1019     Node target(const Edge& i) const {
       
  1020       if (!(i.backward)) {
       
  1021 	return 
       
  1022 	  Node(Parent1::graph->target(i), INVALID, false);
       
  1023       } else {
       
  1024 	return 
       
  1025 	  Node(INVALID, Parent2::graph->target(i), true);
       
  1026       }
       
  1027     }
       
  1028 
       
  1029     using Parent::id;
       
  1030     int id(const Edge& n) const { 
       
  1031       if (!n.backward) 
       
  1032 	return this->Parent1::graph->id(n);
       
  1033       else
       
  1034 	return this->Parent2::graph->id(n);
       
  1035     }
       
  1036 
       
  1037     template <typename _Value> 
       
  1038     class EdgeMap { 
       
  1039     protected:
       
  1040       typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
       
  1041       typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
       
  1042       ParentMap1 forward_map;
       
  1043       ParentMap2 backward_map;
       
  1044     public:
       
  1045       typedef _Value Value;
       
  1046       typedef Edge Key;
       
  1047       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
  1048 	forward_map(*(gw.Parent1::graph)), 
       
  1049 	backward_map(*(gw.Parent2::graph)) { }
       
  1050       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
  1051 	      const _Value& value) : 
       
  1052 	forward_map(*(gw.Parent1::graph), value), 
       
  1053 	backward_map(*(gw.Parent2::graph), value) { }
       
  1054       _Value operator[](const Edge& n) const {
       
  1055 	if (!n.backward) 
       
  1056 	  return forward_map[n];
       
  1057 	else 
       
  1058 	  return backward_map[n];
       
  1059       }
       
  1060       void set(const Edge& n, const _Value& value) {
       
  1061 	if (!n.backward) 
       
  1062 	  forward_map.set(n, value);
       
  1063 	else 
       
  1064 	  backward_map.set(n, value);
       
  1065       }
       
  1066 //       using ParentMap1::operator[];
       
  1067 //       using ParentMap2::operator[];
       
  1068     };
       
  1069 
       
  1070   };
       
  1071 
       
  1072 
       
  1073   /*! A grah wrapper base class 
       
  1074     for merging the node-sets and edge-sets of 
       
  1075     two node-disjoint graphs 
       
  1076     into one graph. 
       
  1077     Specialized implementation for the case 
       
  1078     when _Graph1::Edge is derived from _Graph2::Edge.
       
  1079    */
       
  1080   template <typename _Graph1, typename _Graph2>
       
  1081   class MergeEdgeGraphWrapperBase<
       
  1082     _Graph1, _Graph2, typename boost::enable_if<
       
  1083     boost::is_base_and_derived<typename _Graph2::Edge, typename _Graph1::Edge> >::type> : 
       
  1084     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
       
  1085   public:
       
  1086     static void printEdge() { std::cout << "edge: 1st is derived" << std::endl; }
       
  1087     typedef _Graph1 Graph1;
       
  1088     typedef _Graph2 Graph2;
       
  1089     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
       
  1090     typedef typename Parent::Parent1 Parent1;
       
  1091     typedef typename Parent::Parent2 Parent2;
       
  1092 //     typedef P1<_Graph1> Parent1;
       
  1093 //     typedef P2<_Graph2> Parent2;
       
  1094     typedef typename Parent1::Edge Graph1Edge;
       
  1095     typedef typename Parent2::Edge Graph2Edge;
       
  1096   protected:
       
  1097     MergeEdgeGraphWrapperBase() { }
       
  1098   public:
       
  1099     template <typename _Value> class EdgeMap;
       
  1100 
       
  1101     typedef typename Parent::Node Node;
       
  1102 
       
  1103     class Edge : public Graph1Edge {
       
  1104       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
       
  1105       template <typename _Value> friend class EdgeMap;
       
  1106     protected:
       
  1107       bool backward; //true, iff backward
       
  1108     public:
       
  1109       Edge() { }
       
  1110       /// \todo =false is needed, or causes problems?
       
  1111       /// If \c _backward is false, then we get an edge corresponding to the 
       
  1112       /// original one, otherwise its oppositely directed pair is obtained.
       
  1113       Edge(const Graph1Edge& n1, 
       
  1114 	   const Graph2Edge& n2, bool _backward) : 
       
  1115 	Graph1Edge(n1), backward(_backward) { 
       
  1116 	if (backward) *this=n2;
       
  1117       }
       
  1118       Edge(Invalid i) : Graph1Edge(i), backward(true) { }
       
  1119       bool operator==(const Edge& v) const { 
       
  1120 	if (backward) 
       
  1121 	  return (v.backward && 
       
  1122 		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
       
  1123 	else 
       
  1124 	  return (!v.backward && 
       
  1125 		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
       
  1126       } 
       
  1127       bool operator!=(const Edge& v) const { 
       
  1128 	return !(*this==v);
       
  1129       }
       
  1130     };
       
  1131 
       
  1132     using Parent::first;
       
  1133     void first(Edge& i) const {
       
  1134       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
       
  1135       i.backward=false;
       
  1136       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1137 	Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
  1138 	i.backward=true;
       
  1139       }
       
  1140     }
       
  1141     void firstIn(Edge& i, const Node& n) const {
       
  1142       Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
       
  1143       i.backward=false;
       
  1144       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1145 	Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
       
  1146 	i.backward=true;
       
  1147       }
       
  1148     }
       
  1149     void firstOut(Edge& i, const Node& n) const {
       
  1150       Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
       
  1151       i.backward=false;
       
  1152       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1153 	Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
       
  1154 	i.backward=true;
       
  1155       }
       
  1156     }
       
  1157 
       
  1158     using Parent::next;
       
  1159     void next(Edge& i) const {
       
  1160       if (!(i.backward)) {
       
  1161 	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
       
  1162 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1163 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
  1164 	  i.backward=true;
       
  1165 	}
       
  1166       } else {
       
  1167 	Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
       
  1168       }
       
  1169     }
       
  1170     void nextIn(Edge& i) const {
       
  1171       if (!(i.backward)) {
       
  1172 	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
       
  1173 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1174 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
  1175 	  i.backward=true;
       
  1176 	}
       
  1177       } else {
       
  1178 	Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
       
  1179       }
       
  1180     }
       
  1181     void nextOut(Edge& i) const {
       
  1182       if (!(i.backward)) {
       
  1183 	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
       
  1184 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
  1185 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
  1186 	  i.backward=true;
       
  1187 	}
       
  1188       } else {
       
  1189 	Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
       
  1190       }
       
  1191     }
       
  1192 
       
  1193     Node source(const Edge& i) const {
       
  1194       if (!(i.backward)) {
       
  1195 	return 
       
  1196 	  Node(Parent1::graph->source(i), INVALID, false);
       
  1197       } else {
       
  1198 	return 
       
  1199 	  Node(INVALID, Parent2::graph->source(i), true);
       
  1200       }
       
  1201     }
       
  1202 
       
  1203     Node target(const Edge& i) const {
       
  1204       if (!(i.backward)) {
       
  1205 	return 
       
  1206 	  Node(Parent1::graph->target(i), INVALID, false);
       
  1207       } else {
       
  1208 	return 
       
  1209 	  Node(INVALID, Parent2::graph->target(i), true);
       
  1210       }
       
  1211     }
       
  1212 
       
  1213     using Parent::id;
       
  1214     int id(const Edge& n) const { 
       
  1215       if (!n.backward) 
       
  1216 	return this->Parent1::graph->id(n);
       
  1217       else
       
  1218 	return this->Parent2::graph->id(n);
       
  1219     }
       
  1220 
       
  1221     template <typename _Value> 
       
  1222     class EdgeMap { 
       
  1223     protected:
       
  1224       typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
       
  1225       typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
       
  1226       ParentMap1 forward_map;
       
  1227       ParentMap2 backward_map;
       
  1228     public:
       
  1229       typedef _Value Value;
       
  1230       typedef Edge Key;
       
  1231       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
  1232 	forward_map(*(gw.Parent1::graph)), 
       
  1233 	backward_map(*(gw.Parent2::graph)) { }
       
  1234       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
  1235 	      const _Value& value) : 
       
  1236 	forward_map(*(gw.Parent1::graph), value), 
       
  1237 	backward_map(*(gw.Parent2::graph), value) { }
       
  1238       _Value operator[](const Edge& n) const {
       
  1239 	if (!n.backward) 
       
  1240 	  return forward_map[n];
       
  1241 	else 
       
  1242 	  return backward_map[n];
       
  1243       }
       
  1244       void set(const Edge& n, const _Value& value) {
       
  1245 	if (!n.backward) 
       
  1246 	  forward_map.set(n, value);
       
  1247 	else 
       
  1248 	  backward_map.set(n, value);
       
  1249       }
       
  1250 //       using ParentMap1::operator[];
       
  1251 //       using ParentMap2::operator[];
       
  1252     };
       
  1253 
       
  1254   };
       
  1255 
       
  1256 
   703   /*! A graph wrapper class 
  1257   /*! A graph wrapper class 
   704     for merging the node-sets and edge-sets of 
  1258     for merging the node-sets and edge-sets of 
   705     two node-disjoint graphs 
  1259     two node-disjoint graphs 
   706     into one graph.
  1260     into one graph.
   707    */
  1261    */