82 Parent::attach(graph.notifier(Item())); |
82 Parent::attach(graph.notifier(Item())); |
83 allocate_memory(); |
83 allocate_memory(); |
84 Notifier* nf = Parent::notifier(); |
84 Notifier* nf = Parent::notifier(); |
85 Item it; |
85 Item it; |
86 for (nf->first(it); it != INVALID; nf->next(it)) { |
86 for (nf->first(it); it != INVALID; nf->next(it)) { |
87 int id = nf->id(it);; |
87 int id = nf->id(it);; |
88 allocator.construct(&(values[id]), Value()); |
88 allocator.construct(&(values[id]), Value()); |
89 } |
89 } |
90 } |
90 } |
91 |
91 |
92 /// \brief Constructor to use default value to initialize the map. |
92 /// \brief Constructor to use default value to initialize the map. |
93 /// |
93 /// |
94 /// It constructs a map and initialize all of the the map. |
94 /// It constructs a map and initialize all of the the map. |
95 ArrayMap(const Graph& graph, const Value& value) { |
95 ArrayMap(const Graph& graph, const Value& value) { |
96 Parent::attach(graph.notifier(Item())); |
96 Parent::attach(graph.notifier(Item())); |
97 allocate_memory(); |
97 allocate_memory(); |
98 Notifier* nf = Parent::notifier(); |
98 Notifier* nf = Parent::notifier(); |
99 Item it; |
99 Item it; |
100 for (nf->first(it); it != INVALID; nf->next(it)) { |
100 for (nf->first(it); it != INVALID; nf->next(it)) { |
101 int id = nf->id(it);; |
101 int id = nf->id(it);; |
102 allocator.construct(&(values[id]), value); |
102 allocator.construct(&(values[id]), value); |
103 } |
103 } |
104 } |
104 } |
105 |
105 |
106 /// \brief Constructor to copy a map of the same map type. |
106 /// \brief Constructor to copy a map of the same map type. |
107 /// |
107 /// |
108 /// Constructor to copy a map of the same map type. |
108 /// Constructor to copy a map of the same map type. |
109 ArrayMap(const ArrayMap& copy) : Parent() { |
109 ArrayMap(const ArrayMap& copy) : Parent() { |
110 if (copy.attached()) { |
110 if (copy.attached()) { |
111 attach(*copy.notifier()); |
111 attach(*copy.notifier()); |
112 } |
112 } |
113 capacity = copy.capacity; |
113 capacity = copy.capacity; |
114 if (capacity == 0) return; |
114 if (capacity == 0) return; |
115 values = allocator.allocate(capacity); |
115 values = allocator.allocate(capacity); |
116 Notifier* nf = Parent::notifier(); |
116 Notifier* nf = Parent::notifier(); |
117 Item it; |
117 Item it; |
118 for (nf->first(it); it != INVALID; nf->next(it)) { |
118 for (nf->first(it); it != INVALID; nf->next(it)) { |
119 int id = nf->id(it);; |
119 int id = nf->id(it);; |
120 allocator.construct(&(values[id]), copy.values[id]); |
120 allocator.construct(&(values[id]), copy.values[id]); |
121 } |
121 } |
122 } |
122 } |
123 |
123 |
124 /// \brief Assign operator. |
124 /// \brief Assign operator. |
125 /// |
125 /// |
126 /// This operator assigns for each item in the map the |
126 /// This operator assigns for each item in the map the |
127 /// value mapped to the same item in the copied map. |
127 /// value mapped to the same item in the copied map. |
128 /// The parameter map should be indiced with the same |
128 /// The parameter map should be indiced with the same |
129 /// itemset because this assign operator does not change |
129 /// itemset because this assign operator does not change |
130 /// the container of the map. |
130 /// the container of the map. |
131 ArrayMap& operator=(const ArrayMap& cmap) { |
131 ArrayMap& operator=(const ArrayMap& cmap) { |
132 return operator=<ArrayMap>(cmap); |
132 return operator=<ArrayMap>(cmap); |
133 } |
133 } |
134 |
134 |
135 |
135 |
136 /// \brief Template assign operator. |
136 /// \brief Template assign operator. |
137 /// |
137 /// |
138 /// The given parameter should be conform to the ReadMap |
138 /// The given parameter should be conform to the ReadMap |
139 /// concecpt and could be indiced by the current item set of |
139 /// concecpt and could be indiced by the current item set of |
140 /// the NodeMap. In this case the value for each item |
140 /// the NodeMap. In this case the value for each item |
141 /// is assigned by the value of the given ReadMap. |
141 /// is assigned by the value of the given ReadMap. |
142 template <typename CMap> |
142 template <typename CMap> |
143 ArrayMap& operator=(const CMap& cmap) { |
143 ArrayMap& operator=(const CMap& cmap) { |
144 checkConcept<concepts::ReadMap<Key, _Value>, CMap>(); |
144 checkConcept<concepts::ReadMap<Key, _Value>, CMap>(); |
145 const typename Parent::Notifier* nf = Parent::notifier(); |
145 const typename Parent::Notifier* nf = Parent::notifier(); |
146 Item it; |
146 Item it; |
149 } |
149 } |
150 return *this; |
150 return *this; |
151 } |
151 } |
152 |
152 |
153 /// \brief The destructor of the map. |
153 /// \brief The destructor of the map. |
154 /// |
154 /// |
155 /// The destructor of the map. |
155 /// The destructor of the map. |
156 virtual ~ArrayMap() { |
156 virtual ~ArrayMap() { |
157 if (attached()) { |
157 if (attached()) { |
158 clear(); |
158 clear(); |
159 detach(); |
159 detach(); |
160 } |
160 } |
161 } |
161 } |
162 |
162 |
163 protected: |
163 protected: |
164 |
164 |
165 using Parent::attach; |
165 using Parent::attach; |
166 using Parent::detach; |
166 using Parent::detach; |
167 using Parent::attached; |
167 using Parent::attached; |
168 |
168 |
169 public: |
169 public: |
170 |
170 |
171 /// \brief The subscript operator. |
171 /// \brief The subscript operator. |
172 /// |
172 /// |
173 /// The subscript operator. The map can be subscripted by the |
173 /// The subscript operator. The map can be subscripted by the |
174 /// actual keys of the graph. |
174 /// actual keys of the graph. |
175 Value& operator[](const Key& key) { |
175 Value& operator[](const Key& key) { |
176 int id = Parent::notifier()->id(key); |
176 int id = Parent::notifier()->id(key); |
177 return values[id]; |
177 return values[id]; |
178 } |
178 } |
179 |
179 |
180 /// \brief The const subscript operator. |
180 /// \brief The const subscript operator. |
181 /// |
181 /// |
182 /// The const subscript operator. The map can be subscripted by the |
182 /// The const subscript operator. The map can be subscripted by the |
183 /// actual keys of the graph. |
183 /// actual keys of the graph. |
184 const Value& operator[](const Key& key) const { |
184 const Value& operator[](const Key& key) const { |
185 int id = Parent::notifier()->id(key); |
185 int id = Parent::notifier()->id(key); |
186 return values[id]; |
186 return values[id]; |
187 } |
187 } |
188 |
188 |
189 /// \brief Setter function of the map. |
189 /// \brief Setter function of the map. |
190 /// |
190 /// |
191 /// Setter function of the map. Equivalent with map[key] = val. |
191 /// Setter function of the map. Equivalent with map[key] = val. |
192 /// This is a compatibility feature with the not dereferable maps. |
192 /// This is a compatibility feature with the not dereferable maps. |
193 void set(const Key& key, const Value& val) { |
193 void set(const Key& key, const Value& val) { |
194 (*this)[key] = val; |
194 (*this)[key] = val; |
195 } |
195 } |
196 |
196 |
197 protected: |
197 protected: |
198 |
198 |
199 /// \brief Adds a new key to the map. |
199 /// \brief Adds a new key to the map. |
200 /// |
200 /// |
201 /// It adds a new key to the map. It called by the observer notifier |
201 /// It adds a new key to the map. It called by the observer notifier |
202 /// and it overrides the add() member function of the observer base. |
202 /// and it overrides the add() member function of the observer base. |
203 virtual void add(const Key& key) { |
203 virtual void add(const Key& key) { |
204 Notifier* nf = Parent::notifier(); |
204 Notifier* nf = Parent::notifier(); |
205 int id = nf->id(key); |
205 int id = nf->id(key); |
206 if (id >= capacity) { |
206 if (id >= capacity) { |
207 int new_capacity = (capacity == 0 ? 1 : capacity); |
207 int new_capacity = (capacity == 0 ? 1 : capacity); |
208 while (new_capacity <= id) { |
208 while (new_capacity <= id) { |
209 new_capacity <<= 1; |
209 new_capacity <<= 1; |
210 } |
210 } |
211 Value* new_values = allocator.allocate(new_capacity); |
211 Value* new_values = allocator.allocate(new_capacity); |
212 Item it; |
212 Item it; |
213 for (nf->first(it); it != INVALID; nf->next(it)) { |
213 for (nf->first(it); it != INVALID; nf->next(it)) { |
214 int jd = nf->id(it);; |
214 int jd = nf->id(it);; |
215 if (id != jd) { |
215 if (id != jd) { |
216 allocator.construct(&(new_values[jd]), values[jd]); |
216 allocator.construct(&(new_values[jd]), values[jd]); |
217 allocator.destroy(&(values[jd])); |
217 allocator.destroy(&(values[jd])); |
218 } |
218 } |
219 } |
219 } |
220 if (capacity != 0) allocator.deallocate(values, capacity); |
220 if (capacity != 0) allocator.deallocate(values, capacity); |
221 values = new_values; |
221 values = new_values; |
222 capacity = new_capacity; |
222 capacity = new_capacity; |
223 } |
223 } |
224 allocator.construct(&(values[id]), Value()); |
224 allocator.construct(&(values[id]), Value()); |
225 } |
225 } |
226 |
226 |
227 /// \brief Adds more new keys to the map. |
227 /// \brief Adds more new keys to the map. |
228 /// |
228 /// |
229 /// It adds more new keys to the map. It called by the observer notifier |
229 /// It adds more new keys to the map. It called by the observer notifier |
230 /// and it overrides the add() member function of the observer base. |
230 /// and it overrides the add() member function of the observer base. |
231 virtual void add(const std::vector<Key>& keys) { |
231 virtual void add(const std::vector<Key>& keys) { |
232 Notifier* nf = Parent::notifier(); |
232 Notifier* nf = Parent::notifier(); |
233 int max_id = -1; |
233 int max_id = -1; |
234 for (int i = 0; i < int(keys.size()); ++i) { |
234 for (int i = 0; i < int(keys.size()); ++i) { |
235 int id = nf->id(keys[i]); |
235 int id = nf->id(keys[i]); |
236 if (id > max_id) { |
236 if (id > max_id) { |
237 max_id = id; |
237 max_id = id; |
238 } |
238 } |
239 } |
239 } |
240 if (max_id >= capacity) { |
240 if (max_id >= capacity) { |
241 int new_capacity = (capacity == 0 ? 1 : capacity); |
241 int new_capacity = (capacity == 0 ? 1 : capacity); |
242 while (new_capacity <= max_id) { |
242 while (new_capacity <= max_id) { |
243 new_capacity <<= 1; |
243 new_capacity <<= 1; |
244 } |
244 } |
245 Value* new_values = allocator.allocate(new_capacity); |
245 Value* new_values = allocator.allocate(new_capacity); |
246 Item it; |
246 Item it; |
247 for (nf->first(it); it != INVALID; nf->next(it)) { |
247 for (nf->first(it); it != INVALID; nf->next(it)) { |
248 int id = nf->id(it); |
248 int id = nf->id(it); |
249 bool found = false; |
249 bool found = false; |
250 for (int i = 0; i < int(keys.size()); ++i) { |
250 for (int i = 0; i < int(keys.size()); ++i) { |
251 int jd = nf->id(keys[i]); |
251 int jd = nf->id(keys[i]); |
252 if (id == jd) { |
252 if (id == jd) { |
253 found = true; |
253 found = true; |
254 break; |
254 break; |
255 } |
255 } |
256 } |
256 } |
257 if (found) continue; |
257 if (found) continue; |
258 allocator.construct(&(new_values[id]), values[id]); |
258 allocator.construct(&(new_values[id]), values[id]); |
259 allocator.destroy(&(values[id])); |
259 allocator.destroy(&(values[id])); |
260 } |
260 } |
261 if (capacity != 0) allocator.deallocate(values, capacity); |
261 if (capacity != 0) allocator.deallocate(values, capacity); |
262 values = new_values; |
262 values = new_values; |
263 capacity = new_capacity; |
263 capacity = new_capacity; |
264 } |
264 } |
265 for (int i = 0; i < int(keys.size()); ++i) { |
265 for (int i = 0; i < int(keys.size()); ++i) { |
266 int id = nf->id(keys[i]); |
266 int id = nf->id(keys[i]); |
267 allocator.construct(&(values[id]), Value()); |
267 allocator.construct(&(values[id]), Value()); |
268 } |
268 } |
269 } |
269 } |
270 |
270 |
271 /// \brief Erase a key from the map. |
271 /// \brief Erase a key from the map. |
272 /// |
272 /// |
273 /// Erase a key from the map. It called by the observer notifier |
273 /// Erase a key from the map. It called by the observer notifier |
274 /// and it overrides the erase() member function of the observer base. |
274 /// and it overrides the erase() member function of the observer base. |
275 virtual void erase(const Key& key) { |
275 virtual void erase(const Key& key) { |
276 int id = Parent::notifier()->id(key); |
276 int id = Parent::notifier()->id(key); |
277 allocator.destroy(&(values[id])); |
277 allocator.destroy(&(values[id])); |
278 } |
278 } |
279 |
279 |
280 /// \brief Erase more keys from the map. |
280 /// \brief Erase more keys from the map. |
281 /// |
281 /// |
282 /// Erase more keys from the map. It called by the observer notifier |
282 /// Erase more keys from the map. It called by the observer notifier |
283 /// and it overrides the erase() member function of the observer base. |
283 /// and it overrides the erase() member function of the observer base. |
284 virtual void erase(const std::vector<Key>& keys) { |
284 virtual void erase(const std::vector<Key>& keys) { |
285 for (int i = 0; i < int(keys.size()); ++i) { |
285 for (int i = 0; i < int(keys.size()); ++i) { |
286 int id = Parent::notifier()->id(keys[i]); |
286 int id = Parent::notifier()->id(keys[i]); |
287 allocator.destroy(&(values[id])); |
287 allocator.destroy(&(values[id])); |
288 } |
288 } |
289 } |
289 } |
290 |
290 |
291 /// \brief Buildes the map. |
291 /// \brief Buildes the map. |
292 /// |
292 /// |
293 /// It buildes the map. It called by the observer notifier |
293 /// It buildes the map. It called by the observer notifier |
294 /// and it overrides the build() member function of the observer base. |
294 /// and it overrides the build() member function of the observer base. |
295 virtual void build() { |
295 virtual void build() { |
296 Notifier* nf = Parent::notifier(); |
296 Notifier* nf = Parent::notifier(); |
297 allocate_memory(); |
297 allocate_memory(); |
298 Item it; |
298 Item it; |
299 for (nf->first(it); it != INVALID; nf->next(it)) { |
299 for (nf->first(it); it != INVALID; nf->next(it)) { |
300 int id = nf->id(it);; |
300 int id = nf->id(it);; |
301 allocator.construct(&(values[id]), Value()); |
301 allocator.construct(&(values[id]), Value()); |
302 } |
302 } |
303 } |
303 } |
304 |
304 |
305 /// \brief Clear the map. |
305 /// \brief Clear the map. |
306 /// |
306 /// |
307 /// It erase all items from the map. It called by the observer notifier |
307 /// It erase all items from the map. It called by the observer notifier |
308 /// and it overrides the clear() member function of the observer base. |
308 /// and it overrides the clear() member function of the observer base. |
309 virtual void clear() { |
309 virtual void clear() { |
310 Notifier* nf = Parent::notifier(); |
310 Notifier* nf = Parent::notifier(); |
311 if (capacity != 0) { |
311 if (capacity != 0) { |
312 Item it; |
312 Item it; |
313 for (nf->first(it); it != INVALID; nf->next(it)) { |
313 for (nf->first(it); it != INVALID; nf->next(it)) { |
314 int id = nf->id(it); |
314 int id = nf->id(it); |
315 allocator.destroy(&(values[id])); |
315 allocator.destroy(&(values[id])); |
316 } |
316 } |
317 allocator.deallocate(values, capacity); |
317 allocator.deallocate(values, capacity); |
318 capacity = 0; |
318 capacity = 0; |
319 } |
319 } |
320 } |
320 } |
321 |
321 |
322 private: |
322 private: |
323 |
323 |
324 void allocate_memory() { |
324 void allocate_memory() { |
325 int max_id = Parent::notifier()->maxId(); |
325 int max_id = Parent::notifier()->maxId(); |
326 if (max_id == -1) { |
326 if (max_id == -1) { |
327 capacity = 0; |
327 capacity = 0; |
328 values = 0; |
328 values = 0; |
329 return; |
329 return; |
330 } |
330 } |
331 capacity = 1; |
331 capacity = 1; |
332 while (capacity <= max_id) { |
332 while (capacity <= max_id) { |
333 capacity <<= 1; |
333 capacity <<= 1; |
334 } |
334 } |
335 values = allocator.allocate(capacity); |
335 values = allocator.allocate(capacity); |
336 } |
336 } |
337 |
337 |
338 int capacity; |
338 int capacity; |
339 Value* values; |
339 Value* values; |
340 Allocator allocator; |
340 Allocator allocator; |
341 |
341 |
342 }; |
342 }; |
343 |
343 |
344 } |
344 } |
345 |
345 |
346 #endif |
346 #endif |