diff options
author | Gael Guennebaud <g.gael@free.fr> | 2018-10-02 23:44:36 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2018-10-02 23:44:36 +0200 |
commit | 0481900e25764f16e8723d2588f818d3a610cfad (patch) | |
tree | ddfa9c7bdbefe56b146093389568945c65cc5282 /Eigen | |
parent | 8c385281689c51d997a99cabe76672b7c2efe91d (diff) |
Add pointer-based iterator for direct-access expressions
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/Core/DenseBase.h | 21 | ||||
-rw-r--r-- | Eigen/src/Core/StlIterators.h | 83 | ||||
-rw-r--r-- | Eigen/src/Core/util/ForwardDeclarations.h | 1 |
3 files changed, 85 insertions, 20 deletions
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h index c0699f97d..f69c0b2dc 100644 --- a/Eigen/src/Core/DenseBase.h +++ b/Eigen/src/Core/DenseBase.h @@ -572,12 +572,21 @@ template<typename Derived> class DenseBase } EIGEN_DEVICE_FUNC void reverseInPlace(); - inline DenseStlIterator<Derived> begin(); - inline DenseStlIterator<const Derived> begin() const; - inline DenseStlIterator<const Derived> cbegin() const; - inline DenseStlIterator<Derived> end(); - inline DenseStlIterator<const Derived> end() const; - inline DenseStlIterator<const Derived> cend() const; + typedef typename internal::conditional< (Flags&DirectAccessBit)==DirectAccessBit, + PointerBasedStlIterator<Derived>, + DenseStlIterator<Derived> + >::type iterator; + + typedef typename internal::conditional< (Flags&DirectAccessBit)==DirectAccessBit, + PointerBasedStlIterator<const Derived>, + DenseStlIterator<const Derived> + >::type const_iterator; + inline iterator begin(); + inline const_iterator begin() const; + inline const_iterator cbegin() const; + inline iterator end(); + inline const_iterator end() const; + inline const_iterator cend() const; inline SubVectorsProxy<Derived,Vertical> allCols(); inline SubVectorsProxy<const Derived,Vertical> allCols() const; inline SubVectorsProxy<Derived,Horizontal> allRows(); diff --git a/Eigen/src/Core/StlIterators.h b/Eigen/src/Core/StlIterators.h index c5ed2f6b9..04d3d3c8d 100644 --- a/Eigen/src/Core/StlIterators.h +++ b/Eigen/src/Core/StlIterators.h @@ -57,6 +57,58 @@ protected: }; template<typename XprType> +class PointerBasedStlIterator +{ + enum { is_lvalue = internal::is_lvalue<XprType>::value }; +public: + typedef Index difference_type; + typedef typename XprType::Scalar value_type; + typedef std::random_access_iterator_tag iterator_category; + typedef typename internal::conditional<bool(is_lvalue), value_type*, const value_type*>::type pointer; + typedef typename internal::conditional<bool(is_lvalue), value_type&, const value_type&>::type reference; + + PointerBasedStlIterator() : m_ptr(0) {} + PointerBasedStlIterator(XprType& xpr, Index index) : m_incr(xpr.innerStride()) + { + m_ptr = xpr.data() + index * m_incr.value(); + } + + reference operator*() const { return *m_ptr; } + reference operator[](Index i) const { return *(m_ptr+i*m_incr.value()); } + pointer operator->() const { return m_ptr; } + + PointerBasedStlIterator& operator++() { m_ptr += m_incr.value(); return *this; } + PointerBasedStlIterator& operator--() { m_ptr -= m_incr.value(); return *this; } + + PointerBasedStlIterator operator++(int) { PointerBasedStlIterator prev(*this); operator++(); return prev;} + PointerBasedStlIterator operator--(int) { PointerBasedStlIterator prev(*this); operator--(); return prev;} + + friend PointerBasedStlIterator operator+(const PointerBasedStlIterator& a, Index b) { PointerBasedStlIterator ret(a); ret += b; return ret; } + friend PointerBasedStlIterator operator-(const PointerBasedStlIterator& a, Index b) { PointerBasedStlIterator ret(a); ret -= b; return ret; } + friend PointerBasedStlIterator operator+(Index a, const PointerBasedStlIterator& b) { PointerBasedStlIterator ret(b); ret += a; return ret; } + friend PointerBasedStlIterator operator-(Index a, const PointerBasedStlIterator& b) { PointerBasedStlIterator ret(b); ret -= a; return ret; } + + PointerBasedStlIterator& operator+=(Index b) { m_ptr += b*m_incr.value(); return *this; } + PointerBasedStlIterator& operator-=(Index b) { m_ptr -= b*m_incr.value(); return *this; } + + difference_type operator-(const PointerBasedStlIterator& other) const { + return (m_ptr - other.m_ptr)/m_incr.value(); + } + + bool operator==(const PointerBasedStlIterator& other) { return m_ptr == other.m_ptr; } + bool operator!=(const PointerBasedStlIterator& other) { return m_ptr != other.m_ptr; } + bool operator< (const PointerBasedStlIterator& other) { return m_ptr < other.m_ptr; } + bool operator<=(const PointerBasedStlIterator& other) { return m_ptr <= other.m_ptr; } + bool operator> (const PointerBasedStlIterator& other) { return m_ptr > other.m_ptr; } + bool operator>=(const PointerBasedStlIterator& other) { return m_ptr >= other.m_ptr; } + +protected: + + pointer m_ptr; + internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_incr; +}; + +template<typename XprType> class DenseStlIterator : public IndexedBasedStlIteratorBase<XprType, DenseStlIterator<XprType> > { public: @@ -66,19 +118,22 @@ protected: enum { has_direct_access = (internal::traits<XprType>::Flags & DirectAccessBit) ? 1 : 0, - has_write_access = internal::is_lvalue<XprType>::value + is_lvalue = internal::is_lvalue<XprType>::value }; typedef IndexedBasedStlIteratorBase<XprType,DenseStlIterator> Base; using Base::m_index; using Base::mp_xpr; - typedef typename internal::conditional<bool(has_direct_access), const value_type&, const value_type>::type read_only_ref_t; + // TODO currently const Transpose/Reshape expressions never returns const references, + // so lets return by value too. + //typedef typename internal::conditional<bool(has_direct_access), const value_type&, const value_type>::type read_only_ref_t; + typedef const value_type read_only_ref_t; public: - typedef typename internal::conditional<bool(has_write_access), value_type *, const value_type *>::type pointer; - typedef typename internal::conditional<bool(has_write_access), value_type&, read_only_ref_t>::type reference; + typedef typename internal::conditional<bool(is_lvalue), value_type *, const value_type *>::type pointer; + typedef typename internal::conditional<bool(is_lvalue), value_type&, read_only_ref_t>::type reference; DenseStlIterator() : Base() {} DenseStlIterator(XprType& xpr, Index index) : Base(xpr,index) {} @@ -94,43 +149,43 @@ void swap(IndexedBasedStlIteratorBase<XprType,Derived>& a, IndexedBasedStlIterat } template<typename Derived> -inline DenseStlIterator<Derived> DenseBase<Derived>::begin() +inline typename DenseBase<Derived>::iterator DenseBase<Derived>::begin() { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); - return DenseStlIterator<Derived>(derived(), 0); + return iterator(derived(), 0); } template<typename Derived> -inline DenseStlIterator<const Derived> DenseBase<Derived>::begin() const +inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::begin() const { return cbegin(); } template<typename Derived> -inline DenseStlIterator<const Derived> DenseBase<Derived>::cbegin() const +inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::cbegin() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); - return DenseStlIterator<const Derived>(derived(), 0); + return const_iterator(derived(), 0); } template<typename Derived> -inline DenseStlIterator<Derived> DenseBase<Derived>::end() +inline typename DenseBase<Derived>::iterator DenseBase<Derived>::end() { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); - return DenseStlIterator<Derived>(derived(), size()); + return iterator(derived(), size()); } template<typename Derived> -inline DenseStlIterator<const Derived> DenseBase<Derived>::end() const +inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::end() const { return cend(); } template<typename Derived> -inline DenseStlIterator<const Derived> DenseBase<Derived>::cend() const +inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::cend() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); - return DenseStlIterator<const Derived>(derived(), size()); + return const_iterator(derived(), size()); } template<typename XprType, DirectionType Direction> diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 8ed8dd09b..5fa7e5267 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -134,6 +134,7 @@ template<typename ExpressionType> class MatrixWrapper; template<typename Derived> class SolverBase; template<typename XprType> class InnerIterator; template<typename XprType> class DenseStlIterator; +template<typename XprType> class PointerBasedStlIterator; template<typename XprType, DirectionType Direction> class SubVectorsProxy; namespace internal { |