src/work/deba/map_registry.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000
changeset 822 88226d9fe821
parent 701 c03e073b8394
child 921 818510fa3d99
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

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