klao@946: // -*- c++ -*- klao@946: #ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H klao@946: #define LEMON_ITERABLE_GRAPH_EXTENDER_H klao@946: klao@946: #include alpar@1448: #include klao@946: klao@946: namespace lemon { klao@946: klao@946: template klao@946: class IterableGraphExtender : public _Base { klao@962: public: klao@946: alpar@1448: /// Indicates that the graph is undirected. alpar@1448: alpar@1448: ///\todo Better name? alpar@1448: /// alpar@1448: ///\bug Should it be here? alpar@1448: typedef False UndirTag; alpar@1448: 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 { deba@1564: return Parent::source((Edge)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 { deba@1564: return Parent::target((Edge)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 { deba@1564: return Parent::target((Edge)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 { deba@1564: return Parent::source((Edge)e); klao@1158: } klao@1158: klao@946: using Parent::first; klao@946: klao@946: private: klao@946: klao@1230: // /// \todo When (and if) we change the iterators concept to use operator*, klao@1230: // /// then the following shadowed methods will become superfluous. klao@1230: // /// But for now these are important safety measures. klao@946: klao@1230: // void first(NodeIt &) const; klao@1230: // void first(EdgeIt &) const; klao@1230: // void first(OutEdgeIt &) const; klao@1230: // 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: alpar@1448: /// Indicates that the graph is undirected. alpar@1448: alpar@1448: ///\todo Better name? alpar@1448: /// alpar@1448: ///\bug Should it be here? alpar@1448: ///\bug Should be tested in the concept checker whether it is defined alpar@1448: ///correctly. alpar@1448: typedef True UndirTag; alpar@1448: 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@1230: class UndirEdgeIt : public Parent::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@1230: class IncEdgeIt : public Parent::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