diff -r 4ea2147274db -r d4acebef7276 src/lemon/bits/iterable_graph_extender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lemon/bits/iterable_graph_extender.h Tue Apr 05 12:30:46 2005 +0000 @@ -0,0 +1,250 @@ +// -*- c++ -*- +#ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H +#define LEMON_ITERABLE_GRAPH_EXTENDER_H + +#include + +namespace lemon { + + template + class IterableGraphExtender : public _Base { + public: + + typedef _Base Parent; + typedef IterableGraphExtender<_Base> Graph; + + typedef typename Parent::Node Node; + typedef typename Parent::Edge Edge; + + + class NodeIt : public Node { + const Graph* graph; + public: + + NodeIt() {} + + NodeIt(Invalid i) : Node(i) { } + + explicit NodeIt(const Graph& _graph) : graph(&_graph) { + _graph.first(*static_cast(this)); + } + + NodeIt(const Graph& _graph, const Node& node) + : Node(node), graph(&_graph) {} + + NodeIt& operator++() { + graph->next(*this); + return *this; + } + + }; + + + class EdgeIt : public Edge { + const Graph* graph; + public: + + EdgeIt() { } + + EdgeIt(Invalid i) : Edge(i) { } + + explicit EdgeIt(const Graph& _graph) : graph(&_graph) { + _graph.first(*static_cast(this)); + } + + EdgeIt(const Graph& _graph, const Edge& e) : + Edge(e), graph(&_graph) { } + + EdgeIt& operator++() { + graph->next(*this); + return *this; + } + + }; + + + class OutEdgeIt : public Edge { + const Graph* graph; + public: + + OutEdgeIt() { } + + OutEdgeIt(Invalid i) : Edge(i) { } + + OutEdgeIt(const Graph& _graph, const Node& node) + : graph(&_graph) { + _graph.firstOut(*this, node); + } + + OutEdgeIt(const Graph& _graph, const Edge& edge) + : Edge(edge), graph(&_graph) {} + + OutEdgeIt& operator++() { + graph->nextOut(*this); + return *this; + } + + }; + + + class InEdgeIt : public Edge { + const Graph* graph; + public: + + InEdgeIt() { } + + InEdgeIt(Invalid i) : Edge(i) { } + + InEdgeIt(const Graph& _graph, const Node& node) + : graph(&_graph) { + _graph.firstIn(*this, node); + } + + InEdgeIt(const Graph& _graph, const Edge& edge) : + Edge(edge), graph(&_graph) {} + + InEdgeIt& operator++() { + graph->nextIn(*this); + return *this; + } + + }; + + /// Base node of the iterator + /// + /// Returns the base node (ie. the source in this case) of the iterator + /// + /// \todo Document in the concept! + Node baseNode(const OutEdgeIt &e) const { + return source(e); + } + /// Running node of the iterator + /// + /// Returns the running node (ie. the target in this case) of the + /// iterator + /// + /// \todo Document in the concept! + Node runningNode(const OutEdgeIt &e) const { + return target(e); + } + + /// Base node of the iterator + /// + /// Returns the base node (ie. the target in this case) of the iterator + /// + /// \todo Document in the concept! + Node baseNode(const InEdgeIt &e) const { + return target(e); + } + /// Running node of the iterator + /// + /// Returns the running node (ie. the source in this case) of the + /// iterator + /// + /// \todo Document in the concept! + Node runningNode(const InEdgeIt &e) const { + return source(e); + } + + using Parent::first; + + private: + + // /// \todo When (and if) we change the iterators concept to use operator*, + // /// then the following shadowed methods will become superfluous. + // /// But for now these are important safety measures. + + // void first(NodeIt &) const; + // void first(EdgeIt &) const; + // void first(OutEdgeIt &) const; + // void first(InEdgeIt &) const; + + }; + + + + + + + template + class IterableUndirGraphExtender : public IterableGraphExtender<_Base> { + public: + + typedef IterableGraphExtender<_Base> Parent; + typedef IterableUndirGraphExtender<_Base> Graph; + typedef typename Parent::Node Node; + + typedef typename Parent::UndirEdge UndirEdge; + + class UndirEdgeIt : public Parent::UndirEdge { + const Graph* graph; + public: + + UndirEdgeIt() { } + + UndirEdgeIt(Invalid i) : UndirEdge(i) { } + + explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) { + _graph.first(*static_cast(this)); + } + + UndirEdgeIt(const Graph& _graph, const UndirEdge& e) : + UndirEdge(e), graph(&_graph) { } + + UndirEdgeIt& operator++() { + graph->next(*this); + return *this; + } + + }; + + class IncEdgeIt : public Parent::UndirEdge { + const Graph* graph; + bool forward; + friend class IterableUndirGraphExtender; + template + friend class UndirGraphExtender; + public: + + IncEdgeIt() { } + + IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { } + + IncEdgeIt(const Graph& _graph, const Node &n) + : graph(&_graph) + { + _graph._dirFirstOut(*this, n); + } + + IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n) + : graph(&_graph), UndirEdge(ue) + { + forward = (_graph.source(ue) == n); + } + + IncEdgeIt& operator++() { + graph->_dirNextOut(*this); + return *this; + } + }; + + using Parent::baseNode; + using Parent::runningNode; + + /// Base node of the iterator + /// + /// Returns the base node of the iterator + Node baseNode(const IncEdgeIt &e) const { + return _dirSource(e); + } + /// Running node of the iterator + /// + /// Returns the running node of the iterator + Node runningNode(const IncEdgeIt &e) const { + return _dirTarget(e); + } + + }; +} + +#endif // LEMON_GRAPH_EXTENDER_H