alpar@877: /* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@468:  *
alpar@877:  * This file is a part of LEMON, a generic C++ optimization library.
deba@468:  *
alpar@877:  * Copyright (C) 2003-2010
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 <lemon/core.h>
deba@468: #include <lemon/error.h>
deba@468: #include <lemon/bits/default_map.h>
deba@519: #include <lemon/bits/map_extender.h>
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 <typename Base>
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))
alpar@877:         return Parent::target(e);
deba@468:       else if(n==Parent::target(e))
alpar@877:         return Parent::source(e);
deba@468:       else
alpar@877:         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<ArcSetExtender, Arc> 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: 
alpar@877:     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) {
alpar@877:         _graph.first(static_cast<Node&>(*this));
deba@468:       }
deba@468: 
alpar@877:       NodeIt(const Digraph& _graph, const Node& node)
alpar@877:         : Node(node), digraph(&_graph) {}
deba@468: 
alpar@877:       NodeIt& operator++() {
alpar@877:         digraph->next(*this);
alpar@877:         return *this;
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
alpar@877:     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) {
alpar@877:         _graph.first(static_cast<Arc&>(*this));
deba@468:       }
deba@468: 
alpar@877:       ArcIt(const Digraph& _graph, const Arc& e) :
alpar@877:         Arc(e), digraph(&_graph) { }
deba@468: 
alpar@877:       ArcIt& operator++() {
alpar@877:         digraph->next(*this);
alpar@877:         return *this;
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
alpar@877:     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: 
alpar@877:       OutArcIt(const Digraph& _graph, const Node& node)
alpar@877:         : digraph(&_graph) {
alpar@877:         _graph.firstOut(*this, node);
deba@468:       }
deba@468: 
alpar@877:       OutArcIt(const Digraph& _graph, const Arc& arc)
alpar@877:         : Arc(arc), digraph(&_graph) {}
deba@468: 
alpar@877:       OutArcIt& operator++() {
alpar@877:         digraph->nextOut(*this);
alpar@877:         return *this;
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
alpar@877:     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: 
alpar@877:       InArcIt(const Digraph& _graph, const Node& node)
alpar@877:         : digraph(&_graph) {
alpar@877:         _graph.firstIn(*this, node);
deba@468:       }
deba@468: 
alpar@877:       InArcIt(const Digraph& _graph, const Arc& arc) :
alpar@877:         Arc(arc), digraph(&_graph) {}
deba@468: 
alpar@877:       InArcIt& operator++() {
alpar@877:         digraph->nextIn(*this);
alpar@877:         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<const Arc&>(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<const Arc&>(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<const Arc&>(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<const Arc&>(e));
deba@468:     }
deba@468: 
deba@468:     using Parent::first;
deba@468: 
deba@468:     // Mappable extension
alpar@877: 
deba@468:     template <typename _Value>
alpar@877:     class ArcMap
deba@468:       : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
deba@468:       typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
deba@468: 
kpeter@617:     public:
alpar@877:       explicit ArcMap(const Digraph& _g)
alpar@877:         : Parent(_g) {}
alpar@877:       ArcMap(const Digraph& _g, const _Value& _v)
alpar@877:         : Parent(_g, _v) {}
deba@468: 
deba@468:       ArcMap& operator=(const ArcMap& cmap) {
alpar@877:         return operator=<ArcMap>(cmap);
deba@468:       }
deba@468: 
deba@468:       template <typename CMap>
deba@468:       ArcMap& operator=(const CMap& cmap) {
deba@468:         Parent::operator=(cmap);
alpar@877:         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:     }
alpar@877: 
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 <typename Base>
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))
alpar@877:         return Parent::v(e);
deba@468:       else if( n == Parent::v(e))
alpar@877:         return Parent::u(e);
deba@468:       else
alpar@877:         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<EdgeSetExtender, Arc> ArcNotifier;
deba@468:     typedef AlterationNotifier<EdgeSetExtender, Edge> 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;
alpar@877: 
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: 
alpar@877:     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) {
alpar@877:         _graph.first(static_cast<Node&>(*this));
deba@468:       }
deba@468: 
alpar@877:       NodeIt(const Graph& _graph, const Node& node)
alpar@877:         : Node(node), graph(&_graph) {}
deba@468: 
alpar@877:       NodeIt& operator++() {
alpar@877:         graph->next(*this);
alpar@877:         return *this;
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
alpar@877:     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) {
alpar@877:         _graph.first(static_cast<Arc&>(*this));
deba@468:       }
deba@468: 
alpar@877:       ArcIt(const Graph& _graph, const Arc& e) :
alpar@877:         Arc(e), graph(&_graph) { }
deba@468: 
alpar@877:       ArcIt& operator++() {
alpar@877:         graph->next(*this);
alpar@877:         return *this;
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
alpar@877:     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: 
alpar@877:       OutArcIt(const Graph& _graph, const Node& node)
alpar@877:         : graph(&_graph) {
alpar@877:         _graph.firstOut(*this, node);
deba@468:       }
deba@468: 
alpar@877:       OutArcIt(const Graph& _graph, const Arc& arc)
alpar@877:         : Arc(arc), graph(&_graph) {}
deba@468: 
alpar@877:       OutArcIt& operator++() {
alpar@877:         graph->nextOut(*this);
alpar@877:         return *this;
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
alpar@877:     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: 
alpar@877:       InArcIt(const Graph& _graph, const Node& node)
alpar@877:         : graph(&_graph) {
alpar@877:         _graph.firstIn(*this, node);
deba@468:       }
deba@468: 
alpar@877:       InArcIt(const Graph& _graph, const Arc& arc) :
alpar@877:         Arc(arc), graph(&_graph) {}
deba@468: 
alpar@877:       InArcIt& operator++() {
alpar@877:         graph->nextIn(*this);
alpar@877:         return *this;
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
alpar@877:     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) {
alpar@877:         _graph.first(static_cast<Edge&>(*this));
deba@468:       }
deba@468: 
alpar@877:       EdgeIt(const Graph& _graph, const Edge& e) :
alpar@877:         Edge(e), graph(&_graph) { }
deba@468: 
alpar@877:       EdgeIt& operator++() {
alpar@877:         graph->next(*this);
alpar@877:         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) {
alpar@877:         _graph.firstInc(*this, direction, n);
deba@468:       }
deba@468: 
kpeter@617:       IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
alpar@877:         : graph(&_graph), Edge(ue) {
alpar@877:         direction = (_graph.source(ue) == n);
deba@468:       }
deba@468: 
deba@468:       IncEdgeIt& operator++() {
alpar@877:         graph->nextInc(*this, direction);
alpar@877:         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<const Arc&>(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<const Arc&>(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<const Arc&>(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<const Arc&>(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 <typename _Value>
alpar@877:     class ArcMap
kpeter@617:       : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
kpeter@617:       typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
kpeter@617: 
deba@468:     public:
alpar@877:       explicit ArcMap(const Graph& _g)
alpar@877:         : Parent(_g) {}
alpar@877:       ArcMap(const Graph& _g, const _Value& _v)
alpar@877:         : Parent(_g, _v) {}
deba@468: 
deba@468:       ArcMap& operator=(const ArcMap& cmap) {
alpar@877:         return operator=<ArcMap>(cmap);
deba@468:       }
deba@468: 
deba@468:       template <typename CMap>
deba@468:       ArcMap& operator=(const CMap& cmap) {
deba@468:         Parent::operator=(cmap);
alpar@877:         return *this;
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
deba@468:     template <typename _Value>
alpar@877:     class EdgeMap
kpeter@617:       : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
kpeter@617:       typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
kpeter@617: 
deba@468:     public:
alpar@877:       explicit EdgeMap(const Graph& _g)
alpar@877:         : Parent(_g) {}
deba@468: 
alpar@877:       EdgeMap(const Graph& _g, const _Value& _v)
alpar@877:         : Parent(_g, _v) {}
deba@468: 
deba@468:       EdgeMap& operator=(const EdgeMap& cmap) {
alpar@877:         return operator=<EdgeMap>(cmap);
deba@468:       }
deba@468: 
deba@468:       template <typename CMap>
deba@468:       EdgeMap& operator=(const CMap& cmap) {
deba@468:         Parent::operator=(cmap);
alpar@877:         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<Arc> 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:     }
alpar@877: 
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<Arc> 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:     }
alpar@877: 
deba@468:   };
deba@468: 
deba@468: }
deba@468: 
deba@468: #endif