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