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