Index type

Walter Daems <[email protected]> Tue, 20 Apr 2004 15:56:01 +0200
Newsgroups gmane.comp.lib.mtl.devel
Message-ID <[email protected]>
Hi all,

It seems to me that the default settings of vector and matrix
index types (and the index types of the iterators) is not consistent:
sometimes size_t is used (which I prefer), sometimes int, and sometimes
T::size_type (which usually boils down to size_t).

This prevents one from using sparse/compressed and dense
vectors/matrices and their iterators and performing operations
on a mix of them.
Specifying all template arguments to be size_t get's you along
for a bit, but not all the way.
In order to solve this inconsistency some patching in the code
is needed.

The patchfile in attachment shows you what kind of changes
I'd love to see in a next release of mtl.
The patches solve my particular problem at hand, but are not
complete at all.

bye,

Walter.
-- 
Walter Daems                                     http://www.kimotion.com
                                         mailto:[email protected]
Kimotion Technologies                                 tel: +32 16 298306
Kapeldreef 60, B-3001 Leuven-Heverlee, Belgium        fax: +32 16 298319

_______________________________________________
This list is archived at http://www.osl.iu.edu/MailArchives/mtl-devel/
patch_indices (text/plain, 11.8 KB)
*** orig/matrix.h	2002-07-06 17:48:35.000000000 +0200
--- adpt/matrix.h	2004-04-20 13:48:41.000000000 +0200
***************
*** 495,505 ****
    //!tparam: IndexStyle - Specify whether the underlying index array stores indices starting from one (fortan style) or from zero (c-style)  - index_from_zero
    //!component: type
    //!category: containers, selectors
    //!example: sparse_matrix.cc
    //!definition: matrix.h
!   template <class SizeType = int, int MemLoc=internal, 
              int IndexStyle = index_from_zero>
    struct compressed {
      typedef SizeType size_type;
      enum { id = COMPRESSED, oned_id, ext=MemLoc, 
             issparse=1, index=IndexStyle }; 
--- 495,505 ----
    //!tparam: IndexStyle - Specify whether the underlying index array stores indices starting from one (fortan style) or from zero (c-style)  - index_from_zero
    //!component: type
    //!category: containers, selectors
    //!example: sparse_matrix.cc
    //!definition: matrix.h
!   template <class SizeType = size_t, int MemLoc=internal, 
              int IndexStyle = index_from_zero>
    struct compressed {
      typedef SizeType size_type;
      enum { id = COMPRESSED, oned_id, ext=MemLoc, 
             issparse=1, index=IndexStyle }; 
*** orig/compressed1D.h	2002-07-06 17:48:34.000000000 +0200
--- adpt/compressed1D.h	2004-04-20 13:48:41.000000000 +0200
***************
*** 82,92 ****
  //!definition: compressed1D.h
  //!tparam: T - the element type
  //!tparam: SizeType - the type for the stored indices - int
  //!tparam: IND_OFFSET - To handle indexing from 0 or 1 - index_from_zero
  //!example: gather_scatter.cc, array2D.cc, sparse_copy.cc
! template <class T, class SizeType = int, int IND_OFFSET = index_from_zero>
  class compressed1D {
  
    typedef std::vector<T> values_vec;
    typedef std::vector<SizeType> indices_vec;
    typedef indices_vec indices_t;
--- 82,92 ----
  //!definition: compressed1D.h
  //!tparam: T - the element type
  //!tparam: SizeType - the type for the stored indices - int
  //!tparam: IND_OFFSET - To handle indexing from 0 or 1 - index_from_zero
  //!example: gather_scatter.cc, array2D.cc, sparse_copy.cc
! template <class T, class SizeType = size_t, int IND_OFFSET = index_from_zero>
  class compressed1D {
  
    typedef std::vector<T> values_vec;
    typedef std::vector<SizeType> indices_vec;
    typedef indices_vec indices_t;
*** orig/compressed_iter.h	2002-07-06 17:48:34.000000000 +0200
--- adpt/compressed_iter.h	2004-04-20 13:48:41.000000000 +0200
***************
*** 56,65 ****
--- 56,66 ----
  #if defined(_MSVCPP_)
  	typedef std::random_access_iterator_tag iterator_category;
  #else
    typedef typename std::iterator_traits<value_iterator>::iterator_category iterator_category;
  #endif
+   typedef typename Index::size_type size_type;
    typedef typename Value::value_type value_type;
    typedef int difference_type;
    typedef difference_type distance_type;
    typedef typename IF<isConst, const value_type*,value_type*>::RET pointer;
    typedef typename IF<isConst, const value_type&, value_type&>::RET reference;
***************
*** 83,99 ****
      value_iter_ = x.value_iter_;
      pos         = x.pos; 
      return *this; 
    }
  
!   inline compressed_iter(value_iter_t vals, index_iter_t inds, int p)
      : index_iter_(inds), value_iter_(vals), pos(p) { }
  
!   inline int index() const { 
      return index_iter_[pos] + IND_OFFSET;  /* F to C */
    }
!   inline void set_index(int i) { 
      index_iter_[pos] = i;
    }
    
    inline reference operator*() const { return value_iter_[pos]; }
    
--- 84,100 ----
      value_iter_ = x.value_iter_;
      pos         = x.pos; 
      return *this; 
    }
  
!   inline compressed_iter(value_iter_t vals, index_iter_t inds, size_type p)
      : index_iter_(inds), value_iter_(vals), pos(p) { }
  
!   inline size_type index() const { 
      return index_iter_[pos] + IND_OFFSET;  /* F to C */
    }
!   inline void set_index(size_type i) { 
      index_iter_[pos] = i;
    }
    
    inline reference operator*() const { return value_iter_[pos]; }
    
***************
*** 103,119 ****
    }
    inline self& operator--() { --pos; return *this; }
    inline self operator--(int) {
      self tmp = *this; --pos; return tmp;
    }
!   inline self& operator+=(int n) { pos += n; return *this; }
!   inline self& operator-=(int n) { pos -= n; return *this; }
  
!   inline self operator+(int n) {
      return self(value_iter_, index_iter_, pos + n);
    }
!   inline self operator-(int n) const {
      return self(value_iter_, index_iter_, pos - n);
    }
    inline int operator-(const self& x) const {
      return pos - x.pos;
    }
--- 104,120 ----
    }
    inline self& operator--() { --pos; return *this; }
    inline self operator--(int) {
      self tmp = *this; --pos; return tmp;
    }
!   inline self& operator+=(size_type n) { pos += n; return *this; }
!   inline self& operator-=(size_type n) { pos -= n; return *this; }
  
!   inline self operator+(size_type n) {
      return self(value_iter_, index_iter_, pos + n);
    }
!   inline self operator-(size_type n) const {
      return self(value_iter_, index_iter_, pos - n);
    }
    inline int operator-(const self& x) const {
      return pos - x.pos;
    }
***************
*** 131,141 ****
    inline index_iter_t index_iter() const { return index_iter_ + pos; }
    inline value_iter_t value_iter() const { return value_iter_ + pos; }
    //protected:
    index_iter_t index_iter_;
    value_iter_t value_iter_;
!   int pos;
  };
  
  
  
  } /* namespace mtl */
--- 132,142 ----
    inline index_iter_t index_iter() const { return index_iter_ + pos; }
    inline value_iter_t value_iter() const { return value_iter_ + pos; }
    //protected:
    index_iter_t index_iter_;
    value_iter_t value_iter_;
!   size_type pos;
  };
  
  
  
  } /* namespace mtl */
*** orig/array2D.h	2002-07-06 17:48:34.000000000 +0200
--- adpt/array2D.h	2004-04-20 13:48:41.000000000 +0200
***************
*** 124,139 ****
    typedef typename rep_type::const_reference const_reference;
    //: The integral type for dimensions and indices
    typedef typename rep_type::size_type size_type;
  #if !defined( _MSVCPP_ )
    //: The iterator type
!   typedef dense_iterator<typename rep_type::iterator> iterator;
    //: The const iterator type
!   typedef dense_iterator<typename rep_type::const_iterator> const_iterator;
  #else
!   typedef dense_iterator<typename rep_type::value_type, 0> iterator;
!   typedef dense_iterator<typename rep_type::value_type, 1> const_iterator;
  #endif
    //: The reverse iterator type
    typedef reverse_iter<iterator> reverse_iterator;
    //: The const reverse iterator type
    typedef reverse_iter<const_iterator> const_reverse_iterator;
--- 124,149 ----
    typedef typename rep_type::const_reference const_reference;
    //: The integral type for dimensions and indices
    typedef typename rep_type::size_type size_type;
  #if !defined( _MSVCPP_ )
    //: The iterator type
!   typedef dense_iterator<typename rep_type::iterator, 
!                          0, 
!                          size_type> iterator;
    //: The const iterator type
!   typedef dense_iterator<typename rep_type::const_iterator, 
!                          0, 
!                          size_type> const_iterator;
  #else
!   typedef dense_iterator<typename rep_type::value_type, 
!                          0,
!                          0,
!                          size_type> iterator;
!   typedef dense_iterator<typename rep_type::value_type, 
!                          1,
!                          0,
!                          size_type> const_iterator;
  #endif
    //: The reverse iterator type
    typedef reverse_iter<iterator> reverse_iterator;
    //: The const reverse iterator type
    typedef reverse_iter<const_iterator> const_reverse_iterator;
***************
*** 143,153 ****
    typedef dimension<int> band_type;
  
  protected:
    inline void resize_oned(sparse_tag) {
      for (iterator i = this->begin(); i != this->end(); ++i)
!       *i = OneD();
    }
  
    inline void resize_oned(dense_tag) { 
      for (iterator i = this->begin(); i != this->end(); ++i)
        *i = OneD(dim.second());
--- 153,163 ----
    typedef dimension<int> band_type;
  
  protected:
    inline void resize_oned(sparse_tag) {
      for (iterator i = this->begin(); i != this->end(); ++i)
!       *i = OneD(dim.second());
    }
  
    inline void resize_oned(dense_tag) { 
      for (iterator i = this->begin(); i != this->end(); ++i)
        *i = OneD(dim.second());
*** orig/entry.h	2002-07-06 17:48:34.000000000 +0200
--- adpt/entry.h	2004-04-20 13:48:41.000000000 +0200
***************
*** 88,102 ****
  //!noindex:
  template <class OneD>
  class elt_ref {
    typedef elt_ref self;
  public:
!   typedef typename OneD::value_type value_type;
  
!   inline elt_ref() : vec(OneD()), i(-1) { }
  
!   inline elt_ref(OneD& m, int i_) 
      : vec(m), i(i_) {
        iter = vec.find(i);
        if (iter != vec.end()) {
          if (iter.index() == i)
            val = *iter;
--- 88,106 ----
  //!noindex:
  template <class OneD>
  class elt_ref {
    typedef elt_ref self;
  public:
!   typedef typename OneD::value_type  value_type;
!   typedef typename OneD::size_type   size_type;
  
!   /* removed by WPD when changed because dangerous:
!    * might result in uninitialized use of iter 
!    */
!   /* inline elt_ref() : vec(OneD()), i(-1) { } */
  
!   inline elt_ref(OneD& m, size_type i_) 
      : vec(m), i(i_) {
        iter = vec.find(i);
        if (iter != vec.end()) {
          if (iter.index() == i)
            val = *iter;
***************
*** 171,182 ****
    OneD vec;
    /* JGS, value_typeobably performance issue here, want 
     OneD& vec;
     but vec may be temporary object in the 2D, like comvalue_typeessed2D
     */
    typename OneD::iterator iter;
!   int i;
    value_type val;
  };
  
  
  
--- 175,188 ----
    OneD vec;
    /* JGS, value_typeobably performance issue here, want 
     OneD& vec;
     but vec may be temporary object in the 2D, like comvalue_typeessed2D
     */
+ public:
    typename OneD::iterator iter;
! protected:
!   size_type  i;
    value_type val;
  };
  
  
  
***************
*** 184,210 ****
  //!noindex:
  template <class OneD>
  class const_elt_ref {
    typedef const_elt_ref self;
  public:
!   typedef typename OneD::value_type value_type;
  
    /*  inline const_elt_ref() : vec(0), i(0) { }*/
    template <class EltRef>
    inline const_elt_ref(const EltRef& elt) {
!     typename OneD::const_iterator iter = elt.vec.find(elt.i);
      if (iter != elt.vec.end()) {
        if (iter.index() == elt.i)
          val = *iter;
        else
          val = value_type();
      } else
        val = value_type();
    }
  
!   inline const_elt_ref(const OneD& vec, int i) {
!     typename OneD::const_iterator iter = vec.find(i);
      if (iter != vec.end()) {
        if (iter.index() == i)
          val = *iter;
        else
          val = value_type();
--- 190,217 ----
  //!noindex:
  template <class OneD>
  class const_elt_ref {
    typedef const_elt_ref self;
  public:
!   typedef typename OneD::value_type  value_type;
!   typedef typename OneD::size_type   size_type;
  
    /*  inline const_elt_ref() : vec(0), i(0) { }*/
    template <class EltRef>
    inline const_elt_ref(const EltRef& elt) {
!     iter = elt.vec.find(elt.i);
      if (iter != elt.vec.end()) {
        if (iter.index() == elt.i)
          val = *iter;
        else
          val = value_type();
      } else
        val = value_type();
    }
  
!   inline const_elt_ref(const OneD& vec, size_type i) {
!     iter = vec.find(i);
      if (iter != vec.end()) {
        if (iter.index() == i)
          val = *iter;
        else
          val = value_type();
***************
*** 212,221 ****
--- 219,230 ----
        val = value_type();
    }
  
    inline operator value_type() const { return val; }
  
+ public:
+   typename OneD::const_iterator iter;
  protected:
    value_type val;
  };