lemon/matrix_maps.h
changeset 2058 0b1fc1566fdb
parent 2039 dacc4ce9474d
child 2072 224d3781b00b
equal deleted inserted replaced
7:c1baa9a06a14 8:94b56ffc5738
     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