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