// -*- c++ -*- #ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H #define LEMON_ITERABLE_GRAPH_EXTENDER_H #include #include namespace lemon { template class IterableGraphExtender : public _Base { public: /// Indicates that the graph is undirected. ///\todo Better name? /// ///\bug Should it be here? typedef False UTag; 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; } }; /// \brief Base node of the iterator /// /// Returns the base node (ie. the source in this case) of the iterator Node baseNode(const OutEdgeIt &e) const { return Parent::source((Edge)e); } /// \brief Running node of the iterator /// /// Returns the running node (ie. the target in this case) of the /// iterator Node runningNode(const OutEdgeIt &e) const { return Parent::target((Edge)e); } /// \brief Base node of the iterator /// /// Returns the base node (ie. the target in this case) of the iterator Node baseNode(const InEdgeIt &e) const { return Parent::target((Edge)e); } /// \brief Running node of the iterator /// /// Returns the running node (ie. the source in this case) of the /// iterator Node runningNode(const InEdgeIt &e) const { return Parent::source((Edge)e); } using Parent::first; /// \brief The opposite node on the given edge. /// /// Gives back the opposite on the given edge. Node oppositeNode(const Node& n, const Edge& e) const { if (Parent::source(e) == n) { return Parent::target(e); } else { return Parent::source(e); } } private: // void first(NodeIt &) const; // void first(EdgeIt &) const; // void first(OutEdgeIt &) const; // void first(InEdgeIt &) const; }; template class IterableUGraphExtender : public IterableGraphExtender<_Base> { public: /// Indicates that the graph is undirected. ///\todo Better name? /// ///\bug Should it be here? ///\bug Should be tested in the concept checker whether it is defined ///correctly. typedef True UTag; typedef IterableGraphExtender<_Base> Parent; typedef IterableUGraphExtender<_Base> Graph; typedef typename Parent::Node Node; typedef typename Parent::Edge Edge; typedef typename Parent::UEdge UEdge; class UEdgeIt : public Parent::UEdge { const Graph* graph; public: UEdgeIt() { } UEdgeIt(Invalid i) : UEdge(i) { } explicit UEdgeIt(const Graph& _graph) : graph(&_graph) { _graph.first(*static_cast(this)); } UEdgeIt(const Graph& _graph, const UEdge& e) : UEdge(e), graph(&_graph) { } UEdgeIt& operator++() { graph->next(*this); return *this; } }; class IncEdgeIt : public Parent::UEdge { const Graph* graph; bool direction; friend class IterableUGraphExtender; public: IncEdgeIt() { } IncEdgeIt(Invalid i) : UEdge(i), direction(false) { } IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) { _graph.firstInc(*this, direction, n); } IncEdgeIt(const Graph& _graph, const UEdge &ue, const Node &n) : graph(&_graph), UEdge(ue) { direction = (_graph.source(ue) == n); } IncEdgeIt& operator++() { graph->nextInc(*this, direction); return *this; } }; using Parent::baseNode; using Parent::runningNode; /// Base node of the iterator /// /// Returns the base node of the iterator Node baseNode(const IncEdgeIt &e) const { return e.direction ? source(e) : target(e); } /// Running node of the iterator /// /// Returns the running node of the iterator Node runningNode(const IncEdgeIt &e) const { return e.direction ? target(e) : source(e); } /// \brief The opposite node on the given undirected edge. /// /// Gives back the opposite on the given undirected edge. Node oppositeNode(const Node& n, const UEdge& e) const { if (Parent::source(e) == n) { return Parent::target(e); } else { return Parent::source(e); } } }; template class IterableUBipartiteGraphExtender : public _Base { public: typedef _Base Parent; typedef IterableUBipartiteGraphExtender Graph; typedef typename Parent::Node Node; typedef typename Parent::UpperNode UpperNode; typedef typename Parent::LowerNode LowerNode; typedef typename Parent::Edge Edge; typedef typename Parent::UEdge UEdge; class NodeIt : public Node { const Graph* graph; public: NodeIt() { } NodeIt(Invalid i) : Node(INVALID) { } 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 UpperNodeIt : public Node { friend class IterableUBipartiteGraphExtender; const Graph* graph; public: UpperNodeIt() { } UpperNodeIt(Invalid i) : Node(INVALID) { } explicit UpperNodeIt(const Graph& _graph) : graph(&_graph) { graph->firstUpper(static_cast(*this)); } UpperNodeIt(const Graph& _graph, const Node& node) : Node(node), graph(&_graph) {} UpperNodeIt& operator++() { graph->nextUpper(*this); return *this; } }; class LowerNodeIt : public Node { friend class IterableUBipartiteGraphExtender; const Graph* graph; public: LowerNodeIt() { } LowerNodeIt(Invalid i) : Node(INVALID) { } explicit LowerNodeIt(const Graph& _graph) : graph(&_graph) { graph->firstLower(static_cast(*this)); } LowerNodeIt(const Graph& _graph, const Node& node) : Node(node), graph(&_graph) {} LowerNodeIt& operator++() { graph->nextLower(*this); return *this; } }; class EdgeIt : public Edge { friend class IterableUBipartiteGraphExtender; const Graph* graph; public: EdgeIt() { } EdgeIt(Invalid i) : Edge(INVALID) { } explicit EdgeIt(const Graph& _graph) : graph(&_graph) { graph->first(static_cast(*this)); } EdgeIt(const Graph& _graph, const Edge& edge) : Edge(edge), graph(&_graph) { } EdgeIt& operator++() { graph->next(*this); return *this; } }; class UEdgeIt : public UEdge { friend class IterableUBipartiteGraphExtender; const Graph* graph; public: UEdgeIt() { } UEdgeIt(Invalid i) : UEdge(INVALID) { } explicit UEdgeIt(const Graph& _graph) : graph(&_graph) { graph->first(static_cast(*this)); } UEdgeIt(const Graph& _graph, const UEdge& edge) : UEdge(edge), graph(&_graph) { } UEdgeIt& operator++() { graph->next(*this); return *this; } }; class OutEdgeIt : public Edge { friend class IterableUBipartiteGraphExtender; 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 { friend class IterableUBipartiteGraphExtender; 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; } }; /// \brief Base node of the iterator /// /// Returns the base node (ie. the source in this case) of the iterator Node baseNode(const OutEdgeIt &e) const { return Parent::source((Edge&)e); } /// \brief Running node of the iterator /// /// Returns the running node (ie. the target in this case) of the /// iterator Node runningNode(const OutEdgeIt &e) const { return Parent::target((Edge&)e); } /// \brief Base node of the iterator /// /// Returns the base node (ie. the target in this case) of the iterator Node baseNode(const InEdgeIt &e) const { return Parent::target((Edge&)e); } /// \brief Running node of the iterator /// /// Returns the running node (ie. the source in this case) of the /// iterator Node runningNode(const InEdgeIt &e) const { return Parent::source((Edge&)e); } class IncEdgeIt : public Parent::UEdge { friend class IterableUBipartiteGraphExtender; const Graph* graph; bool direction; public: IncEdgeIt() { } IncEdgeIt(Invalid i) : UEdge(i), direction(true) { } IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) { graph->firstInc(*this, direction, n); } IncEdgeIt(const Graph& _graph, const UEdge &ue, const Node &n) : graph(&_graph), UEdge(ue) { direction = (graph->source(ue) == n); } IncEdgeIt& operator++() { graph->nextInc(*this, direction); return *this; } }; /// Base node of the iterator /// /// Returns the base node of the iterator Node baseNode(const IncEdgeIt &e) const { return e.direction ? source(e) : target(e); } /// Running node of the iterator /// /// Returns the running node of the iterator Node runningNode(const IncEdgeIt &e) const { return e.direction ? target(e) : source(e); } }; } #endif // LEMON_GRAPH_EXTENDER_H