Index: src/work/alpar/smart_graph.h
===================================================================
--- src/work/alpar/smart_graph.h	(revision 177)
+++ src/work/alpar/smart_graph.h	(revision 185)
@@ -1,6 +1,6 @@
 // -*- mode:C++ -*-
 
-#ifndef SMART_GRAPH_H
-#define SMART_GRAPH_H
+#ifndef HUGO_SMART_GRAPH_H
+#define HUGO_SMART_GRAPH_H
 
 #include <vector>
@@ -11,4 +11,8 @@
 namespace hugo {
 
+  class SymSmartGraph;
+
+  //  template<typename T> class SymSmartGraph::SymEdgeMap;
+  
   class SmartGraph {
 
@@ -29,8 +33,10 @@
     std::vector<EdgeT> edges;
     
+    protected:
+    
     template <typename Key> class DynMapBase
     {
     protected:
-      SmartGraph* G; 
+      const SmartGraph* G; 
     public:
       virtual void add(const Key k) = NULL;
@@ -40,13 +46,20 @@
       friend class SmartGraph;
     };
+    
   public:
-    template <typename T> class DynEdgeMap;
-    template <typename T> class DynEdgeMap;
+    template <typename T> class EdgeMap;
+    template <typename T> class EdgeMap;
 
     class Node;
     class Edge;
 
-  protected:
+    //  protected:
+    // HELPME:
+  public:
+    ///\bug It must be public because of SymEdgeMap.
+    ///
     mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
+    ///\bug It must be public because of SymEdgeMap.
+    ///
     mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
     
@@ -169,5 +182,4 @@
       friend class SmartGraph;
       template <typename T> friend class NodeMap;
-      template <typename T> friend class DynNodeMap;
       
       friend class Edge;
@@ -198,5 +210,7 @@
       friend class SmartGraph;
       template <typename T> friend class EdgeMap;
-      template <typename T> friend class DynEdgeMap;
+
+      //template <typename T> friend class SymSmartGraph::SymEdgeMap;      
+      //friend Edge SymSmartGraph::opposite(Edge) const;
       
       friend class Node;
@@ -213,4 +227,8 @@
       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 SymSmartGraph::SymEdgeMap friend of Edge
+      int &idref() {return n;}
+      const int &idref() const {return n;}
     };
     
@@ -221,4 +239,7 @@
       EdgeIt (Invalid i) : Edge(i) { }
       EdgeIt() : Edge() { }
+      ///\bug This is a workaround until somebody tells me how to
+      ///make class \c SymSmartGraph::SymEdgeMap friend of Edge
+      int &idref() {return n;}
     };
     
@@ -243,56 +264,81 @@
     // Map types
 
-    template <typename T>
-    class NodeMap {
-      const SmartGraph& G; 
+//     // Static Maps are not necessary.
+//     template <typename T>
+//     class NodeMap {
+//       const SmartGraph& G; 
+//       std::vector<T> container;
+//     public:
+//       typedef T ValueType;
+//       typedef Node KeyType;
+//       NodeMap(const SmartGraph& _G) : G(_G), container(G.maxNodeId()) { }
+//       NodeMap(const SmartGraph& _G, T a) : 
+// 	G(_G), container(G.maxNodeId(), a) { }
+//       void set(Node n, T a) { container[n.n]=a; }
+//       T get(Node n) const { return container[n.n]; }
+//       T& operator[](Node n) { return container[n.n]; }
+//       const T& operator[](Node n) const { return container[n.n]; }
+//       void update() { container.resize(G.maxNodeId()); }
+//       void update(T a) { container.resize(G.maxNodeId(), a); }
+//     };
+
+//     template <typename T>
+//     class EdgeMap {
+//       const SmartGraph& G; 
+//       std::vector<T> container;
+//     public:
+//       typedef T ValueType;
+//       typedef Edge KeyType;
+//       EdgeMap(const SmartGraph& _G) : G(_G), container(G.maxEdgeId()) { }
+//       EdgeMap(const SmartGraph& _G, T a) : 
+// 	G(_G), container(G.maxEdgeId(), a) { }
+//       void set(Edge e, T a) { container[e.n]=a; }
+//       T get(Edge e) const { return container[e.n]; }
+//       T& operator[](Edge e) { return container[e.n]; } 
+//       const T& operator[](Edge e) const { return container[e.n]; } 
+//       void update() { container.resize(G.maxEdgeId()); }
+//       void update(T a) { container.resize(G.maxEdgeId(), a); }
+//     };
+
+    template <typename T> class NodeMap : public DynMapBase<Node>
+    {
       std::vector<T> container;
+
     public:
       typedef T ValueType;
       typedef Node KeyType;
-      NodeMap(const SmartGraph& _G) : G(_G), container(G.maxNodeId()) { }
-      NodeMap(const SmartGraph& _G, T a) : 
-	G(_G), container(G.maxNodeId(), a) { }
-      void set(Node n, T a) { container[n.n]=a; }
-      T get(Node n) const { return container[n.n]; }
-      T& operator[](Node n) { return container[n.n]; }
-      const T& operator[](Node n) const { return container[n.n]; }
-      void update() { container.resize(G.maxNodeId()); }
-      void update(T a) { container.resize(G.maxNodeId(), a); }
-    };
-
-    template <typename T>
-    class EdgeMap {
-      const SmartGraph& G; 
-      std::vector<T> container;
-    public:
-      typedef T ValueType;
-      typedef Edge KeyType;
-      EdgeMap(const SmartGraph& _G) : G(_G), container(G.maxEdgeId()) { }
-      EdgeMap(const SmartGraph& _G, T a) : 
-	G(_G), container(G.maxEdgeId(), a) { }
-      void set(Edge e, T a) { container[e.n]=a; }
-      T get(Edge e) const { return container[e.n]; }
-      T& operator[](Edge e) { return container[e.n]; } 
-      const T& operator[](Edge e) const { return container[e.n]; } 
-      void update() { container.resize(G.maxEdgeId()); }
-      void update(T a) { container.resize(G.maxEdgeId(), a); }
-    };
-
-    template <typename T> class DynNodeMap : public DynMapBase<Node>
-    {
-      std::vector<T> container;
-
-    public:
-      typedef T ValueType;
-      typedef Node KeyType;
-
-      DynNodeMap(const SmartGraph &_G) :
+
+      NodeMap(const SmartGraph &_G) :
 	DynMapBase<Node>(_G), container(_G.maxNodeId())
       {
-	//FIXME: What if there are empty Id's?
-	//FIXME: Can I use 'this' in a constructor?
 	G->dyn_node_maps.push_back(this);
       }
-      ~DynNodeMap()
+      NodeMap(const SmartGraph &_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) {
@@ -311,15 +357,8 @@
       void add(const Node k) 
       {
-	if(k.n>=container.size()) container.resize(k.n+1);
-      }
-
-//       void erase(const Node k)
-//       {
-// 	//FIXME: Please implement me.
-//       }
-//       void erase(const Edge k)
-//       {
-// 	//FIXME: Please implement me.
-//       }
+	if(k.n>=int(container.size())) container.resize(k.n+1);
+      }
+
+      void erase(const Node k) { }
       
       void set(Node n, T a) { container[n.n]=a; }
@@ -328,9 +367,26 @@
       const T& 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 DynMaps
       void update(T a) {}  //Useless for DynMaps
     };
     
-    template <typename T> class DynEdgeMap : public DynMapBase<Edge>
+    template <typename T> class EdgeMap : public DynMapBase<Edge>
     {
       std::vector<T> container;
@@ -340,5 +396,5 @@
       typedef Edge KeyType;
 
-      DynEdgeMap(const SmartGraph &_G) :
+      EdgeMap(const SmartGraph &_G) :
 	DynMapBase<Edge>(_G), container(_G.maxEdgeId())
       {
@@ -347,5 +403,30 @@
 	G->dyn_edge_maps.push_back(this);
       }
-      ~DynEdgeMap()
+      EdgeMap(const SmartGraph &_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) {
@@ -366,8 +447,5 @@
 	if(k.n>=int(container.size())) container.resize(k.n+1);
       }
-      void erase(const Edge k)
-      {
-	//FIXME: Please implement me.
-      }
+      void erase(const Edge k) { }
       
       void set(Edge n, T a) { container[n.n]=a; }
@@ -376,9 +454,149 @@
       const T& 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
     };
-        
+
   };
+
+  ///Graph for bidirectional edges.
+
+  ///The purpose of this graph structure is to handle graphs
+  ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
+  ///of oppositely directed edges. You can define edge maps which
+  ///stores a common value for the edge pairs. The usual edge maps can be used
+  ///as well.
+  ///
+  ///The oppositely directed edge can also be obtained easily.
+
+  class SymSmartGraph : public SmartGraph
+  {
+  public:
+    SymSmartGraph() : SmartGraph() { }
+    SymSmartGraph(const SmartGraph &_g) : SmartGraph(_g) { }
+    Edge addEdge(Node u, Node v)
+    {
+      Edge e = SmartGraph::addEdge(u,v);
+      SmartGraph::addEdge(v,u);
+      return e;
+    }
+
+    Edge opposite(Edge e) const
+    {
+      Edge f;
+      f.idref() = e.idref() - 2*(e.idref()%2) + 1;
+      return f;
+    }
+    
+    template <typename T> class SymEdgeMap : public DynMapBase<Edge>
+    {
+      std::vector<T> container;
+      
+    public:
+      typedef T ValueType;
+      typedef Edge KeyType;
+
+      SymEdgeMap(const SmartGraph &_G) :
+	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2)
+      {
+	G->dyn_edge_maps.push_back(this);
+      }
+      SymEdgeMap(const SmartGraph &_G,const T &t) :
+	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2,t)
+      {
+	G->dyn_edge_maps.push_back(this);
+      }
+
+      SymEdgeMap(const SymEdgeMap<T> &m) :
+ 	DynMapBase<SymEdge>(*m.G), container(m.container)
+      {
+ 	G->dyn_node_maps.push_back(this);
+      }
+
+      //      template<typename TT> friend class SymEdgeMap;
+
+      ///\todo It can copy between different types.
+      ///
+
+      template<typename TT> SymEdgeMap(const SymEdgeMap<TT> &m) :
+	DynMapBase<SymEdge>(*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);
+      }
+ 
+      ~SymEdgeMap()
+      {
+	if(G) {
+	  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.idref()%2&&k.idref()/2>=int(container.size()))
+	  container.resize(k.idref()/2+1);
+      }
+      void erase(const Edge k) { }
+      
+      void set(Edge n, T a) { container[n.idref()/2]=a; }
+      T get(Edge n) const { return container[n.idref()/2]; }
+      T& operator[](Edge n) { return container[n.idref()/2]; }
+      const T& operator[](Edge n) const { return container[n.idref()/2]; }
+
+      ///\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 SymEdgeMap<T>& operator=(const SymEdgeMap<T> &m)
+      {
+	container = m.container;
+	return *this;
+      }
+      template<typename TT>
+      const SymEdgeMap<T>& operator=(const SymEdgeMap<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
 
