src/hugo/map_registry.h
author deba
Thu, 02 Sep 2004 10:07:30 +0000
changeset 782 df2e45e09652
child 783 81bf2d766164
permissions -rw-r--r--
--This line, and those below, will be ignored--

A hugo/sym_map_factory.h
M hugo/list_graph.h
A hugo/array_map_factory.h
A hugo/map_registry.h
M hugo/smart_graph.h
A hugo/map_defines.h
A hugo/extended_pair.h
M hugo/full_graph.h
A hugo/vector_map_factory.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@782
    59
      MapBase(const MapBase& copy) : registry(0), graph(copy.graph) {
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@782
    77
      }
deba@782
    78
	
deba@782
    79
deba@782
    80
      /** 
deba@782
    81
       * Destructor. 
deba@782
    82
      */		
deba@782
    83
deba@782
    84
      virtual ~MapBase() {
deba@782
    85
	if (registry) {
deba@782
    86
	  registry->detach(*this);
deba@782
    87
	}
deba@782
    88
      }
deba@782
    89
deba@782
    90
      /*
deba@782
    91
       * Returns the graph that the map belongs to.
deba@782
    92
      */
deba@782
    93
deba@782
    94
      const Graph* getGraph() const { return graph; }
deba@782
    95
	
deba@782
    96
    protected:
deba@782
    97
		
deba@782
    98
      const Graph* graph;     
deba@782
    99
      Registry* registry;
deba@782
   100
deba@782
   101
      int registry_index;
deba@782
   102
deba@782
   103
    protected:
deba@782
   104
	
deba@782
   105
      /**
deba@782
   106
	 Helper function to implement constructors in the subclasses.
deba@782
   107
      */
deba@782
   108
	
deba@782
   109
      virtual void init() {
deba@782
   110
	for (KeyIt it(*graph); it != INVALID; ++it) {
deba@782
   111
	  add(it);
deba@782
   112
	}
deba@782
   113
      }
deba@782
   114
	
deba@782
   115
      /**
deba@782
   116
	 Helper function to implement the destructor in the subclasses.
deba@782
   117
      */
deba@782
   118
	
deba@782
   119
      virtual void destroy() {
deba@782
   120
	for (KeyIt it(*getGraph()); it != INVALID; ++it) {
deba@782
   121
	  erase(it);
deba@782
   122
	}
deba@782
   123
      }
deba@782
   124
	
deba@782
   125
      /** 
deba@782
   126
	  The add member function should be overloaded in the subclasses.
deba@782
   127
	  \e Add extends the map with the new node.
deba@782
   128
      */
deba@782
   129
	
deba@782
   130
      virtual void add(const Key&) = 0;	
deba@782
   131
      /** 
deba@782
   132
	  The erase member function should be overloaded in the subclasses.
deba@782
   133
	  \e Erase removes the node from the map.
deba@782
   134
      */
deba@782
   135
	
deba@782
   136
      virtual void erase(const Key&) = 0;
deba@782
   137
deba@782
   138
      /**
deba@782
   139
       *  The clear member function should be overloaded in the subclasses.
deba@782
   140
       *  \e Clear makes empty the data structure.
deba@782
   141
       */
deba@782
   142
deba@782
   143
      virtual void clear() = 0;
deba@782
   144
	
deba@782
   145
      /**
deba@782
   146
	 Exception class to throw at unsupported operation.
deba@782
   147
      */
deba@782
   148
	
deba@782
   149
      class NotSupportedOperationException {};
deba@782
   150
deba@782
   151
    };
deba@782
   152
	
deba@782
   153
  protected:
deba@782
   154
	
deba@782
   155
    /** 
deba@782
   156
     * The container type of the maps.
deba@782
   157
     */
deba@782
   158
    typedef std::vector<MapBase*> Container; 
deba@782
   159
deba@782
   160
    /**
deba@782
   161
     * The container of the registered maps.
deba@782
   162
     */
deba@782
   163
    Container container;
deba@782
   164
deba@782
   165
		
deba@782
   166
  public:
deba@782
   167
	
deba@782
   168
    /**
deba@782
   169
     * Default Constructor of the MapRegistry. It creates an empty registry.
deba@782
   170
     */
deba@782
   171
    MapRegistry() {}
deba@782
   172
	
deba@782
   173
    /**
deba@782
   174
     * Copy Constructor of the MapRegistry. The new registry does not steal
deba@782
   175
     * the maps from the right value. The new registry will be an empty.
deba@782
   176
     */
deba@782
   177
    MapRegistry(const MapRegistry&) {}
deba@782
   178
		
deba@782
   179
    /**
deba@782
   180
     * Assign operator. The left value does not steal the maps 
deba@782
   181
     * from the right value. The left value will be an empty registry.
deba@782
   182
     */
deba@782
   183
    MapRegistry& operator=(const MapRegistry&) {
deba@782
   184
      typename Container::iterator it;
deba@782
   185
      for (it = container.begin(); it != container.end(); ++it) {
deba@782
   186
	(*it)->destroy();
deba@782
   187
	(*it)->graph = 0;
deba@782
   188
	(*it)->registry = 0;
deba@782
   189
      }
deba@782
   190
    }
deba@782
   191
				
deba@782
   192
    /**
deba@782
   193
     * Destructor of the MapRegistry.
deba@782
   194
     */
deba@782
   195
    ~MapRegistry() {
deba@782
   196
      typename Container::iterator it;
deba@782
   197
      for (it = container.begin(); it != container.end(); ++it) {
deba@782
   198
	(*it)->destroy();
deba@782
   199
	(*it)->registry = 0;
deba@782
   200
	(*it)->graph = 0;
deba@782
   201
      }
deba@782
   202
    }
deba@782
   203
	
deba@782
   204
	
deba@782
   205
    public:
deba@782
   206
	
deba@782
   207
    /**
deba@782
   208
     * Attach a map into thr registry. If the map has been attached
deba@782
   209
     * into an other registry it is detached from that automaticly.
deba@782
   210
     */
deba@782
   211
    void attach(MapBase& map) {
deba@782
   212
      if (map.registry) {
deba@782
   213
	map.registry->detach(map);
deba@782
   214
      }
deba@782
   215
      container.push_back(&map);
deba@782
   216
      map.registry = this;
deba@782
   217
      map.registry_index = container.size()-1;
deba@782
   218
    } 
deba@782
   219
	
deba@782
   220
    /**
deba@782
   221
     * Detach the map from the registry.
deba@782
   222
     */
deba@782
   223
    void detach(MapBase& map) {
deba@782
   224
      container.back()->registry_index = map.registry_index; 
deba@782
   225
      container[map.registry_index] = container.back();
deba@782
   226
      container.pop_back();
deba@782
   227
      map.registry = 0;
deba@782
   228
      map.graph = 0;
deba@782
   229
    }
deba@782
   230
	
deba@782
   231
		
deba@782
   232
    /**
deba@782
   233
     * Notify all the registered maps about a Key added.
deba@782
   234
     */
deba@782
   235
    virtual void add(Key& key) {
deba@782
   236
      typename Container::iterator it;
deba@782
   237
      for (it = container.begin(); it != container.end(); ++it) {
deba@782
   238
	(*it)->add(key);
deba@782
   239
      }
deba@782
   240
    }	
deba@782
   241
		
deba@782
   242
    /**
deba@782
   243
     * Notify all the registered maps about a Key erased.
deba@782
   244
     */ 
deba@782
   245
    virtual void erase(Key& key) {
deba@782
   246
      typename Container::iterator it;
deba@782
   247
      for (it = container.begin(); it != container.end(); ++it) {
deba@782
   248
	(*it)->erase(key);
deba@782
   249
      }
deba@782
   250
    }
deba@782
   251
deba@782
   252
    /**
deba@782
   253
     * Notify all the registered maps about the map should be cleared.
deba@782
   254
     */ 
deba@782
   255
    virtual void clear() {
deba@782
   256
      typename Container::iterator it;
deba@782
   257
      for (it = container.begin(); it != container.end(); ++it) {
deba@782
   258
	(*it)->clear();
deba@782
   259
      }
deba@782
   260
    }
deba@782
   261
  };
deba@782
   262
deba@782
   263
}
deba@782
   264
deba@782
   265
#endif