COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/map_registry.h @ 901:69a8e672acb1

Last change on this file since 901:69a8e672acb1 was 901:69a8e672acb1, checked in by marci, 19 years ago

correction of HUGO_... preproc defines.

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