src/hugo/map_registry.h
author klao
Wed, 15 Sep 2004 14:25:44 +0000
changeset 858 acc83957ee4a
parent 786 d7b3b13b9df6
child 891 74589d20dbc3
permissions -rw-r--r--
Handling strings with std::string
Do not segfault if srcdir env. variable is not set.
     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 
    74       const MapBase& operator=(const MapBase& copy) {
    75 	if (registry) {
    76 	  registry->detach(*this);
    77 	}
    78 	graph = copy.graph;
    79 	if (copy.registry) {
    80 	  copy.registry->attach(*this);
    81 	}
    82 	return *this;
    83       }
    84 	
    85 
    86       /** 
    87        * Destructor. 
    88       */		
    89 
    90       virtual ~MapBase() {
    91 	if (registry) {
    92 	  registry->detach(*this);
    93 	}
    94       }
    95 
    96       /*
    97        * Returns the graph that the map belongs to.
    98       */
    99 
   100       const Graph* getGraph() const { return graph; }
   101 	
   102     protected:
   103 		
   104       const Graph* graph;     
   105       Registry* registry;
   106 
   107       int registry_index;
   108 
   109     protected:
   110 	
   111       /**
   112 	 Helper function to implement constructors in the subclasses.
   113       */
   114 	
   115       virtual void init() {
   116 	for (KeyIt it(*graph); it != INVALID; ++it) {
   117 	  add(it);
   118 	}
   119       }
   120 	
   121       /**
   122 	 Helper function to implement the destructor in the subclasses.
   123       */
   124 	
   125       virtual void destroy() {
   126 	for (KeyIt it(*getGraph()); it != INVALID; ++it) {
   127 	  erase(it);
   128 	}
   129       }
   130 	
   131       /** 
   132 	  The add member function should be overloaded in the subclasses.
   133 	  \e Add extends the map with the new node.
   134       */
   135 	
   136       virtual void add(const KeyType&) = 0;	
   137       /** 
   138 	  The erase member function should be overloaded in the subclasses.
   139 	  \e Erase removes the node from the map.
   140       */
   141 	
   142       virtual void erase(const KeyType&) = 0;
   143 
   144       /**
   145        *  The clear member function should be overloaded in the subclasses.
   146        *  \e Clear makes empty the data structure.
   147        */
   148 
   149       virtual void clear() = 0;
   150 	
   151       /**
   152 	 Exception class to throw at unsupported operation.
   153       */
   154 	
   155       class NotSupportedOperationException {};
   156 
   157     };
   158 	
   159   protected:
   160 	
   161     /** 
   162      * The container type of the maps.
   163      */
   164     typedef std::vector<MapBase*> Container; 
   165 
   166     /**
   167      * The container of the registered maps.
   168      */
   169     Container container;
   170 
   171 		
   172   public:
   173 	
   174     /**
   175      * Default Constructor of the MapRegistry. It creates an empty registry.
   176      */
   177     MapRegistry() {}
   178 	
   179     /**
   180      * Copy Constructor of the MapRegistry. The new registry does not steal
   181      * the maps from the right value. The new registry will be an empty.
   182      */
   183     MapRegistry(const MapRegistry&) {}
   184 		
   185     /**
   186      * Assign operator. The left value does not steal the maps 
   187      * from the right value. The left value will be an empty registry.
   188      */
   189     MapRegistry& operator=(const MapRegistry&) {
   190       typename Container::iterator it;
   191       for (it = container.begin(); it != container.end(); ++it) {
   192 	(*it)->destroy();
   193 	(*it)->graph = 0;
   194 	(*it)->registry = 0;
   195       }
   196     }
   197 				
   198     /**
   199      * Destructor of the MapRegistry.
   200      */
   201     ~MapRegistry() {
   202       typename Container::iterator it;
   203       for (it = container.begin(); it != container.end(); ++it) {
   204 	(*it)->destroy();
   205 	(*it)->registry = 0;
   206 	(*it)->graph = 0;
   207       }
   208     }
   209 	
   210 	
   211     public:
   212 	
   213     /**
   214      * Attach a map into thr registry. If the map has been attached
   215      * into an other registry it is detached from that automaticly.
   216      */
   217     void attach(MapBase& map) {
   218       if (map.registry) {
   219 	map.registry->detach(map);
   220       }
   221       container.push_back(&map);
   222       map.registry = this;
   223       map.registry_index = container.size()-1;
   224     } 
   225 	
   226     /**
   227      * Detach the map from the registry.
   228      */
   229     void detach(MapBase& map) {
   230       container.back()->registry_index = map.registry_index; 
   231       container[map.registry_index] = container.back();
   232       container.pop_back();
   233       map.registry = 0;
   234       map.graph = 0;
   235     }
   236 	
   237 		
   238     /**
   239      * Notify all the registered maps about a Key added.
   240      */
   241     void add(KeyType& key) {
   242       typename Container::iterator it;
   243       for (it = container.begin(); it != container.end(); ++it) {
   244 	(*it)->add(key);
   245       }
   246     }	
   247 		
   248     /**
   249      * Notify all the registered maps about a Key erased.
   250      */ 
   251     void erase(KeyType& key) {
   252       typename Container::iterator it;
   253       for (it = container.begin(); it != container.end(); ++it) {
   254 	(*it)->erase(key);
   255       }
   256     }
   257 
   258     /**
   259      * Notify all the registered maps about the map should be cleared.
   260      */ 
   261     void clear() {
   262       typename Container::iterator it;
   263       for (it = container.begin(); it != container.end(); ++it) {
   264 	(*it)->clear();
   265       }
   266     }
   267   };
   268 
   269   
   270 /// @}
   271   
   272 
   273 }
   274 
   275 #endif