// -*- 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; } }; 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::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; } }; }; } #endif // LEMON_GRAPH_EXTENDER_H