COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/map_registry.h @ 786:d7b3b13b9df6

Last change on this file since 786:d7b3b13b9df6 was 786:d7b3b13b9df6, checked in by Alpar Juttner, 16 years ago

Change 'Key' to 'KeyType?' (possibly temporarily).

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