[Lemon-commits] [lemon_svn] alpar: r531 - hugo/trunk/src/work/alpar
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:40:01 CET 2006
Author: alpar
Date: Sun Apr 25 22:16:16 2004
New Revision: 531
Modified:
hugo/trunk/src/work/alpar/list_graph.h
Log:
class NodeSet: A graph class with no edges
class EdgeSet: A graph class using the node set of another graph.
It compiles but untested and undocumented.
Modified: hugo/trunk/src/work/alpar/list_graph.h
==============================================================================
--- hugo/trunk/src/work/alpar/list_graph.h (original)
+++ hugo/trunk/src/work/alpar/list_graph.h Sun Apr 25 22:16:16 2004
@@ -68,7 +68,7 @@
public:
template <typename T> class EdgeMap;
- template <typename T> class EdgeMap;
+ template <typename T> class NodeMap;
class Node;
class Edge;
@@ -300,7 +300,7 @@
class Node {
friend class ListGraph;
template <typename T> friend class NodeMap;
-
+
friend class Edge;
friend class OutEdgeIt;
friend class InEdgeIt;
@@ -321,8 +321,9 @@
class NodeIt : public Node {
friend class ListGraph;
public:
- NodeIt(const ListGraph& G) : Node(G.first_node) { }
NodeIt() : Node() { }
+ NodeIt(Invalid i) : Node(i) { }
+ NodeIt(const ListGraph& G) : Node(G.first_node) { }
};
class Edge {
@@ -721,6 +722,837 @@
};
+
+ ///A smart graph class.
+
+ ///This is a simple and fast erasable graph implementation.
+ ///
+ ///It conforms to the graph interface documented under
+ ///the description of \ref GraphSkeleton.
+ ///\sa \ref GraphSkeleton.
+ class NodeSet {
+
+ //Nodes are double linked.
+ //The free nodes are only single linked using the "next" field.
+ struct NodeT
+ {
+ int first_in,first_out;
+ int prev, next;
+ // NodeT() {}
+ };
+
+ std::vector<NodeT> nodes;
+ //The first node
+ int first_node;
+ //The first free node
+ int first_free_node;
+
+ protected:
+
+ template <typename Key> class DynMapBase
+ {
+ protected:
+ const NodeSet* G;
+ public:
+ virtual void add(const Key k) = NULL;
+ virtual void erase(const Key k) = NULL;
+ DynMapBase(const NodeSet &_G) : G(&_G) {}
+ virtual ~DynMapBase() {}
+ friend class NodeSet;
+ };
+
+ public:
+ template <typename T> class EdgeMap;
+ template <typename T> class NodeMap;
+
+ class Node;
+ class Edge;
+
+ // protected:
+ // HELPME:
+ protected:
+ ///\bug It must be public because of SymEdgeMap.
+ ///
+ mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
+ //mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
+
+ public:
+
+ class NodeIt;
+ class EdgeIt;
+ class OutEdgeIt;
+ class InEdgeIt;
+
+ template <typename T> class NodeMap;
+ template <typename T> class EdgeMap;
+
+ public:
+
+ NodeSet() : nodes(), first_node(-1),
+ first_free_node(-1) {}
+ NodeSet(const NodeSet &_g) : nodes(_g.nodes), first_node(_g.first_node),
+ first_free_node(_g.first_free_node) {}
+
+ ~NodeSet()
+ {
+ for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
+ i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
+ //for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
+ // i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
+ }
+
+ int nodeNum() const { return nodes.size(); } //FIXME: What is this?
+ int edgeNum() const { return 0; } //FIXME: What is this?
+
+ ///\bug This function does something different than
+ ///its name would suggests...
+ int maxNodeId() const { return nodes.size(); } //FIXME: What is this?
+ ///\bug This function does something different than
+ ///its name would suggests...
+ int maxEdgeId() const { return 0; } //FIXME: What is this?
+
+ Node tail(Edge e) const { return INVALID; }
+ Node head(Edge e) const { return INVALID; }
+
+ Node aNode(OutEdgeIt e) const { return INVALID; }
+ Node aNode(InEdgeIt e) const { return INVALID; }
+
+ Node bNode(OutEdgeIt e) const { return INVALID; }
+ Node bNode(InEdgeIt e) const { return INVALID; }
+
+ NodeIt& first(NodeIt& v) const {
+ v=NodeIt(*this); return v; }
+ EdgeIt& first(EdgeIt& e) const {
+ e=EdgeIt(*this); return e; }
+ OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
+ e=OutEdgeIt(*this,v); return e; }
+ InEdgeIt& first(InEdgeIt& e, const Node v) const {
+ e=InEdgeIt(*this,v); return e; }
+
+// template< typename It >
+// It first() const { It e; first(e); return e; }
+
+// template< typename It >
+// It first(Node v) const { It e; first(e,v); return e; }
+
+ bool valid(Edge e) const { return false; }
+ bool valid(Node n) const { return n.n!=-1; }
+
+ void setInvalid(Edge &e) { }
+ void setInvalid(Node &n) { n.n=-1; }
+
+ template <typename It> It getNext(It it) const
+ { It tmp(it); return next(tmp); }
+
+ NodeIt& next(NodeIt& it) const {
+ it.n=nodes[it.n].next;
+ return it;
+ }
+ OutEdgeIt& next(OutEdgeIt& it) const { return it; }
+ InEdgeIt& next(InEdgeIt& it) const { return it; }
+ EdgeIt& next(EdgeIt& it) const { return it; }
+
+ int id(Node v) const { return v.n; }
+ int id(Edge e) const { return -1; }
+
+ /// Adds a new node to the graph.
+
+ /// \todo It adds the nodes in a reversed order.
+ /// (i.e. the lastly added node becomes the first.)
+ Node addNode() {
+ int n;
+
+ if(first_free_node==-1)
+ {
+ n = nodes.size();
+ nodes.push_back(NodeT());
+ }
+ else {
+ n = first_free_node;
+ first_free_node = nodes[n].next;
+ }
+
+ nodes[n].next = first_node;
+ if(first_node != -1) nodes[first_node].prev = n;
+ first_node = n;
+ nodes[n].prev = -1;
+
+ nodes[n].first_in = nodes[n].first_out = -1;
+
+ Node nn; nn.n=n;
+
+ //Update dynamic maps
+ for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
+ i!=dyn_node_maps.end(); ++i) (**i).add(nn);
+
+ return nn;
+ }
+
+ void erase(Node nn) {
+ int n=nn.n;
+
+ if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
+ if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
+ else first_node = nodes[n].next;
+
+ nodes[n].next = first_free_node;
+ first_free_node = n;
+
+ //Update dynamic maps
+ for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
+ i!=dyn_node_maps.end(); ++i) (**i).erase(nn);
+ }
+
+ ///\bug Dynamic maps must be updated!
+ ///
+ void clear() {
+ nodes.clear();
+ first_node = first_free_node = -1;
+ }
+
+ class Node {
+ friend class NodeSet;
+ template <typename T> friend class NodeMap;
+
+ friend class Edge;
+ friend class OutEdgeIt;
+ friend class InEdgeIt;
+
+ protected:
+ int n;
+ friend int NodeSet::id(Node v) const;
+ Node(int nn) {n=nn;}
+ public:
+ Node() {}
+ Node (Invalid i) { n=-1; }
+ bool operator==(const Node i) const {return n==i.n;}
+ bool operator!=(const Node i) const {return n!=i.n;}
+ bool operator<(const Node i) const {return n<i.n;}
+ };
+
+ class NodeIt : public Node {
+ friend class NodeSet;
+ public:
+ NodeIt(const NodeSet& G) : Node(G.first_node) { }
+ NodeIt() : Node() { }
+ };
+
+ class Edge {
+ //friend class NodeSet;
+ //template <typename T> friend class EdgeMap;
+
+ //template <typename T> friend class SymNodeSet::SymEdgeMap;
+ //friend Edge SymNodeSet::opposite(Edge) const;
+
+ // friend class Node;
+ // friend class NodeIt;
+ protected:
+ //friend int NodeSet::id(Edge e) const;
+ // Edge(int nn) {}
+ public:
+ Edge() { }
+ Edge (Invalid) { }
+ bool operator==(const Edge i) const {return true;}
+ bool operator!=(const Edge i) const {return false;}
+ bool operator<(const Edge i) const {return false;}
+ ///\bug This is a workaround until somebody tells me how to
+ ///make class \c SymNodeSet::SymEdgeMap friend of Edge
+ // int idref() {return -1;}
+ // int idref() const {return -1;}
+ };
+
+ class EdgeIt : public Edge {
+ //friend class NodeSet;
+ public:
+ EdgeIt(const NodeSet& G) : Edge() { }
+ EdgeIt (Invalid i) : Edge(i) { }
+ EdgeIt() : Edge() { }
+ ///\bug This is a workaround until somebody tells me how to
+ ///make class \c SymNodeSet::SymEdgeMap friend of Edge
+ // int idref() {return -1;}
+ };
+
+ class OutEdgeIt : public Edge {
+ friend class NodeSet;
+ public:
+ OutEdgeIt() : Edge() { }
+ OutEdgeIt (Invalid i) : Edge(i) { }
+ OutEdgeIt(const NodeSet& G,const Node v) : Edge() {}
+ };
+
+ class InEdgeIt : public Edge {
+ friend class NodeSet;
+ public:
+ InEdgeIt() : Edge() { }
+ InEdgeIt (Invalid i) : Edge(i) { }
+ InEdgeIt(const NodeSet& G,Node v) :Edge() {}
+ };
+
+ template <typename T> class NodeMap : public DynMapBase<Node>
+ {
+ std::vector<T> container;
+
+ public:
+ typedef T ValueType;
+ typedef Node KeyType;
+
+ NodeMap(const NodeSet &_G) :
+ DynMapBase<Node>(_G), container(_G.maxNodeId())
+ {
+ G->dyn_node_maps.push_back(this);
+ }
+ NodeMap(const NodeSet &_G,const T &t) :
+ DynMapBase<Node>(_G), container(_G.maxNodeId(),t)
+ {
+ G->dyn_node_maps.push_back(this);
+ }
+
+ NodeMap(const NodeMap<T> &m) :
+ DynMapBase<Node>(*m.G), container(m.container)
+ {
+ G->dyn_node_maps.push_back(this);
+ }
+
+ template<typename TT> friend class NodeMap;
+
+ ///\todo It can copy between different types.
+ ///
+ template<typename TT> NodeMap(const NodeMap<TT> &m) :
+ DynMapBase<Node>(*m.G)
+ {
+ G->dyn_node_maps.push_back(this);
+ typename std::vector<TT>::const_iterator i;
+ for(typename std::vector<TT>::const_iterator i=m.container.begin();
+ i!=m.container.end();
+ i++)
+ container.push_back(*i);
+ }
+ ~NodeMap()
+ {
+ if(G) {
+ std::vector<DynMapBase<Node>* >::iterator i;
+ for(i=G->dyn_node_maps.begin();
+ i!=G->dyn_node_maps.end() && *i!=this; ++i) ;
+ //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow...
+ //A better way to do that: (Is this really important?)
+ if(*i==this) {
+ *i=G->dyn_node_maps.back();
+ G->dyn_node_maps.pop_back();
+ }
+ }
+ }
+
+ void add(const Node k)
+ {
+ if(k.n>=int(container.size())) container.resize(k.n+1);
+ }
+
+ void erase(const Node) { }
+
+ void set(Node n, T a) { container[n.n]=a; }
+ //'T& operator[](Node n)' would be wrong here
+ typename std::vector<T>::reference
+ operator[](Node n) { return container[n.n]; }
+ //'const T& operator[](Node n)' would be wrong here
+ typename std::vector<T>::const_reference
+ operator[](Node n) const { return container[n.n]; }
+
+ ///\warning There is no safety check at all!
+ ///Using operator = between maps attached to different graph may
+ ///cause serious problem.
+ ///\todo Is this really so?
+ ///\todo It can copy between different types.
+ const NodeMap<T>& operator=(const NodeMap<T> &m)
+ {
+ container = m.container;
+ return *this;
+ }
+ template<typename TT>
+ const NodeMap<T>& operator=(const NodeMap<TT> &m)
+ {
+ copy(m.container.begin(), m.container.end(), container.begin());
+ return *this;
+ }
+
+ void update() {} //Useless for Dynamic Maps
+ void update(T a) {} //Useless for Dynamic Maps
+ };
+
+ template <typename T> class EdgeMap
+ {
+ public:
+ typedef T ValueType;
+ typedef Edge KeyType;
+
+ EdgeMap(const NodeSet &) { }
+ EdgeMap(const NodeSet &,const T &) { }
+ EdgeMap(const EdgeMap<T> &) { }
+ // template<typename TT> friend class EdgeMap;
+
+ ///\todo It can copy between different types.
+ ///
+ template<typename TT> EdgeMap(const EdgeMap<TT> &) { }
+ ~EdgeMap() { }
+
+ void add(const Edge ) { }
+ void erase(const Edge) { }
+
+ void set(Edge, T) { }
+ //T get(Edge n) const { return container[n.n]; }
+ ValueType &operator[](Edge) { return *((T*)(NULL)); }
+ const ValueType &operator[](Edge) const { return *((T*)(NULL)); }
+
+ const EdgeMap<T>& operator=(const EdgeMap<T> &) { return *this; }
+
+ template<typename TT>
+ const EdgeMap<T>& operator=(const EdgeMap<TT> &m) { return *this; }
+
+ void update() {}
+ void update(T a) {}
+ };
+ };
+
+
+
+ ///This is a simple and fast erasable graph implementation.
+ ///
+ ///It conforms to the graph interface documented under
+ ///the description of \ref GraphSkeleton.
+ ///\sa \ref GraphSkeleton.
+ template<typename GG>
+ class EdgeSet {
+
+ typedef GG NodeGraphType;
+
+ NodeGraphType &G;
+
+ class Node;
+
+ //Edges are double linked.
+ //The free edges are only single linked using the "next_in" field.
+ struct NodeT
+ {
+ int first_in,first_out;
+ NodeT() : first_in(-1), first_out(-1) { }
+ };
+
+ struct EdgeT
+ {
+ Node head, tail;
+ int prev_in, prev_out;
+ int next_in, next_out;
+ };
+
+
+ typename NodeGraphType::NodeMap<NodeT> nodes;
+
+ std::vector<EdgeT> edges;
+ //The first free edge
+ int first_free_edge;
+
+ protected:
+
+ template <typename Key> class DynMapBase
+ {
+ protected:
+ const EdgeSet* G;
+ public:
+ virtual void add(const Key k) = NULL;
+ virtual void erase(const Key k) = NULL;
+ DynMapBase(const EdgeSet &_G) : G(&_G) {}
+ virtual ~DynMapBase() {}
+ friend class EdgeSet;
+ };
+
+ public:
+ //template <typename T> class NodeMap;
+ template <typename T> class EdgeMap;
+
+ class Node;
+ class Edge;
+
+ // protected:
+ // HELPME:
+ protected:
+ // mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
+ ///\bug It must be public because of SymEdgeMap.
+ ///
+ mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
+
+ public:
+
+ class NodeIt;
+ class EdgeIt;
+ class OutEdgeIt;
+ class InEdgeIt;
+
+ template <typename T> class NodeMap;
+ template <typename T> class EdgeMap;
+
+ public:
+
+ EdgeSet(const NodeGraphType &_G) : G(_G),
+ nodes(_G), edges(),
+ first_free_edge(-1) {}
+ EdgeSet(const EdgeSet &_g) : G(_g.G), nodes(_g.G), edges(_g.edges),
+ first_free_edge(_g.first_free_edge) {}
+
+ ~EdgeSet()
+ {
+ // for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
+ // i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
+ for(typename std::vector<DynMapBase<Edge> * >::iterator
+ i=dyn_edge_maps.begin();
+ i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
+ }
+
+ int nodeNum() const { return G.nodeNum(); } //FIXME: What is this?
+ int edgeNum() const { return edges.size(); } //FIXME: What is this?
+
+ ///\bug This function does something different than
+ ///its name would suggests...
+ int maxNodeId() const { return G.maxNodeId(); } //FIXME: What is this?
+ ///\bug This function does something different than
+ ///its name would suggests...
+ int maxEdgeId() const { return edges.size(); } //FIXME: What is this?
+
+ Node tail(Edge e) const { return edges[e.n].tail; }
+ Node head(Edge e) const { return edges[e.n].head; }
+
+ Node aNode(OutEdgeIt e) const { return edges[e.n].tail; }
+ Node aNode(InEdgeIt e) const { return edges[e.n].head; }
+
+ Node bNode(OutEdgeIt e) const { return edges[e.n].head; }
+ Node bNode(InEdgeIt e) const { return edges[e.n].tail; }
+
+ NodeIt& first(NodeIt& v) const {
+ v=NodeIt(*this); return v; }
+ EdgeIt& first(EdgeIt& e) const {
+ e=EdgeIt(*this); return e; }
+ OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
+ e=OutEdgeIt(*this,v); return e; }
+ InEdgeIt& first(InEdgeIt& e, const Node v) const {
+ e=InEdgeIt(*this,v); return e; }
+
+// template< typename It >
+// It first() const { It e; first(e); return e; }
+
+// template< typename It >
+// It first(Node v) const { It e; first(e,v); return e; }
+
+ bool valid(Edge e) const { return e.n!=-1; }
+ bool valid(Node n) const { return G.valid(n); }
+
+ void setInvalid(Edge &e) { e.n=-1; }
+ void setInvalid(Node &n) { G.setInvalid(n); }
+
+ template <typename It> It getNext(It it) const
+ { It tmp(it); return next(tmp); }
+
+ NodeIt& next(NodeIt& it) const { G.next(it); return it; }
+ OutEdgeIt& next(OutEdgeIt& it) const
+ { it.n=edges[it.n].next_out; return it; }
+ InEdgeIt& next(InEdgeIt& it) const
+ { it.n=edges[it.n].next_in; return it; }
+ EdgeIt& next(EdgeIt& it) const {
+ if(edges[it.n].next_in!=-1) {
+ it.n=edges[it.n].next_in;
+ }
+ else {
+ typename NodeGraphType::Node n;
+ for(n=G.next(edges[it.n].head);
+ G.valid(n) && nodes[n].first_in == -1;
+ G.next(n)) ;
+ it.n = (G.valid(n))?-1:nodes[n].first_in;
+ }
+ return it;
+ }
+
+ int id(Node v) const { return G.id(v); }
+ int id(Edge e) const { return e.n; }
+
+ /// Adds a new node to the graph.
+ Node addNode() { return G.AddNode(); }
+
+ Edge addEdge(Node u, Node v) {
+ int n;
+
+ if(first_free_edge==-1)
+ {
+ n = edges.size();
+ edges.push_back(EdgeT());
+ }
+ else {
+ n = first_free_edge;
+ first_free_edge = edges[n].next_in;
+ }
+
+ edges[n].tail = u.n; edges[n].head = v.n;
+
+ edges[n].next_out = nodes[u.n].first_out;
+ if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n;
+ edges[n].next_in = nodes[v.n].first_in;
+ if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n;
+ edges[n].prev_in = edges[n].prev_out = -1;
+
+ nodes[u.n].first_out = nodes[v.n].first_in = n;
+
+ Edge e; e.n=n;
+
+ //Update dynamic maps
+ for(typename std::vector<DynMapBase<Edge> * >::iterator
+ i=dyn_edge_maps.begin();
+ i!=dyn_edge_maps.end(); ++i) (**i).add(e);
+
+ return e;
+ }
+
+ private:
+ void eraseEdge(int n) {
+
+ if(edges[n].next_in!=-1)
+ edges[edges[n].next_in].prev_in = edges[n].prev_in;
+ if(edges[n].prev_in!=-1)
+ edges[edges[n].prev_in].next_in = edges[n].next_in;
+ else nodes[edges[n].head].first_in = edges[n].next_in;
+
+ if(edges[n].next_out!=-1)
+ edges[edges[n].next_out].prev_out = edges[n].prev_out;
+ if(edges[n].prev_out!=-1)
+ edges[edges[n].prev_out].next_out = edges[n].next_out;
+ else nodes[edges[n].tail].first_out = edges[n].next_out;
+
+ edges[n].next_in = first_free_edge;
+ first_free_edge = -1;
+
+ //Update dynamic maps
+ Edge e; e.n=n;
+ for(typename std::vector<DynMapBase<Edge> * >::iterator
+ i=dyn_edge_maps.begin();
+ i!=dyn_edge_maps.end(); ++i) (**i).erase(e);
+ }
+
+ public:
+
+// void erase(Node nn) {
+// int n=nn.n;
+// int m;
+// while((m=nodes[n].first_in)!=-1) eraseEdge(m);
+// while((m=nodes[n].first_out)!=-1) eraseEdge(m);
+// }
+
+ void erase(Edge e) { eraseEdge(e.n); }
+
+// //\bug Dynamic maps must be updated!
+// //
+// void clear() {
+// nodes.clear();edges.clear();
+// first_node=first_free_node=first_free_edge=-1;
+// }
+
+ class Node : public NodeGraphType::Node {
+ friend class EdgeSet;
+ // template <typename T> friend class NodeMap;
+
+ friend class Edge;
+ friend class OutEdgeIt;
+ friend class InEdgeIt;
+ friend class SymEdge;
+
+ protected:
+ friend int EdgeSet::id(Node v) const;
+ // Node(int nn) {n=nn;}
+ public:
+ Node() : NodeGraphType::Node() {}
+ Node (Invalid i) : NodeGraphType::Node(i) {}
+ Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {}
+ };
+
+ class NodeIt : public NodeGraphType::NodeIt {
+ friend class EdgeSet;
+ public:
+ NodeIt() : NodeGraphType::NodeIt() { }
+ NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {}
+ NodeIt(const EdgeSet& _G) : NodeGraphType::Node(_G.G) { }
+ NodeIt(const typename NodeGraphType::NodeIt &n)
+ : NodeGraphType::NodeIt(n) {}
+ operator Node() { return Node(*this);}
+ };
+
+ class Edge {
+ friend class EdgeSet;
+ template <typename T> friend class EdgeMap;
+
+ //template <typename T> friend class SymEdgeSet::SymEdgeMap;
+ //friend Edge SymEdgeSet::opposite(Edge) const;
+
+ friend class Node;
+ friend class NodeIt;
+ protected:
+ int n;
+ friend int EdgeSet::id(Edge e) const;
+
+ Edge(int nn) {n=nn;}
+ public:
+ Edge() { }
+ Edge (Invalid) { n=-1; }
+ bool operator==(const Edge i) const {return n==i.n;}
+ bool operator!=(const Edge i) const {return n!=i.n;}
+ bool operator<(const Edge i) const {return n<i.n;}
+ ///\bug This is a workaround until somebody tells me how to
+ ///make class \c SymEdgeSet::SymEdgeMap friend of Edge
+ int &idref() {return n;}
+ const int &idref() const {return n;}
+ };
+
+ class EdgeIt : public Edge {
+ friend class EdgeSet;
+ public:
+ EdgeIt(const EdgeSet& G) : Edge() {
+ typename NodeGraphType::Node m;
+ for(G.first(m);
+ G.valid(m) && nodes[m].first_in == -1; G.next[m]);
+ n = G.valid(m)?-1:nodes[m].first_in;
+ }
+ EdgeIt (Invalid i) : Edge(i) { }
+ EdgeIt() : Edge() { }
+ ///\bug This is a workaround until somebody tells me how to
+ ///make class \c SymEdgeSet::SymEdgeMap friend of Edge
+ int &idref() {return n;}
+ };
+
+ class OutEdgeIt : public Edge {
+ friend class EdgeSet;
+ public:
+ OutEdgeIt() : Edge() { }
+ OutEdgeIt (Invalid i) : Edge(i) { }
+
+ OutEdgeIt(const EdgeSet& G,const Node v) : Edge(nodes[v].first_out) { }
+ };
+
+ class InEdgeIt : public Edge {
+ friend class EdgeSet;
+ public:
+ InEdgeIt() : Edge() { }
+ InEdgeIt (Invalid i) : Edge(i) { }
+ InEdgeIt(const EdgeSet& G,Node v) :Edge(nodes[v].first_in) { }
+ };
+
+ template <typename T> class NodeMap : public NodeGraphType::NodeMap<T>
+ {
+ public:
+ NodeMap(const EdgeSet &_G) :
+ NodeGraphType::NodeMap<T>(_G.G) { }
+ NodeMap(const EdgeSet &_G,const T &t) :
+ NodeGraphType::NodeMap<T>(_G.G,t) { }
+ //It is unnecessary
+ NodeMap(const typename NodeGraphType::NodeMap<T> &m)
+ : NodeGraphType::NodeMap<T>(m) { }
+
+ ///\todo It can copy between different types.
+ ///
+ template<typename TT> friend class NodeMap;
+ NodeMap(const typename NodeGraphType::NodeMap<TT> &m)
+ : NodeGraphType::NodeMap<T>(m) { }
+ };
+
+ template <typename T> class EdgeMap : public DynMapBase<Edge>
+ {
+ std::vector<T> container;
+
+ public:
+ typedef T ValueType;
+ typedef Edge KeyType;
+
+ EdgeMap(const EdgeSet &_G) :
+ DynMapBase<Edge>(_G), container(_G.maxEdgeId())
+ {
+ //FIXME: What if there are empty Id's?
+ //FIXME: Can I use 'this' in a constructor?
+ G->dyn_edge_maps.push_back(this);
+ }
+ EdgeMap(const EdgeSet &_G,const T &t) :
+ DynMapBase<Edge>(_G), container(_G.maxEdgeId(),t)
+ {
+ G->dyn_edge_maps.push_back(this);
+ }
+ EdgeMap(const EdgeMap<T> &m) :
+ DynMapBase<Edge>(*m.G), container(m.container)
+ {
+ G->dyn_node_maps.push_back(this);
+ }
+
+ template<typename TT> friend class EdgeMap;
+
+ ///\todo It can copy between different types.
+ ///
+ template<typename TT> EdgeMap(const EdgeMap<TT> &m) :
+ DynMapBase<Edge>(*m.G)
+ {
+ G->dyn_node_maps.push_back(this);
+ typename std::vector<TT>::const_iterator i;
+ for(typename std::vector<TT>::const_iterator i=m.container.begin();
+ i!=m.container.end();
+ i++)
+ container.push_back(*i);
+ }
+ ~EdgeMap()
+ {
+ if(G) {
+ typename std::vector<DynMapBase<Edge>* >::iterator i;
+ for(i=G->dyn_edge_maps.begin();
+ i!=G->dyn_edge_maps.end() && *i!=this; ++i) ;
+ //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
+ //A better way to do that: (Is this really important?)
+ if(*i==this) {
+ *i=G->dyn_edge_maps.back();
+ G->dyn_edge_maps.pop_back();
+ }
+ }
+ }
+
+ void add(const Edge k)
+ {
+ if(k.n>=int(container.size())) container.resize(k.n+1);
+ }
+ void erase(const Edge) { }
+
+ void set(Edge n, T a) { container[n.n]=a; }
+ //T get(Edge n) const { return container[n.n]; }
+ typename std::vector<T>::reference
+ operator[](Edge n) { return container[n.n]; }
+ typename std::vector<T>::const_reference
+ operator[](Edge n) const { return container[n.n]; }
+
+ ///\warning There is no safety check at all!
+ ///Using operator = between maps attached to different graph may
+ ///cause serious problem.
+ ///\todo Is this really so?
+ ///\todo It can copy between different types.
+ const EdgeMap<T>& operator=(const EdgeMap<T> &m)
+ {
+ container = m.container;
+ return *this;
+ }
+ template<typename TT>
+ const EdgeMap<T>& operator=(const EdgeMap<TT> &m)
+ {
+ copy(m.container.begin(), m.container.end(), container.begin());
+ return *this;
+ }
+
+ void update() {} //Useless for DynMaps
+ void update(T a) {} //Useless for DynMaps
+ };
+
+ };
+
+
+
+
+
+
+
} //namespace hugo
More information about the Lemon-commits
mailing list