3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
19 #ifndef LEMON_MATRIX_MAPS_H
20 #define LEMON_MATRIX_MAPS_H
24 #include <lemon/bits/utility.h>
25 #include <lemon/maps.h>
27 #include <lemon/concept/matrix_maps.h>
31 /// \brief Maps indexed with pairs of items.
33 /// \todo This file has the same name as the concept file in concept/,
34 /// and this is not easily detectable in docs...
37 /// \brief Map for the coloumn view of the matrix
40 /// Map for the coloumn view of the matrix.
42 template <typename _MatrixMap>
43 class MatrixRowMap : public MatrixMapTraits<_MatrixMap> {
45 typedef _MatrixMap MatrixMap;
46 typedef typename MatrixMap::SecondKey Key;
47 typedef typename MatrixMap::Value Value;
50 /// \brief Constructor of the row map
52 /// Constructor of the row map.
53 MatrixRowMap(MatrixMap& _matrix, typename MatrixMap::FirstKey _row)
54 : matrix(_matrix), row(_row) {}
56 /// \brief Subscription operator
58 /// Subscription operator.
59 typename MatrixMapTraits<MatrixMap>::ReturnValue
61 return matrix(row, col);
64 /// \brief Setter function
67 void set(Key col, const Value& val) {
68 matrix.set(row, col, val);
71 /// \brief Subscription operator
73 /// Subscription operator.
74 typename MatrixMapTraits<MatrixMap>::ConstReturnValue
75 operator[](Key col) const {
76 return matrix(row, col);
81 typename MatrixMap::FirstKey row;
84 /// \brief Map for the row view of the matrix
87 /// Map for the row view of the matrix.
89 template <typename _MatrixMap>
90 class ConstMatrixRowMap : public MatrixMapTraits<_MatrixMap> {
92 typedef _MatrixMap MatrixMap;
93 typedef typename MatrixMap::SecondKey Key;
94 typedef typename MatrixMap::Value Value;
97 /// \brief Constructor of the row map
99 /// Constructor of the row map.
100 ConstMatrixRowMap(const MatrixMap& _matrix,
101 typename MatrixMap::FirstKey _row)
102 : matrix(_matrix), row(_row) {}
104 /// \brief Subscription operator
106 /// Subscription operator.
107 typename MatrixMapTraits<MatrixMap>::ConstReturnValue
108 operator[](Key col) const {
109 return matrix(row, col);
113 const MatrixMap& matrix;
114 typename MatrixMap::FirstKey row;
117 /// \ingroup matrices
119 /// \brief Gives back a row view of the matrix map
121 /// Gives back a row view of the matrix map.
124 /// \sa ConstMatrixRowMap
125 template <typename MatrixMap>
126 MatrixRowMap<MatrixMap> matrixRowMap(MatrixMap& matrixMap,
127 typename MatrixMap::FirstKey row) {
128 return MatrixRowMap<MatrixMap>(matrixMap, row);
131 template <typename MatrixMap>
132 ConstMatrixRowMap<MatrixMap>
133 matrixRowMap(const MatrixMap& matrixMap, typename MatrixMap::FirstKey row) {
134 return ConstMatrixRowMap<MatrixMap>(matrixMap, row);
137 /// \brief Map for the column view of the matrix
139 /// \ingroup matrices
140 /// Map for the column view of the matrix.
142 template <typename _MatrixMap>
143 class MatrixColMap : public MatrixMapTraits<_MatrixMap> {
145 typedef _MatrixMap MatrixMap;
146 typedef typename MatrixMap::FirstKey Key;
147 typedef typename MatrixMap::Value Value;
149 /// \brief Constructor of the column map
151 /// Constructor of the column map.
152 MatrixColMap(MatrixMap& _matrix, typename MatrixMap::SecondKey _col)
153 : matrix(_matrix), col(_col) {}
155 /// \brief Subscription operator
157 /// Subscription operator.
158 typename MatrixMapTraits<MatrixMap>::ReturnValue
159 operator[](Key row) {
160 return matrix(row, col);
163 /// \brief Setter function
166 void set(Key row, const Value& val) {
167 matrix.set(row, col, val);
170 /// \brief Subscription operator
172 /// Subscription operator.
173 typename MatrixMapTraits<MatrixMap>::ConstReturnValue
174 operator[](Key row) const {
175 return matrix(row, col);
180 typename MatrixMap::SecondKey col;
183 /// \brief Map for the column view of the matrix
185 /// \ingroup matrices
186 /// Map for the column view of the matrix.
188 template <typename _MatrixMap>
189 class ConstMatrixColMap : public MatrixMapTraits<_MatrixMap> {
191 typedef _MatrixMap MatrixMap;
192 typedef typename MatrixMap::FirstKey Key;
193 typedef typename MatrixMap::Value Value;
195 /// \brief Constructor of the column map
197 /// Constructor of the column map.
198 ConstMatrixColMap(const MatrixMap& _matrix,
199 typename MatrixMap::SecondKey _col)
200 : matrix(_matrix), col(_col) {}
202 /// \brief Subscription operator
204 /// Subscription operator.
205 typename MatrixMapTraits<MatrixMap>::ConstReturnValue
206 operator[](Key row) const {
207 return matrix(row, col);
211 const MatrixMap& matrix;
212 typename MatrixMap::SecondKey col;
215 /// \ingroup matrices
217 /// \brief Gives back a column view of the matrix map
219 /// Gives back a column view of the matrix map.
222 /// \sa ConstMatrixColMap
223 template <typename MatrixMap>
224 MatrixColMap<MatrixMap> matrixColMap(MatrixMap& matrixMap,
225 typename MatrixMap::SecondKey col) {
226 return MatrixColMap<MatrixMap>(matrixMap, col);
229 template <typename MatrixMap>
230 ConstMatrixColMap<MatrixMap>
231 matrixColMap(const MatrixMap& matrixMap, typename MatrixMap::SecondKey col) {
232 return ConstMatrixColMap<MatrixMap>(matrixMap, col);
235 /// \brief Container for store values for each ordered pair of graph items
237 /// \ingroup matrices
238 /// This data structure can strore for each pair of the same item
239 /// type a value. It increase the size of the container when the
240 /// associated graph modified, so it updated automaticly whenever
242 template <typename _Graph, typename _Item, typename _Value>
243 class DynamicMatrixMap
244 : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
246 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase
249 typedef _Graph Graph;
252 typedef _Item FirstKey;
253 typedef _Item SecondKey;
254 typedef _Value Value;
256 typedef True ReferenceMapTag;
260 typedef std::vector<Value> Container;
264 typedef typename Container::reference Reference;
265 typedef typename Container::const_reference ConstReference;
267 /// \brief Creates an item matrix for the given graph
269 /// Creates an item matrix for the given graph.
270 DynamicMatrixMap(const Graph& _graph)
271 : values(size(_graph.maxId(Key()) + 1)) {
272 Parent::attach(_graph.getNotifier(Key()));
275 /// \brief Creates an item matrix for the given graph
277 /// Creates an item matrix for the given graph and assigns for each
278 /// pairs of keys the given parameter.
279 DynamicMatrixMap(const Graph& _graph, const Value& _val)
280 : values(size(_graph.maxId(Key()) + 1), _val) {
281 Parent::attach(_graph.getNotifier(Key()));
284 ///\brief The assignement operator.
286 ///It allow to assign a map to an other.
287 DynamicMatrixMap& operator=(const DynamicMatrixMap& _cmap){
288 return operator=<DynamicMatrixMap>(_cmap);
291 ///\brief Template assignement operator.
293 ///It copy the element of the given map to its own container. The
294 ///type of the two map shall be the same.
295 template <typename CMap>
296 DynamicMatrixMap& operator=(const CMap& _cmap){
297 checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
298 typename Parent::Notifier* notifier = Parent::getNotifier();
300 for(notifier->first(first); first != INVALID;
301 notifier->next(first)){
302 for(notifier->first(second); second != INVALID;
303 notifier->next(second)){
304 set(first, second, _cmap(first, second));
310 /// \brief Gives back the value assigned to the \c first - \c second
313 /// Gives back the value assigned to the \c first - \c second ordered pair.
314 ConstReference operator()(const Key& first, const Key& second) const {
315 return values[index(Parent::getNotifier()->id(first),
316 Parent::getNotifier()->id(second))];
319 /// \brief Gives back the value assigned to the \c first - \c second
322 /// Gives back the value assigned to the \c first - \c second ordered pair.
323 Reference operator()(const Key& first, const Key& second) {
324 return values[index(Parent::getNotifier()->id(first),
325 Parent::getNotifier()->id(second))];
328 /// \brief Setter function for the matrix map.
330 /// Setter function for the matrix map.
331 void set(const Key& first, const Key& second, const Value& val) {
332 values[index(Parent::getNotifier()->id(first),
333 Parent::getNotifier()->id(second))] = val;
338 static int index(int i, int j) {
342 return i * i + i + j;
346 static int size(int s) {
350 virtual void add(const Key& key) {
351 if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
352 values.resize(size(Parent::getNotifier()->id(key) + 1));
356 virtual void erase(const Key&) {}
358 virtual void build() {
359 values.resize(size(Parent::getNotifier()->maxId() + 1));
362 virtual void clear() {
367 std::vector<Value> values;
370 /// \brief Container for store values for each unordered pair of graph items
372 /// \ingroup matrices
373 /// This data structure can strore for each pair of the same item
374 /// type a value. It increase the size of the container when the
375 /// associated graph modified, so it updated automaticly whenever
377 template <typename _Graph, typename _Item, typename _Value>
378 class DynamicSymMatrixMap
379 : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
381 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase
384 typedef _Graph Graph;
387 typedef _Item FirstKey;
388 typedef _Item SecondKey;
389 typedef _Value Value;
391 typedef True ReferenceMapTag;
395 typedef std::vector<Value> Container;
399 typedef typename Container::reference Reference;
400 typedef typename Container::const_reference ConstReference;
402 /// \brief Creates an item matrix for the given graph
404 /// Creates an item matrix for the given graph.
405 DynamicSymMatrixMap(const Graph& _graph)
406 : values(size(_graph.maxId(Key()) + 1)) {
407 Parent::attach(_graph.getNotifier(Key()));
410 /// \brief Creates an item matrix for the given graph
412 /// Creates an item matrix for the given graph and assigns for each
413 /// pairs of keys the given parameter.
414 DynamicSymMatrixMap(const Graph& _graph, const Value& _val)
415 : values(size(_graph.maxId(Key()) + 1), _val) {
416 Parent::attach(_graph.getNotifier(Key()));
420 ///\brief The assignement operator.
422 ///It allow to assign a map to an other.
424 DynamicSymMatrixMap& operator=(const DynamicSymMatrixMap& _cmap){
425 return operator=<DynamicSymMatrixMap>(_cmap);
428 ///\brief Template assignement operator.
430 ///It copy the element of the given map to its own container. The
431 ///type of the two map shall be the same.
432 template <typename CMap>
433 DynamicSymMatrixMap& operator=(const CMap& _cmap){
434 checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
435 typename Parent::Notifier* notifier = Parent::getNotifier();
437 for(notifier->first(first); first != INVALID;
438 notifier->next(first)){
439 for(notifier->first(second); second != first;
440 notifier->next(second)){
441 set(first, second, _cmap(first, second));
443 set(first, first, _cmap(first, first));
448 /// \brief Gives back the value assigned to the \c first - \c second
451 /// Gives back the value assigned to the \c first - \c second unordered
453 ConstReference operator()(const Key& first, const Key& second) const {
454 return values[index(Parent::getNotifier()->id(first),
455 Parent::getNotifier()->id(second))];
458 /// \brief Gives back the value assigned to the \c first - \c second
461 /// Gives back the value assigned to the \c first - \c second unordered
463 Reference operator()(const Key& first, const Key& second) {
464 return values[index(Parent::getNotifier()->id(first),
465 Parent::getNotifier()->id(second))];
468 /// \brief Setter function for the matrix map.
470 /// Setter function for the matrix map.
472 void set(const Key& first, const Key& second, const Value& val) {
473 values[index(Parent::getNotifier()->id(first),
474 Parent::getNotifier()->id(second))] = val;
479 static int index(int i, int j) {
481 return j * (j + 1) / 2 + i;
483 return i * (i + 1) / 2 + j;
487 static int size(int s) {
488 return s * (s + 1) / 2;
491 virtual void add(const Key& key) {
492 if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
493 values.resize(size(Parent::getNotifier()->id(key) + 1));
497 virtual void erase(const Key&) {}
499 virtual void build() {
500 values.resize(size(Parent::getNotifier()->maxId() + 1));
503 virtual void clear() {
508 std::vector<Value> values;
511 ///\brief Dynamic Asymmetric Matrix Map.
514 ///Dynamic Asymmetric Matrix Map. Container for store values for each
515 ///ordered pair of containers items. This data structure can store
516 ///data with different key types from different container types. It
517 ///increases the size of the container if the linked containers
518 ///content change, so it is updated automaticly whenever it is
521 ///This map meet with the concept::ReferenceMatrixMap<typename K1,
522 ///typename K2, typename V, typename R, typename CR> called as
523 ///"ReferenceMatrixMap".
525 ///\param _FirstContainer the desired type of first container. It is
526 ///ususally a Graph type, but can be any type with alteration
529 ///\param _FirstContainerItem the nested type of the
530 ///FirstContainer. It is usually a graph item as Node, Edge,
531 ///etc. This type will be the FirstKey type.
533 ///\param _SecondContainer the desired type of the second
534 ///container. It is usualy a Graph type, but can be any type with
535 ///alteration property.
537 ///\param _SecondContainerItem the nested type of the
538 ///SecondContainer. It is usually a graph item such as Node, Edge,
539 ///UEdge, etc. This type will be the SecondKey type.
541 ///\param _Value the type of the strored values in the container.
543 /// \author Janos Nagy
544 template <typename _FirstContainer, typename _FirstContainerItem,
545 typename _SecondContainer, typename _SecondContainerItem,
547 class DynamicAsymMatrixMap{
550 ///The first key type.
551 typedef _FirstContainerItem FirstKey;
553 ///The second key type.
554 typedef _SecondContainerItem SecondKey;
556 ///The value type of the map.
557 typedef _Value Value;
559 ///Indicates it is a reference map.
560 typedef True ReferenceMapTag;
564 ///\brief Proxy class for the first key type.
566 ///The proxy class belongs to the FirstKey type. It is necessary because
567 ///if one want use the same conatainer types and same nested types but on
568 ///other instances of containers than due to the type equiality of nested
569 ///types it requires a proxy mechanism.
572 ItemSetTraits<_FirstContainer,_FirstContainerItem>::
573 ItemNotifier::ObserverBase
578 friend class DynamicAsymMatrixMap;
581 FirstKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { }
584 ///\brief Add a new FirstKey to the map.
586 ///It adds a new FirstKey to the map. It is called by the
587 ///observer notifier and it is ovverride the add() virtual
588 ///member function in the observer base. It will call the
589 ///maps addFirstKey() function.
590 virtual void add(const FirstKey& _firstKey){
591 _owner.addFirstKey(_firstKey);
594 ///\brief Add more new FirstKey to the map.
596 ///It adds more new FirstKey to the map. It is called by the
597 ///observer notifier and it is ovverride the add() virtual
598 ///member function in the observer base. It will call the
599 ///map's addFirstKeys() function.
600 virtual void add(const std::vector<FirstKey>& _firstKeys){
601 _owner.addFirstKeys(_firstKeys);
604 ///\brief Erase a FirstKey from the map.
606 ///Erase a FirstKey from the map. It called by the observer
607 ///notifier and it overrides the erase() virtual member
608 ///function of the observer base. It will call the map's
609 ///eraseFirstKey() function.
610 virtual void erase(const FirstKey& _firstKey){
611 _owner.eraseFirstKey(_firstKey);
614 ///\brief Erase more FirstKey from the map.
616 ///Erase more FirstKey from the map. It called by the
617 ///observer notifier and it overrides the erase() virtual
618 ///member function of the observer base. It will call the
619 ///map's eraseFirstKeys() function.
620 virtual void erase(const std::vector<FirstKey>& _firstKeys){
621 _owner.eraseFirstKeys(_firstKeys);
624 ///\brief Builds the map.
626 ///It buildes the map. It called by the observer notifier
627 ///and it overrides the build() virtual member function of
628 ///the observer base. It will call the map's build()
630 virtual void build() {
632 //_owner.buildFirst();
635 ///\brief Clear the map.
637 ///It erases all items from the map. It called by the
638 ///observer notifier and it overrides the clear() virtual
639 ///memeber function of the observer base. It will call the
640 ///map's clear() function.
641 virtual void clear() {
643 //_owner.clearFirst();
647 ///The map type for it is linked.
648 DynamicAsymMatrixMap& _owner;
649 };//END OF FIRSTKEYPROXY
651 ///\brief Proxy class for the second key type.
653 ///The proxy class belongs to the SecondKey type. It is
654 ///necessary because if one want use the same conatainer types
655 ///and same nested types but on other instances of containers
656 ///than due to the type equiality of nested types it requires a
660 ItemSetTraits<_SecondContainer, _SecondContainerItem>::
661 ItemNotifier::ObserverBase {
665 friend class DynamicAsymMatrixMap;
667 SecondKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { }
671 ///\brief Add a new SecondKey to the map.
673 ///It adds a new SecondKey to the map. It is called by the
674 ///observer notifier and it is ovverride the add() virtual
675 ///member function in the observer base. It will call the
676 ///maps addSecondKey() function.
677 virtual void add(const SecondKey& _secondKey){
678 _owner.addSecondKey(_secondKey);
681 ///\brief Add more new SecondKey to the map.
683 ///It adds more new SecondKey to the map. It is called by
684 ///the observer notifier and it is ovverride the add()
685 ///virtual member function in the observer base. It will
686 ///call the maps addSecondKeys() function.
687 virtual void add(const std::vector<SecondKey>& _secondKeys){
688 _owner.addSecondKeys(_secondKeys);
691 ///\brief Erase a SecondKey from the map.
693 ///Erase a SecondKey from the map. It called by the observer
694 ///notifier and it overrides the erase() virtual member
695 ///function of the observer base. It will call the map's
696 ///eraseSecondKey() function.
697 virtual void erase(const SecondKey& _secondKey){
698 _owner.eraseSecondKey(_secondKey);
701 ///\brief Erase more SecondKeys from the map.
703 ///Erase more SecondKey from the map. It called by the
704 ///observer notifier and it overrides the erase() virtual
705 ///member function of the observer base. It will call the
706 ///map's eraseSecondKeys() function.
707 virtual void erase(const std::vector<SecondKey>& _secondKeys){
708 _owner.eraseSecondKeys(_secondKeys);
711 ///\brief Builds the map.
713 ///It buildes the map. It called by the observer notifier
714 ///and it overrides the build() virtual member function of
715 ///the observer base. It will call the map's build()
717 virtual void build() {
721 ///\brief Clear the map.
723 ///It erases all items from the map. It called by the
724 ///observer notifier and it overrides the clear() virtual
725 ///memeber function of the observer base. It will call the
726 ///map's clear() function.
727 virtual void clear() {
729 //_owner.clearFirst();
733 ///The type of map for which it is attached.
734 DynamicAsymMatrixMap& _owner;
735 };//END OF SECONDKEYPROXY
740 typedef std::vector<Value> Container;
742 ///The type of constainer which stores the values of the map.
743 typedef std::vector<Container> DContainer;
745 ///The std:vector type which contains the data
748 ///Member for the first proxy class
749 FirstKeyProxy _first_key_proxy;
751 ///Member for the second proxy class
752 SecondKeyProxy _second_key_proxy;
756 ///The refernce type of the map.
757 typedef typename Container::reference Reference;
759 ///The const reference type of the constainer.
760 typedef typename Container::const_reference ConstReference;
762 ///\brief Constructor what create the map for the two containers type.
764 ///Creates the matrix map and initialize the values with Value()
765 DynamicAsymMatrixMap(const _FirstContainer& _firstContainer,
766 const _SecondContainer& _secondContainer)
767 : values(DContainer(_firstContainer.maxId(FirstKey())+1,
768 Container(_secondContainer.maxId(SecondKey())+1))),
769 _first_key_proxy(*this),
770 _second_key_proxy(*this)
772 _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey()));
773 _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey()));
776 ///\brief Constructor what create the map for the two containers type.
778 ///Creates the matrix map and initialize the values with the given _value
779 DynamicAsymMatrixMap(const _FirstContainer& _firstContainer,
780 const _SecondContainer& _secondContainer,
782 : values(DContainer(_firstContainer.maxId(FirstKey())+1,
783 Container(_secondContainer.maxId(SecondKey())+1,
785 _first_key_proxy(*this),
786 _second_key_proxy(*this)
788 _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey()));
789 _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey()));
792 ///\brief Copy constructor.
794 ///The copy constructor of the map.
795 DynamicAsymMatrixMap(const DynamicAsymMatrixMap& _copy)
796 : _first_key_proxy(*this), _second_key_proxy(*this) {
797 if(_copy._first_key_proxy.attached() &&
798 _copy._second_key_proxy.attached()){
799 _first_key_proxy.attach(*_copy._first_key_proxy.getNotifier());
800 _second_key_proxy.attach(*_copy._second_key_proxy.getNotifier());
801 values = _copy.values;
807 ///Destructor what detach() from the attached objects. May this
808 ///function is not necessary because the destructor of
809 ///ObserverBase do the same.
810 ~DynamicAsymMatrixMap() {
811 if(_first_key_proxy.attached()){
812 _first_key_proxy.detach();
814 if(_second_key_proxy.attached()){
815 _second_key_proxy.detach();
819 ///\brief Gives back the value assigned to the \c first - \c
820 ///second ordered pair.
822 ///Gives back the value assigned to the \c first - \c second
824 Reference operator()(const FirstKey& _first, const SecondKey& _second) {
825 return values[_first_key_proxy.getNotifier()->id(_first)]
826 [_second_key_proxy.getNotifier()->id(_second)];
829 ///\brief Gives back the value assigned to the \c first - \c
830 ///second ordered pair.
832 ///Gives back the value assigned to the \c first - \c second
834 ConstReference operator()(const FirstKey& _first,
835 const SecondKey& _second) const {
836 return values[_first_key_proxy.getNotifier()->id(_first)]
837 [_second_key_proxy.getNotifier()->id(_second)];
840 ///\brief Setter function for this matrix map.
842 ///Setter function for this matrix map.
843 void set(const FirstKey& first, const SecondKey& second,
845 values[_first_key_proxy.getNotifier()->id(first)]
846 [_second_key_proxy.getNotifier()->id(second)] = value;
849 ///\brief The assignement operator.
851 ///It allow to assign a map to an other. It
852 DynamicAsymMatrixMap& operator=(const DynamicAsymMatrixMap& _cmap){
853 return operator=<DynamicAsymMatrixMap>(_cmap);
856 ///\brief Template assignement operator.
858 ///It copy the element of the given map to its own container. The
859 ///type of the two map shall be the same.
860 template <typename CMap>
861 DynamicAsymMatrixMap& operator=(const CMap& _cdmap){
862 checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
863 const typename FirstKeyProxy::Notifier* notifierFirstKey =
864 _first_key_proxy.getNotifier();
865 const typename SecondKeyProxy::Notifier* notifierSecondKey =
866 _second_key_proxy.getNotifier();
868 SecondKey itemSecond;
869 for(notifierFirstKey->first(itemFirst); itemFirst != INVALID;
870 notifierFirstKey->next(itemFirst)){
871 for(notifierSecondKey->first(itemSecond); itemSecond != INVALID;
872 notifierSecondKey->next(itemSecond)){
873 set(itemFirst, itemSecond, _cdmap(itemFirst,itemSecond));
881 ///\brief Add a new FirstKey to the map.
883 ///It adds a new FirstKey to the map. It is called by the observer
884 ///class belongs to the FirstKey type.
885 void addFirstKey(const FirstKey& firstKey) {
886 int size = (int)values.size();
887 if( _first_key_proxy.getNotifier()->id(firstKey)+1 >= size ){
888 values.resize(_first_key_proxy.getNotifier()->id(firstKey)+1);
889 if( (int)values[0].size() != 0 ){
890 int innersize = (int)values[0].size();
891 for(int i=size; i!=(int)values.size();++i){
892 (values[i]).resize(innersize);
894 }else if(_second_key_proxy.getNotifier()->maxId() >= 0){
895 int innersize = _second_key_proxy.getNotifier()->maxId();
896 for(int i = 0; i != (int)values.size(); ++i){
897 values[0].resize(innersize);
903 ///\brief Adds more new FirstKeys to the map.
905 ///It adds more new FirstKeys to the map. It called by the
906 ///observer class belongs to the FirstKey type.
907 void addFirstKeys(const std::vector<FirstKey>& firstKeys){
908 int max = values.size() - 1;
909 for(int i=0; i != (int)firstKeys.size(); ++i){
910 int id = _first_key_proxy.getNotifier()->id(firstKeys[i]);
915 int size = (int)values.size();
917 values.resize(max + 1);
918 if( (int)values[0].size() != 0){
919 int innersize = (int)values[0].size();
920 for(int i = size; i != (max + 1); ++i){
921 values[i].resize(innersize);
923 }else if(_second_key_proxy.getNotifier()->maxId() >= 0){
924 int innersize = _second_key_proxy.getNotifier()->maxId();
925 for(int i = 0; i != (int)values.size(); ++i){
926 values[i].resize(innersize);
932 ///\brief Add a new SecondKey to the map.
934 ///It adds a new SecondKey to the map. It is called by the
935 ///observer class belongs to the SecondKey type.
936 void addSecondKey(const SecondKey& secondKey) {
937 if(values.size() == 0){
940 int id = _second_key_proxy.getNotifier()->id(secondKey);
941 if(id >= (int)values[0].size()){
942 for(int i=0;i!=(int)values.size();++i){
943 values[i].resize(id+1);
948 ///\brief Adds more new SecondKeys to the map.
950 ///It adds more new SecondKeys to the map. It called by the
951 ///observer class belongs to the SecondKey type.
952 void addSecondKeys(const std::vector<SecondKey>& secondKeys){
953 if(values.size() == 0){
956 int max = values[0].size();
957 for(int i = 0; i != (int)secondKeys.size(); ++i){
958 int id = _second_key_proxy.getNotifier()->id(secondKeys[i]);
963 if(max > (int)values[0].size()){
964 for(int i = 0; i != (int)values.size(); ++i){
965 values[i].resize(max + 1);
970 ///\brief Erase a FirstKey from the map.
972 ///Erase a FirstKey from the map. It called by the observer
973 ///class belongs to the FirstKey type.
974 void eraseFirstKey(const FirstKey& first) {
975 int id = _first_key_proxy.getNotifier()->id(first);
976 for(int i = 0; i != (int)values[id].size(); ++i){
977 values[id][i] = Value();
981 ///\brief Erase more FirstKey from the map.
983 ///Erase more FirstKey from the map. It called by the observer
984 ///class belongs to the FirstKey type.
985 void eraseFirstKeys(const std::vector<FirstKey>& firstKeys) {
986 for(int j = 0; j != (int)firstKeys.size(); ++j){
987 int id = _first_key_proxy.getNotifier()->id(firstKeys[j]);
988 for(int i = 0; i != (int)values[id].size(); ++i){
989 values[id][i] = Value();
994 ///\brief Erase a SecondKey from the map.
996 ///Erase a SecondKey from the map. It called by the observer class
997 ///belongs to the SecondKey type.
998 void eraseSecondKey(const SecondKey& second) {
999 if(values.size() == 0){
1002 int id = _second_key_proxy.getNotifier()->id(second);
1003 for(int i = 0; i != (int)values.size(); ++i){
1004 values[i][id] = Value();
1008 ///\brief Erase more SecondKey from the map.
1010 ///Erase more SecondKey from the map. It called by the observer
1011 ///class belongs to the SecondKey type.
1012 void eraseSecondKeys(const std::vector<SecondKey>& secondKeys) {
1013 if(values.size() == 0){
1016 for(int j = 0; j != (int)secondKeys.size(); ++j){
1017 int id = _second_key_proxy.getNotifier()->id(secondKeys[j]);
1018 for(int i = 0; i != (int)values.size(); ++i){
1019 values[i][id] = Value();
1024 ///\brief Builds the map.
1026 ///It buildes the map. It is called by the observer class belongs
1027 ///to the FirstKey or SecondKey type.
1029 values.resize(_first_key_proxy.getNotifier()->maxId());
1030 for(int i=0; i!=(int)values.size(); ++i){
1031 values[i].resize(_second_key_proxy.getNotifier()->maxId());
1035 ///\brief Clear the map.
1037 ///It erases all items from the map. It is called by the observer class
1038 ///belongs to the FirstKey or SecondKey type.
1040 for(int i=0; i!=(int)values.size(); ++i) {