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