1 (binary file text/x-chdr, hash: c1baa9a06a141f28cc081626be954c4589ed3a3a) |
1 /* -*- C++ -*- |
|
2 * |
|
3 * This file is a part of LEMON, a generic C++ optimization library |
|
4 * |
|
5 * Copyright (C) 2003-2006 |
|
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
|
8 * |
|
9 * Permission to use, modify and distribute this software is granted |
|
10 * provided that this copyright notice appears in all copies. For |
|
11 * precise terms see the accompanying LICENSE file. |
|
12 * |
|
13 * This software is provided "AS IS" with no warranty of any kind, |
|
14 * express or implied, and with no claim as to its suitability for any |
|
15 * purpose. |
|
16 * |
|
17 */ |
|
18 |
|
19 #ifndef LEMON_MATRIX_MAPS_H |
|
20 #define LEMON_MATRIX_MAPS_H |
|
21 |
|
22 |
|
23 #include <vector> |
|
24 #include <lemon/bits/utility.h> |
|
25 #include <lemon/maps.h> |
|
26 |
|
27 #include <lemon/concept/matrix_maps.h> |
|
28 |
|
29 /// \file |
|
30 /// \ingroup maps |
|
31 /// \brief Maps indexed with pairs of items. |
|
32 /// |
|
33 /// \todo This file has the same name as the concept file in concept/, |
|
34 /// and this is not easily detectable in docs... |
|
35 namespace lemon { |
|
36 |
|
37 /// \brief Map for the coloumn view of the matrix |
|
38 /// |
|
39 /// Map for the coloumn view of the matrix. |
|
40 template <typename _MatrixMap> |
|
41 class MatrixRowMap : public MatrixMapTraits<_MatrixMap> { |
|
42 public: |
|
43 typedef _MatrixMap MatrixMap; |
|
44 typedef typename MatrixMap::SecondKey Key; |
|
45 typedef typename MatrixMap::Value Value; |
|
46 |
|
47 |
|
48 MatrixRowMap(MatrixMap& _matrix, typename MatrixMap::FirstKey _row) |
|
49 : matrix(_matrix), row(_row) {} |
|
50 |
|
51 /// \brief Subscription operator |
|
52 /// |
|
53 /// Subscription operator. |
|
54 typename MatrixMapTraits<MatrixMap>::ReturnValue |
|
55 operator[](Key col) { |
|
56 return matrix(row, col); |
|
57 } |
|
58 |
|
59 /// \brief Setter function |
|
60 /// |
|
61 /// Setter function. |
|
62 void set(Key col, const Value& val) { |
|
63 matrix.set(row, col, val); |
|
64 } |
|
65 |
|
66 /// \brief Subscription operator |
|
67 /// |
|
68 /// Subscription operator. |
|
69 typename MatrixMapTraits<MatrixMap>::ConstReturnValue |
|
70 operator[](Key col) const { |
|
71 return matrix(row, col); |
|
72 } |
|
73 |
|
74 private: |
|
75 MatrixMap& matrix; |
|
76 typename MatrixMap::FirstKey row; |
|
77 }; |
|
78 |
|
79 /// \brief Map for the row view of the matrix |
|
80 /// |
|
81 /// Map for the row view of the matrix. |
|
82 template <typename _MatrixMap> |
|
83 class ConstMatrixRowMap : public MatrixMapTraits<_MatrixMap> { |
|
84 public: |
|
85 typedef _MatrixMap MatrixMap; |
|
86 typedef typename MatrixMap::SecondKey Key; |
|
87 typedef typename MatrixMap::Value Value; |
|
88 |
|
89 |
|
90 ConstMatrixRowMap(const MatrixMap& _matrix, |
|
91 typename MatrixMap::FirstKey _row) |
|
92 : matrix(_matrix), row(_row) {} |
|
93 |
|
94 /// \brief Subscription operator |
|
95 /// |
|
96 /// Subscription operator. |
|
97 typename MatrixMapTraits<MatrixMap>::ConstReturnValue |
|
98 operator[](Key col) const { |
|
99 return matrix(row, col); |
|
100 } |
|
101 |
|
102 private: |
|
103 const MatrixMap& matrix; |
|
104 typename MatrixMap::FirstKey row; |
|
105 }; |
|
106 |
|
107 /// \brief Gives back a row view of the matrix map |
|
108 /// |
|
109 /// Gives back a row view of the matrix map. |
|
110 template <typename MatrixMap> |
|
111 MatrixRowMap<MatrixMap> matrixRowMap(MatrixMap& matrixMap, |
|
112 typename MatrixMap::FirstKey row) { |
|
113 return MatrixRowMap<MatrixMap>(matrixMap, row); |
|
114 } |
|
115 |
|
116 template <typename MatrixMap> |
|
117 ConstMatrixRowMap<MatrixMap> |
|
118 matrixRowMap(const MatrixMap& matrixMap, typename MatrixMap::FirstKey row) { |
|
119 return ConstMatrixRowMap<MatrixMap>(matrixMap, row); |
|
120 } |
|
121 |
|
122 /// \brief Map for the row view of the matrix |
|
123 /// |
|
124 /// Map for the row view of the matrix. |
|
125 template <typename _MatrixMap> |
|
126 class MatrixColMap : public MatrixMapTraits<_MatrixMap> { |
|
127 public: |
|
128 typedef _MatrixMap MatrixMap; |
|
129 typedef typename MatrixMap::FirstKey Key; |
|
130 typedef typename MatrixMap::Value Value; |
|
131 |
|
132 MatrixColMap(MatrixMap& _matrix, typename MatrixMap::SecondKey _col) |
|
133 : matrix(_matrix), col(_col) {} |
|
134 |
|
135 /// \brief Subscription operator |
|
136 /// |
|
137 /// Subscription operator. |
|
138 typename MatrixMapTraits<MatrixMap>::ReturnValue |
|
139 operator[](Key row) { |
|
140 return matrix(row, col); |
|
141 } |
|
142 |
|
143 /// \brief Setter function |
|
144 /// |
|
145 /// Setter function. |
|
146 void set(Key row, const Value& val) { |
|
147 matrix.set(row, col, val); |
|
148 } |
|
149 |
|
150 /// \brief Subscription operator |
|
151 /// |
|
152 /// Subscription operator. |
|
153 typename MatrixMapTraits<MatrixMap>::ConstReturnValue |
|
154 operator[](Key row) const { |
|
155 return matrix(row, col); |
|
156 } |
|
157 |
|
158 private: |
|
159 MatrixMap& matrix; |
|
160 typename MatrixMap::SecondKey col; |
|
161 }; |
|
162 |
|
163 /// \brief Map for the col view of the matrix |
|
164 /// |
|
165 /// Map for the col view of the matrix. |
|
166 template <typename _MatrixMap> |
|
167 class ConstMatrixColMap : public MatrixMapTraits<_MatrixMap> { |
|
168 public: |
|
169 typedef _MatrixMap MatrixMap; |
|
170 typedef typename MatrixMap::FirstKey Key; |
|
171 typedef typename MatrixMap::Value Value; |
|
172 |
|
173 ConstMatrixColMap(const MatrixMap& _matrix, |
|
174 typename MatrixMap::SecondKey _col) |
|
175 : matrix(_matrix), col(_col) {} |
|
176 |
|
177 /// \brief Subscription operator |
|
178 /// |
|
179 /// Subscription operator. |
|
180 typename MatrixMapTraits<MatrixMap>::ConstReturnValue |
|
181 operator[](Key row) const { |
|
182 return matrix(row, col); |
|
183 } |
|
184 |
|
185 private: |
|
186 const MatrixMap& matrix; |
|
187 typename MatrixMap::SecondKey col; |
|
188 }; |
|
189 |
|
190 /// \brief Gives back a col view of the matrix map |
|
191 /// |
|
192 /// Gives back a col view of the matrix map. |
|
193 template <typename MatrixMap> |
|
194 MatrixColMap<MatrixMap> matrixColMap(MatrixMap& matrixMap, |
|
195 typename MatrixMap::SecondKey col) { |
|
196 return MatrixColMap<MatrixMap>(matrixMap, col); |
|
197 } |
|
198 |
|
199 template <typename MatrixMap> |
|
200 ConstMatrixColMap<MatrixMap> |
|
201 matrixColMap(const MatrixMap& matrixMap, typename MatrixMap::SecondKey col) { |
|
202 return ConstMatrixColMap<MatrixMap>(matrixMap, col); |
|
203 } |
|
204 |
|
205 /// \brief Container for store values for each ordered pair of graph items |
|
206 /// |
|
207 /// This data structure can strore for each pair of the same item |
|
208 /// type a value. It increase the size of the container when the |
|
209 /// associated graph modified, so it updated automaticly whenever |
|
210 /// it is needed. |
|
211 template <typename _Graph, typename _Item, typename _Value> |
|
212 class DynamicMatrixMap |
|
213 : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { |
|
214 public: |
|
215 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase |
|
216 Parent; |
|
217 |
|
218 typedef _Graph Graph; |
|
219 typedef _Item Key; |
|
220 |
|
221 typedef _Item FirstKey; |
|
222 typedef _Item SecondKey; |
|
223 typedef _Value Value; |
|
224 |
|
225 typedef True ReferenceMapTag; |
|
226 |
|
227 private: |
|
228 |
|
229 typedef std::vector<Value> Container; |
|
230 |
|
231 public: |
|
232 |
|
233 typedef typename Container::reference Reference; |
|
234 typedef typename Container::const_reference ConstReference; |
|
235 |
|
236 /// \brief Creates an item matrix for the given graph |
|
237 /// |
|
238 /// Creates an item matrix for the given graph. |
|
239 DynamicMatrixMap(const Graph& _graph) |
|
240 : values(size(_graph.maxId(Key()) + 1)) { |
|
241 Parent::attach(_graph.getNotifier(Key())); |
|
242 } |
|
243 |
|
244 /// \brief Creates an item matrix for the given graph |
|
245 /// |
|
246 /// Creates an item matrix for the given graph and assigns for each |
|
247 /// pairs of keys the given parameter. |
|
248 DynamicMatrixMap(const Graph& _graph, const Value& _val) |
|
249 : values(size(_graph.maxId(Key()) + 1), _val) { |
|
250 Parent::attach(_graph.getNotifier(Key())); |
|
251 } |
|
252 |
|
253 ///\brief The assignement operator. |
|
254 /// |
|
255 ///It allow to assign a map to an other. |
|
256 DynamicMatrixMap& operator=(const DynamicMatrixMap& _cmap){ |
|
257 return operator=<DynamicMatrixMap>(_cmap); |
|
258 } |
|
259 |
|
260 ///\brief Template assignement operator. |
|
261 /// |
|
262 ///It copy the element of the given map to its own container. The |
|
263 ///type of the two map shall be the same. |
|
264 template <typename CMap> |
|
265 DynamicMatrixMap& operator=(const CMap& _cmap){ |
|
266 checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>(); |
|
267 typename Parent::Notifier* notifier = Parent::getNotifier(); |
|
268 Key first, second; |
|
269 for(notifier->first(first); first != INVALID; |
|
270 notifier->next(first)){ |
|
271 for(notifier->first(second); second != INVALID; |
|
272 notifier->next(second)){ |
|
273 set(first, second, _cmap(first, second)); |
|
274 } |
|
275 } |
|
276 return *this; |
|
277 } |
|
278 |
|
279 /// \brief Gives back the value assigned to the \c first - \c second |
|
280 /// ordered pair. |
|
281 /// |
|
282 /// Gives back the value assigned to the \c first - \c second ordered pair. |
|
283 ConstReference operator()(const Key& first, const Key& second) const { |
|
284 return values[index(Parent::getNotifier()->id(first), |
|
285 Parent::getNotifier()->id(second))]; |
|
286 } |
|
287 |
|
288 /// \brief Gives back the value assigned to the \c first - \c second |
|
289 /// ordered pair. |
|
290 /// |
|
291 /// Gives back the value assigned to the \c first - \c second ordered pair. |
|
292 Reference operator()(const Key& first, const Key& second) { |
|
293 return values[index(Parent::getNotifier()->id(first), |
|
294 Parent::getNotifier()->id(second))]; |
|
295 } |
|
296 |
|
297 /// \brief Setter function for the matrix map. |
|
298 /// |
|
299 /// Setter function for the matrix map. |
|
300 void set(const Key& first, const Key& second, const Value& val) { |
|
301 values[index(Parent::getNotifier()->id(first), |
|
302 Parent::getNotifier()->id(second))] = val; |
|
303 } |
|
304 |
|
305 protected: |
|
306 |
|
307 static int index(int i, int j) { |
|
308 if (i < j) { |
|
309 return j * j + i; |
|
310 } else { |
|
311 return i * i + i + j; |
|
312 } |
|
313 } |
|
314 |
|
315 static int size(int s) { |
|
316 return s * s; |
|
317 } |
|
318 |
|
319 virtual void add(const Key& key) { |
|
320 if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) { |
|
321 values.resize(size(Parent::getNotifier()->id(key) + 1)); |
|
322 } |
|
323 } |
|
324 |
|
325 virtual void erase(const Key&) {} |
|
326 |
|
327 virtual void build() { |
|
328 values.resize(size(Parent::getNotifier()->maxId() + 1)); |
|
329 } |
|
330 |
|
331 virtual void clear() { |
|
332 values.clear(); |
|
333 } |
|
334 |
|
335 private: |
|
336 std::vector<Value> values; |
|
337 }; |
|
338 |
|
339 /// \brief Container for store values for each unordered pair of graph items |
|
340 /// |
|
341 /// This data structure can strore for each pair of the same item |
|
342 /// type a value. It increase the size of the container when the |
|
343 /// associated graph modified, so it updated automaticly whenever |
|
344 /// it is needed. |
|
345 template <typename _Graph, typename _Item, typename _Value> |
|
346 class DynamicSymMatrixMap |
|
347 : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { |
|
348 public: |
|
349 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase |
|
350 Parent; |
|
351 |
|
352 typedef _Graph Graph; |
|
353 typedef _Item Key; |
|
354 |
|
355 typedef _Item FirstKey; |
|
356 typedef _Item SecondKey; |
|
357 typedef _Value Value; |
|
358 |
|
359 typedef True ReferenceMapTag; |
|
360 |
|
361 private: |
|
362 |
|
363 typedef std::vector<Value> Container; |
|
364 |
|
365 public: |
|
366 |
|
367 typedef typename Container::reference Reference; |
|
368 typedef typename Container::const_reference ConstReference; |
|
369 |
|
370 /// \brief Creates an item matrix for the given graph |
|
371 /// |
|
372 /// Creates an item matrix for the given graph. |
|
373 DynamicSymMatrixMap(const Graph& _graph) |
|
374 : values(size(_graph.maxId(Key()) + 1)) { |
|
375 Parent::attach(_graph.getNotifier(Key())); |
|
376 } |
|
377 |
|
378 /// \brief Creates an item matrix for the given graph |
|
379 /// |
|
380 /// Creates an item matrix for the given graph and assigns for each |
|
381 /// pairs of keys the given parameter. |
|
382 DynamicSymMatrixMap(const Graph& _graph, const Value& _val) |
|
383 : values(size(_graph.maxId(Key()) + 1), _val) { |
|
384 Parent::attach(_graph.getNotifier(Key())); |
|
385 } |
|
386 |
|
387 |
|
388 ///\brief The assignement operator. |
|
389 /// |
|
390 ///It allow to assign a map to an other. |
|
391 DynamicSymMatrixMap& operator=(const DynamicSymMatrixMap& _cmap){ |
|
392 return operator=<DynamicSymMatrixMap>(_cmap); |
|
393 } |
|
394 |
|
395 ///\brief Template assignement operator. |
|
396 /// |
|
397 ///It copy the element of the given map to its own container. The |
|
398 ///type of the two map shall be the same. |
|
399 template <typename CMap> |
|
400 DynamicSymMatrixMap& operator=(const CMap& _cmap){ |
|
401 checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>(); |
|
402 typename Parent::Notifier* notifier = Parent::getNotifier(); |
|
403 Key first, second; |
|
404 for(notifier->first(first); first != INVALID; |
|
405 notifier->next(first)){ |
|
406 for(notifier->first(second); second != first; |
|
407 notifier->next(second)){ |
|
408 set(first, second, _cmap(first, second)); |
|
409 } |
|
410 set(first, first, _cmap(first, first)); |
|
411 } |
|
412 return *this; |
|
413 } |
|
414 |
|
415 /// \brief Gives back the value assigned to the \c first - \c second |
|
416 /// unordered pair. |
|
417 /// |
|
418 /// Gives back the value assigned to the \c first - \c second unordered |
|
419 /// pair. |
|
420 ConstReference operator()(const Key& first, const Key& second) const { |
|
421 return values[index(Parent::getNotifier()->id(first), |
|
422 Parent::getNotifier()->id(second))]; |
|
423 } |
|
424 |
|
425 /// \brief Gives back the value assigned to the \c first - \c second |
|
426 /// unordered pair. |
|
427 /// |
|
428 /// Gives back the value assigned to the \c first - \c second unordered |
|
429 /// pair. |
|
430 Reference operator()(const Key& first, const Key& second) { |
|
431 return values[index(Parent::getNotifier()->id(first), |
|
432 Parent::getNotifier()->id(second))]; |
|
433 } |
|
434 |
|
435 /// \brief Setter function for the matrix map. |
|
436 /// |
|
437 /// Setter function for the matrix map. |
|
438 void set(const Key& first, const Key& second, const Value& val) { |
|
439 values[index(Parent::getNotifier()->id(first), |
|
440 Parent::getNotifier()->id(second))] = val; |
|
441 } |
|
442 |
|
443 protected: |
|
444 |
|
445 static int index(int i, int j) { |
|
446 if (i < j) { |
|
447 return j * (j + 1) / 2 + i; |
|
448 } else { |
|
449 return i * (i + 1) / 2 + j; |
|
450 } |
|
451 } |
|
452 |
|
453 static int size(int s) { |
|
454 return s * (s + 1) / 2; |
|
455 } |
|
456 |
|
457 virtual void add(const Key& key) { |
|
458 if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) { |
|
459 values.resize(size(Parent::getNotifier()->id(key) + 1)); |
|
460 } |
|
461 } |
|
462 |
|
463 virtual void erase(const Key&) {} |
|
464 |
|
465 virtual void build() { |
|
466 values.resize(size(Parent::getNotifier()->maxId() + 1)); |
|
467 } |
|
468 |
|
469 virtual void clear() { |
|
470 values.clear(); |
|
471 } |
|
472 |
|
473 private: |
|
474 std::vector<Value> values; |
|
475 }; |
|
476 |
|
477 ///\brief Dynamic Asymmetric Matrix Map. |
|
478 /// |
|
479 ///Dynamic Asymmetric Matrix Map. Container for store values for each |
|
480 ///ordered pair of containers items. This data structure can store |
|
481 ///data with different key types from different container types. It |
|
482 ///increases the size of the container if the linked containers |
|
483 ///content change, so it is updated automaticly whenever it is |
|
484 ///needed. |
|
485 /// |
|
486 ///This map meet with the concept::ReferenceMatrixMap<typename K1, |
|
487 ///typename K2, typename V, typename R, typename CR> called as |
|
488 ///"ReferenceMatrixMap". |
|
489 /// |
|
490 ///\param _FirstContainer the desired type of first container. It is |
|
491 ///ususally a Graph type, but can be any type with alteration |
|
492 ///property. |
|
493 /// |
|
494 ///\param _FirstContainerItem the nested type of the |
|
495 ///FirstContainer. It is usually a graph item as Node, Edge, |
|
496 ///etc. This type will be the FirstKey type. |
|
497 /// |
|
498 ///\param _SecondContainer the desired type of the second |
|
499 ///container. It is usualy a Graph type, but can be any type with |
|
500 ///alteration property. |
|
501 /// |
|
502 ///\param _SecondContainerItem the nested type of the |
|
503 ///SecondContainer. It is usually a graph item such as Node, Edge, |
|
504 ///UEdge, etc. This type will be the SecondKey type. |
|
505 /// |
|
506 ///\param _Value the type of the strored values in the container. |
|
507 /// |
|
508 /// \author Janos Nagy |
|
509 template <typename _FirstContainer, typename _FirstContainerItem, |
|
510 typename _SecondContainer, typename _SecondContainerItem, |
|
511 typename _Value> |
|
512 class DynamicAsymMatrixMap{ |
|
513 public: |
|
514 |
|
515 ///The first key type. |
|
516 typedef _FirstContainerItem FirstKey; |
|
517 |
|
518 ///The second key type. |
|
519 typedef _SecondContainerItem SecondKey; |
|
520 |
|
521 ///The value type of the map. |
|
522 typedef _Value Value; |
|
523 |
|
524 ///Indicates it is a reference map. |
|
525 typedef True ReferenceMapTag; |
|
526 |
|
527 protected: |
|
528 |
|
529 ///\brief Proxy class for the first key type. |
|
530 /// |
|
531 ///The proxy class belongs to the FirstKey type. It is necessary because |
|
532 ///if one want use the same conatainer types and same nested types but on |
|
533 ///other instances of containers than due to the type equiality of nested |
|
534 ///types it requires a proxy mechanism. |
|
535 class FirstKeyProxy |
|
536 : protected |
|
537 ItemSetTraits<_FirstContainer,_FirstContainerItem>:: |
|
538 ItemNotifier::ObserverBase |
|
539 { |
|
540 |
|
541 public: |
|
542 |
|
543 friend class DynamicAsymMatrixMap; |
|
544 |
|
545 ///Constructor. |
|
546 FirstKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { } |
|
547 protected: |
|
548 |
|
549 ///\brief Add a new FirstKey to the map. |
|
550 /// |
|
551 ///It adds a new FirstKey to the map. It is called by the |
|
552 ///observer notifier and it is ovverride the add() virtual |
|
553 ///member function in the observer base. It will call the |
|
554 ///maps addFirstKey() function. |
|
555 virtual void add(const FirstKey& _firstKey){ |
|
556 _owner.addFirstKey(_firstKey); |
|
557 } |
|
558 |
|
559 ///\brief Add more new FirstKey to the map. |
|
560 /// |
|
561 ///It adds more new FirstKey to the map. It is called by the |
|
562 ///observer notifier and it is ovverride the add() virtual |
|
563 ///member function in the observer base. It will call the |
|
564 ///map's addFirstKeys() function. |
|
565 virtual void add(const std::vector<FirstKey>& _firstKeys){ |
|
566 _owner.addFirstKeys(_firstKeys); |
|
567 } |
|
568 |
|
569 ///\brief Erase a FirstKey from the map. |
|
570 /// |
|
571 ///Erase a FirstKey from the map. It called by the observer |
|
572 ///notifier and it overrides the erase() virtual member |
|
573 ///function of the observer base. It will call the map's |
|
574 ///eraseFirstKey() function. |
|
575 virtual void erase(const FirstKey& _firstKey){ |
|
576 _owner.eraseFirstKey(_firstKey); |
|
577 } |
|
578 |
|
579 ///\brief Erase more FirstKey from the map. |
|
580 /// |
|
581 ///Erase more FirstKey from the map. It called by the |
|
582 ///observer notifier and it overrides the erase() virtual |
|
583 ///member function of the observer base. It will call the |
|
584 ///map's eraseFirstKeys() function. |
|
585 virtual void erase(const std::vector<FirstKey>& _firstKeys){ |
|
586 _owner.eraseFirstKeys(_firstKeys); |
|
587 } |
|
588 |
|
589 ///\brief Builds the map. |
|
590 /// |
|
591 ///It buildes the map. It called by the observer notifier |
|
592 ///and it overrides the build() virtual member function of |
|
593 ///the observer base. It will call the map's build() |
|
594 ///function. |
|
595 virtual void build() { |
|
596 _owner.build(); |
|
597 //_owner.buildFirst(); |
|
598 } |
|
599 |
|
600 ///\brief Clear the map. |
|
601 /// |
|
602 ///It erases all items from the map. It called by the |
|
603 ///observer notifier and it overrides the clear() virtual |
|
604 ///memeber function of the observer base. It will call the |
|
605 ///map's clear() function. |
|
606 virtual void clear() { |
|
607 _owner.clear(); |
|
608 //_owner.clearFirst(); |
|
609 } |
|
610 private: |
|
611 |
|
612 ///The map type for it is linked. |
|
613 DynamicAsymMatrixMap& _owner; |
|
614 };///END OF FIRSTKEYPROXY |
|
615 |
|
616 ///\brief Proxy class for the second key type. |
|
617 /// |
|
618 ///The proxy class belongs to the SecondKey type. It is |
|
619 ///necessary because if one want use the same conatainer types |
|
620 ///and same nested types but on other instances of containers |
|
621 ///than due to the type equiality of nested types it requires a |
|
622 ///proxy mechanism. |
|
623 class SecondKeyProxy |
|
624 : protected |
|
625 ItemSetTraits<_SecondContainer, _SecondContainerItem>:: |
|
626 ItemNotifier::ObserverBase { |
|
627 |
|
628 public: |
|
629 |
|
630 friend class DynamicAsymMatrixMap; |
|
631 ///Constructor. |
|
632 SecondKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { } |
|
633 |
|
634 protected: |
|
635 |
|
636 ///\brief Add a new SecondKey to the map. |
|
637 /// |
|
638 ///It adds a new SecondKey to the map. It is called by the |
|
639 ///observer notifier and it is ovverride the add() virtual |
|
640 ///member function in the observer base. It will call the |
|
641 ///maps addSecondKey() function. |
|
642 virtual void add(const SecondKey& _secondKey){ |
|
643 _owner.addSecondKey(_secondKey); |
|
644 } |
|
645 |
|
646 ///\brief Add more new SecondKey to the map. |
|
647 /// |
|
648 ///It adds more new SecondKey to the map. It is called by |
|
649 ///the observer notifier and it is ovverride the add() |
|
650 ///virtual member function in the observer base. It will |
|
651 ///call the maps addSecondKeys() function. |
|
652 virtual void add(const std::vector<SecondKey>& _secondKeys){ |
|
653 _owner.addSecondKeys(_secondKeys); |
|
654 } |
|
655 |
|
656 ///\brief Erase a SecondKey from the map. |
|
657 /// |
|
658 ///Erase a SecondKey from the map. It called by the observer |
|
659 ///notifier and it overrides the erase() virtual member |
|
660 ///function of the observer base. It will call the map's |
|
661 ///eraseSecondKey() function. |
|
662 virtual void erase(const SecondKey& _secondKey){ |
|
663 _owner.eraseSecondKey(_secondKey); |
|
664 } |
|
665 |
|
666 ///\brief Erase more SecondKeys from the map. |
|
667 /// |
|
668 ///Erase more SecondKey from the map. It called by the |
|
669 ///observer notifier and it overrides the erase() virtual |
|
670 ///member function of the observer base. It will call the |
|
671 ///map's eraseSecondKeys() function. |
|
672 virtual void erase(const std::vector<SecondKey>& _secondKeys){ |
|
673 _owner.eraseSecondKeys(_secondKeys); |
|
674 } |
|
675 |
|
676 ///\brief Builds the map. |
|
677 /// |
|
678 ///It buildes the map. It called by the observer notifier |
|
679 ///and it overrides the build() virtual member function of |
|
680 ///the observer base. It will call the map's build() |
|
681 ///function. |
|
682 virtual void build() { |
|
683 _owner.build(); |
|
684 } |
|
685 |
|
686 ///\brief Clear the map. |
|
687 /// |
|
688 ///It erases all items from the map. It called by the |
|
689 ///observer notifier and it overrides the clear() virtual |
|
690 ///memeber function of the observer base. It will call the |
|
691 ///map's clear() function. |
|
692 virtual void clear() { |
|
693 _owner.clear(); |
|
694 //_owner.clearFirst(); |
|
695 } |
|
696 private: |
|
697 |
|
698 ///The type of map for which it is attached. |
|
699 DynamicAsymMatrixMap& _owner; |
|
700 };///END OF SECONDKEYPROXY |
|
701 |
|
702 private: |
|
703 |
|
704 /// \e |
|
705 typedef std::vector<Value> Container; |
|
706 |
|
707 ///The type of constainer which stores the values of the map. |
|
708 typedef std::vector<Container> DContainer; |
|
709 |
|
710 ///The std:vector type which contains the data |
|
711 DContainer values; |
|
712 |
|
713 ///Member for the first proxy class |
|
714 FirstKeyProxy _first_key_proxy; |
|
715 |
|
716 ///Member for the second proxy class |
|
717 SecondKeyProxy _second_key_proxy; |
|
718 |
|
719 public: |
|
720 |
|
721 ///The refernce type of the map. |
|
722 typedef typename Container::reference Reference; |
|
723 |
|
724 ///The const reference type of the constainer. |
|
725 typedef typename Container::const_reference ConstReference; |
|
726 |
|
727 ///\brief Constructor what create the map for the two containers type. |
|
728 /// |
|
729 ///Creates the matrix map and initialize the values with Value() |
|
730 DynamicAsymMatrixMap(const _FirstContainer& _firstContainer, |
|
731 const _SecondContainer& _secondContainer) |
|
732 : values(DContainer(_firstContainer.maxId(FirstKey())+1, |
|
733 Container(_secondContainer.maxId(SecondKey())+1))), |
|
734 _first_key_proxy(*this), |
|
735 _second_key_proxy(*this) |
|
736 { |
|
737 _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey())); |
|
738 _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey())); |
|
739 } |
|
740 |
|
741 ///\brief Constructor what create the map for the two containers type. |
|
742 /// |
|
743 ///Creates the matrix map and initialize the values with the given _value |
|
744 DynamicAsymMatrixMap(const _FirstContainer& _firstContainer, |
|
745 const _SecondContainer& _secondContainer, |
|
746 const Value& _value) |
|
747 : values(DContainer(_firstContainer.maxId(FirstKey())+1, |
|
748 Container(_secondContainer.maxId(SecondKey())+1, |
|
749 _value))), |
|
750 _first_key_proxy(*this), |
|
751 _second_key_proxy(*this) |
|
752 { |
|
753 _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey())); |
|
754 _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey())); |
|
755 } |
|
756 |
|
757 ///\brief Copy constructor. |
|
758 /// |
|
759 ///The copy constructor of the map. |
|
760 DynamicAsymMatrixMap(const DynamicAsymMatrixMap& _copy) |
|
761 : _first_key_proxy(*this), _second_key_proxy(*this) { |
|
762 if(_copy._first_key_proxy.attached() && |
|
763 _copy._second_key_proxy.attached()){ |
|
764 _first_key_proxy.attach(*_copy._first_key_proxy.getNotifier()); |
|
765 _second_key_proxy.attach(*_copy._second_key_proxy.getNotifier()); |
|
766 values = _copy.values; |
|
767 } |
|
768 } |
|
769 |
|
770 ///\brief Destructor |
|
771 /// |
|
772 ///Destructor what detach() from the attached objects. May this |
|
773 ///function is not necessary because the destructor of |
|
774 ///ObserverBase do the same. |
|
775 ~DynamicAsymMatrixMap() { |
|
776 if(_first_key_proxy.attached()){ |
|
777 _first_key_proxy.detach(); |
|
778 } |
|
779 if(_second_key_proxy.attached()){ |
|
780 _second_key_proxy.detach(); |
|
781 } |
|
782 } |
|
783 |
|
784 ///\brief Gives back the value assigned to the \c first - \c |
|
785 ///second ordered pair. |
|
786 /// |
|
787 ///Gives back the value assigned to the \c first - \c second |
|
788 ///ordered pair. |
|
789 Reference operator()(const FirstKey& _first, const SecondKey& _second) { |
|
790 return values[_first_key_proxy.getNotifier()->id(_first)] |
|
791 [_second_key_proxy.getNotifier()->id(_second)]; |
|
792 } |
|
793 |
|
794 ///\brief Gives back the value assigned to the \c first - \c |
|
795 ///second ordered pair. |
|
796 /// |
|
797 ///Gives back the value assigned to the \c first - \c second |
|
798 ///ordered pair. |
|
799 ConstReference operator()(const FirstKey& _first, |
|
800 const SecondKey& _second) const { |
|
801 return values[_first_key_proxy.getNotifier()->id(_first)] |
|
802 [_second_key_proxy.getNotifier()->id(_second)]; |
|
803 } |
|
804 |
|
805 ///\brief Setter function for this matrix map. |
|
806 /// |
|
807 ///Setter function for this matrix map. |
|
808 void set(const FirstKey& first, const SecondKey& second, |
|
809 const Value& value){ |
|
810 values[_first_key_proxy.getNotifier()->id(first)] |
|
811 [_second_key_proxy.getNotifier()->id(second)] = value; |
|
812 } |
|
813 |
|
814 ///\brief The assignement operator. |
|
815 /// |
|
816 ///It allow to assign a map to an other. It |
|
817 DynamicAsymMatrixMap& operator=(const DynamicAsymMatrixMap& _cmap){ |
|
818 return operator=<DynamicAsymMatrixMap>(_cmap); |
|
819 } |
|
820 |
|
821 ///\brief Template assignement operator. |
|
822 /// |
|
823 ///It copy the element of the given map to its own container. The |
|
824 ///type of the two map shall be the same. |
|
825 template <typename CMap> |
|
826 DynamicAsymMatrixMap& operator=(const CMap& _cdmap){ |
|
827 checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>(); |
|
828 const typename FirstKeyProxy::Notifier* notifierFirstKey = |
|
829 _first_key_proxy.getNotifier(); |
|
830 const typename SecondKeyProxy::Notifier* notifierSecondKey = |
|
831 _second_key_proxy.getNotifier(); |
|
832 FirstKey itemFirst; |
|
833 SecondKey itemSecond; |
|
834 for(notifierFirstKey->first(itemFirst); itemFirst != INVALID; |
|
835 notifierFirstKey->next(itemFirst)){ |
|
836 for(notifierSecondKey->first(itemSecond); itemSecond != INVALID; |
|
837 notifierSecondKey->next(itemSecond)){ |
|
838 set(itemFirst, itemSecond, _cdmap(itemFirst,itemSecond)); |
|
839 } |
|
840 } |
|
841 return *this; |
|
842 } |
|
843 |
|
844 protected: |
|
845 |
|
846 ///\brief Add a new FirstKey to the map. |
|
847 /// |
|
848 ///It adds a new FirstKey to the map. It is called by the observer |
|
849 ///class belongs to the FirstKey type. |
|
850 void addFirstKey(const FirstKey& firstKey) { |
|
851 int size = (int)values.size(); |
|
852 if( _first_key_proxy.getNotifier()->id(firstKey)+1 >= size ){ |
|
853 values.resize(_first_key_proxy.getNotifier()->id(firstKey)+1); |
|
854 if( (int)values[0].size() != 0 ){ |
|
855 int innersize = (int)values[0].size(); |
|
856 for(int i=size; i!=(int)values.size();++i){ |
|
857 (values[i]).resize(innersize); |
|
858 } |
|
859 }else if(_second_key_proxy.getNotifier()->maxId() >= 0){ |
|
860 int innersize = _second_key_proxy.getNotifier()->maxId(); |
|
861 for(int i = 0; i != (int)values.size(); ++i){ |
|
862 values[0].resize(innersize); |
|
863 } |
|
864 } |
|
865 } |
|
866 } |
|
867 |
|
868 ///\brief Adds more new FirstKeys to the map. |
|
869 /// |
|
870 ///It adds more new FirstKeys to the map. It called by the |
|
871 ///observer class belongs to the FirstKey type. |
|
872 void addFirstKeys(const std::vector<FirstKey>& firstKeys){ |
|
873 int max = values.size() - 1; |
|
874 for(int i=0; i != (int)firstKeys.size(); ++i){ |
|
875 int id = _first_key_proxy.getNotifier()->id(firstKeys[i]); |
|
876 if(max < id){ |
|
877 max = id; |
|
878 } |
|
879 } |
|
880 int size = (int)values.size(); |
|
881 if(max >= size){ |
|
882 values.resize(max + 1); |
|
883 if( (int)values[0].size() != 0){ |
|
884 int innersize = (int)values[0].size(); |
|
885 for(int i = size; i != (max + 1); ++i){ |
|
886 values[i].resize(innersize); |
|
887 } |
|
888 }else if(_second_key_proxy.getNotifier()->maxId() >= 0){ |
|
889 int innersize = _second_key_proxy.getNotifier()->maxId(); |
|
890 for(int i = 0; i != (int)values.size(); ++i){ |
|
891 values[i].resize(innersize); |
|
892 } |
|
893 } |
|
894 } |
|
895 } |
|
896 |
|
897 ///\brief Add a new SecondKey to the map. |
|
898 /// |
|
899 ///It adds a new SecondKey to the map. It is called by the |
|
900 ///observer class belongs to the SecondKey type. |
|
901 void addSecondKey(const SecondKey& secondKey) { |
|
902 if(values.size() == 0){ |
|
903 return; |
|
904 } |
|
905 int id = _second_key_proxy.getNotifier()->id(secondKey); |
|
906 if(id >= (int)values[0].size()){ |
|
907 for(int i=0;i!=(int)values.size();++i){ |
|
908 values[i].resize(id+1); |
|
909 } |
|
910 } |
|
911 } |
|
912 |
|
913 ///\brief Adds more new SecondKeys to the map. |
|
914 /// |
|
915 ///It adds more new SecondKeys to the map. It called by the |
|
916 ///observer class belongs to the SecondKey type. |
|
917 void addSecondKeys(const std::vector<SecondKey>& secondKeys){ |
|
918 if(values.size() == 0){ |
|
919 return; |
|
920 } |
|
921 int max = values[0].size(); |
|
922 for(int i = 0; i != (int)secondKeys.size(); ++i){ |
|
923 int id = _second_key_proxy.getNotifier()->id(secondKeys[i]); |
|
924 if(max < id){ |
|
925 max = id; |
|
926 } |
|
927 } |
|
928 if(max > (int)values[0].size()){ |
|
929 for(int i = 0; i != (int)values.size(); ++i){ |
|
930 values[i].resize(max + 1); |
|
931 } |
|
932 } |
|
933 } |
|
934 |
|
935 ///\brief Erase a FirstKey from the map. |
|
936 /// |
|
937 ///Erase a FirstKey from the map. It called by the observer |
|
938 ///class belongs to the FirstKey type. |
|
939 void eraseFirstKey(const FirstKey& first) { |
|
940 int id = _first_key_proxy.getNotifier()->id(first); |
|
941 for(int i = 0; i != (int)values[id].size(); ++i){ |
|
942 values[id][i] = Value(); |
|
943 } |
|
944 } |
|
945 |
|
946 ///\brief Erase more FirstKey from the map. |
|
947 /// |
|
948 ///Erase more FirstKey from the map. It called by the observer |
|
949 ///class belongs to the FirstKey type. |
|
950 void eraseFirstKeys(const std::vector<FirstKey>& firstKeys) { |
|
951 for(int j = 0; j != (int)firstKeys.size(); ++j){ |
|
952 int id = _first_key_proxy.getNotifier()->id(firstKeys[j]); |
|
953 for(int i = 0; i != (int)values[id].size(); ++i){ |
|
954 values[id][i] = Value(); |
|
955 } |
|
956 } |
|
957 } |
|
958 |
|
959 ///\brief Erase a SecondKey from the map. |
|
960 /// |
|
961 ///Erase a SecondKey from the map. It called by the observer class |
|
962 ///belongs to the SecondKey type. |
|
963 void eraseSecondKey(const SecondKey& second) { |
|
964 if(values.size() == 0){ |
|
965 return; |
|
966 } |
|
967 int id = _second_key_proxy.getNotifier()->id(second); |
|
968 for(int i = 0; i != (int)values.size(); ++i){ |
|
969 values[i][id] = Value(); |
|
970 } |
|
971 } |
|
972 |
|
973 ///\brief Erase more SecondKey from the map. |
|
974 /// |
|
975 ///Erase more SecondKey from the map. It called by the observer |
|
976 ///class belongs to the SecondKey type. |
|
977 void eraseSecondKeys(const std::vector<SecondKey>& secondKeys) { |
|
978 if(values.size() == 0){ |
|
979 return; |
|
980 } |
|
981 for(int j = 0; j != (int)secondKeys.size(); ++j){ |
|
982 int id = _second_key_proxy.getNotifier()->id(secondKeys[j]); |
|
983 for(int i = 0; i != (int)values.size(); ++i){ |
|
984 values[i][id] = Value(); |
|
985 } |
|
986 } |
|
987 } |
|
988 |
|
989 ///\brief Builds the map. |
|
990 /// |
|
991 ///It buildes the map. It is called by the observer class belongs |
|
992 ///to the FirstKey or SecondKey type. |
|
993 void build() { |
|
994 values.resize(_first_key_proxy.getNotifier()->maxId()); |
|
995 for(int i=0; i!=(int)values.size(); ++i){ |
|
996 values[i].resize(_second_key_proxy.getNotifier()->maxId()); |
|
997 } |
|
998 } |
|
999 |
|
1000 ///\brief Clear the map. |
|
1001 /// |
|
1002 ///It erases all items from the map. It is called by the observer class |
|
1003 ///belongs to the FirstKey or SecondKey type. |
|
1004 void clear() { |
|
1005 for(int i=0; i!=(int)values.size(); ++i) { |
|
1006 values[i].clear(); |
|
1007 } |
|
1008 values.clear(); |
|
1009 } |
|
1010 |
|
1011 }; |
|
1012 |
|
1013 |
|
1014 |
|
1015 } |
|
1016 |
|
1017 #endif |