COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/deba/map_registry.h @ 676:7ec5e7e6c7b4

Last change on this file since 676:7ec5e7e6c7b4 was 676:7ec5e7e6c7b4, checked in by Alpar Juttner, 16 years ago

c++ setting for emacs
Empty commands for doxygen

File size: 3.9 KB
Line 
1#ifndef MAP_REGISTRY_H
2#define MAP_REGISTRY_H
3
4#include <vector>
5
6using namespace std;
7
8namespace hugo {
9
10/**
11    Registry class to register edge or node maps in 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
27    ///.
28    ///
29    class MapBase {
30    public:
31      typedef G Graph;
32      typedef MapRegistry<G, K, KIt> Registry;
33      typedef K Key;
34      typedef KIt KeyIt;
35       
36      friend class Registry;
37               
38      /**
39          Default constructor.
40      */       
41               
42      MapBase() : graph(0), registry(0) {}
43
44      /**
45          Simple constructor to register into a graph registry.
46      */
47       
48      MapBase(Graph& g, Registry& r) : graph(&g), registry(0) {
49        r.attach(*this);
50      }
51
52      /**
53          Copy constructor with registering into the map.
54      */       
55       
56      MapBase(const MapBase& copy) : registry(0), graph(copy.graph) {
57        if (copy.registry) {
58          copy.registry->attach(*this);
59        }
60      }
61       
62      /**
63          Assign operator.
64      */       
65
66      const MapBase& operator=(const MapBase& copy) {
67        if (registry) {
68          registry->detach(*this);
69        }
70        graph = copy.graph;
71        if (copy.registry) {
72          copy.registry->attach(*this);
73        }
74      }
75       
76
77      /**
78          Destructor.
79      */               
80
81      virtual ~MapBase() {
82        if (registry) {
83          registry->detach(*this);
84        }
85      }
86       
87    protected:
88               
89      Graph* graph;
90      Registry* registry;
91
92      int registry_index;
93       
94      /**
95         Helper function to implement constructors in the subclasses.
96      */
97       
98      virtual void init() {
99        for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
100          add(it);
101        }
102      }
103       
104      /**
105         Helper function to implement the destructor in the subclasses.
106      */
107       
108      virtual void destroy() {
109        for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
110          erase(it);
111        }
112      }
113       
114      /**
115          The add member function should be overloaded in the subclasses.
116          \e Add extends the map with the new node.
117      */
118       
119      virtual void add(const Key&) = 0;
120      /**
121          The erase member function should be overloaded in the subclasses.
122          \e Erase removes the node from the map.
123      */
124       
125      virtual void erase(const Key&) = 0;
126       
127      /**
128         Exception class to throw at unsupported operation.
129      */
130       
131      class NotSupportedOperationException {};
132
133    };
134       
135  protected:
136       
137    typedef std::vector<MapBase*> Container;
138    Container container;
139
140               
141    public:
142       
143    ///.
144    MapRegistry() {}
145       
146    ///.
147    MapRegistry(const MapRegistry&) {}
148               
149    ///.
150    MapRegistry& operator=(const MapRegistry&) {
151      for (it = container.begin(); it != container.end(); ++it) {
152        (*it)->destroy();
153        (*it)->graph = 0;
154        (*it)->registry = 0;
155      }
156    }
157                               
158    ///.
159    ~MapRegistry() {
160      typename Container::iterator it;
161      for (it = container.begin(); it != container.end(); ++it) {
162        (*it)->destroy();
163        (*it)->registry = 0;
164        (*it)->graph = 0;
165      }
166    }
167       
168       
169    public:
170       
171    ///.
172    void attach(MapBase& map) {
173      if (map.registry) {
174        map.registry->detach(map);
175      }
176      container.push_back(&map);
177      map.registry = this;
178      map.registry_index = container.size()-1;
179    }
180       
181    ///.
182    void detach(MapBase& map) {
183      container.back()->registry_index = map.registry_index;
184      container[map.registry_index] = container.back();
185      container.pop_back();
186      map.registry = 0;
187      map.graph = 0;
188    }
189       
190               
191    ///.
192    virtual void add(Key& key) {
193      typename Container::iterator it;
194      for (it = container.begin(); it != container.end(); ++it) {
195        (*it)->add(key);
196      }
197    }   
198               
199    ///.
200    virtual void erase(Key& key) {
201      typename Container::iterator it;
202      for (it = container.begin(); it != container.end(); ++it) {
203        (*it)->erase(key);
204      }
205    }
206
207  };
208
209}
210
211#endif
Note: See TracBrowser for help on using the repository browser.