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