COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/map_registry.h @ 942:75fdd0c6866d

Last change on this file since 942:75fdd0c6866d was 937:d4e911acef3d, checked in by Balazs Dezso, 20 years ago

Revert backport changes -r1230.

File size: 8.6 KB
Line 
1/* -*- C++ -*-
2 * src/lemon/map_registry.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
6 *
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
10 *
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
13 * purpose.
14 *
15 */
16
17#ifndef LEMON_MAP_REGISTRY_H
18#define LEMON_MAP_REGISTRY_H
19
20#include <vector>
21
22///\ingroup graphmapfactory
23///\file
24///\brief Map registry for graph maps.
25
26using namespace std;
27
28namespace lemon {
29
30  /// \addtogroup graphmapfactory
31  /// @{
32
33  /// Map registry for graph maps.
34
35  /**
36   * Registry class to register edge or node maps into the graph. The
37   * registry helps you to implement an observer pattern. If you add
38   * or erase an edge or node you must notify all the maps about the
39   * event.
40   *
41   * \param G The graph type to register maps.
42   * \param K The key type of the maps registered into the registry.
43   * \param KIt The key iterator type iterates on the keys.
44   *
45   * \author Balazs Dezso
46   */
47
48  template <typename G, typename K, typename KIt>
49  class MapRegistry {
50  public:
51    typedef G Graph;
52    typedef K KeyType;
53    typedef KIt KeyIt;
54
55    /// MapBase is the base class of the dynamic maps.
56       
57    /**
58     * MapBase is the base class of the dynamic maps.
59     * It defines the core modification operations on the maps and
60     * implements some helper functions.
61     */
62    class MapBase {
63    public:
64      typedef G Graph;
65      typedef K KeyType;
66      typedef KIt KeyIt;
67
68      typedef MapRegistry<G, K, KIt> Registry;
69       
70      friend class MapRegistry<G, K, KIt>;
71
72      /// Default constructor.
73
74      /**
75       * Default constructor for MapBase.
76       */
77
78      MapBase() : graph(0), registry(0) {}
79
80      /// Constructor to register map into a graph registry.
81               
82      /**
83       * Simple constructor to register dynamic map into a graph registry.
84      */
85       
86      MapBase(const Graph& g, Registry& r) : graph(&g), registry(0) {
87        r.attach(*this);
88      }
89
90      /// Copy constructor.
91
92      /**
93       * Copy constructor to register into the registry.
94       * If the copiable map is registered into a registry
95       * the construated map will be registered to the same registry.
96      */       
97       
98      MapBase(const MapBase& copy) : graph(copy.graph), registry(0) {
99        if (copy.registry) {
100          copy.registry->attach(*this);
101        }
102      }
103
104      /// Assign operator.
105       
106      /**
107       * Assign operator. This member detach first the map
108       * from the current registry and then it attach to the
109       * copiable map's registry if it exists.
110      */       
111      const MapBase& operator=(const MapBase& copy) {
112        if (registry) {
113          registry->detach(*this);
114        }
115        graph = copy.graph;
116        if (copy.registry) {
117          copy.registry->attach(*this);
118        }
119        return *this;
120      }
121       
122      /// Destructor
123
124      /**
125       * This member detach the map from the its registry if the
126       * registry exists.
127      */               
128
129      virtual ~MapBase() {
130        if (registry) {
131          registry->detach(*this);
132        }
133      }
134
135      /// The graph of the map.
136
137      /*
138       * Returns the graph that the map belongs to.
139      */
140
141      const Graph* getGraph() const { return graph; }
142       
143    protected:
144               
145      const Graph* graph;     
146      Registry* registry;
147
148      int registry_index;
149
150    protected:
151
152      /// Helper function to implement constructors in the subclasses.
153       
154      /**
155       * Helper function to implement constructors in the subclasses.
156       * It adds all of the nodes or edges to the map via the
157       * \ref MapRegistry::MapBase::add add
158       * member function.
159      */
160       
161      virtual void init() {
162        for (KeyIt it(*graph); it != INVALID; ++it) {
163          add(it);
164        }
165      }
166       
167
168      /// Helper function to implement destructors in the subclasses.
169       
170      /**
171       * Helper function to implement destructors in the subclasses.
172       * It erases all of the nodes or edges of the map via the
173       * \ref MapRegistry::MapBase::erase erase
174       * member function. It can be used by the clear function also.
175      */
176       
177      virtual void destroy() {
178        for (KeyIt it(*getGraph()); it != INVALID; ++it) {
179          erase(it);
180        }
181      }
182
183      /// The member function to add new node or edge to the map.
184       
185      /**
186          The add member function should be overloaded in the subclasses.
187          \e Add extends the map with the new node or edge.
188      */
189       
190      virtual void add(const KeyType&) = 0;     
191
192
193      /// The member function to erase a node or edge from the map.
194
195      /**
196          The erase member function should be overloaded in the subclasses.
197          \e Erase removes the node or edge from the map.
198      */
199       
200      virtual void erase(const KeyType&) = 0;
201
202      /**
203       *  The clear member function should be overloaded in the subclasses.
204       *  \e Clear makes empty the data structure.
205       */
206
207      virtual void clear() = 0;
208
209      /// Exception class to throw at unsupported operation.
210       
211      /**
212       * Exception class to throw at unsupported operation.
213       * If the map does not support erasing or adding new
214       * node or key it must be throwed.
215      */
216       
217      class NotSupportedOperationException {};
218
219    };
220       
221  protected:
222       
223
224    typedef std::vector<MapBase*> Container;
225
226    Container container;
227
228               
229  public:
230
231    /// Default constructor.
232       
233    /**
234     * Default constructor of the \e MapRegistry.
235     * It creates an empty registry.
236     */
237    MapRegistry() {}
238
239    /// Copy Constructor of the MapRegistry.
240       
241    /**
242     * Copy constructor of the \e MapRegistry.
243     * The new registry does not steal
244     * the maps from the copiable registry.
245     * The new registry will be empty.
246     */
247    MapRegistry(const MapRegistry&) {}
248
249    /// Assign operator.
250               
251    /**
252     * Assign operator. This registry does not steal the maps
253     * from the copiable registry. This registry will be an empty registry.
254     * This operator will be called when a graph is assigned.
255     */
256    MapRegistry& operator=(const MapRegistry&) {
257      typename Container::iterator it;
258      for (it = container.begin(); it != container.end(); ++it) {
259        (*it)->clear();
260        (*it)->graph = 0;
261        (*it)->registry = 0;
262      }
263    }
264
265    /// Destructor.
266                               
267    /**
268     * Destructor of the MapRegistry. It makes empty the attached map
269     * first then detachs them.
270     */
271    ~MapRegistry() {
272      typename Container::iterator it;
273      for (it = container.begin(); it != container.end(); ++it) {
274        (*it)->clear();
275        (*it)->registry = 0;
276        (*it)->graph = 0;
277      }
278    }
279       
280       
281    public:
282
283    /// Attachs a map to the \e MapRegistry.
284       
285    /**
286     * Attachs a map into thr registry. If the map has been attached
287     * into an other registry it is detached from that automaticly.
288     */
289    void attach(MapBase& map) {
290      if (map.registry) {
291        map.registry->detach(map);
292      }
293      container.push_back(&map);
294      map.registry = this;
295      map.registry_index = container.size()-1;
296    }
297
298    /// Detachs a map from the \e MapRegistry.
299       
300    /**
301     * Detachs a map from the \e MapRegistry.
302     */
303    void detach(MapBase& map) {
304      container.back()->registry_index = map.registry_index;
305      container[map.registry_index] = container.back();
306      container.pop_back();
307      map.registry = 0;
308      map.graph = 0;
309    }
310       
311    /// Notify all the registered maps about a Key added.
312               
313    /**
314     * Notify all the registered maps about a Key added.
315     * This member should be called whenever a node or edge
316     * is added to the graph.
317     */
318    void add(const KeyType& key) {
319      typename Container::iterator it;
320      for (it = container.begin(); it != container.end(); ++it) {
321        (*it)->add(key);
322      }
323    }   
324
325    /// Notify all the registered maps about a Key erased.
326               
327    /**
328     * Notify all the registered maps about a Key erased.
329     * This member should be called whenever a node or edge
330     * is erased from the graph.
331     */
332    void erase(const KeyType& key) {
333      typename Container::iterator it;
334      for (it = container.begin(); it != container.end(); ++it) {
335        (*it)->erase(key);
336      }
337    }
338
339
340    /// Notify all the registered maps about all the Keys are erased.
341
342    /**
343     * Notify all the registered maps about the map should be cleared.
344     * This member should be called whenever all of the nodes or edges
345     * are erased from the graph.
346     */
347    void clear() {
348      typename Container::iterator it;
349      for (it = container.begin(); it != container.end(); ++it) {
350        (*it)->clear();
351      }
352    }
353  };
354
355 
356/// @}
357 
358
359}
360
361#endif
Note: See TracBrowser for help on using the repository browser.