[Lemon-commits] [lemon_svn] deba: r2678 - in hugo/trunk: lemon lemon/bits test

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:54:25 CET 2006


Author: deba
Date: Thu Apr  6 11:33:29 2006
New Revision: 2678

Modified:
   hugo/trunk/lemon/bits/traits.h
   hugo/trunk/lemon/matrix_maps.h
   hugo/trunk/test/matrix_maps_test.cc

Log:
Commiting The DynamicAsymMatrixMap from Nagy Jano
 + MatrixMapTraits 



Modified: hugo/trunk/lemon/bits/traits.h
==============================================================================
--- hugo/trunk/lemon/bits/traits.h	(original)
+++ hugo/trunk/lemon/bits/traits.h	Thu Apr  6 11:33:29 2006
@@ -239,6 +239,36 @@
     typedef typename Map::Reference Reference;
  };
 
+  template <typename MatrixMap, typename Enable = void>
+  struct MatrixMapTraits {
+    typedef False ReferenceMapTag;
+
+    typedef typename MatrixMap::FirstKey FirstKey;
+    typedef typename MatrixMap::SecondKey SecondKey;
+    typedef typename MatrixMap::Value Value;
+
+    typedef const Value ConstReturnValue;
+    typedef const Value ReturnValue;
+  };
+
+  template <typename MatrixMap>
+  struct MatrixMapTraits<
+    MatrixMap, typename enable_if<typename MatrixMap::ReferenceMapTag, 
+                                  void>::type > 
+  {
+    typedef True ReferenceMapTag;
+    
+    typedef typename MatrixMap::FirstKey FirstKey;
+    typedef typename MatrixMap::SecondKey SecondKey;
+    typedef typename MatrixMap::Value Value;
+
+    typedef typename MatrixMap::ConstReference ConstReturnValue;
+    typedef typename MatrixMap::Reference ReturnValue;
+
+    typedef typename MatrixMap::ConstReference ConstReference; 
+    typedef typename MatrixMap::Reference Reference;
+ };
+
   // Indicators for the tags
 
   template <typename Graph, typename Enable = void>

Modified: hugo/trunk/lemon/matrix_maps.h
==============================================================================
--- hugo/trunk/lemon/matrix_maps.h	(original)
+++ hugo/trunk/lemon/matrix_maps.h	Thu Apr  6 11:33:29 2006
@@ -24,6 +24,7 @@
 #include <lemon/bits/utility.h>
 #include <lemon/maps.h>
 
+#include <lemon/concept/matrix_maps.h>
 
 /// \file
 /// \ingroup maps
@@ -37,7 +38,7 @@
   ///
   /// Map for the coloumn view of the matrix.
   template <typename _MatrixMap>
-  class MatrixRowMap : public MapTraits<_MatrixMap> {
+  class MatrixRowMap : public MatrixMapTraits<_MatrixMap> {
   public:
     typedef _MatrixMap MatrixMap;
     typedef typename MatrixMap::SecondKey Key;
@@ -50,7 +51,7 @@
     /// \brief Subscription operator
     ///
     /// Subscription operator.
-    typename MapTraits<MatrixMap>::ReturnValue
+    typename MatrixMapTraits<MatrixMap>::ReturnValue
     operator[](Key col) {
       return matrix(row, col);
     }
@@ -65,7 +66,7 @@
     /// \brief Subscription operator
     ///
     /// Subscription operator.
-    typename MapTraits<MatrixMap>::ConstReturnValue
+    typename MatrixMapTraits<MatrixMap>::ConstReturnValue
     operator[](Key col) const {
       return matrix(row, col);
     }
@@ -79,7 +80,7 @@
   ///
   /// Map for the row view of the matrix.
   template <typename _MatrixMap>
-  class ConstMatrixRowMap : public MapTraits<_MatrixMap> {
+  class ConstMatrixRowMap : public MatrixMapTraits<_MatrixMap> {
   public:
     typedef _MatrixMap MatrixMap;
     typedef typename MatrixMap::SecondKey Key;
@@ -93,7 +94,7 @@
     /// \brief Subscription operator
     ///
     /// Subscription operator.
-    typename MapTraits<MatrixMap>::ConstReturnValue
+    typename MatrixMapTraits<MatrixMap>::ConstReturnValue
     operator[](Key col) const {
       return matrix(row, col);
     }
@@ -122,7 +123,7 @@
   ///
   /// Map for the row view of the matrix.
   template <typename _MatrixMap>
-  class MatrixColMap : public MapTraits<_MatrixMap> {
+  class MatrixColMap : public MatrixMapTraits<_MatrixMap> {
   public:
     typedef _MatrixMap MatrixMap;
     typedef typename MatrixMap::FirstKey Key;
@@ -134,7 +135,7 @@
     /// \brief Subscription operator
     ///
     /// Subscription operator.
-    typename MapTraits<MatrixMap>::ReturnValue
+    typename MatrixMapTraits<MatrixMap>::ReturnValue
     operator[](Key row) {
       return matrix(row, col);
     }
@@ -149,7 +150,7 @@
     /// \brief Subscription operator
     ///
     /// Subscription operator.
-    typename MapTraits<MatrixMap>::ConstReturnValue
+    typename MatrixMapTraits<MatrixMap>::ConstReturnValue
     operator[](Key row) const {
       return matrix(row, col);
     }
@@ -163,7 +164,7 @@
   ///
   /// Map for the col view of the matrix.
   template <typename _MatrixMap>
-  class ConstMatrixColMap : public MapTraits<_MatrixMap> {
+  class ConstMatrixColMap : public MatrixMapTraits<_MatrixMap> {
   public:
     typedef _MatrixMap MatrixMap;
     typedef typename MatrixMap::FirstKey Key;
@@ -176,7 +177,7 @@
     /// \brief Subscription operator
     ///
     /// Subscription operator.
-    typename MapTraits<MatrixMap>::ConstReturnValue
+    typename MatrixMapTraits<MatrixMap>::ConstReturnValue
     operator[](Key row) const {
       return matrix(row, col);
     }
@@ -249,6 +250,32 @@
       Parent::attach(_graph.getNotifier(Key()));
     }
 
+    ///\brief The assignement operator.
+    ///
+    ///It allow to assign a map to an other.
+    DynamicMatrixMap& operator=(const DynamicMatrixMap& _cmap){
+      return operator=<DynamicMatrixMap>(_cmap);
+    }
+      
+    ///\brief Template assignement operator.
+    ///
+    ///It copy the element of the given map to its own container.  The
+    ///type of the two map shall be the same.
+    template <typename CMap>
+    DynamicMatrixMap& operator=(const CMap& _cmap){
+      checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
+      typename Parent::Notifier* notifier = Parent::getNotifier();
+      Key first, second;
+      for(notifier->first(first); first != INVALID; 
+          notifier->next(first)){
+        for(notifier->first(second); second != INVALID; 
+            notifier->next(second)){
+          set(first, second, _cmap(first, second));
+        }
+      }
+      return *this;
+    }
+
     /// \brief Gives back the value assigned to the \c first - \c second
     /// ordered pair.
     ///
@@ -357,6 +384,34 @@
       Parent::attach(_graph.getNotifier(Key()));
     }
 
+
+    ///\brief The assignement operator.
+    ///
+    ///It allow to assign a map to an other.
+    DynamicSymMatrixMap& operator=(const DynamicSymMatrixMap& _cmap){
+      return operator=<DynamicSymMatrixMap>(_cmap);
+    }
+      
+    ///\brief Template assignement operator.
+    ///
+    ///It copy the element of the given map to its own container.  The
+    ///type of the two map shall be the same.
+    template <typename CMap>
+    DynamicSymMatrixMap& operator=(const CMap& _cmap){
+      checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
+      typename Parent::Notifier* notifier = Parent::getNotifier();
+      Key first, second;
+      for(notifier->first(first); first != INVALID; 
+          notifier->next(first)){
+        for(notifier->first(second); second != first; 
+            notifier->next(second)){
+          set(first, second, _cmap(first, second));
+        }
+        set(first, first, _cmap(first, first));        
+      }
+      return *this;
+    }
+
     /// \brief Gives back the value assigned to the \c first - \c second
     /// unordered pair.
     ///
@@ -418,6 +473,544 @@
   private:
     std::vector<Value> values;
   };
+  
+  ///\brief Dynamic Asymmetric Matrix Map.
+  ///
+  ///Dynamic Asymmetric Matrix Map.  Container for store values for each
+  ///ordered pair of containers items.  This data structure can store
+  ///data with different key types from different container types. It
+  ///increases the size of the container if the linked containers
+  ///content change, so it is updated automaticly whenever it is
+  ///needed.
+  ///
+  ///This map meet with the concept::ReferenceMatrixMap<typename K1,
+  ///typename K2, typename V, typename R, typename CR> called as
+  ///"ReferenceMatrixMap".
+  ///
+  ///\param _FirstContainer the desired type of first container. It is
+  ///ususally a Graph type, but can be any type with alteration
+  ///property.
+  ///  
+  ///\param _FirstContainerItem the nested type of the
+  ///FirstContainer. It is usually a graph item as Node, Edge,
+  ///etc. This type will be the FirstKey type.
+  ///
+  ///\param _SecondContainer the desired type of the second
+  ///container. It is usualy a Graph type, but can be any type with
+  ///alteration property.
+  ///
+  ///\param _SecondContainerItem the nested type of the
+  ///SecondContainer. It is usually a graph item such as Node, Edge,
+  ///UEdge, etc. This type will be the SecondKey type.
+  ///
+  ///\param _Value the type of the strored values in the container.
+  ///
+  /// \author Janos Nagy
+  template <typename _FirstContainer, typename _FirstContainerItem, 
+            typename _SecondContainer, typename _SecondContainerItem, 
+            typename _Value>
+  class DynamicAsymMatrixMap{
+  public:
+
+    ///The first key type.
+    typedef _FirstContainerItem FirstKey;
+      
+    ///The second key type.
+    typedef _SecondContainerItem SecondKey;
+      
+    ///The value type of the map.
+    typedef _Value Value;
+      
+    ///Indicates it is a reference map.
+    typedef True ReferenceMapTag;
+    
+  protected:
+      
+    ///\brief Proxy class for the first key type.
+    ///
+    ///The proxy class belongs to the FirstKey type. It is necessary because
+    ///if one want use the same conatainer types and same nested types but on
+    ///other instances of containers than due to the type equiality of nested
+    ///types it requires a proxy mechanism. 
+    class FirstKeyProxy 
+      : protected 
+    ItemSetTraits<_FirstContainer,_FirstContainerItem>::
+    ItemNotifier::ObserverBase 
+    {
+        
+    public:
+
+      friend class DynamicAsymMatrixMap;
+          
+      ///Constructor.
+      FirstKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { }
+    protected:
+
+      ///\brief Add a new FirstKey to the map.
+      ///
+      ///It adds a new FirstKey to the map. It is called by the
+      ///observer notifier and it is ovverride the add() virtual
+      ///member function in the observer base. It will call the
+      ///maps addFirstKey() function.
+      virtual void add(const FirstKey& _firstKey){
+        _owner.addFirstKey(_firstKey);
+      }
+          
+      ///\brief Add more new FirstKey to the map.
+      ///
+      ///It adds more new FirstKey to the map. It is called by the
+      ///observer notifier and it is ovverride the add() virtual
+      ///member function in the observer base. It will call the
+      ///map's addFirstKeys() function.
+      virtual void add(const std::vector<FirstKey>& _firstKeys){
+        _owner.addFirstKeys(_firstKeys);
+      }
+          
+      ///\brief Erase a FirstKey from the map.
+      ///
+      ///Erase a FirstKey from the map. It called by the observer
+      ///notifier and it overrides the erase() virtual member
+      ///function of the observer base. It will call the map's
+      ///eraseFirstKey() function.
+      virtual void erase(const FirstKey& _firstKey){
+        _owner.eraseFirstKey(_firstKey);
+      }
+          
+      ///\brief Erase more FirstKey from the map.
+      ///
+      ///Erase more FirstKey from the map. It called by the
+      ///observer notifier and it overrides the erase() virtual
+      ///member function of the observer base. It will call the
+      ///map's eraseFirstKeys() function.
+      virtual void erase(const std::vector<FirstKey>& _firstKeys){
+        _owner.eraseFirstKeys(_firstKeys);
+      }
+          
+      ///\brief Builds the map.
+      ///
+      ///It buildes the map. It called by the observer notifier
+      ///and it overrides the build() virtual member function of
+      ///the observer base.  It will call the map's build()
+      ///function.
+      virtual void build() {
+        _owner.build();
+        //_owner.buildFirst();
+      }
+          
+      ///\brief Clear the map.
+      ///
+      ///It erases all items from the map. It called by the
+      ///observer notifier and it overrides the clear() virtual
+      ///memeber function of the observer base. It will call the
+      ///map's clear() function.
+      virtual void clear() {
+        _owner.clear();
+        //_owner.clearFirst();
+      }
+    private:
+          
+      ///The map type for it is linked.
+      DynamicAsymMatrixMap& _owner;
+    };///END OF FIRSTKEYPROXY
+      
+      ///\brief Proxy class for the second key type.
+      ///
+      ///The proxy class belongs to the SecondKey type.  It is
+      ///necessary because if one want use the same conatainer types
+      ///and same nested types but on other instances of containers
+      ///than due to the type equiality of nested types it requires a
+      ///proxy mechanism.
+    class SecondKeyProxy
+      : protected 
+    ItemSetTraits<_SecondContainer, _SecondContainerItem>::
+    ItemNotifier::ObserverBase {
+        
+    public:
+
+      friend class DynamicAsymMatrixMap;
+      ///Constructor.
+      SecondKeyProxy(DynamicAsymMatrixMap& _map) : _owner(_map) { }
+
+    protected:
+          
+      ///\brief Add a new SecondKey to the map.
+      ///
+      ///It adds a new SecondKey to the map. It is called by the
+      ///observer notifier and it is ovverride the add() virtual
+      ///member function in the observer base. It will call the
+      ///maps addSecondKey() function.
+      virtual void add(const SecondKey& _secondKey){
+        _owner.addSecondKey(_secondKey);
+      }
+    
+      ///\brief Add more new SecondKey to the map.
+      ///
+      ///It adds more new SecondKey to the map. It is called by
+      ///the observer notifier and it is ovverride the add()
+      ///virtual member function in the observer base. It will
+      ///call the maps addSecondKeys() function.
+      virtual void add(const std::vector<SecondKey>& _secondKeys){
+        _owner.addSecondKeys(_secondKeys);
+      }
+          
+      ///\brief Erase a SecondKey from the map.
+      ///
+      ///Erase a SecondKey from the map. It called by the observer
+      ///notifier and it overrides the erase() virtual member
+      ///function of the observer base. It will call the map's
+      ///eraseSecondKey() function.
+      virtual void erase(const SecondKey& _secondKey){
+        _owner.eraseSecondKey(_secondKey);
+      }
+          
+      ///\brief Erase more SecondKeys from the map.
+      ///
+      ///Erase more SecondKey from the map. It called by the
+      ///observer notifier and it overrides the erase() virtual
+      ///member function of the observer base. It will call the
+      ///map's eraseSecondKeys() function.
+      virtual void erase(const std::vector<SecondKey>& _secondKeys){
+        _owner.eraseSecondKeys(_secondKeys);
+      }
+          
+      ///\brief Builds the map.
+      ///
+      ///It buildes the map. It called by the observer notifier
+      ///and it overrides the build() virtual member function of
+      ///the observer base.  It will call the map's build()
+      ///function.
+      virtual void build() {
+        _owner.build();
+      }
+          
+      ///\brief Clear the map.
+      ///
+      ///It erases all items from the map. It called by the
+      ///observer notifier and it overrides the clear() virtual
+      ///memeber function of the observer base. It will call the
+      ///map's clear() function.
+      virtual void clear() {
+        _owner.clear();
+        //_owner.clearFirst();
+      }
+    private:
+          
+      ///The type of map for which it is attached.
+      DynamicAsymMatrixMap& _owner;
+    };///END OF SECONDKEYPROXY
+      
+  private:
+    
+    /// \e
+    typedef std::vector<Value> Container;
+      
+    ///The type of constainer which stores the values of the map.
+    typedef std::vector<Container> DContainer;
+
+    ///The std:vector type which contains the data
+    DContainer values;
+      
+    ///Member for the first proxy class
+    FirstKeyProxy _first_key_proxy;
+      
+    ///Member for the second proxy class
+    SecondKeyProxy _second_key_proxy;
+
+  public:
+    
+    ///The refernce type of the map.
+    typedef typename Container::reference Reference;
+      
+    ///The const reference type of the constainer.
+    typedef typename Container::const_reference ConstReference;
+
+    ///\brief Constructor what create the map for the two containers type.
+    ///
+    ///Creates the matrix map and initialize the values with Value()
+    DynamicAsymMatrixMap(const _FirstContainer& _firstContainer, 
+                  const _SecondContainer& _secondContainer)
+      : values(DContainer(_firstContainer.maxId(FirstKey())+1,
+                          Container(_secondContainer.maxId(SecondKey())+1))),
+        _first_key_proxy(*this),
+        _second_key_proxy(*this)
+    {
+      _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey()));
+      _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey()));
+    }
+
+    ///\brief Constructor what create the map for the two containers type.
+    ///
+    ///Creates the matrix map and initialize the values with the given _value
+    DynamicAsymMatrixMap(const _FirstContainer& _firstContainer, 
+                  const _SecondContainer& _secondContainer, 
+                  const Value& _value)
+      : values(DContainer(_firstContainer.maxId(FirstKey())+1,
+                          Container(_secondContainer.maxId(SecondKey())+1,
+                                    _value))),
+        _first_key_proxy(*this),
+        _second_key_proxy(*this)
+    {
+      _first_key_proxy.attach(_firstContainer.getNotifier(FirstKey()));
+      _second_key_proxy.attach(_secondContainer.getNotifier(SecondKey()));
+    }
+      
+    ///\brief Copy constructor.
+    ///
+    ///The copy constructor of the map.
+    DynamicAsymMatrixMap(const DynamicAsymMatrixMap& _copy) 
+      : _first_key_proxy(*this), _second_key_proxy(*this) {
+      if(_copy._first_key_proxy.attached() && 
+         _copy._second_key_proxy.attached()){
+        _first_key_proxy.attach(*_copy._first_key_proxy.getNotifier());
+        _second_key_proxy.attach(*_copy._second_key_proxy.getNotifier());
+        values = _copy.values;
+      }
+    }
+      
+    ///\brief Destructor
+    ///
+    ///Destructor what detach() from the attached objects.  May this
+    ///function is not necessary because the destructor of
+    ///ObserverBase do the same.
+    ~DynamicAsymMatrixMap() {
+      if(_first_key_proxy.attached()){
+        _first_key_proxy.detach();
+      }
+      if(_second_key_proxy.attached()){
+        _second_key_proxy.detach();
+      }
+    }
+      
+    ///\brief Gives back the value assigned to the \c first - \c
+    ///second ordered pair.
+    ///
+    ///Gives back the value assigned to the \c first - \c second
+    ///ordered pair.
+    Reference operator()(const FirstKey& _first, const SecondKey& _second) {
+      return values[_first_key_proxy.getNotifier()->id(_first)]
+        [_second_key_proxy.getNotifier()->id(_second)];
+    }
+
+    ///\brief Gives back the value assigned to the \c first - \c
+    ///second ordered pair.
+    ///
+    ///Gives back the value assigned to the \c first - \c second
+    ///ordered pair.
+    ConstReference operator()(const FirstKey& _first, 
+                              const SecondKey& _second) const {
+      return values[_first_key_proxy.getNotifier()->id(_first)]
+        [_second_key_proxy.getNotifier()->id(_second)];
+    }
+
+    ///\brief Setter function for this matrix map.
+    ///
+    ///Setter function for this matrix map.
+    void set(const FirstKey& first, const SecondKey& second, 
+             const Value& value){
+      values[_first_key_proxy.getNotifier()->id(first)]
+        [_second_key_proxy.getNotifier()->id(second)] = value;
+    }
+
+    ///\brief The assignement operator.
+    ///
+    ///It allow to assign a map to an other. It
+    DynamicAsymMatrixMap& operator=(const DynamicAsymMatrixMap& _cmap){
+      return operator=<DynamicAsymMatrixMap>(_cmap);
+    }
+      
+    ///\brief Template assignement operator.
+    ///
+    ///It copy the element of the given map to its own container.  The
+    ///type of the two map shall be the same.
+    template <typename CMap>
+    DynamicAsymMatrixMap& operator=(const CMap& _cdmap){
+      checkConcept<concept::ReadMatrixMap<FirstKey, SecondKey, Value>, CMap>();
+      const typename FirstKeyProxy::Notifier* notifierFirstKey = 
+        _first_key_proxy.getNotifier();
+      const typename SecondKeyProxy::Notifier* notifierSecondKey = 
+        _second_key_proxy.getNotifier();
+      FirstKey itemFirst;
+      SecondKey itemSecond;
+      for(notifierFirstKey->first(itemFirst); itemFirst != INVALID; 
+          notifierFirstKey->next(itemFirst)){
+        for(notifierSecondKey->first(itemSecond); itemSecond != INVALID; 
+            notifierSecondKey->next(itemSecond)){
+          set(itemFirst, itemSecond, _cdmap(itemFirst,itemSecond));
+        }
+      }
+      return *this;
+    }
+      
+  protected:
+    
+    ///\brief Add a new FirstKey to the map.
+    ///
+    ///It adds a new FirstKey to the map. It is called by the observer
+    ///class belongs to the FirstKey type.
+    void addFirstKey(const FirstKey& firstKey) {
+      int size = (int)values.size();
+      if( _first_key_proxy.getNotifier()->id(firstKey)+1 >= size ){
+        values.resize(_first_key_proxy.getNotifier()->id(firstKey)+1);
+        if( (int)values[0].size() != 0 ){
+          int innersize = (int)values[0].size();
+          for(int i=size; i!=(int)values.size();++i){
+            (values[i]).resize(innersize);
+          }
+        }else if(_second_key_proxy.getNotifier()->maxId() >= 0){
+          int innersize = _second_key_proxy.getNotifier()->maxId();
+          for(int i = 0; i != (int)values.size(); ++i){
+            values[0].resize(innersize);
+          }
+        }
+      }
+    }
+
+    ///\brief Adds more new FirstKeys to the map.
+    ///
+    ///It adds more new FirstKeys to the map. It called by the
+    ///observer class belongs to the FirstKey type.
+    void addFirstKeys(const std::vector<FirstKey>& firstKeys){
+      int max = values.size() - 1;
+      for(int i=0; i != (int)firstKeys.size(); ++i){
+        int id = _first_key_proxy.getNotifier()->id(firstKeys[i]);
+        if(max < id){
+          max = id;
+        }
+      }
+      int size = (int)values.size();
+      if(max >= size){
+        values.resize(max + 1);
+        if( (int)values[0].size() != 0){
+          int innersize = (int)values[0].size();
+          for(int i = size; i != (max + 1); ++i){
+            values[i].resize(innersize);
+          }
+        }else if(_second_key_proxy.getNotifier()->maxId() >= 0){
+          int innersize = _second_key_proxy.getNotifier()->maxId();
+          for(int i = 0; i != (int)values.size(); ++i){
+            values[i].resize(innersize);
+          }
+        }
+      }
+    }
+
+    ///\brief Add a new SecondKey to the map.
+    ///
+    ///It adds a new SecondKey to the map. It is called by the
+    ///observer class belongs to the SecondKey type.
+    void addSecondKey(const SecondKey& secondKey) {
+      if(values.size() == 0){
+        return;
+      }
+      int id = _second_key_proxy.getNotifier()->id(secondKey);
+      if(id >= (int)values[0].size()){
+        for(int i=0;i!=(int)values.size();++i){
+          values[i].resize(id+1);
+        }
+      }
+    }
+        
+    ///\brief Adds more new SecondKeys to the map.
+    ///
+    ///It adds more new SecondKeys to the map. It called by the
+    ///observer class belongs to the SecondKey type.
+    void addSecondKeys(const std::vector<SecondKey>& secondKeys){
+      if(values.size() == 0){
+        return;
+      }
+      int max = values[0].size();
+      for(int i = 0; i != (int)secondKeys.size(); ++i){
+        int id = _second_key_proxy.getNotifier()->id(secondKeys[i]);
+        if(max < id){
+          max = id;
+        }
+      }
+      if(max > (int)values[0].size()){
+        for(int i = 0; i != (int)values.size(); ++i){
+          values[i].resize(max + 1);
+        }
+      }
+    }
+    
+    ///\brief Erase a FirstKey from the map.
+    ///
+    ///Erase a FirstKey from the map. It called by the observer
+    ///class belongs to the FirstKey type.
+    void eraseFirstKey(const FirstKey& first) {
+      int id = _first_key_proxy.getNotifier()->id(first);
+      for(int i = 0; i != (int)values[id].size(); ++i){
+        values[id][i] = Value();
+      }
+    }
+        
+    ///\brief Erase more FirstKey from the map.
+    ///
+    ///Erase more FirstKey from the map. It called by the observer
+    ///class belongs to the FirstKey type.
+    void eraseFirstKeys(const std::vector<FirstKey>& firstKeys) {
+      for(int j = 0; j != (int)firstKeys.size(); ++j){
+        int id = _first_key_proxy.getNotifier()->id(firstKeys[j]);
+        for(int i = 0; i != (int)values[id].size(); ++i){
+          values[id][i] = Value();
+        }
+      }
+    }
+
+    ///\brief Erase a SecondKey from the map.
+    ///
+    ///Erase a SecondKey from the map. It called by the observer class
+    ///belongs to the SecondKey type.
+    void eraseSecondKey(const SecondKey& second) {
+      if(values.size() == 0){
+        return;
+      }
+      int id = _second_key_proxy.getNotifier()->id(second);
+      for(int i = 0; i != (int)values.size(); ++i){
+        values[i][id] = Value();
+      }
+    }
+        
+    ///\brief Erase more SecondKey from the map.
+    ///
+    ///Erase more SecondKey from the map. It called by the observer
+    ///class belongs to the SecondKey type.
+    void eraseSecondKeys(const std::vector<SecondKey>& secondKeys) {
+      if(values.size() == 0){
+        return;
+      }
+      for(int j = 0; j != (int)secondKeys.size(); ++j){
+        int id = _second_key_proxy.getNotifier()->id(secondKeys[j]);
+        for(int i = 0; i != (int)values.size(); ++i){
+          values[i][id] = Value();
+        }
+      }
+    }
+
+    ///\brief Builds the map.
+    ///
+    ///It buildes the map. It is called by the observer class belongs
+    ///to the FirstKey or SecondKey type.
+    void build() {
+      values.resize(_first_key_proxy.getNotifier()->maxId());
+      for(int i=0; i!=(int)values.size(); ++i){
+        values[i].resize(_second_key_proxy.getNotifier()->maxId());
+      }
+    }
+    
+    ///\brief Clear the map.
+    ///
+    ///It erases all items from the map. It is called by the observer class
+    ///belongs to the FirstKey or SecondKey type.
+    void clear() {
+      for(int i=0; i!=(int)values.size(); ++i) {
+        values[i].clear();
+      }
+      values.clear();
+    }
+ 
+  };
+
+
 
 }
 

Modified: hugo/trunk/test/matrix_maps_test.cc
==============================================================================
--- hugo/trunk/test/matrix_maps_test.cc	(original)
+++ hugo/trunk/test/matrix_maps_test.cc	Thu Apr  6 11:33:29 2006
@@ -40,6 +40,7 @@
 int main() {
   typedef SmartGraph Graph;
   typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
 
   { // checking MatrixMap for int
     typedef DynamicMatrixMap<Graph, Node, int> IntMatrixMap;
@@ -124,6 +125,95 @@
     }
   }
 
+  { // checking MatrixMap for int
+    typedef DynamicAsymMatrixMap<Graph, Node, Graph, Edge, int> IntMatrixMap;
+    checkConcept<ReferenceMatrixMap<Node, Edge, int, 
+      IntMatrixMap::Reference, IntMatrixMap::ConstReference>,
+      IntMatrixMap>();
+
+  }
+
+  { // checking MatrixMap for bool
+    typedef DynamicAsymMatrixMap<Graph, Node, Graph, Edge, bool> BoolMatrixMap;
+    checkConcept<ReferenceMatrixMap<Node, Edge, bool, 
+      BoolMatrixMap::Reference, BoolMatrixMap::ConstReference>,
+      BoolMatrixMap>();
+
+  }
+
+  {
+    Graph graph1, graph2;
+    typedef DynamicAsymMatrixMap<Graph, Node, Graph, Edge, int> IntMatrixMap;
+    IntMatrixMap matrix(graph1, graph2);
+    for (int i = 0; i < 10; ++i) {
+      graph1.addNode();
+    }
+    graph2.addNode();
+    for (int i = 0; i < 20; ++i) {
+      graph2.addEdge(Graph::NodeIt(graph2), Graph::NodeIt(graph2));
+    }
+    for (Graph::NodeIt it(graph1); it != INVALID; ++it) {
+      for (Graph::EdgeIt jt(graph2); jt != INVALID; ++jt) {
+	int val = urandom(100);
+	matrix.set(it, jt, val);
+	check(matrix(it, jt) == val, "Wrong assign");
+	check(matrix(it, jt) == matrixRowMap(matrix, it)[jt], "Wrong rowMap");
+	check(matrix(it, jt) == matrixColMap(matrix, jt)[it], "Wrong colMap");
+      }
+    }
+    const IntMatrixMap& cm = matrix;
+    for (Graph::NodeIt it(graph1); it != INVALID; ++it) {
+      for (Graph::EdgeIt jt(graph2); jt != INVALID; ++jt) {
+	check(cm(it, jt) == matrixRowMap(cm, it)[jt], "Wrong rowMap");
+	check(cm(it, jt) == matrixColMap(cm, jt)[it], "Wrong colMap");
+      }
+    }
+  }
+
+  { // checking MatrixMap for int
+    typedef DynamicAsymMatrixMap<Graph, Node, Graph, Node, int> IntMatrixMap;
+    checkConcept<ReferenceMatrixMap<Node, Node, int, 
+      IntMatrixMap::Reference, IntMatrixMap::ConstReference>,
+      IntMatrixMap>();
+
+  }
+
+  { // checking MatrixMap for bool
+    typedef DynamicAsymMatrixMap<Graph, Node, Graph, Node, bool> BoolMatrixMap;
+    checkConcept<ReferenceMatrixMap<Node, Node, bool, 
+      BoolMatrixMap::Reference, BoolMatrixMap::ConstReference>,
+      BoolMatrixMap>();
+
+  }
+
+  {
+    Graph graph;
+    typedef DynamicAsymMatrixMap<Graph, Node, Graph, Node, int> IntMatrixMap;
+    IntMatrixMap matrix(graph, graph);
+    for (int i = 0; i < 10; ++i) {
+      graph.addNode();
+    }
+    for (int i = 0; i < 20; ++i) {
+      graph.addEdge(Graph::NodeIt(graph), Graph::NodeIt(graph));
+    }
+    for (Graph::NodeIt it(graph); it != INVALID; ++it) {
+      for (Graph::NodeIt jt(graph); jt != INVALID; ++jt) {
+	int val = urandom(100);
+	matrix.set(it, jt, val);
+	check(matrix(it, jt) == val, "Wrong assign");
+	check(matrix(it, jt) == matrixRowMap(matrix, it)[jt], "Wrong rowMap");
+	check(matrix(it, jt) == matrixColMap(matrix, jt)[it], "Wrong colMap");
+      }
+    }
+    const IntMatrixMap& cm = matrix;
+    for (Graph::NodeIt it(graph); it != INVALID; ++it) {
+      for (Graph::NodeIt jt(graph); jt != INVALID; ++jt) {
+	check(cm(it, jt) == matrixRowMap(cm, it)[jt], "Wrong rowMap");
+	check(cm(it, jt) == matrixColMap(cm, jt)[it], "Wrong colMap");
+      }
+    }
+  }
+
   std::cout << __FILE__ ": All tests passed.\n";
 
   return 0;



More information about the Lemon-commits mailing list