Hmmm...
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 /// Base node of the iterator
123 /// Returns the base node (ie. the source in this case) of the iterator
125 /// \todo Document in the concept!
126 Node baseNode(const OutEdgeIt &e) const {
129 /// Running node of the iterator
131 /// Returns the running node (ie. the target in this case) of the
134 /// \todo Document in the concept!
135 Node runningNode(const OutEdgeIt &e) const {
139 /// Base node of the iterator
141 /// Returns the base node (ie. the target in this case) of the iterator
143 /// \todo Document in the concept!
144 Node baseNode(const InEdgeIt &e) const {
147 /// Running node of the iterator
149 /// Returns the running node (ie. the source in this case) of the
152 /// \todo Document in the concept!
153 Node runningNode(const InEdgeIt &e) const {
161 // /// \todo When (and if) we change the iterators concept to use operator*,
162 // /// then the following shadowed methods will become superfluous.
163 // /// But for now these are important safety measures.
165 // void first(NodeIt &) const;
166 // void first(EdgeIt &) const;
167 // void first(OutEdgeIt &) const;
168 // void first(InEdgeIt &) const;
177 template <typename _Base>
178 class IterableUndirGraphExtender : public IterableGraphExtender<_Base> {
181 /// Indicates that the graph is undirected.
183 ///\todo Better name?
185 ///\bug Should it be here?
186 ///\bug Should be tested in the concept checker whether it is defined
188 typedef True UndirTag;
190 typedef IterableGraphExtender<_Base> Parent;
191 typedef IterableUndirGraphExtender<_Base> Graph;
192 typedef typename Parent::Node Node;
194 typedef typename Parent::UndirEdge UndirEdge;
196 class UndirEdgeIt : public Parent::UndirEdge {
202 UndirEdgeIt(Invalid i) : UndirEdge(i) { }
204 explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) {
205 _graph.first(*static_cast<UndirEdge*>(this));
208 UndirEdgeIt(const Graph& _graph, const UndirEdge& e) :
209 UndirEdge(e), graph(&_graph) { }
211 UndirEdgeIt& operator++() {
218 class IncEdgeIt : public Parent::UndirEdge {
221 friend class IterableUndirGraphExtender;
222 template <typename G>
223 friend class UndirGraphExtender;
228 IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
230 IncEdgeIt(const Graph& _graph, const Node &n)
233 _graph._dirFirstOut(*this, n);
236 IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n)
237 : graph(&_graph), UndirEdge(ue)
239 forward = (_graph.source(ue) == n);
242 IncEdgeIt& operator++() {
243 graph->_dirNextOut(*this);
248 using Parent::baseNode;
249 using Parent::runningNode;
251 /// Base node of the iterator
253 /// Returns the base node of the iterator
254 Node baseNode(const IncEdgeIt &e) const {
255 return _dirSource(e);
257 /// Running node of the iterator
259 /// Returns the running node of the iterator
260 Node runningNode(const IncEdgeIt &e) const {
261 return _dirTarget(e);
267 #endif // LEMON_GRAPH_EXTENDER_H