COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/map_registry.h @ 941:186aa53d2802

Last change on this file since 941:186aa53d2802 was 937:d4e911acef3d, checked in by Balazs Dezso, 20 years ago

Revert backport changes -r1230.

File size: 8.6 KB
RevLine 
[906]1/* -*- C++ -*-
[921]2 * src/lemon/map_registry.h - Part of LEMON, a generic C++ optimization library
[906]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
[921]17#ifndef LEMON_MAP_REGISTRY_H
18#define LEMON_MAP_REGISTRY_H
[782]19
20#include <vector>
21
[785]22///\ingroup graphmapfactory
23///\file
24///\brief Map registry for graph maps.
25
[782]26using namespace std;
27
[921]28namespace lemon {
[782]29
[937]30  /// \addtogroup graphmapfactory
31  /// @{
[785]32
[937]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
[782]48  template <typename G, typename K, typename KIt>
49  class MapRegistry {
50  public:
51    typedef G Graph;
[786]52    typedef K KeyType;
[782]53    typedef KIt KeyIt;
[937]54
55    /// MapBase is the base class of the dynamic maps.
[782]56       
57    /**
[937]58     * MapBase is the base class of the dynamic maps.
[782]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;
[786]65      typedef K KeyType;
[782]66      typedef KIt KeyIt;
67
68      typedef MapRegistry<G, K, KIt> Registry;
69       
70      friend class MapRegistry<G, K, KIt>;
71
[937]72      /// Default constructor.
73
[782]74      /**
75       * Default constructor for MapBase.
76       */
77
78      MapBase() : graph(0), registry(0) {}
[937]79
80      /// Constructor to register map into a graph registry.
[782]81               
82      /**
[937]83       * Simple constructor to register dynamic map into a graph registry.
[782]84      */
85       
86      MapBase(const Graph& g, Registry& r) : graph(&g), registry(0) {
87        r.attach(*this);
88      }
89
[937]90      /// Copy constructor.
91
[782]92      /**
93       * Copy constructor to register into the registry.
[937]94       * If the copiable map is registered into a registry
95       * the construated map will be registered to the same registry.
[782]96      */       
97       
[783]98      MapBase(const MapBase& copy) : graph(copy.graph), registry(0) {
[782]99        if (copy.registry) {
100          copy.registry->attach(*this);
101        }
102      }
[937]103
104      /// Assign operator.
[782]105       
106      /**
[937]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.
[782]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        }
[783]119        return *this;
[782]120      }
121       
[937]122      /// Destructor
[782]123
124      /**
[937]125       * This member detach the map from the its registry if the
126       * registry exists.
[782]127      */               
128
129      virtual ~MapBase() {
130        if (registry) {
131          registry->detach(*this);
132        }
133      }
134
[937]135      /// The graph of the map.
136
[782]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:
[937]151
152      /// Helper function to implement constructors in the subclasses.
[782]153       
154      /**
[937]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.
[782]159      */
160       
161      virtual void init() {
162        for (KeyIt it(*graph); it != INVALID; ++it) {
163          add(it);
164        }
165      }
166       
[937]167
168      /// Helper function to implement destructors in the subclasses.
169       
[782]170      /**
[937]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.
[782]175      */
176       
177      virtual void destroy() {
178        for (KeyIt it(*getGraph()); it != INVALID; ++it) {
179          erase(it);
180        }
181      }
[937]182
183      /// The member function to add new node or edge to the map.
[782]184       
185      /**
186          The add member function should be overloaded in the subclasses.
[937]187          \e Add extends the map with the new node or edge.
[782]188      */
189       
[786]190      virtual void add(const KeyType&) = 0;     
[937]191
192
193      /// The member function to erase a node or edge from the map.
194
[782]195      /**
196          The erase member function should be overloaded in the subclasses.
[937]197          \e Erase removes the node or edge from the map.
[782]198      */
199       
[786]200      virtual void erase(const KeyType&) = 0;
[782]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;
[937]208
209      /// Exception class to throw at unsupported operation.
[782]210       
211      /**
[937]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.
[782]215      */
216       
217      class NotSupportedOperationException {};
218
219    };
220       
221  protected:
222       
[937]223
[782]224    typedef std::vector<MapBase*> Container;
225
226    Container container;
227
228               
229  public:
[937]230
231    /// Default constructor.
[782]232       
233    /**
[937]234     * Default constructor of the \e MapRegistry.
235     * It creates an empty registry.
[782]236     */
237    MapRegistry() {}
[937]238
239    /// Copy Constructor of the MapRegistry.
[782]240       
241    /**
[937]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.
[782]246     */
247    MapRegistry(const MapRegistry&) {}
[937]248
249    /// Assign operator.
[782]250               
251    /**
[937]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.
[782]255     */
256    MapRegistry& operator=(const MapRegistry&) {
257      typename Container::iterator it;
258      for (it = container.begin(); it != container.end(); ++it) {
[937]259        (*it)->clear();
[782]260        (*it)->graph = 0;
261        (*it)->registry = 0;
262      }
263    }
[937]264
265    /// Destructor.
[782]266                               
267    /**
[937]268     * Destructor of the MapRegistry. It makes empty the attached map
269     * first then detachs them.
[782]270     */
271    ~MapRegistry() {
272      typename Container::iterator it;
273      for (it = container.begin(); it != container.end(); ++it) {
[937]274        (*it)->clear();
[782]275        (*it)->registry = 0;
276        (*it)->graph = 0;
277      }
278    }
279       
280       
281    public:
[937]282
283    /// Attachs a map to the \e MapRegistry.
[782]284       
285    /**
[937]286     * Attachs a map into thr registry. If the map has been attached
[782]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    }
[937]297
298    /// Detachs a map from the \e MapRegistry.
[782]299       
300    /**
[937]301     * Detachs a map from the \e MapRegistry.
[782]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       
[937]311    /// Notify all the registered maps about a Key added.
[782]312               
313    /**
314     * Notify all the registered maps about a Key added.
[937]315     * This member should be called whenever a node or edge
316     * is added to the graph.
[782]317     */
[937]318    void add(const KeyType& key) {
[782]319      typename Container::iterator it;
320      for (it = container.begin(); it != container.end(); ++it) {
321        (*it)->add(key);
322      }
323    }   
[937]324
325    /// Notify all the registered maps about a Key erased.
[782]326               
327    /**
328     * Notify all the registered maps about a Key erased.
[937]329     * This member should be called whenever a node or edge
330     * is erased from the graph.
[782]331     */
[937]332    void erase(const KeyType& key) {
[782]333      typename Container::iterator it;
334      for (it = container.begin(); it != container.end(); ++it) {
335        (*it)->erase(key);
336      }
337    }
338
[937]339
340    /// Notify all the registered maps about all the Keys are erased.
341
[782]342    /**
343     * Notify all the registered maps about the map should be cleared.
[937]344     * This member should be called whenever all of the nodes or edges
345     * are erased from the graph.
[782]346     */
[783]347    void clear() {
[782]348      typename Container::iterator it;
349      for (it = container.begin(); it != container.end(); ++it) {
350        (*it)->clear();
351      }
352    }
353  };
354
[785]355 
356/// @}
357 
358
[782]359}
360
361#endif
Note: See TracBrowser for help on using the repository browser.