Serious bugfix.
2 #ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H
3 #define LEMON_ITERABLE_GRAPH_EXTENDER_H
5 #include <lemon/invalid.h>
6 #include <lemon/utility.h>
10 template <typename _Base>
11 class IterableGraphExtender : public _Base {
14 /// Indicates that the graph is undirected.
18 ///\bug Should it be here?
19 typedef False UndirTag;
22 typedef IterableGraphExtender<_Base> Graph;
24 typedef typename Parent::Node Node;
25 typedef typename Parent::Edge Edge;
28 class NodeIt : public Node {
34 NodeIt(Invalid i) : Node(i) { }
36 explicit NodeIt(const Graph& _graph) : graph(&_graph) {
37 _graph.first(*static_cast<Node*>(this));
40 NodeIt(const Graph& _graph, const Node& node)
41 : Node(node), graph(&_graph) {}
43 NodeIt& operator++() {
51 class EdgeIt : public Edge {
57 EdgeIt(Invalid i) : Edge(i) { }
59 explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
60 _graph.first(*static_cast<Edge*>(this));
63 EdgeIt(const Graph& _graph, const Edge& e) :
64 Edge(e), graph(&_graph) { }
66 EdgeIt& operator++() {
74 class OutEdgeIt : public Edge {
80 OutEdgeIt(Invalid i) : Edge(i) { }
82 OutEdgeIt(const Graph& _graph, const Node& node)
84 _graph.firstOut(*this, node);
87 OutEdgeIt(const Graph& _graph, const Edge& edge)
88 : Edge(edge), graph(&_graph) {}
90 OutEdgeIt& operator++() {
91 graph->nextOut(*this);
98 class InEdgeIt : public Edge {
104 InEdgeIt(Invalid i) : Edge(i) { }
106 InEdgeIt(const Graph& _graph, const Node& node)
108 _graph.firstIn(*this, node);
111 InEdgeIt(const Graph& _graph, const Edge& edge) :
112 Edge(edge), graph(&_graph) {}
114 InEdgeIt& operator++() {
115 graph->nextIn(*this);
121 /// \brief Base node of the iterator
123 /// Returns the base node (ie. the source in this case) of the iterator
124 Node baseNode(const OutEdgeIt &e) const {
125 return Parent::source((Edge)e);
127 /// \brief Running node of the iterator
129 /// Returns the running node (ie. the target in this case) of the
131 Node runningNode(const OutEdgeIt &e) const {
132 return Parent::target((Edge)e);
135 /// \brief Base node of the iterator
137 /// Returns the base node (ie. the target in this case) of the iterator
138 Node baseNode(const InEdgeIt &e) const {
139 return Parent::target((Edge)e);
141 /// \brief Running node of the iterator
143 /// Returns the running node (ie. the source in this case) of the
145 Node runningNode(const InEdgeIt &e) const {
146 return Parent::source((Edge)e);
151 /// \brief The opposite node on the given edge.
153 /// Gives back the opposite on the given edge.
154 Node oppositeNode(const Node& n, const Edge& e) const {
155 if (Parent::source(e) == n) {
156 return Parent::target(e);
158 return Parent::source(e);
164 // void first(NodeIt &) const;
165 // void first(EdgeIt &) const;
166 // void first(OutEdgeIt &) const;
167 // void first(InEdgeIt &) const;
176 template <typename _Base>
177 class IterableUndirGraphExtender : public IterableGraphExtender<_Base> {
180 /// Indicates that the graph is undirected.
182 ///\todo Better name?
184 ///\bug Should it be here?
185 ///\bug Should be tested in the concept checker whether it is defined
187 typedef True UndirTag;
189 typedef IterableGraphExtender<_Base> Parent;
190 typedef IterableUndirGraphExtender<_Base> Graph;
191 typedef typename Parent::Node Node;
192 typedef typename Parent::Edge Edge;
193 typedef typename Parent::UndirEdge UndirEdge;
195 class UndirEdgeIt : public Parent::UndirEdge {
201 UndirEdgeIt(Invalid i) : UndirEdge(i) { }
203 explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) {
204 _graph.first(*static_cast<UndirEdge*>(this));
207 UndirEdgeIt(const Graph& _graph, const UndirEdge& e) :
208 UndirEdge(e), graph(&_graph) { }
210 UndirEdgeIt& operator++() {
217 class IncEdgeIt : public Parent::UndirEdge {
220 friend class IterableUndirGraphExtender;
221 template <typename G>
222 friend class UndirGraphExtender;
227 IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
229 IncEdgeIt(const Graph& _graph, const Node &n)
232 _graph._dirFirstOut(*this, n);
235 IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n)
236 : graph(&_graph), UndirEdge(ue)
238 forward = (_graph.source(ue) == n);
241 IncEdgeIt& operator++() {
242 graph->_dirNextOut(*this);
247 using Parent::baseNode;
248 using Parent::runningNode;
250 /// Base node of the iterator
252 /// Returns the base node of the iterator
253 Node baseNode(const IncEdgeIt &e) const {
254 return _dirSource(e);
256 /// Running node of the iterator
258 /// Returns the running node of the iterator
259 Node runningNode(const IncEdgeIt &e) const {
260 return _dirTarget(e);
263 /// \brief The opposite node on the given undirected edge.
265 /// Gives back the opposite on the given undirected edge.
266 Node oppositeNode(const Node& n, const UndirEdge& e) const {
267 if (Parent::source(e) == n) {
268 return Parent::target(e);
270 return Parent::source(e);
277 #endif // LEMON_GRAPH_EXTENDER_H