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