COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/deba/map_registry.h @ 921:818510fa3d99

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

hugo -> lemon

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