deba@468: /* -*- C++ -*- deba@468: * deba@468: * This file is a part of LEMON, a generic C++ optimization library deba@468: * deba@468: * Copyright (C) 2003-2008 deba@468: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@468: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@468: * deba@468: * Permission to use, modify and distribute this software is granted deba@468: * provided that this copyright notice appears in all copies. For deba@468: * precise terms see the accompanying LICENSE file. deba@468: * deba@468: * This software is provided "AS IS" with no warranty of any kind, deba@468: * express or implied, and with no claim as to its suitability for any deba@468: * purpose. deba@468: * deba@468: */ deba@468: deba@468: #ifndef LEMON_BITS_EDGE_SET_EXTENDER_H deba@468: #define LEMON_BITS_EDGE_SET_EXTENDER_H deba@468: deba@519: #include deba@468: #include deba@468: #include deba@519: #include deba@468: kpeter@559: //\ingroup digraphbits kpeter@559: //\file kpeter@559: //\brief Extenders for the arc set types deba@468: namespace lemon { deba@468: kpeter@559: // \ingroup digraphbits kpeter@559: // kpeter@559: // \brief Extender for the ArcSets deba@468: template deba@468: class ArcSetExtender : public Base { kpeter@617: typedef Base Parent; kpeter@617: deba@468: public: deba@468: deba@468: typedef ArcSetExtender Digraph; deba@468: deba@468: // Base extensions deba@468: deba@468: typedef typename Parent::Node Node; deba@468: typedef typename Parent::Arc Arc; deba@468: deba@468: int maxId(Node) const { deba@468: return Parent::maxNodeId(); deba@468: } deba@468: deba@468: int maxId(Arc) const { deba@468: return Parent::maxArcId(); deba@468: } deba@468: deba@468: Node fromId(int id, Node) const { deba@468: return Parent::nodeFromId(id); deba@468: } deba@468: deba@468: Arc fromId(int id, Arc) const { deba@468: return Parent::arcFromId(id); deba@468: } deba@468: deba@468: Node oppositeNode(const Node &n, const Arc &e) const { deba@468: if (n == Parent::source(e)) deba@468: return Parent::target(e); deba@468: else if(n==Parent::target(e)) deba@468: return Parent::source(e); deba@468: else deba@468: return INVALID; deba@468: } deba@468: deba@468: deba@468: // Alteration notifier extensions deba@468: kpeter@559: // The arc observer registry. deba@468: typedef AlterationNotifier ArcNotifier; deba@468: deba@468: protected: deba@468: deba@468: mutable ArcNotifier arc_notifier; deba@468: deba@468: public: deba@468: deba@468: using Parent::notifier; deba@468: kpeter@559: // Gives back the arc alteration notifier. deba@468: ArcNotifier& notifier(Arc) const { deba@468: return arc_notifier; deba@468: } deba@468: deba@468: // Iterable extensions deba@468: deba@468: class NodeIt : public Node { deba@468: const Digraph* digraph; deba@468: public: deba@468: deba@468: NodeIt() {} deba@468: deba@468: NodeIt(Invalid i) : Node(i) { } deba@468: deba@468: explicit NodeIt(const Digraph& _graph) : digraph(&_graph) { deba@468: _graph.first(static_cast(*this)); deba@468: } deba@468: deba@468: NodeIt(const Digraph& _graph, const Node& node) deba@468: : Node(node), digraph(&_graph) {} deba@468: deba@468: NodeIt& operator++() { deba@468: digraph->next(*this); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: deba@468: class ArcIt : public Arc { deba@468: const Digraph* digraph; deba@468: public: deba@468: deba@468: ArcIt() { } deba@468: deba@468: ArcIt(Invalid i) : Arc(i) { } deba@468: deba@468: explicit ArcIt(const Digraph& _graph) : digraph(&_graph) { deba@468: _graph.first(static_cast(*this)); deba@468: } deba@468: deba@468: ArcIt(const Digraph& _graph, const Arc& e) : deba@468: Arc(e), digraph(&_graph) { } deba@468: deba@468: ArcIt& operator++() { deba@468: digraph->next(*this); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: deba@468: class OutArcIt : public Arc { deba@468: const Digraph* digraph; deba@468: public: deba@468: deba@468: OutArcIt() { } deba@468: deba@468: OutArcIt(Invalid i) : Arc(i) { } deba@468: deba@468: OutArcIt(const Digraph& _graph, const Node& node) deba@468: : digraph(&_graph) { deba@468: _graph.firstOut(*this, node); deba@468: } deba@468: deba@468: OutArcIt(const Digraph& _graph, const Arc& arc) deba@468: : Arc(arc), digraph(&_graph) {} deba@468: deba@468: OutArcIt& operator++() { deba@468: digraph->nextOut(*this); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: deba@468: class InArcIt : public Arc { deba@468: const Digraph* digraph; deba@468: public: deba@468: deba@468: InArcIt() { } deba@468: deba@468: InArcIt(Invalid i) : Arc(i) { } deba@468: deba@468: InArcIt(const Digraph& _graph, const Node& node) deba@468: : digraph(&_graph) { deba@468: _graph.firstIn(*this, node); deba@468: } deba@468: deba@468: InArcIt(const Digraph& _graph, const Arc& arc) : deba@468: Arc(arc), digraph(&_graph) {} deba@468: deba@468: InArcIt& operator++() { deba@468: digraph->nextIn(*this); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: kpeter@559: // \brief Base node of the iterator kpeter@559: // kpeter@559: // Returns the base node (ie. the source in this case) of the iterator deba@468: Node baseNode(const OutArcIt &e) const { deba@468: return Parent::source(static_cast(e)); deba@468: } kpeter@559: // \brief Running node of the iterator kpeter@559: // kpeter@559: // Returns the running node (ie. the target in this case) of the kpeter@559: // iterator deba@468: Node runningNode(const OutArcIt &e) const { deba@468: return Parent::target(static_cast(e)); deba@468: } deba@468: kpeter@559: // \brief Base node of the iterator kpeter@559: // kpeter@559: // Returns the base node (ie. the target in this case) of the iterator deba@468: Node baseNode(const InArcIt &e) const { deba@468: return Parent::target(static_cast(e)); deba@468: } kpeter@559: // \brief Running node of the iterator kpeter@559: // kpeter@559: // Returns the running node (ie. the source in this case) of the kpeter@559: // iterator deba@468: Node runningNode(const InArcIt &e) const { deba@468: return Parent::source(static_cast(e)); deba@468: } deba@468: deba@468: using Parent::first; deba@468: deba@468: // Mappable extension deba@468: deba@468: template deba@468: class ArcMap deba@468: : public MapExtender > { deba@468: typedef MapExtender > Parent; deba@468: kpeter@617: public: deba@468: explicit ArcMap(const Digraph& _g) deba@468: : Parent(_g) {} deba@468: ArcMap(const Digraph& _g, const _Value& _v) deba@468: : Parent(_g, _v) {} deba@468: deba@468: ArcMap& operator=(const ArcMap& cmap) { deba@468: return operator=(cmap); deba@468: } deba@468: deba@468: template deba@468: ArcMap& operator=(const CMap& cmap) { deba@468: Parent::operator=(cmap); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: deba@468: // Alteration extension deba@468: deba@468: Arc addArc(const Node& from, const Node& to) { deba@468: Arc arc = Parent::addArc(from, to); deba@468: notifier(Arc()).add(arc); deba@468: return arc; deba@468: } deba@468: deba@468: void clear() { deba@468: notifier(Arc()).clear(); deba@468: Parent::clear(); deba@468: } deba@468: deba@468: void erase(const Arc& arc) { deba@468: notifier(Arc()).erase(arc); deba@468: Parent::erase(arc); deba@468: } deba@468: deba@468: ArcSetExtender() { deba@468: arc_notifier.setContainer(*this); deba@468: } deba@468: deba@468: ~ArcSetExtender() { deba@468: arc_notifier.clear(); deba@468: } deba@468: deba@468: }; deba@468: deba@468: kpeter@559: // \ingroup digraphbits kpeter@559: // kpeter@559: // \brief Extender for the EdgeSets deba@468: template deba@468: class EdgeSetExtender : public Base { kpeter@617: typedef Base Parent; deba@468: deba@468: public: deba@468: kpeter@617: typedef EdgeSetExtender Graph; deba@468: kpeter@882: typedef True UndirectedTag; kpeter@882: deba@468: typedef typename Parent::Node Node; deba@468: typedef typename Parent::Arc Arc; deba@468: typedef typename Parent::Edge Edge; deba@468: deba@468: int maxId(Node) const { deba@468: return Parent::maxNodeId(); deba@468: } deba@468: deba@468: int maxId(Arc) const { deba@468: return Parent::maxArcId(); deba@468: } deba@468: deba@468: int maxId(Edge) const { deba@468: return Parent::maxEdgeId(); deba@468: } deba@468: deba@468: Node fromId(int id, Node) const { deba@468: return Parent::nodeFromId(id); deba@468: } deba@468: deba@468: Arc fromId(int id, Arc) const { deba@468: return Parent::arcFromId(id); deba@468: } deba@468: deba@468: Edge fromId(int id, Edge) const { deba@468: return Parent::edgeFromId(id); deba@468: } deba@468: deba@468: Node oppositeNode(const Node &n, const Edge &e) const { deba@468: if( n == Parent::u(e)) deba@468: return Parent::v(e); deba@468: else if( n == Parent::v(e)) deba@468: return Parent::u(e); deba@468: else deba@468: return INVALID; deba@468: } deba@468: deba@468: Arc oppositeArc(const Arc &e) const { deba@468: return Parent::direct(e, !Parent::direction(e)); deba@468: } deba@468: deba@468: using Parent::direct; deba@468: Arc direct(const Edge &e, const Node &s) const { deba@468: return Parent::direct(e, Parent::u(e) == s); deba@468: } deba@468: deba@468: typedef AlterationNotifier ArcNotifier; deba@468: typedef AlterationNotifier EdgeNotifier; deba@468: deba@468: deba@468: protected: deba@468: deba@468: mutable ArcNotifier arc_notifier; deba@468: mutable EdgeNotifier edge_notifier; deba@468: deba@468: public: deba@468: deba@468: using Parent::notifier; deba@468: deba@468: ArcNotifier& notifier(Arc) const { deba@468: return arc_notifier; deba@468: } deba@468: deba@468: EdgeNotifier& notifier(Edge) const { deba@468: return edge_notifier; deba@468: } deba@468: deba@468: deba@468: class NodeIt : public Node { kpeter@617: const Graph* graph; deba@468: public: deba@468: deba@468: NodeIt() {} deba@468: deba@468: NodeIt(Invalid i) : Node(i) { } deba@468: kpeter@617: explicit NodeIt(const Graph& _graph) : graph(&_graph) { deba@468: _graph.first(static_cast(*this)); deba@468: } deba@468: kpeter@617: NodeIt(const Graph& _graph, const Node& node) kpeter@617: : Node(node), graph(&_graph) {} deba@468: deba@468: NodeIt& operator++() { kpeter@617: graph->next(*this); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: deba@468: class ArcIt : public Arc { kpeter@617: const Graph* graph; deba@468: public: deba@468: deba@468: ArcIt() { } deba@468: deba@468: ArcIt(Invalid i) : Arc(i) { } deba@468: kpeter@617: explicit ArcIt(const Graph& _graph) : graph(&_graph) { deba@468: _graph.first(static_cast(*this)); deba@468: } deba@468: kpeter@617: ArcIt(const Graph& _graph, const Arc& e) : kpeter@617: Arc(e), graph(&_graph) { } deba@468: deba@468: ArcIt& operator++() { kpeter@617: graph->next(*this); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: deba@468: class OutArcIt : public Arc { kpeter@617: const Graph* graph; deba@468: public: deba@468: deba@468: OutArcIt() { } deba@468: deba@468: OutArcIt(Invalid i) : Arc(i) { } deba@468: kpeter@617: OutArcIt(const Graph& _graph, const Node& node) kpeter@617: : graph(&_graph) { deba@468: _graph.firstOut(*this, node); deba@468: } deba@468: kpeter@617: OutArcIt(const Graph& _graph, const Arc& arc) kpeter@617: : Arc(arc), graph(&_graph) {} deba@468: deba@468: OutArcIt& operator++() { kpeter@617: graph->nextOut(*this); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: deba@468: class InArcIt : public Arc { kpeter@617: const Graph* graph; deba@468: public: deba@468: deba@468: InArcIt() { } deba@468: deba@468: InArcIt(Invalid i) : Arc(i) { } deba@468: kpeter@617: InArcIt(const Graph& _graph, const Node& node) kpeter@617: : graph(&_graph) { deba@468: _graph.firstIn(*this, node); deba@468: } deba@468: kpeter@617: InArcIt(const Graph& _graph, const Arc& arc) : kpeter@617: Arc(arc), graph(&_graph) {} deba@468: deba@468: InArcIt& operator++() { kpeter@617: graph->nextIn(*this); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: deba@468: class EdgeIt : public Parent::Edge { kpeter@617: const Graph* graph; deba@468: public: deba@468: deba@468: EdgeIt() { } deba@468: deba@468: EdgeIt(Invalid i) : Edge(i) { } deba@468: kpeter@617: explicit EdgeIt(const Graph& _graph) : graph(&_graph) { deba@468: _graph.first(static_cast(*this)); deba@468: } deba@468: kpeter@617: EdgeIt(const Graph& _graph, const Edge& e) : kpeter@617: Edge(e), graph(&_graph) { } deba@468: deba@468: EdgeIt& operator++() { kpeter@617: graph->next(*this); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: class IncEdgeIt : public Parent::Edge { deba@468: friend class EdgeSetExtender; kpeter@617: const Graph* graph; deba@468: bool direction; deba@468: public: deba@468: deba@468: IncEdgeIt() { } deba@468: deba@468: IncEdgeIt(Invalid i) : Edge(i), direction(false) { } deba@468: kpeter@617: IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) { deba@468: _graph.firstInc(*this, direction, n); deba@468: } deba@468: kpeter@617: IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n) kpeter@617: : graph(&_graph), Edge(ue) { deba@468: direction = (_graph.source(ue) == n); deba@468: } deba@468: deba@468: IncEdgeIt& operator++() { kpeter@617: graph->nextInc(*this, direction); deba@468: return *this; deba@468: } deba@468: }; deba@468: kpeter@559: // \brief Base node of the iterator kpeter@559: // kpeter@559: // Returns the base node (ie. the source in this case) of the iterator deba@468: Node baseNode(const OutArcIt &e) const { deba@468: return Parent::source(static_cast(e)); deba@468: } kpeter@559: // \brief Running node of the iterator kpeter@559: // kpeter@559: // Returns the running node (ie. the target in this case) of the kpeter@559: // iterator deba@468: Node runningNode(const OutArcIt &e) const { deba@468: return Parent::target(static_cast(e)); deba@468: } deba@468: kpeter@559: // \brief Base node of the iterator kpeter@559: // kpeter@559: // Returns the base node (ie. the target in this case) of the iterator deba@468: Node baseNode(const InArcIt &e) const { deba@468: return Parent::target(static_cast(e)); deba@468: } kpeter@559: // \brief Running node of the iterator kpeter@559: // kpeter@559: // Returns the running node (ie. the source in this case) of the kpeter@559: // iterator deba@468: Node runningNode(const InArcIt &e) const { deba@468: return Parent::source(static_cast(e)); deba@468: } deba@468: kpeter@559: // Base node of the iterator kpeter@559: // kpeter@559: // Returns the base node of the iterator deba@468: Node baseNode(const IncEdgeIt &e) const { alpar@997: return e.direction ? this->u(e) : this->v(e); deba@468: } kpeter@559: // Running node of the iterator kpeter@559: // kpeter@559: // Returns the running node of the iterator deba@468: Node runningNode(const IncEdgeIt &e) const { alpar@997: return e.direction ? this->v(e) : this->u(e); deba@468: } deba@468: deba@468: deba@468: template deba@468: class ArcMap kpeter@617: : public MapExtender > { kpeter@617: typedef MapExtender > Parent; kpeter@617: deba@468: public: kpeter@685: explicit ArcMap(const Graph& _g) deba@468: : Parent(_g) {} kpeter@617: ArcMap(const Graph& _g, const _Value& _v) deba@468: : Parent(_g, _v) {} deba@468: deba@468: ArcMap& operator=(const ArcMap& cmap) { deba@468: return operator=(cmap); deba@468: } deba@468: deba@468: template deba@468: ArcMap& operator=(const CMap& cmap) { deba@468: Parent::operator=(cmap); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: deba@468: template deba@468: class EdgeMap kpeter@617: : public MapExtender > { kpeter@617: typedef MapExtender > Parent; kpeter@617: deba@468: public: kpeter@685: explicit EdgeMap(const Graph& _g) deba@468: : Parent(_g) {} deba@468: kpeter@617: EdgeMap(const Graph& _g, const _Value& _v) deba@468: : Parent(_g, _v) {} deba@468: deba@468: EdgeMap& operator=(const EdgeMap& cmap) { deba@468: return operator=(cmap); deba@468: } deba@468: deba@468: template deba@468: EdgeMap& operator=(const CMap& cmap) { deba@468: Parent::operator=(cmap); deba@468: return *this; deba@468: } deba@468: deba@468: }; deba@468: deba@468: deba@468: // Alteration extension deba@468: deba@468: Edge addEdge(const Node& from, const Node& to) { deba@468: Edge edge = Parent::addEdge(from, to); deba@468: notifier(Edge()).add(edge); deba@468: std::vector arcs; deba@468: arcs.push_back(Parent::direct(edge, true)); deba@468: arcs.push_back(Parent::direct(edge, false)); deba@468: notifier(Arc()).add(arcs); deba@468: return edge; deba@468: } deba@468: deba@468: void clear() { deba@468: notifier(Arc()).clear(); deba@468: notifier(Edge()).clear(); deba@468: Parent::clear(); deba@468: } deba@468: deba@468: void erase(const Edge& edge) { deba@468: std::vector arcs; deba@468: arcs.push_back(Parent::direct(edge, true)); deba@468: arcs.push_back(Parent::direct(edge, false)); deba@468: notifier(Arc()).erase(arcs); deba@468: notifier(Edge()).erase(edge); deba@468: Parent::erase(edge); deba@468: } deba@468: deba@468: deba@468: EdgeSetExtender() { deba@468: arc_notifier.setContainer(*this); deba@468: edge_notifier.setContainer(*this); deba@468: } deba@468: deba@468: ~EdgeSetExtender() { deba@468: edge_notifier.clear(); deba@468: arc_notifier.clear(); deba@468: } deba@468: deba@468: }; deba@468: deba@468: } deba@468: deba@468: #endif