1 /* -*- C++ -*- |
1 /* -*- C++ -*- |
2 * src/hugo/graph_wrapper.h - Part of HUGOlib, a generic C++ optimization library |
2 * src/hugo/merge_node_graph_wrapper.h - Part of HUGOlib, a generic C++ optimization library |
3 * |
3 * |
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
5 * (Egervary Combinatorial Optimization Research Group, EGRES). |
5 * (Egervary Combinatorial Optimization Research Group, EGRES). |
6 * |
6 * |
7 * Permission to use, modify and distribute this software is granted |
7 * Permission to use, modify and distribute this software is granted |
12 * express or implied, and with no claim as to its suitability for any |
12 * express or implied, and with no claim as to its suitability for any |
13 * purpose. |
13 * purpose. |
14 * |
14 * |
15 */ |
15 */ |
16 |
16 |
|
17 #ifndef HUGO_MERGE_NODE_GRAPH_WRAPPER_H |
|
18 #define HUGO_MERGE_NODE_GRAPH_WRAPPER_H |
|
19 |
17 #include <hugo/invalid.h> |
20 #include <hugo/invalid.h> |
18 #include <hugo/maps.h> |
21 #include <hugo/maps.h> |
19 #include <hugo/map_defines.h> |
22 #include <hugo/map_defines.h> |
20 #include <hugo/graph_wrapper.h> |
23 #include <hugo/graph_wrapper.h> |
21 #include <iostream> |
24 #include <iostream> |
22 |
25 |
23 #ifndef HUGO_MERGE_NODE_GRAPH_WRAPPER_H |
|
24 #define HUGO_MERGE_NODE_GRAPH_WRAPPER_H |
|
25 |
|
26 namespace hugo { |
26 namespace hugo { |
27 |
27 |
28 template <typename Graph1, typename Graph2> |
28 template <typename Graph1, typename Graph2, typename Enable=void> |
29 class MergeNodeGraphWrapper : |
29 class MergeNodeGraphWrapper : |
30 public GraphWrapper<Graph1>, public GraphWrapper<Graph2> { |
30 public GraphWrapper<Graph1>, public GraphWrapper<Graph2> { |
31 typedef GraphWrapper<Graph1> Parent1; |
31 typedef GraphWrapper<Graph1> Parent1; |
32 typedef GraphWrapper<Graph2> Parent2; |
32 typedef GraphWrapper<Graph2> Parent2; |
33 typedef typename GraphWrapper<Graph1>::Node Graph1Node; |
33 typedef typename GraphWrapper<Graph1>::Node Graph1Node; |
35 public: |
35 public: |
36 class Node; |
36 class Node; |
37 class NodeIt; |
37 class NodeIt; |
38 friend class Node; |
38 friend class Node; |
39 friend class NodeIt; |
39 friend class NodeIt; |
|
40 template<typename Value> class NodeMap; |
40 |
41 |
41 MergeNodeGraphWrapper(Graph1& _graph1, Graph2& _graph2) : |
42 MergeNodeGraphWrapper(Graph1& _graph1, Graph2& _graph2) : |
42 Parent1(_graph1), Parent2(_graph2) { } |
43 Parent1(_graph1), Parent2(_graph2) { } |
43 |
44 |
44 class Node : public Graph1Node, public Graph2Node { |
45 class Node : public Graph1Node, public Graph2Node { |
45 friend class MergeNodeGraphWrapper<Graph1, Graph2>; |
46 friend class MergeNodeGraphWrapper<Graph1, Graph2>; |
46 //template<typename T> friend class NodeMap; |
47 template<typename Value> friend class NodeMap; |
47 protected: |
48 protected: |
48 bool backward; //true, iff backward |
49 bool backward; //true, iff backward |
49 public: |
50 public: |
50 Node() { } |
51 Node() { } |
51 /// \todo =false is needed, or causes problems? |
52 /// \todo =false is needed, or causes problems? |
78 public: |
79 public: |
79 NodeIt() { } |
80 NodeIt() { } |
80 NodeIt(Invalid i) : Node(i) { } |
81 NodeIt(Invalid i) : Node(i) { } |
81 NodeIt(const MergeNodeGraphWrapper<Graph1, Graph2>& _gw) : |
82 NodeIt(const MergeNodeGraphWrapper<Graph1, Graph2>& _gw) : |
82 Node(typename Graph1::NodeIt(*_gw.Parent1::graph), |
83 Node(typename Graph1::NodeIt(*_gw.Parent1::graph), |
83 typename Graph2::NodeIt(), |
84 typename Graph2::Node(), |
84 false), gw(&_gw) { |
85 false), gw(&_gw) { |
85 if (*static_cast<Graph1Node*>(this)==INVALID) { |
86 if (*static_cast<Graph1Node*>(this)==INVALID) { |
86 *static_cast<Node*>(this)= |
87 // *static_cast<Node*>(this)= |
87 Node(Graph1Node(INVALID), |
88 // Node(Graph1Node(INVALID), |
88 typename Graph2::NodeIt(*_gw.Parent2::graph), |
89 // typename Graph2::NodeIt(*_gw.Parent2::graph), |
89 true); |
90 // true); |
|
91 *static_cast<Graph2Node*>(this)= |
|
92 typename Graph2::NodeIt(*_gw.Parent2::graph); |
|
93 backward=true; |
90 } |
94 } |
91 } |
95 } |
92 NodeIt(const MergeNodeGraphWrapper<Graph1, Graph2>& _gw, |
96 NodeIt(const MergeNodeGraphWrapper<Graph1, Graph2>& _gw, |
93 const Node& n) : |
97 const Node& n) : |
94 Node(n), gw(&_gw) { } |
98 Node(n), gw(&_gw) { } |
95 NodeIt& operator++() { |
99 NodeIt& operator++() { |
96 if (!this->backward) { |
100 if (!this->backward) { |
97 *(static_cast<Graph1Node*>(this))= |
101 *(static_cast<Graph1Node*>(this))= |
98 ++(typename Graph1::NodeIt(*gw->Parent1::graph, *this)); |
102 ++(typename Graph1::NodeIt(*gw->Parent1::graph, *this)); |
99 if (*static_cast<Graph1Node*>(this)==INVALID) { |
103 if (*static_cast<Graph1Node*>(this)==INVALID) { |
100 *static_cast<Node*>(this)= |
104 // *static_cast<Node*>(this)= |
101 Node(typename Graph1::Node(INVALID), |
105 // Node(typename Graph1::Node(INVALID), |
102 typename Graph2::NodeIt(*gw->Parent2::graph), true); |
106 // typename Graph2::NodeIt(*gw->Parent2::graph), true); |
|
107 *static_cast<Graph2Node*>(this)= |
|
108 typename Graph2::NodeIt(*gw->Parent2::graph); |
|
109 backward=true; |
103 } |
110 } |
104 } else { |
111 } else { |
105 *(static_cast<Graph2Node*>(this))= |
112 *(static_cast<Graph2Node*>(this))= |
106 ++(typename Graph2::NodeIt(*gw->Parent2::graph, *this)); |
113 ++(typename Graph2::NodeIt(*gw->Parent2::graph, *this)); |
107 } |
114 } |
114 return this->Parent1::graph->id(n); |
121 return this->Parent1::graph->id(n); |
115 else |
122 else |
116 return this->Parent2::graph->id(n); |
123 return this->Parent2::graph->id(n); |
117 } |
124 } |
118 |
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 |
119 }; |
173 }; |
120 |
174 |
121 } //namespace hugo |
175 } //namespace hugo |
122 |
176 |
123 #endif //HUGO_MERGE_NODE_GRAPH_WRAPPER_H |
177 #endif //HUGO_MERGE_NODE_GRAPH_WRAPPER_H |