COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/map_registry.h @ 932:ade3cdb9b45d

Last change on this file since 932:ade3cdb9b45d was 921:818510fa3d99, checked in by Alpar Juttner, 16 years ago

hugo -> lemon

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