2 #ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H
3 #define LEMON_ITERABLE_GRAPH_EXTENDER_H
5 #include <lemon/invalid.h>
9 template <typename _Base>
10 class IterableGraphExtender : public _Base {
14 typedef IterableGraphExtender<_Base> Graph;
16 typedef typename Parent::Node Node;
17 typedef typename Parent::Edge Edge;
20 class NodeIt : public Node {
26 NodeIt(Invalid i) : Node(i) { }
28 explicit NodeIt(const Graph& _graph) : graph(&_graph) {
29 _graph.first(*static_cast<Node*>(this));
32 NodeIt(const Graph& _graph, const Node& node)
33 : Node(node), graph(&_graph) {}
35 NodeIt& operator++() {
43 class EdgeIt : public Edge {
49 EdgeIt(Invalid i) : Edge(i) { }
51 explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
52 _graph.first(*static_cast<Edge*>(this));
55 EdgeIt(const Graph& _graph, const Edge& e) :
56 Edge(e), graph(&_graph) { }
58 EdgeIt& operator++() {
66 class OutEdgeIt : public Edge {
72 OutEdgeIt(Invalid i) : Edge(i) { }
74 OutEdgeIt(const Graph& _graph, const Node& node)
76 _graph.firstOut(*this, node);
79 OutEdgeIt(const Graph& _graph, const Edge& edge)
80 : Edge(edge), graph(&_graph) {}
82 OutEdgeIt& operator++() {
83 graph->nextOut(*this);
90 class InEdgeIt : public Edge {
96 InEdgeIt(Invalid i) : Edge(i) { }
98 InEdgeIt(const Graph& _graph, const Node& node)
100 _graph.firstIn(*this, node);
103 InEdgeIt(const Graph& _graph, const Edge& edge) :
104 Edge(edge), graph(&_graph) {}
106 InEdgeIt& operator++() {
107 graph->nextIn(*this);
117 /// \todo When (and if) we change the iterators concept to use operator*,
118 /// then the following shadowed methods will become superfluous.
119 /// But for now these are important safety measures.
121 void first(NodeIt &) const;
122 void first(EdgeIt &) const;
123 void first(OutEdgeIt &) const;
124 void first(InEdgeIt &) const;
128 template <typename _Base>
129 class IterableUndirGraphExtender : public IterableGraphExtender<_Base> {
132 typedef IterableGraphExtender<_Base> Parent;
133 typedef IterableUndirGraphExtender<_Base> Graph;
134 typedef typename Parent::Node Node;
136 typedef typename Parent::UndirEdge UndirEdge;
138 class UndirEdgeIt : public UndirEdge {
144 UndirEdgeIt(Invalid i) : UndirEdge(i) { }
146 explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) {
147 _graph.first(*static_cast<UndirEdge*>(this));
150 UndirEdgeIt(const Graph& _graph, const UndirEdge& e) :
151 UndirEdge(e), graph(&_graph) { }
153 UndirEdgeIt& operator++() {
160 class IncEdgeIt : public UndirEdge {
163 friend class IterableUndirGraphExtender;
164 template <typename G>
165 friend class UndirGraphExtender;
170 IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
172 explicit IncEdgeIt(const Graph& _graph, const Node &n)
175 _graph._dirFirstOut(*this, n);
178 // FIXME: Do we need this type of constructor here?
179 // IncEdgeIt(const Graph& _graph, const Edge& e) :
180 // UndirEdge(e), graph(&_graph), forward(_graph.forward(e)) { }
182 // IncEdgeIt(const Graph& _graph, const Node& n,
183 // Const UndirEdge &e) ... ?
185 IncEdgeIt& operator++() {
186 graph->_dirNextOut(*this);
191 Node source(const IncEdgeIt &e) const {
192 return _dirSource(e);
195 /// \todo Shouldn't the "source" of an undirected edge be called "aNode"
197 using Parent::source;
199 /// Target of the given Edge.
200 Node target(const IncEdgeIt &e) const {
201 return _dirTarget(e);
204 /// \todo Shouldn't the "target" of an undirected edge be called "bNode"
206 using Parent::target;
211 #endif // LEMON_GRAPH_EXTENDER_H