src/lemon/map_registry.h
author alpar
Mon, 25 Oct 2004 13:29:46 +0000
changeset 945 f2ea4aac9ada
parent 937 d4e911acef3d
permissions -rw-r--r--
Modify to compile with ++-style iterators.
     1 /* -*- C++ -*-
     2  * src/lemon/map_registry.h - Part of LEMON, 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 LEMON_MAP_REGISTRY_H
    18 #define LEMON_MAP_REGISTRY_H
    19 
    20 #include <vector>
    21 
    22 ///\ingroup graphmapfactory
    23 ///\file
    24 ///\brief Map registry for graph maps.
    25 
    26 namespace lemon {
    27 
    28   /// \addtogroup graphmapfactory
    29   /// @{
    30 
    31   /// Map registry for graph maps.
    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    * \param G The graph type to register maps.
    40    * \param K The key type of the maps registered into the registry.
    41    * \param KIt The key iterator type iterates on the keys.
    42    *
    43    * \author Balazs Dezso
    44    */
    45 
    46   template <typename G, typename K, typename KIt>
    47   class MapRegistry {
    48   public:
    49     typedef G Graph;
    50     typedef K KeyType;
    51     typedef KIt KeyIt;
    52 
    53     /// MapBase is the base class of the dynamic maps.
    54 	
    55     /**
    56      * MapBase is the base class of the dynamic maps.
    57      * It defines the core modification operations on the maps and
    58      * implements some helper functions. 
    59      */
    60     class MapBase {
    61     public:
    62       typedef G Graph;
    63       typedef K KeyType;
    64       typedef KIt KeyIt;
    65 
    66       typedef MapRegistry<G, K, KIt> Registry;
    67 	
    68       friend class MapRegistry<G, K, KIt>;
    69 
    70       /// Default constructor.
    71 
    72       /**
    73        * Default constructor for MapBase.
    74        */
    75 
    76       MapBase() : graph(0), registry(0) {}
    77 
    78       /// Constructor to register map into a graph registry.
    79 		
    80       /** 
    81        * Simple constructor to register dynamic map into a graph registry.
    82       */
    83 	
    84       MapBase(const Graph& g, Registry& r) : graph(&g), registry(0) {
    85 	r.attach(*this);
    86       }
    87 
    88       /// Copy constructor.
    89 
    90       /** 
    91        * Copy constructor to register into the registry.
    92        * If the copiable map is registered into a registry
    93        * the construated map will be registered to the same registry.
    94       */	
    95 	
    96       MapBase(const MapBase& copy) : graph(copy.graph), registry(0) {
    97 	if (copy.registry) {
    98 	  copy.registry->attach(*this);
    99 	}
   100       } 
   101 
   102       /// Assign operator.
   103 	
   104       /** 
   105        * Assign operator. This member detach first the map
   106        * from the current registry and then it attach to the
   107        * copiable map's registry if it exists.
   108       */	
   109       const MapBase& operator=(const MapBase& copy) {
   110 	if (registry) {
   111 	  registry->detach(*this);
   112 	}
   113 	graph = copy.graph;
   114 	if (copy.registry) {
   115 	  copy.registry->attach(*this);
   116 	}
   117 	return *this;
   118       }
   119 	
   120       /// Destructor
   121 
   122       /** 
   123        * This member detach the map from the its registry if the
   124        * registry exists.
   125       */		
   126 
   127       virtual ~MapBase() {
   128 	if (registry) {
   129 	  registry->detach(*this);
   130 	}
   131       }
   132 
   133       /// The graph of the map.
   134 
   135       /*
   136        * Returns the graph that the map belongs to.
   137       */
   138 
   139       const Graph* getGraph() const { return graph; }
   140 	
   141     protected:
   142 		
   143       const Graph* graph;     
   144       Registry* registry;
   145 
   146       int registry_index;
   147 
   148     protected:
   149 
   150       /// Helper function to implement constructors in the subclasses.
   151 	
   152       /**
   153        * Helper function to implement constructors in the subclasses.
   154        * It adds all of the nodes or edges to the map via the 
   155        * \ref MapRegistry::MapBase::add add
   156        * member function.
   157       */
   158 	
   159       virtual void init() {
   160 	for (KeyIt it(*graph); it != INVALID; ++it) {
   161 	  add(it);
   162 	}
   163       }
   164 	
   165 
   166       /// Helper function to implement destructors in the subclasses.
   167 	
   168       /**
   169        * Helper function to implement destructors in the subclasses.
   170        * It erases all of the nodes or edges of the map via the 
   171        * \ref MapRegistry::MapBase::erase erase
   172        * member function. It can be used by the clear function also.
   173       */
   174 	
   175       virtual void destroy() {
   176 	for (KeyIt it(*getGraph()); it != INVALID; ++it) {
   177 	  erase(it);
   178 	}
   179       }
   180 
   181       /// The member function to add new node or edge to the map.
   182 	
   183       /** 
   184 	  The add member function should be overloaded in the subclasses.
   185 	  \e Add extends the map with the new node or edge.
   186       */
   187 	
   188       virtual void add(const KeyType&) = 0;	
   189 
   190 
   191       /// The member function to erase a node or edge from the map.
   192 
   193       /** 
   194 	  The erase member function should be overloaded in the subclasses.
   195 	  \e Erase removes the node or edge from the map.
   196       */
   197 	
   198       virtual void erase(const KeyType&) = 0;
   199 
   200       /**
   201        *  The clear member function should be overloaded in the subclasses.
   202        *  \e Clear makes empty the data structure.
   203        */
   204 
   205       virtual void clear() = 0;
   206 
   207       /// Exception class to throw at unsupported operation.
   208 	
   209       /**
   210        * Exception class to throw at unsupported operation.
   211        * If the map does not support erasing or adding new
   212        * node or key it must be throwed.
   213       */
   214 	
   215       class NotSupportedOperationException {};
   216 
   217     };
   218 	
   219   protected:
   220 	
   221 
   222     typedef std::vector<MapBase*> Container; 
   223 
   224     Container container;
   225 
   226 		
   227   public:
   228 
   229     /// Default constructor.
   230 	
   231     /**
   232      * Default constructor of the \e MapRegistry. 
   233      * It creates an empty registry.
   234      */
   235     MapRegistry() {}
   236 
   237     /// Copy Constructor of the MapRegistry. 
   238 	
   239     /**
   240      * Copy constructor of the \e MapRegistry. 
   241      * The new registry does not steal
   242      * the maps from the copiable registry. 
   243      * The new registry will be empty.
   244      */
   245     MapRegistry(const MapRegistry&) {}
   246 
   247     /// Assign operator.
   248 		
   249     /**
   250      * Assign operator. This registry does not steal the maps 
   251      * from the copiable registry. This registry will be an empty registry.
   252      * This operator will be called when a graph is assigned.
   253      */
   254     MapRegistry& operator=(const MapRegistry&) {
   255       typename Container::iterator it;
   256       for (it = container.begin(); it != container.end(); ++it) {
   257 	(*it)->clear();
   258 	(*it)->graph = 0;
   259 	(*it)->registry = 0;
   260       }
   261     }
   262 
   263     /// Destructor.
   264 				
   265     /**
   266      * Destructor of the MapRegistry. It makes empty the attached map
   267      * first then detachs them.
   268      */
   269     ~MapRegistry() {
   270       typename Container::iterator it;
   271       for (it = container.begin(); it != container.end(); ++it) {
   272 	(*it)->clear();
   273 	(*it)->registry = 0;
   274 	(*it)->graph = 0;
   275       }
   276     }
   277 	
   278 	
   279     public:
   280 
   281     /// Attachs a map to the \e MapRegistry.
   282 	
   283     /**
   284      * Attachs a map into thr registry. If the map has been attached
   285      * into an other registry it is detached from that automaticly.
   286      */
   287     void attach(MapBase& map) {
   288       if (map.registry) {
   289 	map.registry->detach(map);
   290       }
   291       container.push_back(&map);
   292       map.registry = this;
   293       map.registry_index = container.size()-1;
   294     } 
   295 
   296     /// Detachs a map from the \e MapRegistry.
   297 	
   298     /**
   299      * Detachs a map from the \e MapRegistry.
   300      */
   301     void detach(MapBase& map) {
   302       container.back()->registry_index = map.registry_index; 
   303       container[map.registry_index] = container.back();
   304       container.pop_back();
   305       map.registry = 0;
   306       map.graph = 0;
   307     }
   308 	
   309     /// Notify all the registered maps about a Key added.
   310 		
   311     /**
   312      * Notify all the registered maps about a Key added.
   313      * This member should be called whenever a node or edge
   314      * is added to the graph.
   315      */
   316     void add(const KeyType& key) {
   317       typename Container::iterator it;
   318       for (it = container.begin(); it != container.end(); ++it) {
   319 	(*it)->add(key);
   320       }
   321     }	
   322 
   323     /// Notify all the registered maps about a Key erased.
   324 		
   325     /**
   326      * Notify all the registered maps about a Key erased.
   327      * This member should be called whenever a node or edge
   328      * is erased from the graph.
   329      */ 
   330     void erase(const KeyType& key) {
   331       typename Container::iterator it;
   332       for (it = container.begin(); it != container.end(); ++it) {
   333 	(*it)->erase(key);
   334       }
   335     }
   336 
   337 
   338     /// Notify all the registered maps about all the Keys are erased.
   339 
   340     /**
   341      * Notify all the registered maps about the map should be cleared.
   342      * This member should be called whenever all of the nodes or edges
   343      * are erased from the graph.
   344      */ 
   345     void clear() {
   346       typename Container::iterator it;
   347       for (it = container.begin(); it != container.end(); ++it) {
   348 	(*it)->clear();
   349       }
   350     }
   351   };
   352 
   353   
   354 /// @}
   355   
   356 
   357 }
   358 
   359 #endif