// -*- 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::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) { } explicit IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) { _graph._dirFirstOut(*this, n); } // FIXME: Do we need this type of constructor here? // IncEdgeIt(const Graph& _graph, const Edge& e) : // UndirEdge(e), graph(&_graph), forward(_graph.forward(e)) { } // or // IncEdgeIt(const Graph& _graph, const Node& n, // Const UndirEdge &e) ... ? IncEdgeIt& operator++() { graph->_dirNextOut(*this); return *this; } }; Node source(const IncEdgeIt &e) const { return _dirSource(e); } /// \todo Shouldn't the "source" of an undirected edge be called "aNode" /// or something??? using Parent::source; /// Target of the given Edge. Node target(const IncEdgeIt &e) const { return _dirTarget(e); } /// \todo Shouldn't the "target" of an undirected edge be called "bNode" /// or something??? using Parent::target; }; } #endif // LEMON_GRAPH_EXTENDER_H