// -*- 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 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 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