COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/map_registry.h @ 868:805963ea8654

Last change on this file since 868:805963ea8654 was 822:88226d9fe821, checked in by Balazs Dezso, 20 years ago

The MapFactories? have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

Some macros and comments has been changed.

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