aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2018-10-02 23:44:36 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2018-10-02 23:44:36 +0200
commit0481900e25764f16e8723d2588f818d3a610cfad (patch)
treeddfa9c7bdbefe56b146093389568945c65cc5282 /Eigen
parent8c385281689c51d997a99cabe76672b7c2efe91d (diff)
Add pointer-based iterator for direct-access expressions
Diffstat (limited to 'Eigen')
-rw-r--r--Eigen/src/Core/DenseBase.h21
-rw-r--r--Eigen/src/Core/StlIterators.h83
-rw-r--r--Eigen/src/Core/util/ForwardDeclarations.h1
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 {