src/hugo/map_registry.h
author deba
Mon, 20 Sep 2004 22:57:48 +0000
changeset 891 74589d20dbc3
parent 822 88226d9fe821
child 901 69a8e672acb1
permissions -rw-r--r--
template<typename CMap> Map(const CMap&) like constructors and
assigns are removed.
     1 // -*- c++ -*-
     2 #ifndef MAP_REGISTRY_H
     3 #define MAP_REGISTRY_H
     4 
     5 #include <vector>
     6 
     7 ///\ingroup graphmapfactory
     8 ///\file
     9 ///\brief Map registry for graph maps.
    10 
    11 using namespace std;
    12 
    13 namespace hugo {
    14 
    15 /// \addtogroup graphmapfactory
    16 /// @{
    17 
    18 /** 
    19  * Registry class to register edge or node maps into the graph. The
    20  * registry helps you to implement an observer pattern. If you add
    21  * or erase an edge or node you must notify all the maps about the
    22  * event.
    23 */
    24   template <typename G, typename K, typename KIt>
    25   class MapRegistry {
    26   public:
    27     typedef G Graph;
    28     typedef K KeyType;
    29     typedef KIt KeyIt;
    30 	
    31     /**
    32      * MapBase is the base class of the registered maps.
    33      * It defines the core modification operations on the maps and
    34      * implements some helper functions. 
    35      */
    36     class MapBase {
    37     public:
    38       typedef G Graph;
    39       typedef K KeyType;
    40       typedef KIt KeyIt;
    41 
    42       typedef MapRegistry<G, K, KIt> Registry;
    43 	
    44       friend class MapRegistry<G, K, KIt>;
    45 
    46       /**
    47        * Default constructor for MapBase.
    48        */
    49 
    50       MapBase() : graph(0), registry(0) {}
    51 		
    52       /** 
    53        * Simple constructor to register into a graph registry.
    54       */
    55 	
    56       MapBase(const Graph& g, Registry& r) : graph(&g), registry(0) {
    57 	r.attach(*this);
    58       }
    59 
    60       /** 
    61        * Copy constructor to register into the registry.
    62       */	
    63 	
    64       MapBase(const MapBase& copy) : graph(copy.graph), registry(0) {
    65 	if (copy.registry) {
    66 	  copy.registry->attach(*this);
    67 	}
    68       } 
    69 	
    70       /** 
    71        * Assign operator.
    72       */	
    73       const MapBase& operator=(const MapBase& copy) {
    74 	if (registry) {
    75 	  registry->detach(*this);
    76 	}
    77 	graph = copy.graph;
    78 	if (copy.registry) {
    79 	  copy.registry->attach(*this);
    80 	}
    81 	return *this;
    82       }
    83 	
    84 
    85       /** 
    86        * Destructor. 
    87       */		
    88 
    89       virtual ~MapBase() {
    90 	if (registry) {
    91 	  registry->detach(*this);
    92 	}
    93       }
    94 
    95       /*
    96        * Returns the graph that the map belongs to.
    97       */
    98 
    99       const Graph* getGraph() const { return graph; }
   100 	
   101     protected:
   102 		
   103       const Graph* graph;     
   104       Registry* registry;
   105 
   106       int registry_index;
   107 
   108     protected:
   109 	
   110       /**
   111 	 Helper function to implement constructors in the subclasses.
   112       */
   113 	
   114       virtual void init() {
   115 	for (KeyIt it(*graph); it != INVALID; ++it) {
   116 	  add(it);
   117 	}
   118       }
   119 	
   120       /**
   121 	 Helper function to implement the destructor in the subclasses.
   122       */
   123 	
   124       virtual void destroy() {
   125 	for (KeyIt it(*getGraph()); it != INVALID; ++it) {
   126 	  erase(it);
   127 	}
   128       }
   129 	
   130       /** 
   131 	  The add member function should be overloaded in the subclasses.
   132 	  \e Add extends the map with the new node.
   133       */
   134 	
   135       virtual void add(const KeyType&) = 0;	
   136       /** 
   137 	  The erase member function should be overloaded in the subclasses.
   138 	  \e Erase removes the node from the map.
   139       */
   140 	
   141       virtual void erase(const KeyType&) = 0;
   142 
   143       /**
   144        *  The clear member function should be overloaded in the subclasses.
   145        *  \e Clear makes empty the data structure.
   146        */
   147 
   148       virtual void clear() = 0;
   149 	
   150       /**
   151 	 Exception class to throw at unsupported operation.
   152       */
   153 	
   154       class NotSupportedOperationException {};
   155 
   156     };
   157 	
   158   protected:
   159 	
   160     /** 
   161      * The container type of the maps.
   162      */
   163     typedef std::vector<MapBase*> Container; 
   164 
   165     /**
   166      * The container of the registered maps.
   167      */
   168     Container container;
   169 
   170 		
   171   public:
   172 	
   173     /**
   174      * Default Constructor of the MapRegistry. It creates an empty registry.
   175      */
   176     MapRegistry() {}
   177 	
   178     /**
   179      * Copy Constructor of the MapRegistry. The new registry does not steal
   180      * the maps from the right value. The new registry will be an empty.
   181      */
   182     MapRegistry(const MapRegistry&) {}
   183 		
   184     /**
   185      * Assign operator. The left value does not steal the maps 
   186      * from the right value. The left value will be an empty registry.
   187      */
   188     MapRegistry& operator=(const MapRegistry&) {
   189       typename Container::iterator it;
   190       for (it = container.begin(); it != container.end(); ++it) {
   191 	(*it)->destroy();
   192 	(*it)->graph = 0;
   193 	(*it)->registry = 0;
   194       }
   195     }
   196 				
   197     /**
   198      * Destructor of the MapRegistry.
   199      */
   200     ~MapRegistry() {
   201       typename Container::iterator it;
   202       for (it = container.begin(); it != container.end(); ++it) {
   203 	(*it)->destroy();
   204 	(*it)->registry = 0;
   205 	(*it)->graph = 0;
   206       }
   207     }
   208 	
   209 	
   210     public:
   211 	
   212     /**
   213      * Attach a map into thr registry. If the map has been attached
   214      * into an other registry it is detached from that automaticly.
   215      */
   216     void attach(MapBase& map) {
   217       if (map.registry) {
   218 	map.registry->detach(map);
   219       }
   220       container.push_back(&map);
   221       map.registry = this;
   222       map.registry_index = container.size()-1;
   223     } 
   224 	
   225     /**
   226      * Detach the map from the registry.
   227      */
   228     void detach(MapBase& map) {
   229       container.back()->registry_index = map.registry_index; 
   230       container[map.registry_index] = container.back();
   231       container.pop_back();
   232       map.registry = 0;
   233       map.graph = 0;
   234     }
   235 	
   236 		
   237     /**
   238      * Notify all the registered maps about a Key added.
   239      */
   240     void add(KeyType& key) {
   241       typename Container::iterator it;
   242       for (it = container.begin(); it != container.end(); ++it) {
   243 	(*it)->add(key);
   244       }
   245     }	
   246 		
   247     /**
   248      * Notify all the registered maps about a Key erased.
   249      */ 
   250     void erase(KeyType& key) {
   251       typename Container::iterator it;
   252       for (it = container.begin(); it != container.end(); ++it) {
   253 	(*it)->erase(key);
   254       }
   255     }
   256 
   257     /**
   258      * Notify all the registered maps about the map should be cleared.
   259      */ 
   260     void clear() {
   261       typename Container::iterator it;
   262       for (it = container.begin(); it != container.end(); ++it) {
   263 	(*it)->clear();
   264       }
   265     }
   266   };
   267 
   268   
   269 /// @}
   270   
   271 
   272 }
   273 
   274 #endif