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