COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/map_registry.h @ 782:df2e45e09652

Last change on this file since 782:df2e45e09652 was 782:df2e45e09652, checked in by Balazs Dezso, 20 years ago

--This line, and those below, will be ignored--

A hugo/sym_map_factory.h
M hugo/list_graph.h
A hugo/array_map_factory.h
A hugo/map_registry.h
M hugo/smart_graph.h
A hugo/map_defines.h
A hugo/extended_pair.h
M hugo/full_graph.h
A hugo/vector_map_factory.h

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