1.1 --- a/src/lemon/graph_wrapper.h Sat Nov 20 16:12:47 2004 +0000
1.2 +++ b/src/lemon/graph_wrapper.h Mon Nov 22 09:09:18 2004 +0000
1.3 @@ -1192,7 +1192,7 @@
1.4 // }
1.5
1.6 // typename _Graph::template EdgeMap<T>::Reference
1.7 - T operator[](Edge e) {
1.8 + T operator[](Edge e) const {
1.9 if (!e.backward)
1.10 return forward_map[e];
1.11 else
2.1 --- a/src/work/marci/makefile Sat Nov 20 16:12:47 2004 +0000
2.2 +++ b/src/work/marci/makefile Mon Nov 22 09:09:18 2004 +0000
2.3 @@ -1,7 +1,7 @@
2.4 CXX2 = g++-2.95
2.5 CXX3=$(CXX)
2.6 BOOSTROOT ?= /home/marci/boost
2.7 -INCLUDEDIRS ?= -I../{jacint,marci,alpar,klao,akos,athos} -I../.. -I.. -I$(BOOSTROOT)
2.8 +INCLUDEDIRS ?= -ftemplate-depth-50 -I../{jacint,marci,alpar,klao,akos,athos} -I../.. -I.. -I$(BOOSTROOT)
2.9
2.10 LEDABINARIES = leda_graph_demo leda_bfs_dfs max_bipartite_matching_demo
2.11 BINARIES = merge_node_graph_wrapper_test# bfsit_vs_byhand max_flow_demo bfs_mm_test# sub_graph_wrapper_demo.cc graph_wrapper_time iterator_bfs_demo macro_test lg_vs_sg_vs_sg bipartite_graph_wrapper_test bipartite_matching_demo top_sort_test max_flow_1 proba7 proba10
3.1 --- a/src/work/marci/merge_node_graph_wrapper.h Sat Nov 20 16:12:47 2004 +0000
3.2 +++ b/src/work/marci/merge_node_graph_wrapper.h Mon Nov 22 09:09:18 2004 +0000
3.3 @@ -270,8 +270,7 @@
3.4 for merging the node-set of two node-disjoint graphs
3.5 into the node-set of one graph.
3.6 Specialization for the case when
3.7 - _Graph1::Node are base and derived _Graph2::Node.
3.8 - NOT YET IMPLEMENTED
3.9 + _Graph1::Node is a base class and _Graph2::Node is derived from it.
3.10 */
3.11 template <typename _Graph1, typename _Graph2>
3.12 class MergeNodeGraphWrapperBase<
3.13 @@ -289,13 +288,109 @@
3.14 protected:
3.15 MergeNodeGraphWrapperBase() { }
3.16 public:
3.17 - class Node { };
3.18 + template <typename _Value> class NodeMap;
3.19 +
3.20 + class Node : public Graph2Node {
3.21 + friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
3.22 + template <typename _Value> friend class NodeMap;
3.23 + protected:
3.24 + bool backward; //true, iff backward
3.25 + public:
3.26 + Node() { }
3.27 + /// \todo =false is needed, or causes problems?
3.28 + /// If \c _backward is false, then we get an edge corresponding to the
3.29 + /// original one, otherwise its oppositely directed pair is obtained.
3.30 + Node(const Graph1Node& n1,
3.31 + const Graph2Node& n2, bool _backward) :
3.32 + Graph2Node(n2), backward(_backward) {
3.33 + if (!backward) *this=n1;
3.34 + }
3.35 + Node(Invalid i) : Graph2Node(i), backward(true) { }
3.36 + bool operator==(const Node& v) const {
3.37 + if (backward)
3.38 + return (v.backward &&
3.39 + static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v));
3.40 + else
3.41 + return (!v.backward &&
3.42 + static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
3.43 + }
3.44 + bool operator!=(const Node& v) const {
3.45 + return !(*this==v);
3.46 + }
3.47 + };
3.48 +
3.49 + //typedef void Edge;
3.50 class Edge { };
3.51 - void first() const;
3.52 - void next() const;
3.53 +
3.54 + void first(Node& i) const {
3.55 + Parent1::graph->first(*static_cast<Graph1Node*>(&i));
3.56 + i.backward=false;
3.57 + if (*static_cast<Graph1Node*>(&i)==INVALID) {
3.58 + Parent2::graph->first(*static_cast<Graph2Node*>(&i));
3.59 + i.backward=true;
3.60 + }
3.61 + }
3.62 + void next(Node& i) const {
3.63 + if (!(i.backward)) {
3.64 + Parent1::graph->next(*static_cast<Graph1Node*>(&i));
3.65 + if (*static_cast<Graph1Node*>(&i)==INVALID) {
3.66 + Parent2::graph->first(*static_cast<Graph2Node*>(&i));
3.67 + i.backward=true;
3.68 + }
3.69 + } else {
3.70 + Parent2::graph->next(*static_cast<Graph2Node*>(&i));
3.71 + }
3.72 + }
3.73 +
3.74 + int id(const Node& n) const {
3.75 + if (!n.backward)
3.76 + return this->Parent1::graph->id(n);
3.77 + else
3.78 + return this->Parent2::graph->id(n);
3.79 + }
3.80 +
3.81 + template <typename _Value>
3.82 + class NodeMap {
3.83 + protected:
3.84 + typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
3.85 + typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
3.86 + ParentMap1 forward_map;
3.87 + ParentMap2 backward_map;
3.88 + public:
3.89 + typedef _Value Value;
3.90 + typedef Node Key;
3.91 + NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) :
3.92 + forward_map(*(gw.Parent1::graph)),
3.93 + backward_map(*(gw.Parent2::graph)) { }
3.94 + NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw,
3.95 + const _Value& value) :
3.96 + forward_map(*(gw.Parent1::graph), value),
3.97 + backward_map(*(gw.Parent2::graph), value) { }
3.98 + _Value operator[](const Node& n) const {
3.99 + if (!n.backward)
3.100 + return forward_map[n];
3.101 + else
3.102 + return backward_map[n];
3.103 + }
3.104 + void set(const Node& n, const _Value& value) {
3.105 + if (!n.backward)
3.106 + forward_map.set(n, value);
3.107 + else
3.108 + backward_map.set(n, value);
3.109 + }
3.110 +// using ParentMap1::operator[];
3.111 +// using ParentMap2::operator[];
3.112 + };
3.113 +
3.114 };
3.115
3.116 - //not yet working
3.117 +
3.118 + /*! A graph wrapper base class
3.119 + for merging the node-set of two node-disjoint graphs
3.120 + into the node-set of one graph.
3.121 + Specialized implementaton for the case when _Graph1::Node is derived
3.122 + from _Graph2::Node.
3.123 + */
3.124 template <typename _Graph1, typename _Graph2>
3.125 class MergeNodeGraphWrapperBase<
3.126 _Graph1, _Graph2, typename boost::enable_if<
3.127 @@ -312,10 +407,100 @@
3.128 protected:
3.129 MergeNodeGraphWrapperBase() { }
3.130 public:
3.131 - class Node { };
3.132 + template <typename _Value> class NodeMap;
3.133 +
3.134 + class Node : public Graph1Node {
3.135 + friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
3.136 + template <typename _Value> friend class NodeMap;
3.137 + protected:
3.138 + bool backward; //true, iff backward
3.139 + public:
3.140 + Node() { }
3.141 + /// \todo =false is needed, or causes problems?
3.142 + /// If \c _backward is false, then we get an edge corresponding to the
3.143 + /// original one, otherwise its oppositely directed pair is obtained.
3.144 + Node(const Graph1Node& n1,
3.145 + const Graph2Node& n2, bool _backward) :
3.146 + Graph1Node(n1), backward(_backward) {
3.147 + if (backward) *this=n2;
3.148 + }
3.149 + Node(Invalid i) : Graph1Node(i), backward(true) { }
3.150 + bool operator==(const Node& v) const {
3.151 + if (backward)
3.152 + return (v.backward &&
3.153 + static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v));
3.154 + else
3.155 + return (!v.backward &&
3.156 + static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
3.157 + }
3.158 + bool operator!=(const Node& v) const {
3.159 + return !(*this==v);
3.160 + }
3.161 + };
3.162 +
3.163 + //typedef void Edge;
3.164 class Edge { };
3.165 - void first() const;
3.166 - void next() const;
3.167 +
3.168 + void first(Node& i) const {
3.169 + Parent1::graph->first(*static_cast<Graph1Node*>(&i));
3.170 + i.backward=false;
3.171 + if (*static_cast<Graph1Node*>(&i)==INVALID) {
3.172 + Parent2::graph->first(*static_cast<Graph2Node*>(&i));
3.173 + i.backward=true;
3.174 + }
3.175 + }
3.176 + void next(Node& i) const {
3.177 + if (!(i.backward)) {
3.178 + Parent1::graph->next(*static_cast<Graph1Node*>(&i));
3.179 + if (*static_cast<Graph1Node*>(&i)==INVALID) {
3.180 + Parent2::graph->first(*static_cast<Graph2Node*>(&i));
3.181 + i.backward=true;
3.182 + }
3.183 + } else {
3.184 + Parent2::graph->next(*static_cast<Graph2Node*>(&i));
3.185 + }
3.186 + }
3.187 +
3.188 + int id(const Node& n) const {
3.189 + if (!n.backward)
3.190 + return this->Parent1::graph->id(n);
3.191 + else
3.192 + return this->Parent2::graph->id(n);
3.193 + }
3.194 +
3.195 + template <typename _Value>
3.196 + class NodeMap {
3.197 + protected:
3.198 + typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
3.199 + typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
3.200 + ParentMap1 forward_map;
3.201 + ParentMap2 backward_map;
3.202 + public:
3.203 + typedef _Value Value;
3.204 + typedef Node Key;
3.205 + NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) :
3.206 + forward_map(*(gw.Parent1::graph)),
3.207 + backward_map(*(gw.Parent2::graph)) { }
3.208 + NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw,
3.209 + const _Value& value) :
3.210 + forward_map(*(gw.Parent1::graph), value),
3.211 + backward_map(*(gw.Parent2::graph), value) { }
3.212 + _Value operator[](const Node& n) const {
3.213 + if (!n.backward)
3.214 + return forward_map[n];
3.215 + else
3.216 + return backward_map[n];
3.217 + }
3.218 + void set(const Node& n, const _Value& value) {
3.219 + if (!n.backward)
3.220 + forward_map.set(n, value);
3.221 + else
3.222 + backward_map.set(n, value);
3.223 + }
3.224 +// using ParentMap1::operator[];
3.225 +// using ParentMap2::operator[];
3.226 + };
3.227 +
3.228 };
3.229
3.230
3.231 @@ -532,7 +717,7 @@
3.232 template <typename _Graph1, typename _Graph2>
3.233 class MergeEdgeGraphWrapperBase<
3.234 _Graph1, _Graph2, typename boost::enable_if<
3.235 - boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> :
3.236 + boost::is_same<typename _Graph1::Edge, typename _Graph2::Edge> >::type> :
3.237 public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
3.238 public:
3.239 static void printEdge() { std::cout << "edge: same" << std::endl; }
3.240 @@ -700,6 +885,375 @@
3.241 };
3.242
3.243
3.244 + /*! A grah wrapper base class
3.245 + for merging the node-sets and edge-sets of
3.246 + two node-disjoint graphs
3.247 + into one graph.
3.248 + Specialized implementation for the case
3.249 + when _Graph1::Edge is a base class and _Graph2::Edge
3.250 + is derived from it.
3.251 + */
3.252 + template <typename _Graph1, typename _Graph2>
3.253 + class MergeEdgeGraphWrapperBase<
3.254 + _Graph1, _Graph2, typename boost::enable_if<
3.255 + boost::is_base_and_derived<typename _Graph1::Edge, typename _Graph2::Edge> >::type> :
3.256 + public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
3.257 + public:
3.258 + static void printEdge() { std::cout << "edge: 2nd is derived" << std::endl; }
3.259 + typedef _Graph1 Graph1;
3.260 + typedef _Graph2 Graph2;
3.261 + typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
3.262 + typedef typename Parent::Parent1 Parent1;
3.263 + typedef typename Parent::Parent2 Parent2;
3.264 +// typedef P1<_Graph1> Parent1;
3.265 +// typedef P2<_Graph2> Parent2;
3.266 + typedef typename Parent1::Edge Graph1Edge;
3.267 + typedef typename Parent2::Edge Graph2Edge;
3.268 + protected:
3.269 + MergeEdgeGraphWrapperBase() { }
3.270 + public:
3.271 + template <typename _Value> class EdgeMap;
3.272 +
3.273 + typedef typename Parent::Node Node;
3.274 +
3.275 + class Edge : public Graph2Edge {
3.276 + friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
3.277 + template <typename _Value> friend class EdgeMap;
3.278 + protected:
3.279 + bool backward; //true, iff backward
3.280 + public:
3.281 + Edge() { }
3.282 + /// \todo =false is needed, or causes problems?
3.283 + /// If \c _backward is false, then we get an edge corresponding to the
3.284 + /// original one, otherwise its oppositely directed pair is obtained.
3.285 + Edge(const Graph1Edge& n1,
3.286 + const Graph2Edge& n2, bool _backward) :
3.287 + Graph2Edge(n2), backward(_backward) {
3.288 + if (!backward) *this=n1;
3.289 + }
3.290 + Edge(Invalid i) : Graph2Edge(i), backward(true) { }
3.291 + bool operator==(const Edge& v) const {
3.292 + if (backward)
3.293 + return (v.backward &&
3.294 + static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
3.295 + else
3.296 + return (!v.backward &&
3.297 + static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
3.298 + }
3.299 + bool operator!=(const Edge& v) const {
3.300 + return !(*this==v);
3.301 + }
3.302 + };
3.303 +
3.304 + using Parent::first;
3.305 + void first(Edge& i) const {
3.306 + Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
3.307 + i.backward=false;
3.308 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.309 + Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
3.310 + i.backward=true;
3.311 + }
3.312 + }
3.313 + void firstIn(Edge& i, const Node& n) const {
3.314 + Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
3.315 + i.backward=false;
3.316 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.317 + Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
3.318 + i.backward=true;
3.319 + }
3.320 + }
3.321 + void firstOut(Edge& i, const Node& n) const {
3.322 + Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
3.323 + i.backward=false;
3.324 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.325 + Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
3.326 + i.backward=true;
3.327 + }
3.328 + }
3.329 +
3.330 + using Parent::next;
3.331 + void next(Edge& i) const {
3.332 + if (!(i.backward)) {
3.333 + Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
3.334 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.335 + Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
3.336 + i.backward=true;
3.337 + }
3.338 + } else {
3.339 + Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
3.340 + }
3.341 + }
3.342 + void nextIn(Edge& i) const {
3.343 + if (!(i.backward)) {
3.344 + Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
3.345 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.346 + Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
3.347 + i.backward=true;
3.348 + }
3.349 + } else {
3.350 + Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
3.351 + }
3.352 + }
3.353 + void nextOut(Edge& i) const {
3.354 + if (!(i.backward)) {
3.355 + Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
3.356 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.357 + Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
3.358 + i.backward=true;
3.359 + }
3.360 + } else {
3.361 + Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
3.362 + }
3.363 + }
3.364 +
3.365 + Node source(const Edge& i) const {
3.366 + if (!(i.backward)) {
3.367 + return
3.368 + Node(Parent1::graph->source(i), INVALID, false);
3.369 + } else {
3.370 + return
3.371 + Node(INVALID, Parent2::graph->source(i), true);
3.372 + }
3.373 + }
3.374 +
3.375 + Node target(const Edge& i) const {
3.376 + if (!(i.backward)) {
3.377 + return
3.378 + Node(Parent1::graph->target(i), INVALID, false);
3.379 + } else {
3.380 + return
3.381 + Node(INVALID, Parent2::graph->target(i), true);
3.382 + }
3.383 + }
3.384 +
3.385 + using Parent::id;
3.386 + int id(const Edge& n) const {
3.387 + if (!n.backward)
3.388 + return this->Parent1::graph->id(n);
3.389 + else
3.390 + return this->Parent2::graph->id(n);
3.391 + }
3.392 +
3.393 + template <typename _Value>
3.394 + class EdgeMap {
3.395 + protected:
3.396 + typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
3.397 + typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
3.398 + ParentMap1 forward_map;
3.399 + ParentMap2 backward_map;
3.400 + public:
3.401 + typedef _Value Value;
3.402 + typedef Edge Key;
3.403 + EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
3.404 + forward_map(*(gw.Parent1::graph)),
3.405 + backward_map(*(gw.Parent2::graph)) { }
3.406 + EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
3.407 + const _Value& value) :
3.408 + forward_map(*(gw.Parent1::graph), value),
3.409 + backward_map(*(gw.Parent2::graph), value) { }
3.410 + _Value operator[](const Edge& n) const {
3.411 + if (!n.backward)
3.412 + return forward_map[n];
3.413 + else
3.414 + return backward_map[n];
3.415 + }
3.416 + void set(const Edge& n, const _Value& value) {
3.417 + if (!n.backward)
3.418 + forward_map.set(n, value);
3.419 + else
3.420 + backward_map.set(n, value);
3.421 + }
3.422 +// using ParentMap1::operator[];
3.423 +// using ParentMap2::operator[];
3.424 + };
3.425 +
3.426 + };
3.427 +
3.428 +
3.429 + /*! A grah wrapper base class
3.430 + for merging the node-sets and edge-sets of
3.431 + two node-disjoint graphs
3.432 + into one graph.
3.433 + Specialized implementation for the case
3.434 + when _Graph1::Edge is derived from _Graph2::Edge.
3.435 + */
3.436 + template <typename _Graph1, typename _Graph2>
3.437 + class MergeEdgeGraphWrapperBase<
3.438 + _Graph1, _Graph2, typename boost::enable_if<
3.439 + boost::is_base_and_derived<typename _Graph2::Edge, typename _Graph1::Edge> >::type> :
3.440 + public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
3.441 + public:
3.442 + static void printEdge() { std::cout << "edge: 1st is derived" << std::endl; }
3.443 + typedef _Graph1 Graph1;
3.444 + typedef _Graph2 Graph2;
3.445 + typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
3.446 + typedef typename Parent::Parent1 Parent1;
3.447 + typedef typename Parent::Parent2 Parent2;
3.448 +// typedef P1<_Graph1> Parent1;
3.449 +// typedef P2<_Graph2> Parent2;
3.450 + typedef typename Parent1::Edge Graph1Edge;
3.451 + typedef typename Parent2::Edge Graph2Edge;
3.452 + protected:
3.453 + MergeEdgeGraphWrapperBase() { }
3.454 + public:
3.455 + template <typename _Value> class EdgeMap;
3.456 +
3.457 + typedef typename Parent::Node Node;
3.458 +
3.459 + class Edge : public Graph1Edge {
3.460 + friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
3.461 + template <typename _Value> friend class EdgeMap;
3.462 + protected:
3.463 + bool backward; //true, iff backward
3.464 + public:
3.465 + Edge() { }
3.466 + /// \todo =false is needed, or causes problems?
3.467 + /// If \c _backward is false, then we get an edge corresponding to the
3.468 + /// original one, otherwise its oppositely directed pair is obtained.
3.469 + Edge(const Graph1Edge& n1,
3.470 + const Graph2Edge& n2, bool _backward) :
3.471 + Graph1Edge(n1), backward(_backward) {
3.472 + if (backward) *this=n2;
3.473 + }
3.474 + Edge(Invalid i) : Graph1Edge(i), backward(true) { }
3.475 + bool operator==(const Edge& v) const {
3.476 + if (backward)
3.477 + return (v.backward &&
3.478 + static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
3.479 + else
3.480 + return (!v.backward &&
3.481 + static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
3.482 + }
3.483 + bool operator!=(const Edge& v) const {
3.484 + return !(*this==v);
3.485 + }
3.486 + };
3.487 +
3.488 + using Parent::first;
3.489 + void first(Edge& i) const {
3.490 + Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
3.491 + i.backward=false;
3.492 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.493 + Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
3.494 + i.backward=true;
3.495 + }
3.496 + }
3.497 + void firstIn(Edge& i, const Node& n) const {
3.498 + Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
3.499 + i.backward=false;
3.500 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.501 + Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
3.502 + i.backward=true;
3.503 + }
3.504 + }
3.505 + void firstOut(Edge& i, const Node& n) const {
3.506 + Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
3.507 + i.backward=false;
3.508 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.509 + Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
3.510 + i.backward=true;
3.511 + }
3.512 + }
3.513 +
3.514 + using Parent::next;
3.515 + void next(Edge& i) const {
3.516 + if (!(i.backward)) {
3.517 + Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
3.518 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.519 + Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
3.520 + i.backward=true;
3.521 + }
3.522 + } else {
3.523 + Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
3.524 + }
3.525 + }
3.526 + void nextIn(Edge& i) const {
3.527 + if (!(i.backward)) {
3.528 + Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
3.529 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.530 + Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
3.531 + i.backward=true;
3.532 + }
3.533 + } else {
3.534 + Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
3.535 + }
3.536 + }
3.537 + void nextOut(Edge& i) const {
3.538 + if (!(i.backward)) {
3.539 + Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
3.540 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
3.541 + Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
3.542 + i.backward=true;
3.543 + }
3.544 + } else {
3.545 + Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
3.546 + }
3.547 + }
3.548 +
3.549 + Node source(const Edge& i) const {
3.550 + if (!(i.backward)) {
3.551 + return
3.552 + Node(Parent1::graph->source(i), INVALID, false);
3.553 + } else {
3.554 + return
3.555 + Node(INVALID, Parent2::graph->source(i), true);
3.556 + }
3.557 + }
3.558 +
3.559 + Node target(const Edge& i) const {
3.560 + if (!(i.backward)) {
3.561 + return
3.562 + Node(Parent1::graph->target(i), INVALID, false);
3.563 + } else {
3.564 + return
3.565 + Node(INVALID, Parent2::graph->target(i), true);
3.566 + }
3.567 + }
3.568 +
3.569 + using Parent::id;
3.570 + int id(const Edge& n) const {
3.571 + if (!n.backward)
3.572 + return this->Parent1::graph->id(n);
3.573 + else
3.574 + return this->Parent2::graph->id(n);
3.575 + }
3.576 +
3.577 + template <typename _Value>
3.578 + class EdgeMap {
3.579 + protected:
3.580 + typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
3.581 + typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
3.582 + ParentMap1 forward_map;
3.583 + ParentMap2 backward_map;
3.584 + public:
3.585 + typedef _Value Value;
3.586 + typedef Edge Key;
3.587 + EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
3.588 + forward_map(*(gw.Parent1::graph)),
3.589 + backward_map(*(gw.Parent2::graph)) { }
3.590 + EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
3.591 + const _Value& value) :
3.592 + forward_map(*(gw.Parent1::graph), value),
3.593 + backward_map(*(gw.Parent2::graph), value) { }
3.594 + _Value operator[](const Edge& n) const {
3.595 + if (!n.backward)
3.596 + return forward_map[n];
3.597 + else
3.598 + return backward_map[n];
3.599 + }
3.600 + void set(const Edge& n, const _Value& value) {
3.601 + if (!n.backward)
3.602 + forward_map.set(n, value);
3.603 + else
3.604 + backward_map.set(n, value);
3.605 + }
3.606 +// using ParentMap1::operator[];
3.607 +// using ParentMap2::operator[];
3.608 + };
3.609 +
3.610 + };
3.611 +
3.612 +
3.613 /*! A graph wrapper class
3.614 for merging the node-sets and edge-sets of
3.615 two node-disjoint graphs
4.1 --- a/src/work/marci/merge_node_graph_wrapper_test.cc Sat Nov 20 16:12:47 2004 +0000
4.2 +++ b/src/work/marci/merge_node_graph_wrapper_test.cc Mon Nov 22 09:09:18 2004 +0000
4.3 @@ -48,6 +48,14 @@
4.4 checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph1, Graph1> >();
4.5 MergeEdgeGraphWrapper<Graph1, Graph1>::printNode();
4.6 MergeEdgeGraphWrapper<Graph1, Graph1>::printEdge();
4.7 + typedef ResGraphWrapper<Graph1, int,
4.8 + ConstMap<Graph1, int>, ConstMap<Graph1, int> > Graph4;
4.9 + checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph1, Graph4> >();
4.10 + MergeEdgeGraphWrapper<Graph1, Graph4>::printNode();
4.11 + MergeEdgeGraphWrapper<Graph1, Graph4>::printEdge();
4.12 + checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph4, Graph1> >();
4.13 + MergeEdgeGraphWrapper<Graph4, Graph1>::printNode();
4.14 + MergeEdgeGraphWrapper<Graph4, Graph1>::printEdge();
4.15 }
4.16
4.17 Graph1 g1;
4.18 @@ -118,6 +126,7 @@
4.19 printGraph(gw);
4.20
4.21 typedef ListGraph Graph3;
4.22 + //typedef SmartGraph Graph3;
4.23 Graph3 g3;
4.24 GW::NodeMap<Graph3::Node> gwn(gw);
4.25 Graph3::NodeMap<GW::Node> g3n(g3);