src/work/deba/map_registry.h
author ladanyi
Fri, 28 May 2004 07:48:16 +0000
changeset 666 410a1419e86b
parent 595 e10b5e9419ef
child 676 7ec5e7e6c7b4
permissions -rw-r--r--
Added a short tutorial on using graphs.
     1 #ifndef MAP_REGISTRY_H
     2 #define MAP_REGISTRY_H
     3 
     4 #include <vector>
     5 
     6 using namespace std;
     7 
     8 /** 
     9     Registry class to register edge or node maps in the graph. The
    10     registry helps you to implement an observer pattern. If you add
    11     or erase an edge or node you must notify all the maps about the
    12     event.
    13 */
    14 
    15 namespace hugo {
    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     class MapBase {
    27     public:
    28       typedef G Graph;
    29       typedef MapRegistry<G, K, KIt> Registry;
    30       typedef K Key;
    31       typedef KIt KeyIt;
    32 	
    33       friend class Registry;
    34 		
    35       /** 
    36 	  Default constructor.
    37       */	
    38 		
    39       MapBase() : graph(0), registry(0) {}
    40 
    41       /** 
    42 	  Simple constructor to register into a graph registry.
    43       */
    44 	
    45       MapBase(Graph& g, Registry& r) : graph(&g), registry(0) {
    46 	r.attach(*this);
    47       }
    48 
    49       /** 
    50 	  Copy constructor with registering into the map.
    51       */	
    52 	
    53       MapBase(const MapBase& copy) : registry(0), graph(copy.graph) {
    54 	if (copy.registry) {
    55 	  copy.registry->attach(*this);
    56 	}
    57       } 
    58 	
    59       /** 
    60 	  Assign operator.
    61       */	
    62 
    63       const MapBase& operator=(const MapBase& copy) {
    64 	if (registry) {
    65 	  registry->detach(*this);
    66 	}
    67 	graph = copy.graph;
    68 	if (copy.registry) {
    69 	  copy.registry->attach(*this);
    70 	}
    71       }
    72 	
    73 
    74       /** 
    75 	  Destructor.
    76       */		
    77 
    78       virtual ~MapBase() {
    79 	if (registry) {
    80 	  registry->detach(*this);
    81 	}
    82       }
    83 	
    84     protected:
    85 		
    86       Graph* graph;
    87       Registry* registry;
    88 
    89       int registry_index;
    90 	
    91       /**
    92 	 Helper function to implement constructors in the subclasses.
    93       */
    94 	
    95       virtual void init() {
    96 	for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
    97 	  add(it);
    98 	}
    99       }
   100 	
   101       /**
   102 	 Helper function to implement the destructor in the subclasses.
   103       */
   104 	
   105       virtual void destroy() {
   106 	for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
   107 	  erase(it);
   108 	}
   109       }
   110 	
   111       /** 
   112 	  The add member function should be overloaded in the subclasses.
   113 	  \e Add extends the map with the new node.
   114       */
   115 	
   116       virtual void add(const Key&) = 0;	
   117       /** 
   118 	  The erase member function should be overloaded in the subclasses.
   119 	  \e Erase removes the node from the map.
   120       */
   121 	
   122       virtual void erase(const Key&) = 0;
   123 	
   124       /**
   125 	 Exception class to throw at unsupported operation.
   126       */
   127 	
   128       class NotSupportedOperationException {};
   129 
   130     };
   131 	
   132   protected:
   133 	
   134     typedef std::vector<MapBase*> Container; 
   135     Container container;
   136 
   137 		
   138     public:
   139 	
   140     MapRegistry() {}
   141 	
   142     MapRegistry(const MapRegistry&) {}
   143 		
   144     MapRegistry& operator=(const MapRegistry&) {
   145       for (it = container.begin(); it != container.end(); ++it) {
   146 	(*it)->destroy();
   147 	(*it)->graph = 0;
   148 	(*it)->registry = 0;
   149       }
   150     }
   151 				
   152     ~MapRegistry() {
   153       typename Container::iterator it;
   154       for (it = container.begin(); it != container.end(); ++it) {
   155 	(*it)->destroy();
   156 	(*it)->registry = 0;
   157 	(*it)->graph = 0;
   158       }
   159     }
   160 	
   161 	
   162     public:
   163 	
   164     void attach(MapBase& map) {
   165       if (map.registry) {
   166 	map.registry->detach(map);
   167       }
   168       container.push_back(&map);
   169       map.registry = this;
   170       map.registry_index = container.size()-1;
   171     } 
   172 	
   173     void detach(MapBase& map) {
   174       container.back()->registry_index = map.registry_index; 
   175       container[map.registry_index] = container.back();
   176       container.pop_back();
   177       map.registry = 0;
   178       map.graph = 0;
   179     }
   180 	
   181 		
   182     virtual void add(Key& key) {
   183       typename Container::iterator it;
   184       for (it = container.begin(); it != container.end(); ++it) {
   185 	(*it)->add(key);
   186       }
   187     }	
   188 		
   189     virtual void erase(Key& key) {
   190       typename Container::iterator it;
   191       for (it = container.begin(); it != container.end(); ++it) {
   192 	(*it)->erase(key);
   193       }
   194     }
   195 
   196   };
   197 
   198 }
   199 
   200 #endif