213 void first() const; |
216 void first() const; |
214 void next() const; |
217 void next() const; |
215 }; |
218 }; |
216 |
219 |
217 |
220 |
|
221 template <typename _Graph1, typename _Graph2> |
|
222 class MergeNodeGraphWrapper : public |
|
223 IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > { |
|
224 public: |
|
225 typedef _Graph1 Graph1; |
|
226 typedef _Graph2 Graph2; |
|
227 typedef IterableGraphExtender< |
|
228 MergeNodeGraphWrapperBase<_Graph1, _Graph2> > Parent; |
|
229 protected: |
|
230 MergeNodeGraphWrapper() { } |
|
231 public: |
|
232 MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { |
|
233 Parent::Parent1::setGraph(_graph1); |
|
234 Parent::Parent2::setGraph(_graph2); |
|
235 } |
|
236 }; |
|
237 |
|
238 |
|
239 /*! A base class for merging the node-sets and edge-sets of |
|
240 two node-disjoint graphs |
|
241 into one graph. |
|
242 */ |
218 template <typename _Graph1, typename _Graph2, typename Enable=void> |
243 template <typename _Graph1, typename _Graph2, typename Enable=void> |
219 class MergeNodeGraphWrapper : public |
244 class MergeEdgeGraphWrapperBase : |
220 IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > { |
245 public MergeNodeGraphWrapperBase<_Graph1, _Graph2> { |
|
246 public: |
|
247 void printEdge() const { std::cout << "generic" << std::endl; } |
|
248 typedef _Graph1 Graph1; |
|
249 typedef _Graph2 Graph2; |
|
250 typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent; |
|
251 typedef typename Parent::Parent1 Parent1; |
|
252 typedef typename Parent::Parent2 Parent2; |
|
253 // typedef P1<_Graph1> Parent1; |
|
254 // typedef P2<_Graph2> Parent2; |
|
255 typedef typename Parent1::Edge Graph1Edge; |
|
256 typedef typename Parent2::Edge Graph2Edge; |
|
257 protected: |
|
258 MergeEdgeGraphWrapperBase() { } |
|
259 public: |
|
260 template <typename _Value> class EdgeMap; |
|
261 |
|
262 typedef typename Parent::Node Node; |
|
263 |
|
264 class Edge : public Graph1Edge, public Graph2Edge { |
|
265 friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>; |
|
266 template <typename Value> friend class EdgeMap; |
|
267 protected: |
|
268 bool backward; //true, iff backward |
|
269 public: |
|
270 Edge() { } |
|
271 /// \todo =false is needed, or causes problems? |
|
272 /// If \c _backward is false, then we get an edge corresponding to the |
|
273 /// original one, otherwise its oppositely directed pair is obtained. |
|
274 Edge(const Graph1Edge& n1, |
|
275 const Graph2Edge& n2, bool _backward) : |
|
276 Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { } |
|
277 Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { } |
|
278 bool operator==(const Edge& v) const { |
|
279 return (this->backward==v.backward && |
|
280 static_cast<Graph1Edge>(*this)== |
|
281 static_cast<Graph1Edge>(v) && |
|
282 static_cast<Graph2Edge>(*this)== |
|
283 static_cast<Graph2Edge>(v)); |
|
284 } |
|
285 bool operator!=(const Edge& v) const { |
|
286 return (this->backward!=v.backward || |
|
287 static_cast<Graph1Edge>(*this)!= |
|
288 static_cast<Graph1Edge>(v) || |
|
289 static_cast<Graph2Edge>(*this)!= |
|
290 static_cast<Graph2Edge>(v)); |
|
291 } |
|
292 }; |
|
293 |
|
294 using Parent::first; |
|
295 void first(Edge& i) const { |
|
296 Parent1::graph->first(*static_cast<Graph1Edge*>(&i)); |
|
297 i.backward=false; |
|
298 if (*static_cast<Graph1Edge*>(&i)==INVALID) { |
|
299 Parent2::graph->first(*static_cast<Graph2Edge*>(&i)); |
|
300 i.backward=true; |
|
301 } |
|
302 } |
|
303 void firstIn(Edge& i, const Node& n) const { |
|
304 Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n); |
|
305 i.backward=false; |
|
306 if (*static_cast<Graph1Edge*>(&i)==INVALID) { |
|
307 Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n); |
|
308 i.backward=true; |
|
309 } |
|
310 } |
|
311 void firstOut(Edge& i, const Node& n) const { |
|
312 Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n); |
|
313 i.backward=false; |
|
314 if (*static_cast<Graph1Edge*>(&i)==INVALID) { |
|
315 Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n); |
|
316 i.backward=true; |
|
317 } |
|
318 } |
|
319 |
|
320 using Parent::next; |
|
321 void next(Edge& i) const { |
|
322 if (!(i.backward)) { |
|
323 Parent1::graph->next(*static_cast<Graph1Edge*>(&i)); |
|
324 if (*static_cast<Graph1Edge*>(&i)==INVALID) { |
|
325 Parent2::graph->first(*static_cast<Graph2Edge*>(&i)); |
|
326 i.backward=true; |
|
327 } |
|
328 } else { |
|
329 Parent2::graph->next(*static_cast<Graph2Edge*>(&i)); |
|
330 } |
|
331 } |
|
332 void nextIn(Edge& i) const { |
|
333 if (!(i.backward)) { |
|
334 Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i)); |
|
335 if (*static_cast<Graph1Edge*>(&i)==INVALID) { |
|
336 Parent2::graph->first(*static_cast<Graph2Edge*>(&i)); |
|
337 i.backward=true; |
|
338 } |
|
339 } else { |
|
340 Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i)); |
|
341 } |
|
342 } |
|
343 void nextOut(Edge& i) const { |
|
344 if (!(i.backward)) { |
|
345 Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i)); |
|
346 if (*static_cast<Graph1Edge*>(&i)==INVALID) { |
|
347 Parent2::graph->first(*static_cast<Graph2Edge*>(&i)); |
|
348 i.backward=true; |
|
349 } |
|
350 } else { |
|
351 Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i)); |
|
352 } |
|
353 } |
|
354 |
|
355 Node source(const Edge& i) const { |
|
356 if (!(i.backward)) { |
|
357 return |
|
358 Node(Parent1::graph->source(i), INVALID, false); |
|
359 } else { |
|
360 return |
|
361 Node(INVALID, Parent2::graph->source(i), true); |
|
362 } |
|
363 } |
|
364 |
|
365 Node target(const Edge& i) const { |
|
366 if (!(i.backward)) { |
|
367 return |
|
368 Node(Parent1::graph->target(i), INVALID, false); |
|
369 } else { |
|
370 return |
|
371 Node(INVALID, Parent2::graph->target(i), true); |
|
372 } |
|
373 } |
|
374 |
|
375 using Parent::id; |
|
376 int id(const Edge& n) const { |
|
377 if (!n.backward) |
|
378 return this->Parent1::graph->id(n); |
|
379 else |
|
380 return this->Parent2::graph->id(n); |
|
381 } |
|
382 |
|
383 template <typename _Value> |
|
384 class EdgeMap : public Parent1::template EdgeMap<_Value>, |
|
385 public Parent2::template EdgeMap<_Value> { |
|
386 typedef typename Parent1::template EdgeMap<_Value> ParentMap1; |
|
387 typedef typename Parent2::template EdgeMap<_Value> ParentMap2; |
|
388 public: |
|
389 typedef _Value Value; |
|
390 typedef Edge Key; |
|
391 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : |
|
392 ParentMap1(gw), ParentMap2(gw) { } |
|
393 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, |
|
394 const _Value& value) : |
|
395 ParentMap1(gw, value), ParentMap2(gw, value) { } |
|
396 _Value operator[](const Edge& n) const { |
|
397 if (!n.backward) |
|
398 return ParentMap1::operator[](n); |
|
399 else |
|
400 return ParentMap2::operator[](n); |
|
401 } |
|
402 void set(const Edge& n, const _Value& value) { |
|
403 if (!n.backward) |
|
404 ParentMap1::set(n, value); |
|
405 else |
|
406 ParentMap2::set(n, value); |
|
407 } |
|
408 // using ParentMap1::operator[]; |
|
409 // using ParentMap2::operator[]; |
|
410 }; |
|
411 |
|
412 }; |
|
413 |
|
414 |
|
415 template <typename _Graph1, typename _Graph2> |
|
416 class MergeEdgeGraphWrapper : public |
|
417 IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > { |
221 public: |
418 public: |
222 typedef _Graph1 Graph1; |
419 typedef _Graph1 Graph1; |
223 typedef _Graph2 Graph2; |
420 typedef _Graph2 Graph2; |
224 typedef IterableGraphExtender< |
421 typedef IterableGraphExtender< |
225 MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > Parent; |
422 MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > Parent; |
226 protected: |
423 protected: |
227 MergeNodeGraphWrapper() { } |
424 MergeEdgeGraphWrapper() { } |
228 public: |
425 public: |
229 MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { |
426 MergeEdgeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { |
230 Parent::Parent1::setGraph(_graph1); |
427 Parent::Parent1::setGraph(_graph1); |
231 Parent::Parent2::setGraph(_graph2); |
428 Parent::Parent2::setGraph(_graph2); |
232 } |
429 } |
233 }; |
430 }; |
234 |
431 |