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@503: #include <lemon/core.h>
deba@468: #include <lemon/error.h>
deba@468: #include <lemon/bits/default_map.h>
deba@503: #include <lemon/bits/map_extender.h>
deba@468: 
kpeter@550: //\ingroup digraphbits
kpeter@550: //\file
kpeter@550: //\brief Extenders for the arc set types
deba@468: namespace lemon {
deba@468: 
kpeter@550:   // \ingroup digraphbits
kpeter@550:   //
kpeter@550:   // \brief Extender for the ArcSets
deba@468:   template <typename Base>
deba@468:   class ArcSetExtender : public Base {
kpeter@609:     typedef Base Parent;
kpeter@609: 
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@550:     // 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@550:     // 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<Node&>(*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<Arc&>(*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@550:     // \brief Base node of the iterator
kpeter@550:     //
kpeter@550:     // 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@550:     // \brief Running node of the iterator
kpeter@550:     //
kpeter@550:     // Returns the running node (ie. the target in this case) of the
kpeter@550:     // iterator
deba@468:     Node runningNode(const OutArcIt &e) const {
deba@468:       return Parent::target(static_cast<const Arc&>(e));
deba@468:     }
deba@468: 
kpeter@550:     // \brief Base node of the iterator
kpeter@550:     //
kpeter@550:     // 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@550:     // \brief Running node of the iterator
kpeter@550:     //
kpeter@550:     // Returns the running node (ie. the source in this case) of the
kpeter@550:     // 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
deba@468:     
deba@468:     template <typename _Value>
deba@468:     class ArcMap 
deba@468:       : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
deba@468:       typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
deba@468: 
kpeter@609:     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=<ArcMap>(cmap);
deba@468:       }
deba@468: 
deba@468:       template <typename CMap>
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@550:   // \ingroup digraphbits
kpeter@550:   //
kpeter@550:   // \brief Extender for the EdgeSets
deba@468:   template <typename Base>
deba@468:   class EdgeSetExtender : public Base {
kpeter@609:     typedef Base Parent;
deba@468: 
deba@468:   public:
deba@468: 
kpeter@609:     typedef EdgeSetExtender Graph;
deba@468: 
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<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;
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@609:       const Graph* graph;
deba@468:     public:
deba@468: 
deba@468:       NodeIt() {}
deba@468: 
deba@468:       NodeIt(Invalid i) : Node(i) { }
deba@468: 
kpeter@609:       explicit NodeIt(const Graph& _graph) : graph(&_graph) {
deba@468: 	_graph.first(static_cast<Node&>(*this));
deba@468:       }
deba@468: 
kpeter@609:       NodeIt(const Graph& _graph, const Node& node) 
kpeter@609: 	: Node(node), graph(&_graph) {}
deba@468: 
deba@468:       NodeIt& operator++() { 
kpeter@609: 	graph->next(*this);
deba@468: 	return *this; 
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
deba@468:     class ArcIt : public Arc { 
kpeter@609:       const Graph* graph;
deba@468:     public:
deba@468: 
deba@468:       ArcIt() { }
deba@468: 
deba@468:       ArcIt(Invalid i) : Arc(i) { }
deba@468: 
kpeter@609:       explicit ArcIt(const Graph& _graph) : graph(&_graph) {
deba@468: 	_graph.first(static_cast<Arc&>(*this));
deba@468:       }
deba@468: 
kpeter@609:       ArcIt(const Graph& _graph, const Arc& e) : 
kpeter@609: 	Arc(e), graph(&_graph) { }
deba@468: 
deba@468:       ArcIt& operator++() { 
kpeter@609: 	graph->next(*this);
deba@468: 	return *this; 
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
deba@468:     class OutArcIt : public Arc { 
kpeter@609:       const Graph* graph;
deba@468:     public:
deba@468: 
deba@468:       OutArcIt() { }
deba@468: 
deba@468:       OutArcIt(Invalid i) : Arc(i) { }
deba@468: 
kpeter@609:       OutArcIt(const Graph& _graph, const Node& node) 
kpeter@609: 	: graph(&_graph) {
deba@468: 	_graph.firstOut(*this, node);
deba@468:       }
deba@468: 
kpeter@609:       OutArcIt(const Graph& _graph, const Arc& arc) 
kpeter@609: 	: Arc(arc), graph(&_graph) {}
deba@468: 
deba@468:       OutArcIt& operator++() { 
kpeter@609: 	graph->nextOut(*this);
deba@468: 	return *this; 
deba@468:       }
deba@468: 
deba@468:     };
deba@468: 
deba@468: 
deba@468:     class InArcIt : public Arc { 
kpeter@609:       const Graph* graph;
deba@468:     public:
deba@468: 
deba@468:       InArcIt() { }
deba@468: 
deba@468:       InArcIt(Invalid i) : Arc(i) { }
deba@468: 
kpeter@609:       InArcIt(const Graph& _graph, const Node& node) 
kpeter@609: 	: graph(&_graph) {
deba@468: 	_graph.firstIn(*this, node);
deba@468:       }
deba@468: 
kpeter@609:       InArcIt(const Graph& _graph, const Arc& arc) : 
kpeter@609: 	Arc(arc), graph(&_graph) {}
deba@468: 
deba@468:       InArcIt& operator++() { 
kpeter@609: 	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@609:       const Graph* graph;
deba@468:     public:
deba@468: 
deba@468:       EdgeIt() { }
deba@468: 
deba@468:       EdgeIt(Invalid i) : Edge(i) { }
deba@468: 
kpeter@609:       explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
deba@468: 	_graph.first(static_cast<Edge&>(*this));
deba@468:       }
deba@468: 
kpeter@609:       EdgeIt(const Graph& _graph, const Edge& e) : 
kpeter@609: 	Edge(e), graph(&_graph) { }
deba@468: 
deba@468:       EdgeIt& operator++() { 
kpeter@609: 	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@609:       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@609:       IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
deba@468: 	_graph.firstInc(*this, direction, n);
deba@468:       }
deba@468: 
kpeter@609:       IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
kpeter@609: 	: graph(&_graph), Edge(ue) {
deba@468: 	direction = (_graph.source(ue) == n);
deba@468:       }
deba@468: 
deba@468:       IncEdgeIt& operator++() {
kpeter@609: 	graph->nextInc(*this, direction);
deba@468: 	return *this; 
deba@468:       }
deba@468:     };
deba@468: 
kpeter@550:     // \brief Base node of the iterator
kpeter@550:     //
kpeter@550:     // 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@550:     // \brief Running node of the iterator
kpeter@550:     //
kpeter@550:     // Returns the running node (ie. the target in this case) of the
kpeter@550:     // iterator
deba@468:     Node runningNode(const OutArcIt &e) const {
deba@468:       return Parent::target(static_cast<const Arc&>(e));
deba@468:     }
deba@468: 
kpeter@550:     // \brief Base node of the iterator
kpeter@550:     //
kpeter@550:     // 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@550:     // \brief Running node of the iterator
kpeter@550:     //
kpeter@550:     // Returns the running node (ie. the source in this case) of the
kpeter@550:     // iterator
deba@468:     Node runningNode(const InArcIt &e) const {
deba@468:       return Parent::source(static_cast<const Arc&>(e));
deba@468:     }
deba@468: 
kpeter@550:     // Base node of the iterator
kpeter@550:     //
kpeter@550:     // Returns the base node of the iterator
deba@468:     Node baseNode(const IncEdgeIt &e) const {
deba@468:       return e.direction ? u(e) : v(e);
deba@468:     }
kpeter@550:     // Running node of the iterator
kpeter@550:     //
kpeter@550:     // Returns the running node of the iterator
deba@468:     Node runningNode(const IncEdgeIt &e) const {
deba@468:       return e.direction ? v(e) : u(e);
deba@468:     }
deba@468: 
deba@468: 
deba@468:     template <typename _Value>
deba@468:     class ArcMap 
kpeter@609:       : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
kpeter@609:       typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
kpeter@609: 
deba@468:     public:
kpeter@609:       ArcMap(const Graph& _g) 
deba@468: 	: Parent(_g) {}
kpeter@609:       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=<ArcMap>(cmap);
deba@468:       }
deba@468: 
deba@468:       template <typename CMap>
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 <typename _Value>
deba@468:     class EdgeMap 
kpeter@609:       : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
kpeter@609:       typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
kpeter@609: 
deba@468:     public:
kpeter@609:       EdgeMap(const Graph& _g) 
deba@468: 	: Parent(_g) {}
deba@468: 
kpeter@609:       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=<EdgeMap>(cmap);
deba@468:       }
deba@468: 
deba@468:       template <typename CMap>
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<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:     }
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<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:     }
deba@468:     
deba@468:   };
deba@468: 
deba@468: }
deba@468: 
deba@468: #endif