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@1158: /// Base node of the iterator klao@1158: /// klao@1158: /// Returns the base node (ie. the source in this case) of the iterator klao@1158: /// klao@1158: /// \todo Document in the concept! klao@1158: Node baseNode(const OutEdgeIt &e) const { klao@1158: return source(e); klao@1158: } klao@1158: /// Running node of the iterator klao@1158: /// klao@1158: /// Returns the running node (ie. the target in this case) of the klao@1158: /// iterator klao@1158: /// klao@1158: /// \todo Document in the concept! klao@1158: Node runningNode(const OutEdgeIt &e) const { klao@1158: return target(e); klao@1158: } klao@1158: klao@1158: /// Base node of the iterator klao@1158: /// klao@1158: /// Returns the base node (ie. the target in this case) of the iterator klao@1158: /// klao@1158: /// \todo Document in the concept! klao@1158: Node baseNode(const InEdgeIt &e) const { klao@1158: return target(e); klao@1158: } klao@1158: /// Running node of the iterator klao@1158: /// klao@1158: /// Returns the running node (ie. the source in this case) of the klao@1158: /// iterator klao@1158: /// klao@1158: /// \todo Document in the concept! klao@1158: Node runningNode(const InEdgeIt &e) const { klao@1158: return source(e); klao@1158: } klao@1158: 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@1158: klao@1158: klao@1158: klao@1158: klao@1158: 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@1030: class IncEdgeIt : 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@1030: IncEdgeIt() { } klao@1021: klao@1030: IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { } klao@1021: klao@1158: IncEdgeIt(const Graph& _graph, const Node &n) klao@1021: : graph(&_graph) klao@1021: { klao@1021: _graph._dirFirstOut(*this, n); klao@1021: } klao@1021: klao@1158: IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n) klao@1158: : graph(&_graph), UndirEdge(ue) klao@1158: { klao@1158: forward = (_graph.source(ue) == n); klao@1158: } klao@1021: klao@1030: IncEdgeIt& operator++() { klao@1021: graph->_dirNextOut(*this); klao@1021: return *this; klao@1021: } klao@1021: }; klao@1021: klao@1158: using Parent::baseNode; klao@1158: using Parent::runningNode; klao@1158: klao@1158: /// Base node of the iterator klao@1158: /// klao@1158: /// Returns the base node of the iterator klao@1158: Node baseNode(const IncEdgeIt &e) const { klao@1021: return _dirSource(e); klao@1021: } klao@1158: /// Running node of the iterator klao@1158: /// klao@1158: /// Returns the running node of the iterator klao@1158: Node runningNode(const IncEdgeIt &e) const { klao@1021: return _dirTarget(e); klao@1021: } klao@1021: klao@962: }; klao@946: } klao@946: klao@946: #endif // LEMON_GRAPH_EXTENDER_H