2 * src/lemon/merge_node_graph_wrapper.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
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.
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
17 #ifndef LEMON_MERGE_NODE_GRAPH_WRAPPER_H
18 #define LEMON_MERGE_NODE_GRAPH_WRAPPER_H
20 #include <lemon/invalid.h>
21 #include <lemon/maps.h>
22 #include <lemon/map_defines.h>
23 #include <lemon/graph_wrapper.h>
29 #include <boost/type_traits.hpp>
30 #include <boost/utility/enable_if.hpp>
34 template <class _Graph1>
35 class P1 : public GraphWrapperBase<_Graph1> {
38 template <class _Graph2>
39 class P2 : public GraphWrapperBase<_Graph2> {
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.
48 template <typename _Graph1, typename _Graph2, typename Enable=void>
49 class MergeNodeGraphWrapperBase :
50 public P1<_Graph1>, public P2<_Graph2> {
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;
60 MergeNodeGraphWrapperBase() { }
62 template <typename _Value> class NodeMap;
64 class Node : public Graph1Node, public Graph2Node {
65 friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
66 template <typename _Value> friend class NodeMap;
68 bool backward; //true, iff backward
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 {
81 static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v));
83 return (!v.backward &&
84 static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
86 bool operator!=(const Node& v) const {
94 void first(Node& i) const {
95 Parent1::graph->first(*static_cast<Graph1Node*>(&i));
97 if (*static_cast<Graph1Node*>(&i)==INVALID) {
98 Parent2::graph->first(*static_cast<Graph2Node*>(&i));
102 void next(Node& i) const {
104 Parent1::graph->next(*static_cast<Graph1Node*>(&i));
105 if (*static_cast<Graph1Node*>(&i)==INVALID) {
106 Parent2::graph->first(*static_cast<Graph2Node*>(&i));
110 Parent2::graph->next(*static_cast<Graph2Node*>(&i));
114 int id(const Node& n) const {
116 return this->Parent1::graph->id(n);
118 return this->Parent2::graph->id(n);
121 template <typename _Value>
124 typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
125 typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
126 ParentMap1 forward_map;
127 ParentMap2 backward_map;
129 typedef _Value Value;
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 {
140 return forward_map[n];
142 return backward_map[n];
144 void set(const Node& n, const _Value& value) {
146 forward_map.set(n, value);
148 backward_map.set(n, value);
150 // using ParentMap1::operator[];
151 // using ParentMap2::operator[];
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.
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> {
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;
176 MergeNodeGraphWrapperBase() { }
178 template <typename _Value> class NodeMap;
180 class Node : public Graph1Node {
181 friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
182 template <typename _Value> friend class NodeMap;
184 bool backward; //true, iff backward
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));
198 bool operator!=(const Node& v) const {
206 void first(Node& i) const {
207 Parent1::graph->first(*static_cast<Graph1Node*>(&i));
209 if (*static_cast<Graph1Node*>(&i)==INVALID) {
210 Parent2::graph->first(*static_cast<Graph1Node*>(&i));
214 void next(Node& i) const {
216 Parent1::graph->next(*static_cast<Graph1Node*>(&i));
217 if (*static_cast<Graph1Node*>(&i)==INVALID) {
218 Parent2::graph->first(*static_cast<Graph1Node*>(&i));
222 Parent2::graph->next(*static_cast<Graph1Node*>(&i));
226 int id(const Node& n) const {
228 return this->Parent1::graph->id(n);
230 return this->Parent2::graph->id(n);
233 template <typename _Value>
236 typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
237 typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
238 ParentMap1 forward_map;
239 ParentMap2 backward_map;
241 typedef _Value Value;
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 {
252 return forward_map[n];
254 return backward_map[n];
256 void set(const Node& n, const _Value& value) {
258 forward_map.set(n, value);
260 backward_map.set(n, value);
262 // using ParentMap1::operator[];
263 // using ParentMap2::operator[];
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 is a base class and _Graph2::Node is derived from it.
275 template <typename _Graph1, typename _Graph2>
276 class MergeNodeGraphWrapperBase<
277 _Graph1, _Graph2, typename boost::enable_if<
278 boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> :
279 public P1<_Graph1>, public P2<_Graph2> {
281 static void printNode() { std::cout << "node: 2nd is derived" << std::endl; }
282 typedef _Graph1 Graph1;
283 typedef _Graph2 Graph2;
284 typedef P1<_Graph1> Parent1;
285 typedef P2<_Graph2> Parent2;
286 typedef typename Parent1::Node Graph1Node;
287 typedef typename Parent2::Node Graph2Node;
289 MergeNodeGraphWrapperBase() { }
291 template <typename _Value> class NodeMap;
293 class Node : public Graph2Node {
294 friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
295 template <typename _Value> friend class NodeMap;
297 bool backward; //true, iff backward
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;
308 Node(Invalid i) : Graph2Node(i), backward(true) { }
309 bool operator==(const Node& v) const {
311 return (v.backward &&
312 static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v));
314 return (!v.backward &&
315 static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
317 bool operator!=(const Node& v) const {
325 void first(Node& i) const {
326 Parent1::graph->first(*static_cast<Graph1Node*>(&i));
328 if (*static_cast<Graph1Node*>(&i)==INVALID) {
329 Parent2::graph->first(*static_cast<Graph2Node*>(&i));
333 void next(Node& i) const {
335 Parent1::graph->next(*static_cast<Graph1Node*>(&i));
336 if (*static_cast<Graph1Node*>(&i)==INVALID) {
337 Parent2::graph->first(*static_cast<Graph2Node*>(&i));
341 Parent2::graph->next(*static_cast<Graph2Node*>(&i));
345 int id(const Node& n) const {
347 return this->Parent1::graph->id(n);
349 return this->Parent2::graph->id(n);
352 template <typename _Value>
355 typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
356 typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
357 ParentMap1 forward_map;
358 ParentMap2 backward_map;
360 typedef _Value Value;
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 {
371 return forward_map[n];
373 return backward_map[n];
375 void set(const Node& n, const _Value& value) {
377 forward_map.set(n, value);
379 backward_map.set(n, value);
381 // using ParentMap1::operator[];
382 // using ParentMap2::operator[];
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
394 template <typename _Graph1, typename _Graph2>
395 class MergeNodeGraphWrapperBase<
396 _Graph1, _Graph2, typename boost::enable_if<
397 boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> :
398 public P1<_Graph1>, public P2<_Graph2> {
400 static void printNode() { std::cout << "node: 1st is derived" << std::endl; }
401 typedef _Graph1 Graph1;
402 typedef _Graph2 Graph2;
403 typedef P1<_Graph1> Parent1;
404 typedef P2<_Graph2> Parent2;
405 typedef typename Parent1::Node Graph1Node;
406 typedef typename Parent2::Node Graph2Node;
408 MergeNodeGraphWrapperBase() { }
410 template <typename _Value> class NodeMap;
412 class Node : public Graph1Node {
413 friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
414 template <typename _Value> friend class NodeMap;
416 bool backward; //true, iff backward
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;
427 Node(Invalid i) : Graph1Node(i), backward(true) { }
428 bool operator==(const Node& v) const {
430 return (v.backward &&
431 static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v));
433 return (!v.backward &&
434 static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
436 bool operator!=(const Node& v) const {
444 void first(Node& i) const {
445 Parent1::graph->first(*static_cast<Graph1Node*>(&i));
447 if (*static_cast<Graph1Node*>(&i)==INVALID) {
448 Parent2::graph->first(*static_cast<Graph2Node*>(&i));
452 void next(Node& i) const {
454 Parent1::graph->next(*static_cast<Graph1Node*>(&i));
455 if (*static_cast<Graph1Node*>(&i)==INVALID) {
456 Parent2::graph->first(*static_cast<Graph2Node*>(&i));
460 Parent2::graph->next(*static_cast<Graph2Node*>(&i));
464 int id(const Node& n) const {
466 return this->Parent1::graph->id(n);
468 return this->Parent2::graph->id(n);
471 template <typename _Value>
474 typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
475 typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
476 ParentMap1 forward_map;
477 ParentMap2 backward_map;
479 typedef _Value Value;
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 {
490 return forward_map[n];
492 return backward_map[n];
494 void set(const Node& n, const _Value& value) {
496 forward_map.set(n, value);
498 backward_map.set(n, value);
500 // using ParentMap1::operator[];
501 // using ParentMap2::operator[];
507 /*! A graph wrapper class
508 fors merging the node-set of two node-disjoint graphs
509 into one node-set. It does not satisfy
510 StaticGraph concept as it has no edge-set which
511 works together with the node-set.
513 template <typename _Graph1, typename _Graph2>
514 class MergeNodeGraphWrapper : public
515 IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
517 typedef _Graph1 Graph1;
518 typedef _Graph2 Graph2;
519 typedef IterableGraphExtender<
520 MergeNodeGraphWrapperBase<_Graph1, _Graph2> > Parent;
522 MergeNodeGraphWrapper() { }
524 MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) {
525 Parent::Parent1::setGraph(_graph1);
526 Parent::Parent2::setGraph(_graph2);
531 /*! A grah wrapper base class
532 for merging the node-sets and edge-sets of
533 two node-disjoint graphs
535 Generic implementation for unrelated _Graph1::Edge and _Graph2::Edge.
537 template <typename _Graph1, typename _Graph2, typename Enable=void>
538 class MergeEdgeGraphWrapperBase :
539 public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
541 static void printEdge() { std::cout << "edge: generic" << std::endl; }
542 typedef _Graph1 Graph1;
543 typedef _Graph2 Graph2;
544 typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
545 typedef typename Parent::Parent1 Parent1;
546 typedef typename Parent::Parent2 Parent2;
547 // typedef P1<_Graph1> Parent1;
548 // typedef P2<_Graph2> Parent2;
549 typedef typename Parent1::Edge Graph1Edge;
550 typedef typename Parent2::Edge Graph2Edge;
552 MergeEdgeGraphWrapperBase() { }
554 template <typename _Value> class EdgeMap;
556 typedef typename Parent::Node Node;
558 class Edge : public Graph1Edge, public Graph2Edge {
559 friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
560 template <typename _Value> friend class EdgeMap;
562 bool backward; //true, iff backward
565 /// \todo =false is needed, or causes problems?
566 /// If \c _backward is false, then we get an edge corresponding to the
567 /// original one, otherwise its oppositely directed pair is obtained.
568 Edge(const Graph1Edge& n1,
569 const Graph2Edge& n2, bool _backward) :
570 Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
571 Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
572 bool operator==(const Edge& v) const {
574 return (v.backward &&
575 static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
577 return (!v.backward &&
578 static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
580 bool operator!=(const Edge& v) const {
586 void first(Edge& i) const {
587 Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
589 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
590 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
594 void firstIn(Edge& i, const Node& n) const {
595 Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
597 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
598 Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
602 void firstOut(Edge& i, const Node& n) const {
603 Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
605 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
606 Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
612 void next(Edge& i) const {
614 Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
615 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
616 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
620 Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
623 void nextIn(Edge& i) const {
625 Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
626 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
627 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
631 Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
634 void nextOut(Edge& i) const {
636 Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
637 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
638 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
642 Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
646 Node source(const Edge& i) const {
649 Node(Parent1::graph->source(i), INVALID, false);
652 Node(INVALID, Parent2::graph->source(i), true);
656 Node target(const Edge& i) const {
659 Node(Parent1::graph->target(i), INVALID, false);
662 Node(INVALID, Parent2::graph->target(i), true);
667 int id(const Edge& n) const {
669 return this->Parent1::graph->id(n);
671 return this->Parent2::graph->id(n);
674 template <typename _Value>
677 typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
678 typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
679 ParentMap1 forward_map;
680 ParentMap2 backward_map;
682 typedef _Value Value;
684 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
685 forward_map(*(gw.Parent1::graph)),
686 backward_map(*(gw.Parent2::graph)) { }
687 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
688 const _Value& value) :
689 forward_map(*(gw.Parent1::graph), value),
690 backward_map(*(gw.Parent2::graph), value) { }
691 _Value operator[](const Edge& n) const {
693 return forward_map[n];
695 return backward_map[n];
697 void set(const Edge& n, const _Value& value) {
699 forward_map.set(n, value);
701 backward_map.set(n, value);
703 // using ParentMap1::operator[];
704 // using ParentMap2::operator[];
710 /*! A graph wrapper base class
711 for merging the node-sets and edge-sets of
712 two node-disjoint graphs
714 Specialization for the case when _Graph1::Edge and _Graph2::Edge
717 template <typename _Graph1, typename _Graph2>
718 class MergeEdgeGraphWrapperBase<
719 _Graph1, _Graph2, typename boost::enable_if<
720 boost::is_same<typename _Graph1::Edge, typename _Graph2::Edge> >::type> :
721 public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
723 static void printEdge() { std::cout << "edge: same" << std::endl; }
724 typedef _Graph1 Graph1;
725 typedef _Graph2 Graph2;
726 typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
727 typedef typename Parent::Parent1 Parent1;
728 typedef typename Parent::Parent2 Parent2;
729 // typedef P1<_Graph1> Parent1;
730 // typedef P2<_Graph2> Parent2;
731 typedef typename Parent1::Edge Graph1Edge;
732 typedef typename Parent2::Edge Graph2Edge;
734 MergeEdgeGraphWrapperBase() { }
736 template <typename _Value> class EdgeMap;
738 typedef typename Parent::Node Node;
740 class Edge : public Graph1Edge {
741 friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
742 template <typename _Value> friend class EdgeMap;
744 bool backward; //true, iff backward
747 /// \todo =false is needed, or causes problems?
748 /// If \c _backward is false, then we get an edge corresponding to the
749 /// original one, otherwise its oppositely directed pair is obtained.
750 Edge(const Graph1Edge& n1,
751 const Graph2Edge& n2, bool _backward) :
752 Graph1Edge(!backward ? n1 : n2), backward(_backward) { }
753 Edge(Invalid i) : Graph1Edge(i), backward(true) { }
754 bool operator==(const Edge& v) const {
755 return (backward==v.backward &&
756 static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
758 bool operator!=(const Edge& v) const {
764 void first(Edge& i) const {
765 Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
767 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
768 Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
772 void firstIn(Edge& i, const Node& n) const {
773 Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
775 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
776 Parent2::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
780 void firstOut(Edge& i, const Node& n) const {
781 Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
783 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
784 Parent2::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
790 void next(Edge& i) const {
792 Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
793 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
794 Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
798 Parent2::graph->next(*static_cast<Graph1Edge*>(&i));
801 void nextIn(Edge& i) const {
803 Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
804 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
805 Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
809 Parent2::graph->nextIn(*static_cast<Graph1Edge*>(&i));
812 void nextOut(Edge& i) const {
814 Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
815 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
816 Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
820 Parent2::graph->nextOut(*static_cast<Graph1Edge*>(&i));
824 Node source(const Edge& i) const {
827 Node(Parent1::graph->source(i), INVALID, false);
830 Node(INVALID, Parent2::graph->source(i), true);
834 Node target(const Edge& i) const {
837 Node(Parent1::graph->target(i), INVALID, false);
840 Node(INVALID, Parent2::graph->target(i), true);
845 int id(const Edge& n) const {
847 return this->Parent1::graph->id(n);
849 return this->Parent2::graph->id(n);
852 template <typename _Value>
855 typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
856 typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
857 ParentMap1 forward_map;
858 ParentMap2 backward_map;
860 typedef _Value Value;
862 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
863 forward_map(*(gw.Parent1::graph)),
864 backward_map(*(gw.Parent2::graph)) { }
865 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
866 const _Value& value) :
867 forward_map(*(gw.Parent1::graph), value),
868 backward_map(*(gw.Parent2::graph), value) { }
869 _Value operator[](const Edge& n) const {
871 return forward_map[n];
873 return backward_map[n];
875 void set(const Edge& n, const _Value& value) {
877 forward_map.set(n, value);
879 backward_map.set(n, value);
881 // using ParentMap1::operator[];
882 // using ParentMap2::operator[];
888 /*! A grah wrapper base class
889 for merging the node-sets and edge-sets of
890 two node-disjoint graphs
892 Specialized implementation for the case
893 when _Graph1::Edge is a base class and _Graph2::Edge
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> {
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;
913 MergeEdgeGraphWrapperBase() { }
915 template <typename _Value> class EdgeMap;
917 typedef typename Parent::Node Node;
919 class Edge : public Graph2Edge {
920 friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
921 template <typename _Value> friend class EdgeMap;
923 bool backward; //true, iff backward
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;
934 Edge(Invalid i) : Graph2Edge(i), backward(true) { }
935 bool operator==(const Edge& v) const {
937 return (v.backward &&
938 static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
940 return (!v.backward &&
941 static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
943 bool operator!=(const Edge& v) const {
949 void first(Edge& i) const {
950 Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
952 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
953 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
957 void firstIn(Edge& i, const Node& n) const {
958 Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
960 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
961 Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
965 void firstOut(Edge& i, const Node& n) const {
966 Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
968 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
969 Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
975 void next(Edge& i) const {
977 Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
978 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
979 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
983 Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
986 void nextIn(Edge& i) const {
988 Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
989 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
990 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
994 Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
997 void nextOut(Edge& i) const {
999 Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
1000 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
1001 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
1005 Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
1009 Node source(const Edge& i) const {
1010 if (!(i.backward)) {
1012 Node(Parent1::graph->source(i), INVALID, false);
1015 Node(INVALID, Parent2::graph->source(i), true);
1019 Node target(const Edge& i) const {
1020 if (!(i.backward)) {
1022 Node(Parent1::graph->target(i), INVALID, false);
1025 Node(INVALID, Parent2::graph->target(i), true);
1030 int id(const Edge& n) const {
1032 return this->Parent1::graph->id(n);
1034 return this->Parent2::graph->id(n);
1037 template <typename _Value>
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;
1045 typedef _Value Value;
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 {
1056 return forward_map[n];
1058 return backward_map[n];
1060 void set(const Edge& n, const _Value& value) {
1062 forward_map.set(n, value);
1064 backward_map.set(n, value);
1066 // using ParentMap1::operator[];
1067 // using ParentMap2::operator[];
1073 /*! A grah wrapper base class
1074 for merging the node-sets and edge-sets of
1075 two node-disjoint graphs
1077 Specialized implementation for the case
1078 when _Graph1::Edge is derived from _Graph2::Edge.
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> {
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;
1097 MergeEdgeGraphWrapperBase() { }
1099 template <typename _Value> class EdgeMap;
1101 typedef typename Parent::Node Node;
1103 class Edge : public Graph1Edge {
1104 friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
1105 template <typename _Value> friend class EdgeMap;
1107 bool backward; //true, iff backward
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;
1118 Edge(Invalid i) : Graph1Edge(i), backward(true) { }
1119 bool operator==(const Edge& v) const {
1121 return (v.backward &&
1122 static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
1124 return (!v.backward &&
1125 static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
1127 bool operator!=(const Edge& v) const {
1132 using Parent::first;
1133 void first(Edge& i) const {
1134 Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
1136 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
1137 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
1141 void firstIn(Edge& i, const Node& n) const {
1142 Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
1144 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
1145 Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
1149 void firstOut(Edge& i, const Node& n) const {
1150 Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
1152 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
1153 Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
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));
1167 Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
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));
1178 Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
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));
1189 Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
1193 Node source(const Edge& i) const {
1194 if (!(i.backward)) {
1196 Node(Parent1::graph->source(i), INVALID, false);
1199 Node(INVALID, Parent2::graph->source(i), true);
1203 Node target(const Edge& i) const {
1204 if (!(i.backward)) {
1206 Node(Parent1::graph->target(i), INVALID, false);
1209 Node(INVALID, Parent2::graph->target(i), true);
1214 int id(const Edge& n) const {
1216 return this->Parent1::graph->id(n);
1218 return this->Parent2::graph->id(n);
1221 template <typename _Value>
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;
1229 typedef _Value Value;
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 {
1240 return forward_map[n];
1242 return backward_map[n];
1244 void set(const Edge& n, const _Value& value) {
1246 forward_map.set(n, value);
1248 backward_map.set(n, value);
1250 // using ParentMap1::operator[];
1251 // using ParentMap2::operator[];
1257 /*! A graph wrapper class
1258 for merging the node-sets and edge-sets of
1259 two node-disjoint graphs
1262 template <typename _Graph1, typename _Graph2>
1263 class MergeEdgeGraphWrapper : public
1264 IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
1266 typedef _Graph1 Graph1;
1267 typedef _Graph2 Graph2;
1268 typedef IterableGraphExtender<
1269 MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > Parent;
1271 MergeEdgeGraphWrapper() { }
1273 MergeEdgeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) {
1274 Parent::Parent1::setGraph(_graph1);
1275 Parent::Parent2::setGraph(_graph2);
1280 /*! A graph wrapper base class for the following functionality.
1281 If a bijection is given between the node-sets of two graphs,
1282 then the second one can be considered as a new edge-set
1283 over th first node-set.
1285 template <typename _Graph, typename _EdgeSetGraph>
1286 class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> {
1288 typedef GraphWrapperBase<_Graph> Parent;
1289 typedef _Graph Graph;
1290 typedef _EdgeSetGraph EdgeSetGraph;
1291 typedef typename _Graph::Node Node;
1292 typedef typename _EdgeSetGraph::Node ENode;
1294 EdgeSetGraph* edge_set_graph;
1295 typename Graph::NodeMap<ENode>* e_node;
1296 typename EdgeSetGraph::NodeMap<Node>* n_node;
1297 void setEdgeSetGraph(EdgeSetGraph& _edge_set_graph) {
1298 edge_set_graph=&_edge_set_graph;
1300 /// For each node of \c Graph, this gives a node of \c EdgeSetGraph .
1301 void setNodeMap(typename EdgeSetGraph::NodeMap<Node>& _n_node) {
1304 /// For each node of \c EdgeSetGraph, this gives a node of \c Graph .
1305 void setENodeMap(typename Graph::NodeMap<ENode>& _e_node) {
1309 class Edge : public EdgeSetGraph::Edge {
1310 typedef typename EdgeSetGraph::Edge Parent;
1313 Edge(const Parent& e) : Parent(e) { }
1314 Edge(Invalid i) : Parent(i) { }
1317 using Parent::first;
1318 void first(Edge &e) const {
1319 edge_set_graph->first(e);
1321 void firstOut(Edge& e, const Node& n) const {
1322 // cout << e_node << endl;
1323 // cout << n_node << endl;
1324 edge_set_graph->firstOut(e, (*e_node)[n]);
1326 void firstIn(Edge& e, const Node& n) const {
1327 edge_set_graph->firstIn(e, (*e_node)[n]);
1331 void next(Edge &e) const {
1332 edge_set_graph->next(e);
1334 void nextOut(Edge& e) const {
1335 edge_set_graph->nextOut(e);
1337 void nextIn(Edge& e) const {
1338 edge_set_graph->nextIn(e);
1341 Node source(const Edge& e) const {
1342 return (*n_node)[edge_set_graph->source(e)];
1344 Node target(const Edge& e) const {
1345 return (*n_node)[edge_set_graph->target(e)];
1348 int edgeNum() const { return edge_set_graph->edgeNum(); }
1350 Edge addEdge(const Node& u, const Node& v) {
1351 return edge_set_graph->addEdge((*e_node)[u], (*e_node)[v]);
1354 using Parent::erase;
1355 void erase(const Edge& i) const { edge_set_graph->erase(i); }
1357 void clear() const { Parent::clear(); edge_set_graph->clear(); }
1359 bool forward(const Edge& e) const { return edge_set_graph->forward(e); }
1360 bool backward(const Edge& e) const { return edge_set_graph->backward(e); }
1362 int id(const Node& e) const { return Parent::id(e); }
1363 int id(const Edge& e) const { return edge_set_graph->id(e); }
1365 Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); }
1367 template <typename _Value>
1368 class EdgeMap : public EdgeSetGraph::EdgeMap<_Value> {
1370 typedef typename EdgeSetGraph::EdgeMap<_Value> Parent;
1371 typedef _Value Value;
1373 EdgeMap(const NewEdgeSetGraphWrapperBase& gw) :
1374 Parent(*(gw.edge_set_graph)) { }
1375 EdgeMap(const NewEdgeSetGraphWrapperBase& gw, const _Value& _value) :
1376 Parent(*(gw.edge_set_graph), _value) { }
1382 /*! A graph wrapper class for the following functionality.
1383 If a bijection is given between the node-sets of two graphs,
1384 then the second one can be considered as a new edge-set
1385 over th first node-set.
1387 template <typename _Graph, typename _EdgeSetGraph>
1388 class NewEdgeSetGraphWrapper :
1389 public IterableGraphExtender<
1390 NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > {
1392 typedef _Graph Graph;
1393 typedef _EdgeSetGraph EdgeSetGraph;
1394 typedef IterableGraphExtender<
1395 NewEdgeSetGraphWrapper<_Graph, _EdgeSetGraph> > Parent;
1397 NewEdgeSetGraphWrapper() { }
1399 NewEdgeSetGraphWrapper(_Graph& _graph,
1400 _EdgeSetGraph& _edge_set_graph,
1402 NodeMap<typename _EdgeSetGraph::Node>& _e_node,
1403 typename _EdgeSetGraph::
1404 NodeMap<typename _Graph::Node>& _n_node) {
1406 setEdgeSetGraph(_edge_set_graph);
1407 setNodeMap(_n_node);
1408 setENodeMap(_e_node);
1413 /*! A graph wrapper base class
1414 for merging graphs of type _Graph1 and _Graph2
1415 which are given on the same node-set
1416 (specially on the node-set of Graph1)
1418 In an other point of view, _Graph1 is extended with
1419 the edge-set of _Graph2.
1421 template <typename _Graph1, typename _Graph2, typename Enable=void>
1422 class AugmentingGraphWrapperBase :
1423 public P1<_Graph1> {
1425 void printAugment() const { std::cout << "generic" << std::endl; }
1426 typedef _Graph1 Graph1;
1427 typedef _Graph2 Graph2;
1428 typedef P1<_Graph1> Parent1;
1429 typedef P2<_Graph2> Parent2;
1430 typedef typename Parent1::Edge Graph1Edge;
1431 typedef typename Parent2::Edge Graph2Edge;
1433 AugmentingGraphWrapperBase() { }
1435 void setGraph2(_Graph2& _graph2) { graph2=&_graph2; }
1438 template <typename _Value> class EdgeMap;
1440 typedef typename Parent1::Node Node;
1442 class Edge : public Graph1Edge, public Graph2Edge {
1443 friend class AugmentingGraphWrapperBase<_Graph1, _Graph2>;
1444 template <typename _Value> friend class EdgeMap;
1446 bool backward; //true, iff backward
1449 /// \todo =false is needed, or causes problems?
1450 /// If \c _backward is false, then we get an edge corresponding to the
1451 /// original one, otherwise its oppositely directed pair is obtained.
1452 Edge(const Graph1Edge& n1,
1453 const Graph2Edge& n2, bool _backward) :
1454 Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
1455 Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
1456 bool operator==(const Edge& v) const {
1458 return (v.backward &&
1459 static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
1461 return (!v.backward &&
1462 static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
1464 bool operator!=(const Edge& v) const {
1469 using Parent1::first;
1470 void first(Edge& i) const {
1471 Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
1473 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
1474 graph2->first(*static_cast<Graph2Edge*>(&i));
1478 void firstIn(Edge& i, const Node& n) const {
1479 Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
1481 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
1482 graph2->firstIn(*static_cast<Graph2Edge*>(&i), n);
1486 void firstOut(Edge& i, const Node& n) const {
1487 Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
1489 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
1490 graph2->firstOut(*static_cast<Graph2Edge*>(&i), n);
1495 using Parent1::next;
1496 void next(Edge& i) const {
1497 if (!(i.backward)) {
1498 Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
1499 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
1500 graph2->first(*static_cast<Graph2Edge*>(&i));
1504 graph2->next(*static_cast<Graph2Edge*>(&i));
1507 void nextIn(Edge& i) const {
1508 if (!(i.backward)) {
1509 Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
1510 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
1511 graph2->first(*static_cast<Graph2Edge*>(&i));
1515 graph2->nextIn(*static_cast<Graph2Edge*>(&i));
1518 void nextOut(Edge& i) const {
1519 if (!(i.backward)) {
1520 Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
1521 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
1522 graph2->first(*static_cast<Graph2Edge*>(&i));
1526 graph2->nextOut(*static_cast<Graph2Edge*>(&i));
1530 Node source(const Edge& i) const {
1531 if (!(i.backward)) {
1532 return Parent1::graph->source(i);
1534 return graph2->source(i);
1538 Node target(const Edge& i) const {
1539 if (!(i.backward)) {
1540 return Parent1::graph->target(i);
1542 return graph2->target(i);
1546 int id(const Node& n) const {
1547 return Parent1::id(n);
1549 int id(const Edge& n) const {
1551 return this->Parent1::graph->id(n);
1553 return this->graph2->id(n);
1556 template <typename _Value>
1559 typedef typename _Graph1::template EdgeMap<_Value> ParentMap1;
1560 typedef typename _Graph2::template EdgeMap<_Value> ParentMap2;
1561 ParentMap1 forward_map;
1562 ParentMap2 backward_map;
1564 typedef _Value Value;
1566 EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw) :
1567 forward_map(*(gw.Parent1::graph)),
1568 backward_map(*(gw.graph2)) { }
1569 EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw,
1570 const _Value& value) :
1571 forward_map(*(gw.Parent1::graph), value),
1572 backward_map(*(gw.graph2), value) { }
1573 _Value operator[](const Edge& n) const {
1575 return forward_map[n];
1577 return backward_map[n];
1579 void set(const Edge& n, const _Value& value) {
1581 forward_map.set(n, value);
1583 backward_map.set(n, value);
1585 // using ParentMap1::operator[];
1586 // using ParentMap2::operator[];
1592 /*! A graph wrapper class
1593 for merging two graphs (of type _Graph1 and _Graph2)
1594 with the same node-set
1595 (specially on the node-set of Graph1)
1597 In an other point of view, _Graph1 is extended with
1598 the edge-set of _Graph2.
1600 template <typename _Graph1, typename _Graph2>
1601 class AugmentingGraphWrapper : public
1602 IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> > {
1605 IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> >
1607 typedef _Graph1 Graph1;
1608 typedef _Graph2 Graph2;
1610 AugmentingGraphWrapper() { }
1612 AugmentingGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) {
1620 #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H