COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/marci/merge_node_graph_wrapper.h @ 921:818510fa3d99

Last change on this file since 921:818510fa3d99 was 921:818510fa3d99, checked in by Alpar Juttner, 17 years ago

hugo -> lemon

File size: 5.5 KB
Line 
1/* -*- C++ -*-
2 * src/lemon/merge_node_graph_wrapper.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
6 *
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
10 *
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
13 * purpose.
14 *
15 */
16
17#ifndef LEMON_MERGE_NODE_GRAPH_WRAPPER_H
18#define LEMON_MERGE_NODE_GRAPH_WRAPPER_H
19
20#include <lemon/invalid.h>
21#include <lemon/maps.h>
22#include <lemon/map_defines.h>
23#include <lemon/graph_wrapper.h>
24#include <iostream>
25
26namespace lemon {
27
28  template <typename Graph1, typename Graph2, typename Enable=void>
29  class MergeNodeGraphWrapper :
30    public GraphWrapper<Graph1>, public GraphWrapper<Graph2> {
31    typedef GraphWrapper<Graph1> Parent1;
32    typedef GraphWrapper<Graph2> Parent2;
33    typedef typename GraphWrapper<Graph1>::Node Graph1Node;
34    typedef typename GraphWrapper<Graph2>::Node Graph2Node;
35  public:
36    class Node;
37    class NodeIt;
38    friend class Node;
39    friend class NodeIt;
40    template<typename Value> class NodeMap;
41
42    MergeNodeGraphWrapper(Graph1& _graph1, Graph2& _graph2) :
43      Parent1(_graph1), Parent2(_graph2) { }
44
45    class Node : public Graph1Node, public Graph2Node {
46      friend class MergeNodeGraphWrapper<Graph1, Graph2>;
47      template<typename Value> friend class NodeMap;
48    protected:
49      bool backward; //true, iff backward
50    public:
51      Node() { }
52      /// \todo =false is needed, or causes problems?
53      /// If \c _backward is false, then we get an edge corresponding to the
54      /// original one, otherwise its oppositely directed pair is obtained.
55      Node(const Graph1Node& n1,
56           const Graph2Node& n2, bool _backward) :
57        Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
58      Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
59      bool operator==(const Node& v) const {
60        return (this->backward==v.backward &&
61                static_cast<Graph1Node>(*this)==
62                static_cast<Graph1Node>(v) &&
63                static_cast<Graph2Node>(*this)==
64                static_cast<Graph2Node>(v));
65      }
66      bool operator!=(const Node& v) const {
67        return (this->backward!=v.backward ||
68                static_cast<Graph1Node>(*this)!=
69                static_cast<Graph1Node>(v) ||
70                static_cast<Graph2Node>(*this)!=
71                static_cast<Graph2Node>(v));
72      }
73    };
74
75    class NodeIt : public Node {
76      friend class MergeNodeGraphWrapper<Graph1, Graph2>;
77    protected:
78      const MergeNodeGraphWrapper<Graph1, Graph2>* gw;
79    public:
80      NodeIt() { }
81      NodeIt(Invalid i) : Node(i) { }
82      NodeIt(const MergeNodeGraphWrapper<Graph1, Graph2>& _gw) :
83        Node(typename Graph1::NodeIt(*_gw.Parent1::graph),
84             typename Graph2::Node(),
85             false), gw(&_gw) {
86        if (*static_cast<Graph1Node*>(this)==INVALID) {
87//        *static_cast<Node*>(this)=
88//          Node(Graph1Node(INVALID),
89//               typename Graph2::NodeIt(*_gw.Parent2::graph),
90//               true);
91          *static_cast<Graph2Node*>(this)=
92            typename Graph2::NodeIt(*_gw.Parent2::graph);
93          backward=true;
94        }
95      }
96      NodeIt(const MergeNodeGraphWrapper<Graph1, Graph2>& _gw,
97             const Node& n) :
98        Node(n), gw(&_gw) { }
99      NodeIt& operator++() {
100        if (!this->backward) {
101          *(static_cast<Graph1Node*>(this))=
102            ++(typename Graph1::NodeIt(*gw->Parent1::graph, *this));
103          if (*static_cast<Graph1Node*>(this)==INVALID) {
104//          *static_cast<Node*>(this)=
105//            Node(typename Graph1::Node(INVALID),
106//                 typename Graph2::NodeIt(*gw->Parent2::graph), true);
107            *static_cast<Graph2Node*>(this)=
108              typename Graph2::NodeIt(*gw->Parent2::graph);
109            backward=true;
110          }
111        } else {
112          *(static_cast<Graph2Node*>(this))=
113            ++(typename Graph2::NodeIt(*gw->Parent2::graph, *this));
114        }
115        return *this;
116      }
117    };
118
119    int id(const Node& n) const {
120      if (!n.backward)
121        return this->Parent1::graph->id(n);
122      else
123        return this->Parent2::graph->id(n);
124    }
125
126    template <typename Value>
127    class NodeMap : public Parent1::template NodeMap<Value>,
128                    public Parent2::template NodeMap<Value> {
129      typedef typename Parent1::template NodeMap<Value> ParentMap1;
130      typedef typename Parent2::template NodeMap<Value> ParentMap2;
131    public:
132      NodeMap(const MergeNodeGraphWrapper<Graph1, Graph2>& gw) :
133        ParentMap1(gw),
134        ParentMap2(gw) { }
135      NodeMap(const MergeNodeGraphWrapper<Graph1, Graph2>& gw,
136              const Value& value)
137        : ParentMap1(gw, value),
138          ParentMap2(gw, value) { }
139      NodeMap(const NodeMap& copy)
140        : ParentMap1(copy),
141          ParentMap2(copy) { }
142      template <typename TT>
143      NodeMap(const NodeMap<TT>& copy)
144        : ParentMap1(copy),
145          ParentMap2(copy) { }
146      NodeMap& operator=(const NodeMap& copy) {
147        ParentMap1::operator=(copy);
148        ParentMap2::operator=(copy);
149        return *this;
150      }
151      template <typename TT>
152      NodeMap& operator=(const NodeMap<TT>& copy) {
153        ParentMap1::operator=(copy);
154        ParentMap2::operator=(copy);
155        return *this;
156      }
157      Value operator[](const Node& n) const {
158        if (!n.backward)
159          return ParentMap1::operator[](n);
160        else
161          return ParentMap2::operator[](n);
162      }
163      void set(const Node& n, const Value& value) {
164        if (!n.backward)
165          ParentMap1::set(n, value);
166        else
167          ParentMap2::set(n, value);
168      }
169      using ParentMap1::operator[];
170      using ParentMap2::operator[];
171    };
172   
173  };
174
175} //namespace lemon
176
177#endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H
Note: See TracBrowser for help on using the repository browser.