src/work/deba/map_registry.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000
changeset 822 88226d9fe821
parent 701 c03e073b8394
child 921 818510fa3d99
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

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