Dynamic maps became the defaults.
authoralpar
Sat, 13 Mar 2004 22:53:07 +0000
changeset 185259540358bbf
parent 184 08735c8704cd
child 186 47cd1716870e
Dynamic maps became the defaults.
Maps got copy constructors and operator=. Also work between different types.
SymSmartGraph added
smart_graph_demo.cc was extended.
src/work/alpar/smart_graph.h
src/work/alpar/smart_graph_demo.cc
     1.1 --- a/src/work/alpar/smart_graph.h	Sat Mar 13 22:49:54 2004 +0000
     1.2 +++ b/src/work/alpar/smart_graph.h	Sat Mar 13 22:53:07 2004 +0000
     1.3 @@ -1,7 +1,7 @@
     1.4  // -*- mode:C++ -*-
     1.5  
     1.6 -#ifndef SMART_GRAPH_H
     1.7 -#define SMART_GRAPH_H
     1.8 +#ifndef HUGO_SMART_GRAPH_H
     1.9 +#define HUGO_SMART_GRAPH_H
    1.10  
    1.11  #include <vector>
    1.12  #include <limits.h>
    1.13 @@ -10,6 +10,10 @@
    1.14  
    1.15  namespace hugo {
    1.16  
    1.17 +  class SymSmartGraph;
    1.18 +
    1.19 +  //  template<typename T> class SymSmartGraph::SymEdgeMap;
    1.20 +  
    1.21    class SmartGraph {
    1.22  
    1.23      struct NodeT 
    1.24 @@ -28,10 +32,12 @@
    1.25  
    1.26      std::vector<EdgeT> edges;
    1.27      
    1.28 +    protected:
    1.29 +    
    1.30      template <typename Key> class DynMapBase
    1.31      {
    1.32      protected:
    1.33 -      SmartGraph* G; 
    1.34 +      const SmartGraph* G; 
    1.35      public:
    1.36        virtual void add(const Key k) = NULL;
    1.37        virtual void erase(const Key k) = NULL;
    1.38 @@ -39,15 +45,22 @@
    1.39        virtual ~DynMapBase() {}
    1.40        friend class SmartGraph;
    1.41      };
    1.42 +    
    1.43    public:
    1.44 -    template <typename T> class DynEdgeMap;
    1.45 -    template <typename T> class DynEdgeMap;
    1.46 +    template <typename T> class EdgeMap;
    1.47 +    template <typename T> class EdgeMap;
    1.48  
    1.49      class Node;
    1.50      class Edge;
    1.51  
    1.52 -  protected:
    1.53 +    //  protected:
    1.54 +    // HELPME:
    1.55 +  public:
    1.56 +    ///\bug It must be public because of SymEdgeMap.
    1.57 +    ///
    1.58      mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
    1.59 +    ///\bug It must be public because of SymEdgeMap.
    1.60 +    ///
    1.61      mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
    1.62      
    1.63    public:
    1.64 @@ -168,7 +181,6 @@
    1.65      class Node {
    1.66        friend class SmartGraph;
    1.67        template <typename T> friend class NodeMap;
    1.68 -      template <typename T> friend class DynNodeMap;
    1.69        
    1.70        friend class Edge;
    1.71        friend class OutEdgeIt;
    1.72 @@ -197,7 +209,9 @@
    1.73      class Edge {
    1.74        friend class SmartGraph;
    1.75        template <typename T> friend class EdgeMap;
    1.76 -      template <typename T> friend class DynEdgeMap;
    1.77 +
    1.78 +      //template <typename T> friend class SymSmartGraph::SymEdgeMap;      
    1.79 +      //friend Edge SymSmartGraph::opposite(Edge) const;
    1.80        
    1.81        friend class Node;
    1.82        friend class NodeIt;
    1.83 @@ -212,6 +226,10 @@
    1.84        bool operator==(const Edge i) const {return n==i.n;}
    1.85        bool operator!=(const Edge i) const {return n!=i.n;}
    1.86        bool operator<(const Edge i) const {return n<i.n;}
    1.87 +      ///\bug This is a workaround until somebody tells me how to
    1.88 +      ///make class \c SymSmartGraph::SymEdgeMap friend of Edge
    1.89 +      int &idref() {return n;}
    1.90 +      const int &idref() const {return n;}
    1.91      };
    1.92      
    1.93      class EdgeIt : public Edge {
    1.94 @@ -220,6 +238,9 @@
    1.95        EdgeIt(const SmartGraph& G) : Edge(G.edges.size()-1) { }
    1.96        EdgeIt (Invalid i) : Edge(i) { }
    1.97        EdgeIt() : Edge() { }
    1.98 +      ///\bug This is a workaround until somebody tells me how to
    1.99 +      ///make class \c SymSmartGraph::SymEdgeMap friend of Edge
   1.100 +      int &idref() {return n;}
   1.101      };
   1.102      
   1.103      class OutEdgeIt : public Edge {
   1.104 @@ -242,43 +263,44 @@
   1.105  
   1.106      // Map types
   1.107  
   1.108 -    template <typename T>
   1.109 -    class NodeMap {
   1.110 -      const SmartGraph& G; 
   1.111 -      std::vector<T> container;
   1.112 -    public:
   1.113 -      typedef T ValueType;
   1.114 -      typedef Node KeyType;
   1.115 -      NodeMap(const SmartGraph& _G) : G(_G), container(G.maxNodeId()) { }
   1.116 -      NodeMap(const SmartGraph& _G, T a) : 
   1.117 -	G(_G), container(G.maxNodeId(), a) { }
   1.118 -      void set(Node n, T a) { container[n.n]=a; }
   1.119 -      T get(Node n) const { return container[n.n]; }
   1.120 -      T& operator[](Node n) { return container[n.n]; }
   1.121 -      const T& operator[](Node n) const { return container[n.n]; }
   1.122 -      void update() { container.resize(G.maxNodeId()); }
   1.123 -      void update(T a) { container.resize(G.maxNodeId(), a); }
   1.124 -    };
   1.125 +//     // Static Maps are not necessary.
   1.126 +//     template <typename T>
   1.127 +//     class NodeMap {
   1.128 +//       const SmartGraph& G; 
   1.129 +//       std::vector<T> container;
   1.130 +//     public:
   1.131 +//       typedef T ValueType;
   1.132 +//       typedef Node KeyType;
   1.133 +//       NodeMap(const SmartGraph& _G) : G(_G), container(G.maxNodeId()) { }
   1.134 +//       NodeMap(const SmartGraph& _G, T a) : 
   1.135 +// 	G(_G), container(G.maxNodeId(), a) { }
   1.136 +//       void set(Node n, T a) { container[n.n]=a; }
   1.137 +//       T get(Node n) const { return container[n.n]; }
   1.138 +//       T& operator[](Node n) { return container[n.n]; }
   1.139 +//       const T& operator[](Node n) const { return container[n.n]; }
   1.140 +//       void update() { container.resize(G.maxNodeId()); }
   1.141 +//       void update(T a) { container.resize(G.maxNodeId(), a); }
   1.142 +//     };
   1.143  
   1.144 -    template <typename T>
   1.145 -    class EdgeMap {
   1.146 -      const SmartGraph& G; 
   1.147 -      std::vector<T> container;
   1.148 -    public:
   1.149 -      typedef T ValueType;
   1.150 -      typedef Edge KeyType;
   1.151 -      EdgeMap(const SmartGraph& _G) : G(_G), container(G.maxEdgeId()) { }
   1.152 -      EdgeMap(const SmartGraph& _G, T a) : 
   1.153 -	G(_G), container(G.maxEdgeId(), a) { }
   1.154 -      void set(Edge e, T a) { container[e.n]=a; }
   1.155 -      T get(Edge e) const { return container[e.n]; }
   1.156 -      T& operator[](Edge e) { return container[e.n]; } 
   1.157 -      const T& operator[](Edge e) const { return container[e.n]; } 
   1.158 -      void update() { container.resize(G.maxEdgeId()); }
   1.159 -      void update(T a) { container.resize(G.maxEdgeId(), a); }
   1.160 -    };
   1.161 +//     template <typename T>
   1.162 +//     class EdgeMap {
   1.163 +//       const SmartGraph& G; 
   1.164 +//       std::vector<T> container;
   1.165 +//     public:
   1.166 +//       typedef T ValueType;
   1.167 +//       typedef Edge KeyType;
   1.168 +//       EdgeMap(const SmartGraph& _G) : G(_G), container(G.maxEdgeId()) { }
   1.169 +//       EdgeMap(const SmartGraph& _G, T a) : 
   1.170 +// 	G(_G), container(G.maxEdgeId(), a) { }
   1.171 +//       void set(Edge e, T a) { container[e.n]=a; }
   1.172 +//       T get(Edge e) const { return container[e.n]; }
   1.173 +//       T& operator[](Edge e) { return container[e.n]; } 
   1.174 +//       const T& operator[](Edge e) const { return container[e.n]; } 
   1.175 +//       void update() { container.resize(G.maxEdgeId()); }
   1.176 +//       void update(T a) { container.resize(G.maxEdgeId(), a); }
   1.177 +//     };
   1.178  
   1.179 -    template <typename T> class DynNodeMap : public DynMapBase<Node>
   1.180 +    template <typename T> class NodeMap : public DynMapBase<Node>
   1.181      {
   1.182        std::vector<T> container;
   1.183  
   1.184 @@ -286,14 +308,38 @@
   1.185        typedef T ValueType;
   1.186        typedef Node KeyType;
   1.187  
   1.188 -      DynNodeMap(const SmartGraph &_G) :
   1.189 +      NodeMap(const SmartGraph &_G) :
   1.190  	DynMapBase<Node>(_G), container(_G.maxNodeId())
   1.191        {
   1.192 -	//FIXME: What if there are empty Id's?
   1.193 -	//FIXME: Can I use 'this' in a constructor?
   1.194  	G->dyn_node_maps.push_back(this);
   1.195        }
   1.196 -      ~DynNodeMap()
   1.197 +      NodeMap(const SmartGraph &_G,const T &t) :
   1.198 +	DynMapBase<Node>(_G), container(_G.maxNodeId(),t)
   1.199 +      {
   1.200 +	G->dyn_node_maps.push_back(this);
   1.201 +      }
   1.202 +      
   1.203 +      NodeMap(const NodeMap<T> &m) :
   1.204 + 	DynMapBase<Node>(*m.G), container(m.container)
   1.205 +      {
   1.206 + 	G->dyn_node_maps.push_back(this);
   1.207 +      }
   1.208 +
   1.209 +      template<typename TT> friend class NodeMap;
   1.210 + 
   1.211 +      ///\todo It can copy between different types.
   1.212 +      ///
   1.213 +      template<typename TT> NodeMap(const NodeMap<TT> &m) :
   1.214 +	DynMapBase<Node>(*m.G)
   1.215 +      {
   1.216 +	G->dyn_node_maps.push_back(this);
   1.217 +	typename std::vector<TT>::const_iterator i;
   1.218 +	for(typename std::vector<TT>::const_iterator i=m.container.begin();
   1.219 +	    i!=m.container.end();
   1.220 +	    i++)
   1.221 +	  container.push_back(*i);
   1.222 +      }
   1.223 +      ~NodeMap()
   1.224        {
   1.225  	if(G) {
   1.226  	  std::vector<DynMapBase<Node>* >::iterator i;
   1.227 @@ -310,28 +356,38 @@
   1.228  
   1.229        void add(const Node k) 
   1.230        {
   1.231 -	if(k.n>=container.size()) container.resize(k.n+1);
   1.232 +	if(k.n>=int(container.size())) container.resize(k.n+1);
   1.233        }
   1.234  
   1.235 -//       void erase(const Node k)
   1.236 -//       {
   1.237 -// 	//FIXME: Please implement me.
   1.238 -//       }
   1.239 -//       void erase(const Edge k)
   1.240 -//       {
   1.241 -// 	//FIXME: Please implement me.
   1.242 -//       }
   1.243 +      void erase(const Node k) { }
   1.244        
   1.245        void set(Node n, T a) { container[n.n]=a; }
   1.246        T get(Node n) const { return container[n.n]; }
   1.247        T& operator[](Node n) { return container[n.n]; }
   1.248        const T& operator[](Node n) const { return container[n.n]; }
   1.249  
   1.250 +      ///\warning There is no safety check at all!
   1.251 +      ///Using operator = between maps attached to different graph may
   1.252 +      ///cause serious problem.
   1.253 +      ///\todo Is this really so?
   1.254 +      ///\todo It can copy between different types.
   1.255 +      const NodeMap<T>& operator=(const NodeMap<T> &m)
   1.256 +      {
   1.257 +	container = m.container;
   1.258 +	return *this;
   1.259 +      }
   1.260 +      template<typename TT>
   1.261 +      const NodeMap<T>& operator=(const NodeMap<TT> &m)
   1.262 +      {
   1.263 +	copy(m.container.begin(), m.container.end(), container.begin());
   1.264 +	return *this;
   1.265 +      }
   1.266 +      
   1.267        void update() {}    //Useless for DynMaps
   1.268        void update(T a) {}  //Useless for DynMaps
   1.269      };
   1.270      
   1.271 -    template <typename T> class DynEdgeMap : public DynMapBase<Edge>
   1.272 +    template <typename T> class EdgeMap : public DynMapBase<Edge>
   1.273      {
   1.274        std::vector<T> container;
   1.275  
   1.276 @@ -339,14 +395,39 @@
   1.277        typedef T ValueType;
   1.278        typedef Edge KeyType;
   1.279  
   1.280 -      DynEdgeMap(const SmartGraph &_G) :
   1.281 +      EdgeMap(const SmartGraph &_G) :
   1.282  	DynMapBase<Edge>(_G), container(_G.maxEdgeId())
   1.283        {
   1.284  	//FIXME: What if there are empty Id's?
   1.285  	//FIXME: Can I use 'this' in a constructor?
   1.286  	G->dyn_edge_maps.push_back(this);
   1.287        }
   1.288 -      ~DynEdgeMap()
   1.289 +      EdgeMap(const SmartGraph &_G,const T &t) :
   1.290 +	DynMapBase<Edge>(_G), container(_G.maxEdgeId(),t)
   1.291 +      {
   1.292 +	G->dyn_edge_maps.push_back(this);
   1.293 +      } 
   1.294 +      EdgeMap(const EdgeMap<T> &m) :
   1.295 + 	DynMapBase<Edge>(*m.G), container(m.container)
   1.296 +      {
   1.297 + 	G->dyn_node_maps.push_back(this);
   1.298 +      }
   1.299 +
   1.300 +      template<typename TT> friend class EdgeMap;
   1.301 +
   1.302 +      ///\todo It can copy between different types.
   1.303 +      ///
   1.304 +      template<typename TT> EdgeMap(const EdgeMap<TT> &m) :
   1.305 +	DynMapBase<Edge>(*m.G)
   1.306 +      {
   1.307 +	G->dyn_node_maps.push_back(this);
   1.308 +	typename std::vector<TT>::const_iterator i;
   1.309 +	for(typename std::vector<TT>::const_iterator i=m.container.begin();
   1.310 +	    i!=m.container.end();
   1.311 +	    i++)
   1.312 +	  container.push_back(*i);
   1.313 +      }
   1.314 +      ~EdgeMap()
   1.315        {
   1.316  	if(G) {
   1.317  	  std::vector<DynMapBase<Edge>* >::iterator i;
   1.318 @@ -365,21 +446,158 @@
   1.319        {
   1.320  	if(k.n>=int(container.size())) container.resize(k.n+1);
   1.321        }
   1.322 -      void erase(const Edge k)
   1.323 -      {
   1.324 -	//FIXME: Please implement me.
   1.325 -      }
   1.326 +      void erase(const Edge k) { }
   1.327        
   1.328        void set(Edge n, T a) { container[n.n]=a; }
   1.329        T get(Edge n) const { return container[n.n]; }
   1.330        T& operator[](Edge n) { return container[n.n]; }
   1.331        const T& operator[](Edge n) const { return container[n.n]; }
   1.332  
   1.333 +      ///\warning There is no safety check at all!
   1.334 +      ///Using operator = between maps attached to different graph may
   1.335 +      ///cause serious problem.
   1.336 +      ///\todo Is this really so?
   1.337 +      ///\todo It can copy between different types.
   1.338 +      const EdgeMap<T>& operator=(const EdgeMap<T> &m)
   1.339 +      {
   1.340 +	container = m.container;
   1.341 +	return *this;
   1.342 +      }
   1.343 +      template<typename TT>
   1.344 +      const EdgeMap<T>& operator=(const EdgeMap<TT> &m)
   1.345 +      {
   1.346 +	copy(m.container.begin(), m.container.end(), container.begin());
   1.347 +	return *this;
   1.348 +      }
   1.349 +      
   1.350        void update() {}    //Useless for DynMaps
   1.351        void update(T a) {}  //Useless for DynMaps
   1.352      };
   1.353 -        
   1.354 +
   1.355    };
   1.356 +
   1.357 +  ///Graph for bidirectional edges.
   1.358 +
   1.359 +  ///The purpose of this graph structure is to handle graphs
   1.360 +  ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
   1.361 +  ///of oppositely directed edges. You can define edge maps which
   1.362 +  ///stores a common value for the edge pairs. The usual edge maps can be used
   1.363 +  ///as well.
   1.364 +  ///
   1.365 +  ///The oppositely directed edge can also be obtained easily.
   1.366 +
   1.367 +  class SymSmartGraph : public SmartGraph
   1.368 +  {
   1.369 +  public:
   1.370 +    SymSmartGraph() : SmartGraph() { }
   1.371 +    SymSmartGraph(const SmartGraph &_g) : SmartGraph(_g) { }
   1.372 +    Edge addEdge(Node u, Node v)
   1.373 +    {
   1.374 +      Edge e = SmartGraph::addEdge(u,v);
   1.375 +      SmartGraph::addEdge(v,u);
   1.376 +      return e;
   1.377 +    }
   1.378 +
   1.379 +    Edge opposite(Edge e) const
   1.380 +    {
   1.381 +      Edge f;
   1.382 +      f.idref() = e.idref() - 2*(e.idref()%2) + 1;
   1.383 +      return f;
   1.384 +    }
   1.385 +    
   1.386 +    template <typename T> class SymEdgeMap : public DynMapBase<Edge>
   1.387 +    {
   1.388 +      std::vector<T> container;
   1.389 +      
   1.390 +    public:
   1.391 +      typedef T ValueType;
   1.392 +      typedef Edge KeyType;
   1.393 +
   1.394 +      SymEdgeMap(const SmartGraph &_G) :
   1.395 +	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2)
   1.396 +      {
   1.397 +	G->dyn_edge_maps.push_back(this);
   1.398 +      }
   1.399 +      SymEdgeMap(const SmartGraph &_G,const T &t) :
   1.400 +	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2,t)
   1.401 +      {
   1.402 +	G->dyn_edge_maps.push_back(this);
   1.403 +      }
   1.404 +
   1.405 +      SymEdgeMap(const SymEdgeMap<T> &m) :
   1.406 + 	DynMapBase<SymEdge>(*m.G), container(m.container)
   1.407 +      {
   1.408 + 	G->dyn_node_maps.push_back(this);
   1.409 +      }
   1.410 +
   1.411 +      //      template<typename TT> friend class SymEdgeMap;
   1.412 +
   1.413 +      ///\todo It can copy between different types.
   1.414 +      ///
   1.415 +
   1.416 +      template<typename TT> SymEdgeMap(const SymEdgeMap<TT> &m) :
   1.417 +	DynMapBase<SymEdge>(*m.G)
   1.418 +      {
   1.419 +	G->dyn_node_maps.push_back(this);
   1.420 +	typename std::vector<TT>::const_iterator i;
   1.421 +	for(typename std::vector<TT>::const_iterator i=m.container.begin();
   1.422 +	    i!=m.container.end();
   1.423 +	    i++)
   1.424 +	  container.push_back(*i);
   1.425 +      }
   1.426 + 
   1.427 +      ~SymEdgeMap()
   1.428 +      {
   1.429 +	if(G) {
   1.430 +	  std::vector<DynMapBase<Edge>* >::iterator i;
   1.431 +	  for(i=G->dyn_edge_maps.begin();
   1.432 +	      i!=G->dyn_edge_maps.end() && *i!=this; ++i) ;
   1.433 +	  //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
   1.434 +	  //A better way to do that: (Is this really important?)
   1.435 +	  if(*i==this) {
   1.436 +	    *i=G->dyn_edge_maps.back();
   1.437 +	    G->dyn_edge_maps.pop_back();
   1.438 +	  }
   1.439 +	}
   1.440 +      }
   1.441 +      
   1.442 +      void add(const Edge k) 
   1.443 +      {
   1.444 +	if(!k.idref()%2&&k.idref()/2>=int(container.size()))
   1.445 +	  container.resize(k.idref()/2+1);
   1.446 +      }
   1.447 +      void erase(const Edge k) { }
   1.448 +      
   1.449 +      void set(Edge n, T a) { container[n.idref()/2]=a; }
   1.450 +      T get(Edge n) const { return container[n.idref()/2]; }
   1.451 +      T& operator[](Edge n) { return container[n.idref()/2]; }
   1.452 +      const T& operator[](Edge n) const { return container[n.idref()/2]; }
   1.453 +
   1.454 +      ///\warning There is no safety check at all!
   1.455 +      ///Using operator = between maps attached to different graph may
   1.456 +      ///cause serious problem.
   1.457 +      ///\todo Is this really so?
   1.458 +      ///\todo It can copy between different types.
   1.459 +      const SymEdgeMap<T>& operator=(const SymEdgeMap<T> &m)
   1.460 +      {
   1.461 +	container = m.container;
   1.462 +	return *this;
   1.463 +      }
   1.464 +      template<typename TT>
   1.465 +      const SymEdgeMap<T>& operator=(const SymEdgeMap<TT> &m)
   1.466 +      {
   1.467 +	copy(m.container.begin(), m.container.end(), container.begin());
   1.468 +	return *this;
   1.469 +      }
   1.470 +      
   1.471 +      void update() {}    //Useless for DynMaps
   1.472 +      void update(T a) {}  //Useless for DynMaps
   1.473 +
   1.474 +    };
   1.475 +
   1.476 +  };
   1.477 +  
   1.478 +  
   1.479  } //namespace hugo
   1.480  
   1.481  
     2.1 --- a/src/work/alpar/smart_graph_demo.cc	Sat Mar 13 22:49:54 2004 +0000
     2.2 +++ b/src/work/alpar/smart_graph_demo.cc	Sat Mar 13 22:53:07 2004 +0000
     2.3 @@ -6,8 +6,8 @@
     2.4  
     2.5  using namespace hugo;
     2.6  
     2.7 -//typedef SmartGraph Graph;
     2.8 -typedef EmptyGraph Graph;
     2.9 +typedef SmartGraph Graph;
    2.10 +//typedef GraphSkeleton Graph;
    2.11  
    2.12  
    2.13  Graph::OutEdgeIt safeFirstOut(const Graph &G, Graph::Node n)
    2.14 @@ -26,42 +26,99 @@
    2.15    typedef Graph::NodeIt NodeIt;
    2.16    
    2.17    Graph G;
    2.18 -  NodeIt n;
    2.19 +  
    2.20 +  {
    2.21 +    NodeIt n;
    2.22  
    2.23 +    for(int i=0;i<10;i++) G.addNode();
    2.24 +    for(G.first(n);G.valid(n);G.next(n)) 
    2.25 +      for(NodeIt m(G);m!=INVALID;G.next(m)) 
    2.26 +	if(n!=m) G.addEdge(n,m);
    2.27 +    
    2.28 +    OutEdgeIt e = safeFirstOut(G,n);
    2.29 +    OutEdgeIt f = safeFirstOut(G,NodeIt(G));
    2.30 +    
    2.31 +    
    2.32 +    InEdgeIt i(INVALID), j;
    2.33 +    InEdgeIt ii(i);
    2.34 +    ii=G.first(i,n);
    2.35 +    ii=G.next(i);
    2.36 +    
    2.37 +    OutEdgeIt o(INVALID), oo;
    2.38 +    OutEdgeIt ooo(oo);
    2.39 +    oo=G.first(o,n);
    2.40 +    oo=G.next(o);
    2.41 +    
    2.42 +    EdgeIt ei(INVALID), eie;
    2.43 +    EdgeIt eiee(ei);
    2.44 +    eie=G.first(ei);
    2.45 +    eie=G.next(ei);
    2.46 +    
    2.47 +    Edge eee(i);
    2.48 +    eee=o;
    2.49 +    eee=eie;
    2.50 +    
    2.51 +    
    2.52 +    bool tm;
    2.53 +    tm = G.valid(n) && G.valid(i) && G.valid(o) && G.valid(ei);
    2.54 +    
    2.55 +    std::vector<InEdgeIt> v(10);
    2.56 +    std::vector<InEdgeIt> w(10,INVALID);
    2.57 +    
    2.58 +  }
    2.59 +  
    2.60 +  // Test of maps
    2.61  
    2.62 +  G.clear();
    2.63 +  
    2.64    for(int i=0;i<10;i++) G.addNode();
    2.65 -  for(G.first(n);G.valid(n);G.next(n)) 
    2.66 -    for(NodeIt m(G);m!=INVALID;G.next(m)) 
    2.67 -      if(n!=m) G.addEdge(n,m);
    2.68 +  for(NodeIt i(G);G.valid(i);G.next(i)) 
    2.69 +    for(NodeIt j(G);G.valid(j);G.next(j)) 
    2.70 +      if(i<j) G.addEdge(i,j);           //The iterators are comparable
    2.71 +  
    2.72 +  Graph::NodeMap<int> n(G);
    2.73 +  int count=0;
    2.74 +  for(NodeIt i(G);G.valid(i);G.next(i)) n[i]=count++;
    2.75 +  
    2.76 +  Graph::NodeMap<int> nn=n;
    2.77 +  Graph::NodeMap<double> dd=n;
    2.78  
    2.79 -  OutEdgeIt e = safeFirstOut(G,n);
    2.80 -  OutEdgeIt f = safeFirstOut(G,NodeIt(G));
    2.81 +  n = nn;
    2.82    
    2.83 +  dd = nn;
    2.84 +  
    2.85 +  Graph::EdgeMap<int> emap(G);
    2.86  
    2.87 -  InEdgeIt i(INVALID), j;
    2.88 -  InEdgeIt ii(i);
    2.89 -  ii=G.first(i,n);
    2.90 -  ii=G.next(i);
    2.91 +  // Test of SymSmartGraph
    2.92    
    2.93 -  OutEdgeIt o(INVALID), oo;
    2.94 -  OutEdgeIt ooo(oo);
    2.95 -  oo=G.first(o,n);
    2.96 -  oo=G.next(o);
    2.97 +  {
    2.98 +    typedef SymSmartGraph Graph;
    2.99 +    typedef Graph::Edge Edge;
   2.100 +    typedef Graph::InEdgeIt InEdgeIt;
   2.101 +    typedef Graph::OutEdgeIt OutEdgeIt;
   2.102 +    typedef Graph::EdgeIt EdgeIt;
   2.103 +    typedef Graph::Node Node;
   2.104 +    typedef Graph::NodeIt NodeIt;
   2.105 +
   2.106 +    Graph G;
   2.107 +
   2.108 +    for(int i=0;i<10;i++) G.addNode();
   2.109 +    for(NodeIt i(G);G.valid(i);G.next(i)) 
   2.110 +      for(NodeIt j(G);G.valid(j);G.next(j)) 
   2.111 +	if(i<j) G.addEdge(i,j);           //The iterators are comparable
   2.112    
   2.113 -  EdgeIt ei(INVALID), eie;
   2.114 -  EdgeIt eiee(ei);
   2.115 -  eie=G.first(ei);
   2.116 -  eie=G.next(ei);
   2.117 -
   2.118 -  Edge eee(i);
   2.119 -  eee=o;
   2.120 -  eee=eie;
   2.121 -  
   2.122 -  
   2.123 -  bool tm;
   2.124 -  tm = G.valid(n) && G.valid(i) && G.valid(o) && G.valid(ei);
   2.125 -
   2.126 -  std::vector<InEdgeIt> v(10);
   2.127 -  std::vector<InEdgeIt> w(10,INVALID);
   2.128 +    Graph::EdgeMap<int> em(G);
   2.129 +    Graph::SymEdgeMap<int> sm(G);
   2.130 +    for(EdgeIt e(G);G.valid(e);G.next(e)) em[e]=G.id(e);
   2.131 +    for(EdgeIt e(G);G.valid(e);G.next(e))
   2.132 +      if(G.tail(e)<G.head(e)) sm[e]=G.id(e);
   2.133 +    
   2.134 +    for(EdgeIt e(G);G.valid(e);G.next(e))
   2.135 +      std::cout << G.id(G.tail(e)) << "->" << G.id(G.head(e))
   2.136 +		<< ": id=" << G.id(e) << " oppid=" << G.id(G.opposite(e))
   2.137 +		<< " em=" << em[e]
   2.138 +		<< " sm=" << sm[e] << "\n";
   2.139 +    
   2.140 +  }
   2.141    
   2.142  }