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/bits/invalid.h>
26 #include <lemon/maps.h>
28 #include <lemon/concepts/matrix_maps.h>
32 /// \brief Maps indexed with pairs of items.
34 /// \todo This file has the same name as the concept file in concepts/,
35 /// and this is not easily detectable in docs...
38 /// \brief Map for the coloumn view of the matrix
41 /// Map for the coloumn view of the matrix.
43 template <typename _MatrixMap>
44 class MatrixRowMap : public MatrixMapTraits<_MatrixMap> {
46 typedef _MatrixMap MatrixMap;
47 typedef typename MatrixMap::SecondKey Key;
48 typedef typename MatrixMap::Value Value;
51 /// \brief Constructor of the row map
53 /// Constructor of the row map.
54 MatrixRowMap(MatrixMap& _matrix, typename MatrixMap::FirstKey _row)
55 : matrix(_matrix), row(_row) {}
57 /// \brief Subscription operator
59 /// Subscription operator.
60 typename MatrixMapTraits<MatrixMap>::ReturnValue
62 return matrix(row, col);
65 /// \brief Setter function
68 void set(Key col, const Value& val) {
69 matrix.set(row, col, val);
72 /// \brief Subscription operator
74 /// Subscription operator.
75 typename MatrixMapTraits<MatrixMap>::ConstReturnValue
76 operator[](Key col) const {
77 return matrix(row, col);
82 typename MatrixMap::FirstKey row;
85 /// \brief Map for the row view of the matrix
88 /// Map for the row view of the matrix.
90 template <typename _MatrixMap>
91 class ConstMatrixRowMap : public MatrixMapTraits<_MatrixMap> {
93 typedef _MatrixMap MatrixMap;
94 typedef typename MatrixMap::SecondKey Key;
95 typedef typename MatrixMap::Value Value;
98 /// \brief Constructor of the row map
100 /// Constructor of the row map.
101 ConstMatrixRowMap(const MatrixMap& _matrix,
102 typename MatrixMap::FirstKey _row)
103 : matrix(_matrix), row(_row) {}
105 /// \brief Subscription operator
107 /// Subscription operator.
108 typename MatrixMapTraits<MatrixMap>::ConstReturnValue
109 operator[](Key col) const {
110 return matrix(row, col);
114 const MatrixMap& matrix;
115 typename MatrixMap::FirstKey row;
118 /// \ingroup matrices
120 /// \brief Gives back a row view of the matrix map
122 /// Gives back a row view of the matrix map.
125 /// \sa ConstMatrixRowMap
126 template <typename MatrixMap>
127 MatrixRowMap<MatrixMap> matrixRowMap(MatrixMap& matrixMap,
128 typename MatrixMap::FirstKey row) {
129 return MatrixRowMap<MatrixMap>(matrixMap, row);
132 template <typename MatrixMap>
133 ConstMatrixRowMap<MatrixMap>
134 matrixRowMap(const MatrixMap& matrixMap, typename MatrixMap::FirstKey row) {
135 return ConstMatrixRowMap<MatrixMap>(matrixMap, row);
138 /// \brief Map for the column view of the matrix
140 /// \ingroup matrices
141 /// Map for the column view of the matrix.
143 template <typename _MatrixMap>
144 class MatrixColMap : public MatrixMapTraits<_MatrixMap> {
146 typedef _MatrixMap MatrixMap;
147 typedef typename MatrixMap::FirstKey Key;
148 typedef typename MatrixMap::Value Value;
150 /// \brief Constructor of the column map
152 /// Constructor of the column map.
153 MatrixColMap(MatrixMap& _matrix, typename MatrixMap::SecondKey _col)
154 : matrix(_matrix), col(_col) {}
156 /// \brief Subscription operator
158 /// Subscription operator.
159 typename MatrixMapTraits<MatrixMap>::ReturnValue
160 operator[](Key row) {
161 return matrix(row, col);
164 /// \brief Setter function
167 void set(Key row, const Value& val) {
168 matrix.set(row, col, val);
171 /// \brief Subscription operator
173 /// Subscription operator.
174 typename MatrixMapTraits<MatrixMap>::ConstReturnValue
175 operator[](Key row) const {
176 return matrix(row, col);
181 typename MatrixMap::SecondKey col;
184 /// \brief Map for the column view of the matrix
186 /// \ingroup matrices
187 /// Map for the column view of the matrix.
189 template <typename _MatrixMap>
190 class ConstMatrixColMap : public MatrixMapTraits<_MatrixMap> {
192 typedef _MatrixMap MatrixMap;
193 typedef typename MatrixMap::FirstKey Key;
194 typedef typename MatrixMap::Value Value;
196 /// \brief Constructor of the column map
198 /// Constructor of the column map.
199 ConstMatrixColMap(const MatrixMap& _matrix,
200 typename MatrixMap::SecondKey _col)
201 : matrix(_matrix), col(_col) {}
203 /// \brief Subscription operator
205 /// Subscription operator.
206 typename MatrixMapTraits<MatrixMap>::ConstReturnValue
207 operator[](Key row) const {
208 return matrix(row, col);
212 const MatrixMap& matrix;
213 typename MatrixMap::SecondKey col;
216 /// \ingroup matrices
218 /// \brief Gives back a column view of the matrix map
220 /// Gives back a column view of the matrix map.
223 /// \sa ConstMatrixColMap
224 template <typename MatrixMap>
225 MatrixColMap<MatrixMap> matrixColMap(MatrixMap& matrixMap,
226 typename MatrixMap::SecondKey col) {
227 return MatrixColMap<MatrixMap>(matrixMap, col);
230 template <typename MatrixMap>
231 ConstMatrixColMap<MatrixMap>
232 matrixColMap(const MatrixMap& matrixMap, typename MatrixMap::SecondKey col) {
233 return ConstMatrixColMap<MatrixMap>(matrixMap, col);
236 /// \brief Container for store values for each ordered pair of graph items
238 /// \ingroup matrices
239 /// This data structure can strore for each pair of the same item
240 /// type a value. It increase the size of the container when the
241 /// associated graph modified, so it updated automaticly whenever
243 template <typename _Graph, typename _Item, typename _Value>
244 class DynamicMatrixMap
245 : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
247 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase
250 typedef _Graph Graph;
253 typedef _Item FirstKey;
254 typedef _Item SecondKey;
255 typedef _Value Value;
257 typedef True ReferenceMapTag;
261 typedef std::vector<Value> Container;
265 typedef typename Container::reference Reference;
266 typedef typename Container::const_reference ConstReference;
268 /// \brief Creates an item matrix for the given graph
270 /// Creates an item matrix for the given graph.
271 DynamicMatrixMap(const Graph& _graph)
272 : values(size(_graph.maxId(Key()) + 1)) {
273 Parent::attach(_graph.getNotifier(Key()));
276 /// \brief Creates an item matrix for the given graph
278 /// Creates an item matrix for the given graph and assigns for each
279 /// pairs of keys the given parameter.
280 DynamicMatrixMap(const Graph& _graph, const Value& _val)
281 : values(size(_graph.maxId(Key()) + 1), _val) {
282 Parent::attach(_graph.getNotifier(Key()));
285 ///\brief The assignement operator.
287 ///It allow to assign a map to an other.
288 DynamicMatrixMap& operator=(const DynamicMatrixMap& _cmap){
289 return operator=<DynamicMatrixMap>(_cmap);
292 ///\brief Template assignement operator.
294 ///It copy the element of the given map to its own container. The
295 ///type of the two map shall be the same.
296 template <typename CMap>
297 DynamicMatrixMap& operator=(const CMap& _cmap){
298 checkConcept<concepts::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
299 typename Parent::Notifier* notifier = Parent::getNotifier();
301 for(notifier->first(first); first != INVALID;
302 notifier->next(first)){
303 for(notifier->first(second); second != INVALID;
304 notifier->next(second)){
305 set(first, second, _cmap(first, second));
311 /// \brief Gives back the value assigned to the \c first - \c second
314 /// Gives back the value assigned to the \c first - \c second ordered pair.
315 ConstReference operator()(const Key& first, const Key& second) const {
316 return values[index(Parent::getNotifier()->id(first),
317 Parent::getNotifier()->id(second))];
320 /// \brief Gives back the value assigned to the \c first - \c second
323 /// Gives back the value assigned to the \c first - \c second ordered pair.
324 Reference operator()(const Key& first, const Key& second) {
325 return values[index(Parent::getNotifier()->id(first),
326 Parent::getNotifier()->id(second))];
329 /// \brief Setter function for the matrix map.
331 /// Setter function for the matrix map.
332 void set(const Key& first, const Key& second, const Value& val) {
333 values[index(Parent::getNotifier()->id(first),
334 Parent::getNotifier()->id(second))] = val;
339 static int index(int i, int j) {
343 return i * i + i + j;
347 static int size(int s) {
351 virtual void add(const Key& key) {
352 if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
353 values.resize(size(Parent::getNotifier()->id(key) + 1));
357 virtual void erase(const Key&) {}
359 virtual void build() {
360 values.resize(size(Parent::getNotifier()->maxId() + 1));
363 virtual void clear() {
368 std::vector<Value> values;
371 /// \brief Container for store values for each unordered pair of graph items
373 /// \ingroup matrices
374 /// This data structure can strore for each pair of the same item
375 /// type a value. It increase the size of the container when the
376 /// associated graph modified, so it updated automaticly whenever
378 template <typename _Graph, typename _Item, typename _Value>
379 class DynamicSymMatrixMap
380 : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
382 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase
385 typedef _Graph Graph;
388 typedef _Item FirstKey;
389 typedef _Item SecondKey;
390 typedef _Value Value;
392 typedef True ReferenceMapTag;
396 typedef std::vector<Value> Container;
400 typedef typename Container::reference Reference;
401 typedef typename Container::const_reference ConstReference;
403 /// \brief Creates an item matrix for the given graph
405 /// Creates an item matrix for the given graph.
406 DynamicSymMatrixMap(const Graph& _graph)
407 : values(size(_graph.maxId(Key()) + 1)) {
408 Parent::attach(_graph.getNotifier(Key()));
411 /// \brief Creates an item matrix for the given graph
413 /// Creates an item matrix for the given graph and assigns for each
414 /// pairs of keys the given parameter.
415 DynamicSymMatrixMap(const Graph& _graph, const Value& _val)
416 : values(size(_graph.maxId(Key()) + 1), _val) {
417 Parent::attach(_graph.getNotifier(Key()));
421 ///\brief The assignement operator.
423 ///It allow to assign a map to an other.
425 DynamicSymMatrixMap& operator=(const DynamicSymMatrixMap& _cmap){
426 return operator=<DynamicSymMatrixMap>(_cmap);
429 ///\brief Template assignement operator.
431 ///It copy the element of the given map to its own container. The
432 ///type of the two map shall be the same.
433 template <typename CMap>
434 DynamicSymMatrixMap& operator=(const CMap& _cmap){
435 checkConcept<concepts::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
436 typename Parent::Notifier* notifier = Parent::getNotifier();
438 for(notifier->first(first); first != INVALID;
439 notifier->next(first)){
440 for(notifier->first(second); second != first;
441 notifier->next(second)){
442 set(first, second, _cmap(first, second));
444 set(first, first, _cmap(first, first));
449 /// \brief Gives back the value assigned to the \c first - \c second
452 /// Gives back the value assigned to the \c first - \c second unordered
454 ConstReference operator()(const Key& first, const Key& second) const {
455 return values[index(Parent::getNotifier()->id(first),
456 Parent::getNotifier()->id(second))];
459 /// \brief Gives back the value assigned to the \c first - \c second
462 /// Gives back the value assigned to the \c first - \c second unordered
464 Reference operator()(const Key& first, const Key& second) {
465 return values[index(Parent::getNotifier()->id(first),
466 Parent::getNotifier()->id(second))];
469 /// \brief Setter function for the matrix map.
471 /// Setter function for the matrix map.
473 void set(const Key& first, const Key& second, const Value& val) {
474 values[index(Parent::getNotifier()->id(first),
475 Parent::getNotifier()->id(second))] = val;
480 static int index(int i, int j) {
482 return j * (j + 1) / 2 + i;
484 return i * (i + 1) / 2 + j;
488 static int size(int s) {
489 return s * (s + 1) / 2;
492 virtual void add(const Key& key) {
493 if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
494 values.resize(size(Parent::getNotifier()->id(key) + 1));
498 virtual void erase(const Key&) {}
500 virtual void build() {
501 values.resize(size(Parent::getNotifier()->maxId() + 1));
504 virtual void clear() {
509 std::vector<Value> values;
512 ///\brief Dynamic Asymmetric Matrix Map.
515 ///Dynamic Asymmetric Matrix Map. Container for store values for each
516 ///ordered pair of containers items. This data structure can store
517 ///data with different key types from different container types. It
518 ///increases the size of the container if the linked containers
519 ///content change, so it is updated automaticly whenever it is
522 ///This map meet with the concepts::ReferenceMatrixMap<typename K1,
523 ///typename K2, typename V, typename R, typename CR> called as
524 ///"ReferenceMatrixMap".
526 ///\param _FirstContainer the desired type of first container. It is
527 ///ususally a Graph type, but can be any type with alteration
530 ///\param _FirstContainerItem the nested type of the
531 ///FirstContainer. It is usually a graph item as Node, Edge,
532 ///etc. This type will be the FirstKey type.
534 ///\param _SecondContainer the desired type of the second
535 ///container. It is usualy a Graph type, but can be any type with
536 ///alteration property.
538 ///\param _SecondContainerItem the nested type of the
539 ///SecondContainer. It is usually a graph item such as Node, Edge,
540 ///UEdge, etc. This type will be the SecondKey type.
542 ///\param _Value the type of the strored values in the container.
544 /// \author Janos Nagy
545 template <typename _FirstContainer, typename _FirstContainerItem,
546 typename _SecondContainer, typename _SecondContainerItem,
548 class DynamicAsymMatrixMap{
551 ///The first key type.
552 typedef _FirstContainerItem FirstKey;
554 ///The second key type.
555 typedef _SecondContainerItem SecondKey;
557 ///The value type of the map.
558 typedef _Value Value;
560 ///Indicates it is a reference map.
561 typedef True ReferenceMapTag;
565 ///\brief Proxy class for the first key type.
567 ///The proxy class belongs to the FirstKey type. It is necessary because
568 ///if one want use the same conatainer types and same nested types but on
569 ///other instances of containers than due to the type equiality of nested
570 ///types it requires a proxy mechanism.
573 ItemSetTraits<_FirstContainer,_FirstContainerItem>::
574 ItemNotifier::ObserverBase
579 friend class DynamicAsymMatrixMap;
582 FirstKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { }
585 ///\brief Add a new FirstKey to the map.
587 ///It adds a new FirstKey to the map. It is called by the
588 ///observer notifier and it is ovverride the add() virtual
589 ///member function in the observer base. It will call the
590 ///maps addFirstKey() function.
591 virtual void add(const FirstKey& _firstKey){
592 _owner.addFirstKey(_firstKey);
595 ///\brief Add more new FirstKey to the map.
597 ///It adds more new FirstKey to the map. It is called by the
598 ///observer notifier and it is ovverride the add() virtual
599 ///member function in the observer base. It will call the
600 ///map's addFirstKeys() function.
601 virtual void add(const std::vector<FirstKey>& _firstKeys){
602 _owner.addFirstKeys(_firstKeys);
605 ///\brief Erase a FirstKey from the map.
607 ///Erase a FirstKey from the map. It called by the observer
608 ///notifier and it overrides the erase() virtual member
609 ///function of the observer base. It will call the map's
610 ///eraseFirstKey() function.
611 virtual void erase(const FirstKey& _firstKey){
612 _owner.eraseFirstKey(_firstKey);
615 ///\brief Erase more FirstKey from the map.
617 ///Erase more FirstKey from the map. It called by the
618 ///observer notifier and it overrides the erase() virtual
619 ///member function of the observer base. It will call the
620 ///map's eraseFirstKeys() function.
621 virtual void erase(const std::vector<FirstKey>& _firstKeys){
622 _owner.eraseFirstKeys(_firstKeys);
625 ///\brief Builds the map.
627 ///It buildes the map. It called by the observer notifier
628 ///and it overrides the build() virtual member function of
629 ///the observer base. It will call the map's build()
631 virtual void build() {
633 //_owner.buildFirst();
636 ///\brief Clear the map.
638 ///It erases all items from the map. It called by the
639 ///observer notifier and it overrides the clear() virtual
640 ///memeber function of the observer base. It will call the
641 ///map's clear() function.
642 virtual void clear() {
644 //_owner.clearFirst();
648 ///The map type for it is linked.
649 DynamicAsymMatrixMap& _owner;
650 };//END OF FIRSTKEYPROXY
652 ///\brief Proxy class for the second key type.
654 ///The proxy class belongs to the SecondKey type. It is
655 ///necessary because if one want use the same conatainer types
656 ///and same nested types but on other instances of containers
657 ///than due to the type equiality of nested types it requires a
661 ItemSetTraits<_SecondContainer, _SecondContainerItem>::
662 ItemNotifier::ObserverBase {
666 friend class DynamicAsymMatrixMap;
668 SecondKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { }
672 ///\brief Add a new SecondKey to the map.
674 ///It adds a new SecondKey to the map. It is called by the
675 ///observer notifier and it is ovverride the add() virtual
676 ///member function in the observer base. It will call the
677 ///maps addSecondKey() function.
678 virtual void add(const SecondKey& _secondKey){
679 _owner.addSecondKey(_secondKey);
682 ///\brief Add more new SecondKey to the map.
684 ///It adds more new SecondKey to the map. It is called by
685 ///the observer notifier and it is ovverride the add()
686 ///virtual member function in the observer base. It will
687 ///call the maps addSecondKeys() function.
688 virtual void add(const std::vector<SecondKey>& _secondKeys){
689 _owner.addSecondKeys(_secondKeys);
692 ///\brief Erase a SecondKey from the map.
694 ///Erase a SecondKey from the map. It called by the observer
695 ///notifier and it overrides the erase() virtual member
696 ///function of the observer base. It will call the map's
697 ///eraseSecondKey() function.
698 virtual void erase(const SecondKey& _secondKey){
699 _owner.eraseSecondKey(_secondKey);
702 ///\brief Erase more SecondKeys from the map.
704 ///Erase more SecondKey from the map. It called by the
705 ///observer notifier and it overrides the erase() virtual
706 ///member function of the observer base. It will call the
707 ///map's eraseSecondKeys() function.
708 virtual void erase(const std::vector<SecondKey>& _secondKeys){
709 _owner.eraseSecondKeys(_secondKeys);
712 ///\brief Builds the map.
714 ///It buildes the map. It called by the observer notifier
715 ///and it overrides the build() virtual member function of
716 ///the observer base. It will call the map's build()
718 virtual void build() {
722 ///\brief Clear the map.
724 ///It erases all items from the map. It called by the
725 ///observer notifier and it overrides the clear() virtual
726 ///memeber function of the observer base. It will call the
727 ///map's clear() function.
728 virtual void clear() {
730 //_owner.clearFirst();
734 ///The type of map for which it is attached.
735 DynamicAsymMatrixMap& _owner;
736 };//END OF SECONDKEYPROXY
741 typedef std::vector<Value> Container;
743 ///The type of constainer which stores the values of the map.
744 typedef std::vector<Container> DContainer;
746 ///The std:vector type which contains the data
749 ///Member for the first proxy class
750 FirstKeyProxy _first_key_proxy;
752 ///Member for the second proxy class
753 SecondKeyProxy _second_key_proxy;
757 ///The refernce type of the map.
758 typedef typename Container::reference Reference;
760 ///The const reference type of the constainer.
761 typedef typename Container::const_reference ConstReference;
763 ///\brief Constructor what create the map for the two containers type.
765 ///Creates the matrix map and initialize the values with Value()
766 DynamicAsymMatrixMap(const _FirstContainer& _firstContainer,
767 const _SecondContainer& _secondContainer)
768 : values(DContainer(_firstContainer.maxId(FirstKey())+1,
769 Container(_secondContainer.maxId(SecondKey())+1))),
770 _first_key_proxy(*this),
771 _second_key_proxy(*this)
773 _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey()));
774 _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey()));
777 ///\brief Constructor what create the map for the two containers type.
779 ///Creates the matrix map and initialize the values with the given _value
780 DynamicAsymMatrixMap(const _FirstContainer& _firstContainer,
781 const _SecondContainer& _secondContainer,
783 : values(DContainer(_firstContainer.maxId(FirstKey())+1,
784 Container(_secondContainer.maxId(SecondKey())+1,
786 _first_key_proxy(*this),
787 _second_key_proxy(*this)
789 _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey()));
790 _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey()));
793 ///\brief Copy constructor.
795 ///The copy constructor of the map.
796 DynamicAsymMatrixMap(const DynamicAsymMatrixMap& _copy)
797 : _first_key_proxy(*this), _second_key_proxy(*this) {
798 if(_copy._first_key_proxy.attached() &&
799 _copy._second_key_proxy.attached()){
800 _first_key_proxy.attach(*_copy._first_key_proxy.getNotifier());
801 _second_key_proxy.attach(*_copy._second_key_proxy.getNotifier());
802 values = _copy.values;
808 ///Destructor what detach() from the attached objects. May this
809 ///function is not necessary because the destructor of
810 ///ObserverBase do the same.
811 ~DynamicAsymMatrixMap() {
812 if(_first_key_proxy.attached()){
813 _first_key_proxy.detach();
815 if(_second_key_proxy.attached()){
816 _second_key_proxy.detach();
820 ///\brief Gives back the value assigned to the \c first - \c
821 ///second ordered pair.
823 ///Gives back the value assigned to the \c first - \c second
825 Reference operator()(const FirstKey& _first, const SecondKey& _second) {
826 return values[_first_key_proxy.getNotifier()->id(_first)]
827 [_second_key_proxy.getNotifier()->id(_second)];
830 ///\brief Gives back the value assigned to the \c first - \c
831 ///second ordered pair.
833 ///Gives back the value assigned to the \c first - \c second
835 ConstReference operator()(const FirstKey& _first,
836 const SecondKey& _second) const {
837 return values[_first_key_proxy.getNotifier()->id(_first)]
838 [_second_key_proxy.getNotifier()->id(_second)];
841 ///\brief Setter function for this matrix map.
843 ///Setter function for this matrix map.
844 void set(const FirstKey& first, const SecondKey& second,
846 values[_first_key_proxy.getNotifier()->id(first)]
847 [_second_key_proxy.getNotifier()->id(second)] = value;
850 ///\brief The assignement operator.
852 ///It allow to assign a map to an other. It
853 DynamicAsymMatrixMap& operator=(const DynamicAsymMatrixMap& _cmap){
854 return operator=<DynamicAsymMatrixMap>(_cmap);
857 ///\brief Template assignement operator.
859 ///It copy the element of the given map to its own container. The
860 ///type of the two map shall be the same.
861 template <typename CMap>
862 DynamicAsymMatrixMap& operator=(const CMap& _cdmap){
863 checkConcept<concepts::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
864 const typename FirstKeyProxy::Notifier* notifierFirstKey =
865 _first_key_proxy.getNotifier();
866 const typename SecondKeyProxy::Notifier* notifierSecondKey =
867 _second_key_proxy.getNotifier();
869 SecondKey itemSecond;
870 for(notifierFirstKey->first(itemFirst); itemFirst != INVALID;
871 notifierFirstKey->next(itemFirst)){
872 for(notifierSecondKey->first(itemSecond); itemSecond != INVALID;
873 notifierSecondKey->next(itemSecond)){
874 set(itemFirst, itemSecond, _cdmap(itemFirst,itemSecond));
882 ///\brief Add a new FirstKey to the map.
884 ///It adds a new FirstKey to the map. It is called by the observer
885 ///class belongs to the FirstKey type.
886 void addFirstKey(const FirstKey& firstKey) {
887 int size = (int)values.size();
888 if( _first_key_proxy.getNotifier()->id(firstKey)+1 >= size ){
889 values.resize(_first_key_proxy.getNotifier()->id(firstKey)+1);
890 if( (int)values[0].size() != 0 ){
891 int innersize = (int)values[0].size();
892 for(int i=size; i!=(int)values.size();++i){
893 (values[i]).resize(innersize);
895 }else if(_second_key_proxy.getNotifier()->maxId() >= 0){
896 int innersize = _second_key_proxy.getNotifier()->maxId();
897 for(int i = 0; i != (int)values.size(); ++i){
898 values[0].resize(innersize);
904 ///\brief Adds more new FirstKeys to the map.
906 ///It adds more new FirstKeys to the map. It called by the
907 ///observer class belongs to the FirstKey type.
908 void addFirstKeys(const std::vector<FirstKey>& firstKeys){
909 int max = values.size() - 1;
910 for(int i=0; i != (int)firstKeys.size(); ++i){
911 int id = _first_key_proxy.getNotifier()->id(firstKeys[i]);
916 int size = (int)values.size();
918 values.resize(max + 1);
919 if( (int)values[0].size() != 0){
920 int innersize = (int)values[0].size();
921 for(int i = size; i != (max + 1); ++i){
922 values[i].resize(innersize);
924 }else if(_second_key_proxy.getNotifier()->maxId() >= 0){
925 int innersize = _second_key_proxy.getNotifier()->maxId();
926 for(int i = 0; i != (int)values.size(); ++i){
927 values[i].resize(innersize);
933 ///\brief Add a new SecondKey to the map.
935 ///It adds a new SecondKey to the map. It is called by the
936 ///observer class belongs to the SecondKey type.
937 void addSecondKey(const SecondKey& secondKey) {
938 if(values.size() == 0){
941 int id = _second_key_proxy.getNotifier()->id(secondKey);
942 if(id >= (int)values[0].size()){
943 for(int i=0;i!=(int)values.size();++i){
944 values[i].resize(id+1);
949 ///\brief Adds more new SecondKeys to the map.
951 ///It adds more new SecondKeys to the map. It called by the
952 ///observer class belongs to the SecondKey type.
953 void addSecondKeys(const std::vector<SecondKey>& secondKeys){
954 if(values.size() == 0){
957 int max = values[0].size();
958 for(int i = 0; i != (int)secondKeys.size(); ++i){
959 int id = _second_key_proxy.getNotifier()->id(secondKeys[i]);
964 if(max > (int)values[0].size()){
965 for(int i = 0; i != (int)values.size(); ++i){
966 values[i].resize(max + 1);
971 ///\brief Erase a FirstKey from the map.
973 ///Erase a FirstKey from the map. It called by the observer
974 ///class belongs to the FirstKey type.
975 void eraseFirstKey(const FirstKey& first) {
976 int id = _first_key_proxy.getNotifier()->id(first);
977 for(int i = 0; i != (int)values[id].size(); ++i){
978 values[id][i] = Value();
982 ///\brief Erase more FirstKey from the map.
984 ///Erase more FirstKey from the map. It called by the observer
985 ///class belongs to the FirstKey type.
986 void eraseFirstKeys(const std::vector<FirstKey>& firstKeys) {
987 for(int j = 0; j != (int)firstKeys.size(); ++j){
988 int id = _first_key_proxy.getNotifier()->id(firstKeys[j]);
989 for(int i = 0; i != (int)values[id].size(); ++i){
990 values[id][i] = Value();
995 ///\brief Erase a SecondKey from the map.
997 ///Erase a SecondKey from the map. It called by the observer class
998 ///belongs to the SecondKey type.
999 void eraseSecondKey(const SecondKey& second) {
1000 if(values.size() == 0){
1003 int id = _second_key_proxy.getNotifier()->id(second);
1004 for(int i = 0; i != (int)values.size(); ++i){
1005 values[i][id] = Value();
1009 ///\brief Erase more SecondKey from the map.
1011 ///Erase more SecondKey from the map. It called by the observer
1012 ///class belongs to the SecondKey type.
1013 void eraseSecondKeys(const std::vector<SecondKey>& secondKeys) {
1014 if(values.size() == 0){
1017 for(int j = 0; j != (int)secondKeys.size(); ++j){
1018 int id = _second_key_proxy.getNotifier()->id(secondKeys[j]);
1019 for(int i = 0; i != (int)values.size(); ++i){
1020 values[i][id] = Value();
1025 ///\brief Builds the map.
1027 ///It buildes the map. It is called by the observer class belongs
1028 ///to the FirstKey or SecondKey type.
1030 values.resize(_first_key_proxy.getNotifier()->maxId());
1031 for(int i=0; i!=(int)values.size(); ++i){
1032 values[i].resize(_second_key_proxy.getNotifier()->maxId());
1036 ///\brief Clear the map.
1038 ///It erases all items from the map. It is called by the observer class
1039 ///belongs to the FirstKey or SecondKey type.
1041 for(int i=0; i!=(int)values.size(); ++i) {