3 * src/lemon/undir_graph_extender.h - Part of LEMON, a generic C++
6 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi
7 * Kutatocsoport (Egervary Combinatorial Optimization Research Group,
10 * Permission to use, modify and distribute this software is granted
11 * provided that this copyright notice appears in all copies. For
12 * precise terms see the accompanying LICENSE file.
14 * This software is provided "AS IS" with no warranty of any kind,
15 * express or implied, and with no claim as to its suitability for any
20 #ifndef LEMON_UNDIR_GRAPH_EXTENDER_H
21 #define LEMON_UNDIR_GRAPH_EXTENDER_H
23 #include <lemon/invalid.h>
27 template <typename _Base>
28 class UndirGraphExtender : public _Base {
30 typedef UndirGraphExtender Graph;
34 typedef typename Parent::Edge UndirEdge;
35 typedef typename Parent::Node Node;
37 class Edge : public UndirEdge {
38 friend class UndirGraphExtender;
41 // FIXME: Marci use opposite logic in his graph wrappers. It would
42 // be reasonable to syncronize...
47 /// Construct a direct edge from undirect edge and a direction.
48 Edge(const UndirEdge &ue, bool _forward) :
49 UndirEdge(ue), forward(_forward) {}
50 /// Invalid edge constructor
51 Edge(Invalid i) : UndirEdge(i), forward(false) {}
53 bool operator==(const Edge &that) const {
54 return forward==that.forward && UndirEdge(*this)==UndirEdge(that);
56 bool operator!=(const Edge &that) const {
57 return forward!=that.forward || UndirEdge(*this)!=UndirEdge(that);
59 bool operator<(const Edge &that) const {
60 return forward<that.forward ||
61 (!(that.forward<forward) && UndirEdge(*this)<UndirEdge(that));
66 /// \brief Returns the Edge of opposite direction.
68 /// \bug Is this a good name for this? Or "reverse" is better?
69 Edge opposite(const Edge &e) const {
70 return Edge(e,!e.forward);
73 /// Source of the given Edge.
74 Node source(const Edge &e) const {
75 return e.forward ? Parent::source(e) : Parent::target(e);
78 /// \todo Shouldn't the "source" of an undirected edge be called "aNode"
82 /// Target of the given Edge.
83 Node target(const Edge &e) const {
84 return e.forward ? Parent::target(e) : Parent::source(e);
87 /// \todo Shouldn't the "target" of an undirected edge be called "bNode"
91 /// Returns whether the given directed edge is same orientation as the
92 /// corresponding undirected edge.
94 /// \todo reference to the corresponding point of the undirected graph
95 /// concept. "What does the direction of an undirected edge mean?"
96 bool forward(const Edge &e) const { return e.forward; }
98 Node oppsiteNode(const Node &n, const Edge &e) const {
99 if( n == Parent::source(e))
100 return Parent::target(e);
101 else if( n == Parent::target(e))
102 return Parent::source(e);
109 void first(Edge &e) const {
115 void next(Edge &e) const {
125 void firstOut(Edge &e, const Node &n) const {
126 Parent::firstOut(e,n);
127 if( UndirEdge(e) != INVALID ) {
131 Parent::firstIn(e,n);
135 void firstIn(Edge &e, const Node &n) const {
136 Parent::firstIn(e,n);
137 if( UndirEdge(e) != INVALID ) {
141 Parent::firstOut(e,n);
146 void nextOut(Edge &e) const {
149 if( UndirEdge(e) == INVALID ) {
150 Parent::firstIn(e, Parent::source(e));
158 void nextIn(Edge &e) const {
161 if( UndirEdge(e) == INVALID ) {
162 Parent::firstOut(e, Parent::target(e));
171 // Miscellaneous stuff:
173 /// \todo these methods (id, maxEdgeId) should be moved into separate
178 int id(const Edge &e) const {
179 return 2 * Parent::id(e) + int(e.forward);
182 int maxId(Edge = INVALID) const {
183 return 2 * Parent::maxId(typename Parent::Edge()) + 1;
185 int maxId(UndirEdge = INVALID) const {
186 return Parent::maxId(typename Parent::Edge());
193 #endif // LEMON_UNDIR_GRAPH_EXTENDER_H