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);
76 Node _dirSource(const E &e) const {
77 return e.forward ? Parent::source(e) : Parent::target(e);
81 Node _dirTarget(const E &e) const {
82 return e.forward ? Parent::target(e) : Parent::source(e);
86 /// \todo Shouldn't the "source" of an undirected edge be called "aNode"
90 /// Source of the given Edge.
91 Node source(const Edge &e) const {
95 /// \todo Shouldn't the "target" of an undirected edge be called "bNode"
99 /// Target of the given Edge.
100 Node target(const Edge &e) const {
101 return _dirTarget(e);
104 /// Returns whether the given directed edge is same orientation as the
105 /// corresponding undirected edge.
107 /// \todo reference to the corresponding point of the undirected graph
108 /// concept. "What does the direction of an undirected edge mean?"
109 bool forward(const Edge &e) const { return e.forward; }
111 Node oppsiteNode(const Node &n, const Edge &e) const {
112 if( n == Parent::source(e))
113 return Parent::target(e);
114 else if( n == Parent::target(e))
115 return Parent::source(e);
122 void first(Edge &e) const {
128 void next(Edge &e) const {
141 template <typename E>
142 void _dirFirstOut(E &e, const Node &n) const {
143 Parent::firstOut(e,n);
144 if( UndirEdge(e) != INVALID ) {
148 Parent::firstIn(e,n);
152 template <typename E>
153 void _dirFirstIn(E &e, const Node &n) const {
154 Parent::firstIn(e,n);
155 if( UndirEdge(e) != INVALID ) {
159 Parent::firstOut(e,n);
164 template <typename E>
165 void _dirNextOut(E &e) const {
168 if( UndirEdge(e) == INVALID ) {
169 Parent::firstIn(e, Parent::source(e));
177 template <typename E>
178 void _dirNextIn(E &e) const {
181 if( UndirEdge(e) == INVALID ) {
182 Parent::firstOut(e, Parent::target(e));
193 void firstOut(Edge &e, const Node &n) const {
196 void firstIn(Edge &e, const Node &n) const {
200 void nextOut(Edge &e) const {
203 void nextIn(Edge &e) const {
207 // Miscellaneous stuff:
209 /// \todo these methods (id, maxEdgeId) should be moved into separate
213 // Using "using" is not a good idea, cause it could be that there is
214 // no "id" in Parent...
216 int id(const Node &n) const {
217 return Parent::id(n);
220 int id(const UndirEdge &e) const {
221 return Parent::id(e);
224 int id(const Edge &e) const {
225 return 2 * Parent::id(e) + int(e.forward);
229 int maxId(Node n) const {
230 return Parent::maxId(Node());
233 int maxId(Edge) const {
234 return 2 * Parent::maxId(typename Parent::Edge()) + 1;
236 int maxId(UndirEdge) const {
237 return Parent::maxId(typename Parent::Edge());
244 #endif // LEMON_UNDIR_GRAPH_EXTENDER_H