src/work/deba/map_registry.h
author klao
Sun, 09 Jan 2005 23:44:29 +0000
changeset 1068 e0b0dcee5e17
parent 703 32f280a5ed7d
permissions -rw-r--r--
(none)
     1 #ifndef MAP_REGISTRY_H
     2 #define MAP_REGISTRY_H
     3 
     4 #include <vector>
     5 
     6 using namespace std;
     7 
     8 namespace lemon {
     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