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