COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/deba/map_registry.h @ 959:c80ef5912903

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

hugo -> lemon

File size: 5.1 KB
RevLine 
[378]1#ifndef MAP_REGISTRY_H
2#define MAP_REGISTRY_H
3
4#include <vector>
5
[595]6using namespace std;
7
[921]8namespace lemon {
[676]9
[627]10/**
[701]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.
[627]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;
[378]22       
[627]23
24
[701]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     */
[627]30    class MapBase {
31    public:
32      typedef G Graph;
33      typedef MapRegistry<G, K, KIt> Registry;
34      typedef K Key;
35      typedef KIt KeyIt;
[378]36       
[627]37      friend class Registry;
[701]38
39      /**
40       * Default constructor for MapBase.
41       */
42
43      MapBase() : graph(0), registry(0) {}
[627]44               
45      /**
[701]46       * Simple constructor to register into a graph registry.
[627]47      */
[378]48       
[701]49      MapBase(const Graph& g, Registry& r) : graph(&g), registry(0) {
[627]50        r.attach(*this);
51      }
52
53      /**
[701]54       * Copy constructor to register into the registry.
[627]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      /**
[701]64       * Assign operator.
[627]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      /**
[701]79       * Destructor.
[627]80      */               
81
82      virtual ~MapBase() {
83        if (registry) {
84          registry->detach(*this);
85        }
86      }
[701]87
88      /*
89       * Returns the graph that the map belongs to.
90      */
91
92      const Graph* getGraph() const { return graph; }
[627]93       
[703]94    protected:
[627]95               
[703]96      const Graph* graph;     
[627]97      Registry* registry;
98
99      int registry_index;
[701]100
101    protected:
[627]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() {
[701]118        for (KeyIt it(*getGraph()); getGraph()->valid(it); getGraph()->next(it)) {
[627]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       
[701]146    /**
147     * The container type of the maps.
148     */
[627]149    typedef std::vector<MapBase*> Container;
[701]150
151    /**
152     * The container of the registered maps.
153     */
[627]154    Container container;
[378]155
156               
[701]157  public:
[378]158       
[701]159    /**
160     * Default Constructor of the MapRegistry. It creates an empty registry.
161     */
[627]162    MapRegistry() {}
[571]163       
[701]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     */
[627]168    MapRegistry(const MapRegistry&) {}
[571]169               
[701]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     */
[627]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    }
[378]181                               
[701]182    /**
183     * Destructor of the MapRegistry.
184     */
[627]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    }
[378]193       
194       
[627]195    public:
[378]196       
[701]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     */
[627]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    }
[378]209       
[701]210    /**
211     * Detach the map from the registry.
212     */
[627]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    }
[378]220       
221               
[701]222    /**
223     * Notify all the registered maps about a Key added.
224     */
[627]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    }   
[378]231               
[701]232    /**
233     * Notify all the registered maps about a Key erased.
234     */
[627]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    }
[378]241
[627]242  };
[378]243
244}
245
246#endif
Note: See TracBrowser for help on using the repository browser.