klao@946: // -*- c++ -*- klao@946: #ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H klao@946: #define LEMON_ITERABLE_GRAPH_EXTENDER_H klao@946: klao@946: #include klao@946: klao@946: namespace lemon { klao@946: klao@946: template klao@946: class IterableGraphExtender : public _Base { klao@962: public: klao@946: klao@946: typedef _Base Parent; klao@946: typedef IterableGraphExtender<_Base> Graph; klao@946: klao@946: typedef typename Parent::Node Node; klao@946: typedef typename Parent::Edge Edge; klao@946: klao@946: klao@946: class NodeIt : public Node { klao@946: const Graph* graph; klao@946: public: klao@946: klao@946: NodeIt() {} klao@946: klao@946: NodeIt(Invalid i) : Node(i) { } klao@946: klao@962: explicit NodeIt(const Graph& _graph) : graph(&_graph) { klao@946: _graph.first(*static_cast(this)); klao@946: } klao@946: klao@946: NodeIt(const Graph& _graph, const Node& node) klao@946: : Node(node), graph(&_graph) {} klao@946: klao@946: NodeIt& operator++() { klao@946: graph->next(*this); klao@946: return *this; klao@946: } klao@946: klao@946: }; klao@946: klao@946: klao@946: class EdgeIt : public Edge { klao@946: const Graph* graph; klao@946: public: klao@946: klao@946: EdgeIt() { } klao@946: klao@946: EdgeIt(Invalid i) : Edge(i) { } klao@946: klao@962: explicit EdgeIt(const Graph& _graph) : graph(&_graph) { klao@946: _graph.first(*static_cast(this)); klao@946: } klao@946: klao@946: EdgeIt(const Graph& _graph, const Edge& e) : klao@946: Edge(e), graph(&_graph) { } klao@946: klao@946: EdgeIt& operator++() { klao@946: graph->next(*this); klao@946: return *this; klao@946: } klao@946: klao@946: }; klao@946: klao@946: klao@946: class OutEdgeIt : public Edge { klao@946: const Graph* graph; klao@946: public: klao@946: klao@946: OutEdgeIt() { } klao@946: klao@946: OutEdgeIt(Invalid i) : Edge(i) { } klao@946: klao@946: OutEdgeIt(const Graph& _graph, const Node& node) klao@962: : graph(&_graph) { klao@946: _graph.firstOut(*this, node); klao@946: } klao@946: klao@946: OutEdgeIt(const Graph& _graph, const Edge& edge) klao@946: : Edge(edge), graph(&_graph) {} klao@946: klao@946: OutEdgeIt& operator++() { klao@946: graph->nextOut(*this); klao@946: return *this; klao@946: } klao@946: klao@946: }; klao@946: klao@946: klao@946: class InEdgeIt : public Edge { klao@946: const Graph* graph; klao@946: public: klao@946: klao@946: InEdgeIt() { } klao@946: klao@946: InEdgeIt(Invalid i) : Edge(i) { } klao@946: klao@946: InEdgeIt(const Graph& _graph, const Node& node) klao@962: : graph(&_graph) { klao@946: _graph.firstIn(*this, node); klao@946: } klao@946: klao@946: InEdgeIt(const Graph& _graph, const Edge& edge) : klao@946: Edge(edge), graph(&_graph) {} klao@946: klao@946: InEdgeIt& operator++() { klao@946: graph->nextIn(*this); klao@946: return *this; klao@946: } klao@946: klao@946: }; klao@946: klao@946: using Parent::first; klao@946: klao@946: private: klao@946: klao@946: /// \todo When (and if) we change the iterators concept to use operator*, klao@946: /// then the following shadowed methods will become superfluous. klao@946: /// But for now these are important safety measures. klao@946: klao@946: void first(NodeIt &) const; klao@946: void first(EdgeIt &) const; klao@946: void first(OutEdgeIt &) const; klao@946: void first(InEdgeIt &) const; klao@946: klao@946: }; klao@946: klao@962: template klao@962: class IterableUndirGraphExtender : public IterableGraphExtender<_Base> { klao@962: public: klao@962: klao@962: typedef IterableGraphExtender<_Base> Parent; klao@962: typedef IterableUndirGraphExtender<_Base> Graph; klao@1021: typedef typename Parent::Node Node; klao@962: klao@962: typedef typename Parent::UndirEdge UndirEdge; klao@962: klao@962: class UndirEdgeIt : public UndirEdge { klao@962: const Graph* graph; klao@962: public: klao@962: klao@962: UndirEdgeIt() { } klao@962: klao@962: UndirEdgeIt(Invalid i) : UndirEdge(i) { } klao@962: klao@962: explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) { klao@962: _graph.first(*static_cast(this)); klao@962: } klao@962: klao@962: UndirEdgeIt(const Graph& _graph, const UndirEdge& e) : klao@962: UndirEdge(e), graph(&_graph) { } klao@962: klao@962: UndirEdgeIt& operator++() { klao@962: graph->next(*this); klao@962: return *this; klao@962: } klao@962: klao@962: }; klao@962: klao@1021: class UndirIncEdgeIt : public UndirEdge { klao@1021: const Graph* graph; klao@1021: bool forward; klao@1021: friend class IterableUndirGraphExtender; klao@1021: template klao@1021: friend class UndirGraphExtender; klao@1021: public: klao@1021: klao@1021: UndirIncEdgeIt() { } klao@1021: klao@1021: UndirIncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { } klao@1021: klao@1021: explicit UndirIncEdgeIt(const Graph& _graph, const Node &n) klao@1021: : graph(&_graph) klao@1021: { klao@1021: _graph._dirFirstOut(*this, n); klao@1021: } klao@1021: klao@1021: // FIXME: Do we need this type of constructor here? klao@1022: // UndirIncEdgeIt(const Graph& _graph, const Edge& e) : klao@1022: // UndirEdge(e), graph(&_graph), forward(_graph.forward(e)) { } klao@1022: // or klao@1022: // UndirIncEdgeIt(const Graph& _graph, const Node& n, klao@1022: // Const UndirEdge &e) ... ? klao@1021: klao@1021: UndirIncEdgeIt& operator++() { klao@1021: graph->_dirNextOut(*this); klao@1021: return *this; klao@1021: } klao@1021: }; klao@1021: klao@1021: Node source(const UndirIncEdgeIt &e) const { klao@1021: return _dirSource(e); klao@1021: } klao@1021: klao@1021: /// \todo Shouldn't the "source" of an undirected edge be called "aNode" klao@1021: /// or something??? klao@1021: using Parent::source; klao@1021: klao@1021: /// Target of the given Edge. klao@1021: Node target(const UndirIncEdgeIt &e) const { klao@1021: return _dirTarget(e); klao@1021: } klao@1021: klao@1021: /// \todo Shouldn't the "target" of an undirected edge be called "bNode" klao@1021: /// or something??? klao@1021: using Parent::target; klao@962: klao@962: }; klao@946: } klao@946: klao@946: #endif // LEMON_GRAPH_EXTENDER_H