diff options
-rw-r--r-- | Eigen/src/Core/StlIterators.h | 25 | ||||
-rw-r--r-- | test/stl_iterators.cpp | 28 |
2 files changed, 46 insertions, 7 deletions
diff --git a/Eigen/src/Core/StlIterators.h b/Eigen/src/Core/StlIterators.h index 4f25a60c4..0d8bd1aa3 100644 --- a/Eigen/src/Core/StlIterators.h +++ b/Eigen/src/Core/StlIterators.h @@ -241,17 +241,30 @@ protected: typedef typename internal::conditional<Direction==Vertical,typename XprType::ColXpr,typename XprType::RowXpr>::type SubVectorType; typedef typename internal::conditional<Direction==Vertical,typename XprType::ConstColXpr,typename XprType::ConstRowXpr>::type ConstSubVectorType; + +public: + typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference; + typedef typename reference::PlainObject value_type; + +private: + class subvector_stl_iterator_ptr + { + public: + subvector_stl_iterator_ptr(const reference &subvector) : m_subvector(subvector) {} + reference* operator->() { return &m_subvector; } + private: + reference m_subvector; + }; public: - typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type value_type; - typedef value_type* pointer; - typedef value_type reference; + + typedef subvector_stl_iterator_ptr pointer; subvector_stl_iterator() : Base() {} subvector_stl_iterator(XprType& xpr, Index index) : Base(xpr,index) {} - reference operator*() const { return (*mp_xpr).template subVector<Direction>(m_index); } - reference operator[](Index i) const { return (*mp_xpr).template subVector<Direction>(m_index+i); } - pointer operator->() const { return &((*mp_xpr).template subVector<Direction>(m_index)); } + reference operator*() const { return (*mp_xpr).template subVector<Direction>(m_index); } + reference operator[](Index i) const { return (*mp_xpr).template subVector<Direction>(m_index+i); } + pointer operator->() const { return (*mp_xpr).template subVector<Direction>(m_index); } }; } // namespace internal diff --git a/test/stl_iterators.cpp b/test/stl_iterators.cpp index cdd9e5c33..9ede923ee 100644 --- a/test/stl_iterators.cpp +++ b/test/stl_iterators.cpp @@ -272,6 +272,31 @@ void test_stl_iterators(int rows=Rows, int cols=Cols) } } } + + { + // check basic for loop on vector-wise iterators + j=0; + for (auto it = A.colwise().cbegin(); it != A.colwise().cend(); ++it, ++j) { + VERIFY_IS_APPROX( it->coeff(0), A(0,j) ); + VERIFY_IS_APPROX( (*it).coeff(0), A(0,j) ); + } + j=0; + for (auto it = A.colwise().begin(); it != A.colwise().end(); ++it, ++j) { + (*it).coeffRef(0) = (*it).coeff(0); // compilation check + it->coeffRef(0) = it->coeff(0); // compilation check + VERIFY_IS_APPROX( it->coeff(0), A(0,j) ); + VERIFY_IS_APPROX( (*it).coeff(0), A(0,j) ); + } + + // check valuetype gives us a copy + j=0; + for (auto it = A.colwise().cbegin(); it != A.colwise().cend(); ++it, ++j) { + typename decltype(it)::value_type tmp = *it; + VERIFY_IS_NOT_EQUAL( tmp.data() , it->data() ); + VERIFY_IS_APPROX( tmp, A.col(j) ); + } + } + #endif if(rows>=3) { @@ -410,7 +435,8 @@ void test_stl_iterators(int rows=Rows, int cols=Cols) VectorType col = VectorType::Random(rows); A.colwise() = col; - VERIFY( std::all_of(A.colwise().begin(), A.colwise().end(), [&col](typename ColMatrixType::ColXpr x) { return internal::isApprox(x.norm(),col.norm()); }) ); + VERIFY( std::all_of(A.colwise().begin(), A.colwise().end(), [&col](typename ColMatrixType::ColXpr x) { return internal::isApprox(x.norm(),col.norm()); }) ); + VERIFY( std::all_of(A.colwise().cbegin(), A.colwise().cend(), [&col](typename ColMatrixType::ConstColXpr x) { return internal::isApprox(x.norm(),col.norm()); }) ); i = internal::random<Index>(0,A.rows()-1); A.setRandom(); |