68 /// \bug Is this a good name for this? Or "reverse" is better? |
68 /// \bug Is this a good name for this? Or "reverse" is better? |
69 Edge opposite(const Edge &e) const { |
69 Edge opposite(const Edge &e) const { |
70 return Edge(e,!e.forward); |
70 return Edge(e,!e.forward); |
71 } |
71 } |
72 |
72 |
73 /// Source of the given Edge. |
73 protected: |
74 Node source(const Edge &e) const { |
74 |
|
75 template <typename E> |
|
76 Node _dirSource(const E &e) const { |
75 return e.forward ? Parent::source(e) : Parent::target(e); |
77 return e.forward ? Parent::source(e) : Parent::target(e); |
76 } |
78 } |
77 |
79 |
|
80 template <typename E> |
|
81 Node _dirTarget(const E &e) const { |
|
82 return e.forward ? Parent::target(e) : Parent::source(e); |
|
83 } |
|
84 |
|
85 public: |
78 /// \todo Shouldn't the "source" of an undirected edge be called "aNode" |
86 /// \todo Shouldn't the "source" of an undirected edge be called "aNode" |
79 /// or something??? |
87 /// or something??? |
80 using Parent::source; |
88 using Parent::source; |
81 |
89 |
82 /// Target of the given Edge. |
90 /// Source of the given Edge. |
83 Node target(const Edge &e) const { |
91 Node source(const Edge &e) const { |
84 return e.forward ? Parent::target(e) : Parent::source(e); |
92 return _dirSource(e); |
85 } |
93 } |
86 |
94 |
87 /// \todo Shouldn't the "target" of an undirected edge be called "bNode" |
95 /// \todo Shouldn't the "target" of an undirected edge be called "bNode" |
88 /// or something??? |
96 /// or something??? |
89 using Parent::target; |
97 using Parent::target; |
|
98 |
|
99 /// Target of the given Edge. |
|
100 Node target(const Edge &e) const { |
|
101 return _dirTarget(e); |
|
102 } |
90 |
103 |
91 /// Returns whether the given directed edge is same orientation as the |
104 /// Returns whether the given directed edge is same orientation as the |
92 /// corresponding undirected edge. |
105 /// corresponding undirected edge. |
93 /// |
106 /// |
94 /// \todo reference to the corresponding point of the undirected graph |
107 /// \todo reference to the corresponding point of the undirected graph |
120 Parent::next(e); |
133 Parent::next(e); |
121 e.forward = true; |
134 e.forward = true; |
122 } |
135 } |
123 } |
136 } |
124 |
137 |
125 void firstOut(Edge &e, const Node &n) const { |
138 |
|
139 protected: |
|
140 |
|
141 template <typename E> |
|
142 void _dirFirstOut(E &e, const Node &n) const { |
126 Parent::firstOut(e,n); |
143 Parent::firstOut(e,n); |
127 if( UndirEdge(e) != INVALID ) { |
144 if( UndirEdge(e) != INVALID ) { |
128 e.forward = true; |
145 e.forward = true; |
129 } |
146 } |
130 else { |
147 else { |
131 Parent::firstIn(e,n); |
148 Parent::firstIn(e,n); |
132 e.forward = false; |
149 e.forward = false; |
133 } |
150 } |
134 } |
151 } |
135 void firstIn(Edge &e, const Node &n) const { |
152 template <typename E> |
|
153 void _dirFirstIn(E &e, const Node &n) const { |
136 Parent::firstIn(e,n); |
154 Parent::firstIn(e,n); |
137 if( UndirEdge(e) != INVALID ) { |
155 if( UndirEdge(e) != INVALID ) { |
138 e.forward = true; |
156 e.forward = true; |
139 } |
157 } |
140 else { |
158 else { |
141 Parent::firstOut(e,n); |
159 Parent::firstOut(e,n); |
142 e.forward = false; |
160 e.forward = false; |
143 } |
161 } |
144 } |
162 } |
145 |
163 |
146 void nextOut(Edge &e) const { |
164 template <typename E> |
|
165 void _dirNextOut(E &e) const { |
147 if( e.forward ) { |
166 if( e.forward ) { |
148 Parent::nextOut(e); |
167 Parent::nextOut(e); |
149 if( UndirEdge(e) == INVALID ) { |
168 if( UndirEdge(e) == INVALID ) { |
150 Parent::firstIn(e, Parent::source(e)); |
169 Parent::firstIn(e, Parent::source(e)); |
151 e.forward = false; |
170 e.forward = false; |
166 else { |
186 else { |
167 Parent::nextOut(e); |
187 Parent::nextOut(e); |
168 } |
188 } |
169 } |
189 } |
170 |
190 |
|
191 public: |
|
192 |
|
193 void firstOut(Edge &e, const Node &n) const { |
|
194 _dirFirstOut(e, n); |
|
195 } |
|
196 void firstIn(Edge &e, const Node &n) const { |
|
197 _dirFirstIn(e, n); |
|
198 } |
|
199 |
|
200 void nextOut(Edge &e) const { |
|
201 _dirNextOut(e); |
|
202 } |
|
203 void nextIn(Edge &e) const { |
|
204 _dirNextIn(e); |
|
205 } |
|
206 |
171 // Miscellaneous stuff: |
207 // Miscellaneous stuff: |
172 |
208 |
173 /// \todo these methods (id, maxEdgeId) should be moved into separate |
209 /// \todo these methods (id, maxEdgeId) should be moved into separate |
174 /// Extender |
210 /// Extender |
175 |
211 |
176 using Parent::id; |
212 // using Parent::id; |
|
213 // Using "using" is not a good idea, cause it could be that there is |
|
214 // no "id" in Parent... |
|
215 |
|
216 int id(const Node &n) const { |
|
217 return Parent::id(n); |
|
218 } |
|
219 |
|
220 int id(const UndirEdge &e) const { |
|
221 return Parent::id(e); |
|
222 } |
177 |
223 |
178 int id(const Edge &e) const { |
224 int id(const Edge &e) const { |
179 return 2 * Parent::id(e) + int(e.forward); |
225 return 2 * Parent::id(e) + int(e.forward); |
180 } |
226 } |
181 |
227 |
182 int maxId(Edge = INVALID) const { |
228 |
|
229 int maxId(Node n) const { |
|
230 return Parent::maxId(Node()); |
|
231 } |
|
232 |
|
233 int maxId(Edge) const { |
183 return 2 * Parent::maxId(typename Parent::Edge()) + 1; |
234 return 2 * Parent::maxId(typename Parent::Edge()) + 1; |
184 } |
235 } |
185 int maxId(UndirEdge = INVALID) const { |
236 int maxId(UndirEdge) const { |
186 return Parent::maxId(typename Parent::Edge()); |
237 return Parent::maxId(typename Parent::Edge()); |
187 } |
238 } |
188 |
239 |
189 }; |
240 }; |
190 |
241 |