if you have a nuclear power plant and wanna compute small magic squares, then let's do it
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(true) {}
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 oppositeNode(const Node &n, const UndirEdge &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::firstIn(e,n);
144 if( UndirEdge(e) != INVALID ) {
148 Parent::firstOut(e,n);
152 template <typename E>
153 void _dirFirstIn(E &e, const Node &n) const {
154 Parent::firstOut(e,n);
155 if( UndirEdge(e) != INVALID ) {
159 Parent::firstIn(e,n);
164 template <typename E>
165 void _dirNextOut(E &e) const {
167 Node n = Parent::target(e);
169 if( UndirEdge(e) == INVALID ) {
170 Parent::firstOut(e, n);
178 template <typename E>
179 void _dirNextIn(E &e) const {
181 Node n = Parent::source(e);
183 if( UndirEdge(e) == INVALID ) {
184 Parent::firstIn(e, n);
195 void firstOut(Edge &e, const Node &n) const {
198 void firstIn(Edge &e, const Node &n) const {
202 void nextOut(Edge &e) const {
205 void nextIn(Edge &e) const {
209 // Miscellaneous stuff:
211 /// \todo these methods (id, maxEdgeId) should be moved into separate
215 // Using "using" is not a good idea, cause it could be that there is
216 // no "id" in Parent...
218 int id(const Node &n) const {
219 return Parent::id(n);
222 int id(const UndirEdge &e) const {
223 return Parent::id(e);
226 int id(const Edge &e) const {
227 return 2 * Parent::id(e) + int(e.forward);
231 int maxId(Node) const {
232 return Parent::maxId(Node());
235 int maxId(Edge) const {
236 return 2 * Parent::maxId(typename Parent::Edge()) + 1;
238 int maxId(UndirEdge) const {
239 return Parent::maxId(typename Parent::Edge());
243 int edgeNum() const {
244 return 2 * Parent::edgeNum();
246 int undirEdgeNum() const {
247 return Parent::edgeNum();
254 #endif // LEMON_UNDIR_GRAPH_EXTENDER_H