COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/deba/map_registry.h @ 627:6cc21a9c9fda

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