3 |
3 |
4 #include <vector> |
4 #include <vector> |
5 |
5 |
6 using namespace std; |
6 using namespace std; |
7 |
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 */ |
8 |
14 |
9 namespace hugo { |
15 namespace hugo { |
10 template <typename G, typename K, typename KIt> |
16 |
11 class MapRegistry; |
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 |
12 } |
198 } |
13 |
199 |
14 #include "map_base.h" |
|
15 |
|
16 namespace hugo { |
|
17 |
|
18 template <typename G, typename K, typename KIt> |
|
19 class MapRegistry { |
|
20 public: |
|
21 typedef G Graph; |
|
22 typedef K Key; |
|
23 typedef KIt KeyIt; |
|
24 |
|
25 typedef MapBase<Graph, Key, KIt> Map; |
|
26 friend class Base; |
|
27 |
|
28 protected: |
|
29 |
|
30 typedef std::vector<Map*> Container; |
|
31 Container container; |
|
32 |
|
33 |
|
34 public: |
|
35 |
|
36 MapRegistry() {} |
|
37 |
|
38 MapRegistry(const MapRegistry&) {} |
|
39 |
|
40 MapRegistry& operator=(const MapRegistry&) { |
|
41 for (it = container.begin(); it != container.end(); ++it) { |
|
42 (*it)->destroy(); |
|
43 (*it)->graph = 0; |
|
44 (*it)->registry = 0; |
|
45 } |
|
46 } |
|
47 |
|
48 ~MapRegistry() { |
|
49 typename Container::iterator it; |
|
50 for (it = container.begin(); it != container.end(); ++it) { |
|
51 (*it)->destroy(); |
|
52 (*it)->registry = 0; |
|
53 (*it)->graph = 0; |
|
54 } |
|
55 } |
|
56 |
|
57 |
|
58 public: |
|
59 |
|
60 void attach(Map& map) { |
|
61 if (map.registry) { |
|
62 map.registry->detach(map); |
|
63 } |
|
64 container.push_back(&map); |
|
65 map.registry = this; |
|
66 map.registry_index = container.size()-1; |
|
67 } |
|
68 |
|
69 void detach(Map& map) { |
|
70 container.back()->registry_index = map.registry_index; |
|
71 container[map.registry_index] = container.back(); |
|
72 container.pop_back(); |
|
73 map.registry = 0; |
|
74 map.graph = 0; |
|
75 } |
|
76 |
|
77 |
|
78 virtual void add(Key& key) { |
|
79 typename Container::iterator it; |
|
80 for (it = container.begin(); it != container.end(); ++it) { |
|
81 (*it)->add(key); |
|
82 } |
|
83 } |
|
84 |
|
85 virtual void erase(Key& key) { |
|
86 typename Container::iterator it; |
|
87 for (it = container.begin(); it != container.end(); ++it) { |
|
88 (*it)->erase(key); |
|
89 } |
|
90 } |
|
91 |
|
92 }; |
|
93 |
|
94 } |
|
95 |
|
96 #endif |
200 #endif |