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 /test/stl_iterators.cpp | |
parent | 8c385281689c51d997a99cabe76672b7c2efe91d (diff) |
Add pointer-based iterator for direct-access expressions
Diffstat (limited to 'test/stl_iterators.cpp')
-rw-r--r-- | test/stl_iterators.cpp | 118 |
1 files changed, 115 insertions, 3 deletions
diff --git a/test/stl_iterators.cpp b/test/stl_iterators.cpp index f56209f07..4e04d28b7 100644 --- a/test/stl_iterators.cpp +++ b/test/stl_iterators.cpp @@ -7,6 +7,7 @@ // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include <numeric> #include "main.h" template< class Iterator > @@ -16,6 +17,12 @@ make_reverse_iterator( Iterator i ) return std::reverse_iterator<Iterator>(i); } +template<typename XprType> +bool is_PointerBasedStlIterator(const PointerBasedStlIterator<XprType> &) { return true; } + +template<typename XprType> +bool is_DenseStlIterator(const DenseStlIterator<XprType> &) { return true; } + template<typename Scalar, int Rows, int Cols> void test_range_for_loop(int rows=Rows, int cols=Cols) { @@ -26,10 +33,37 @@ void test_range_for_loop(int rows=Rows, int cols=Cols) typedef Matrix<Scalar,Rows,Cols,ColMajor> ColMatrixType; typedef Matrix<Scalar,Rows,Cols,RowMajor> RowMatrixType; VectorType v = VectorType::Random(rows); + const VectorType& cv(v); ColMatrixType A = ColMatrixType::Random(rows,cols); + const ColMatrixType& cA(A); RowMatrixType B = RowMatrixType::Random(rows,cols); Index i, j; + + VERIFY( is_PointerBasedStlIterator(v.begin()) ); + VERIFY( is_PointerBasedStlIterator(v.end()) ); + VERIFY( is_PointerBasedStlIterator(cv.begin()) ); + VERIFY( is_PointerBasedStlIterator(cv.end()) ); + + j = internal::random<Index>(0,A.cols()-1); + VERIFY( is_PointerBasedStlIterator(A.col(j).begin()) ); + VERIFY( is_PointerBasedStlIterator(A.col(j).end()) ); + VERIFY( is_PointerBasedStlIterator(cA.col(j).begin()) ); + VERIFY( is_PointerBasedStlIterator(cA.col(j).end()) ); + + i = internal::random<Index>(0,A.rows()-1); + VERIFY( is_PointerBasedStlIterator(A.row(i).begin()) ); + VERIFY( is_PointerBasedStlIterator(A.row(i).end()) ); + VERIFY( is_PointerBasedStlIterator(cA.row(i).begin()) ); + VERIFY( is_PointerBasedStlIterator(cA.row(i).end()) ); + + VERIFY( is_PointerBasedStlIterator(A.reshaped().begin()) ); + VERIFY( is_PointerBasedStlIterator(A.reshaped().end()) ); + VERIFY( is_PointerBasedStlIterator(cA.reshaped().begin()) ); + VERIFY( is_PointerBasedStlIterator(cA.reshaped().end()) ); + + VERIFY( is_DenseStlIterator(A.template reshaped<RowMajor>().begin()) ); + VERIFY( is_DenseStlIterator(A.template reshaped<RowMajor>().end()) ); #if EIGEN_HAS_CXX11 i = 0; @@ -49,6 +83,19 @@ void test_range_for_loop(int rows=Rows, int cols=Cols) i = 0; for(auto x : A.reshaped()) { VERIFY_IS_EQUAL(x,A(i++)); } + // check const_iterator + { + i = 0; + for(auto x : cv) { VERIFY_IS_EQUAL(x,v[i++]); } + + i = 0; + for(auto x : cA.reshaped()) { VERIFY_IS_EQUAL(x,A(i++)); } + + j = 0; + i = internal::random<Index>(0,A.rows()-1); + for(auto x : cA.row(i)) { VERIFY_IS_EQUAL(x,A(i,j++)); } + } + Matrix<Scalar,Dynamic,Dynamic,ColMajor> Bc = B; i = 0; for(auto x : B.reshaped()) { VERIFY_IS_EQUAL(x,Bc(i++)); } @@ -57,6 +104,41 @@ void test_range_for_loop(int rows=Rows, int cols=Cols) i = 0; for(auto& x : w) { x = v(i++); } VERIFY_IS_EQUAL(v,w); + + { + j = internal::random<Index>(0,A.cols()-1); + auto it = A.col(j).begin(); + for(i=0;i<rows;++i) { + VERIFY_IS_EQUAL(it[i],A(i,j)); + } + } + + { + i = internal::random<Index>(0,A.rows()-1); + auto it = A.row(i).begin(); + for(j=0;j<cols;++j) { VERIFY_IS_EQUAL(it[j],A(i,j)); } + } + + { + j = internal::random<Index>(0,A.cols()-1); + // this would produce a dangling pointer: + // auto it = (A+2*A).col(j).begin(); + // we need to name the temporary expression: + auto tmp = (A+2*A).col(j); + auto it = tmp.begin(); + for(i=0;i<rows;++i) { + VERIFY_IS_APPROX(it[i],3*A(i,j)); + } + } + + + // { + // j = internal::random<Index>(0,A.cols()-1); + // auto it = (A+2*A).col(j).begin(); + // for(i=0;i<rows;++i) { + // VERIFY_IS_APPROX(it[i],3*A(i,j)); + // } + // } #endif if(rows>=3) { @@ -78,16 +160,45 @@ void test_range_for_loop(int rows=Rows, int cols=Cols) VERIFY(std::is_sorted(begin(v),end(v))); VERIFY(!std::is_sorted(make_reverse_iterator(end(v)),make_reverse_iterator(begin(v)))); + // std::sort with pointer-based iterator and default increment { j = internal::random<Index>(0,A.cols()-1); // std::sort(begin(A.col(j)),end(A.col(j))); // does not compile because this returns const iterators typename ColMatrixType::ColXpr Acol = A.col(j); std::sort(begin(Acol),end(Acol)); VERIFY(std::is_sorted(Acol.cbegin(),Acol.cend())); + A.setRandom(); + + std::sort(A.col(j).begin(),A.col(j).end()); + VERIFY(std::is_sorted(A.col(j).cbegin(),A.col(j).cend())); + A.setRandom(); + } + + // std::sort with pointer-based iterator and runtime increment + { + i = internal::random<Index>(0,A.rows()-1); + typename ColMatrixType::RowXpr Arow = A.row(i); + VERIFY_IS_EQUAL( std::distance(begin(Arow),end(Arow)), cols); + std::sort(begin(Arow),end(Arow)); + VERIFY(std::is_sorted(Arow.cbegin(),Arow.cend())); + A.setRandom(); + + std::sort(A.row(i).begin(),A.row(i).end()); + VERIFY(std::is_sorted(A.row(i).cbegin(),A.row(i).cend())); + A.setRandom(); + } + + // std::sort with generic iterator + { + auto B1 = B.reshaped(); + std::sort(begin(B1),end(B1)); + VERIFY(std::is_sorted(B1.cbegin(),B1.cend())); + B.setRandom(); - // This raises an assert because this creates a pair of iterator referencing two different proxy objects: - // std::sort(A.col(j).begin(),A.col(j).end()); - // VERIFY(std::is_sorted(A.col(j).cbegin(),A.col(j).cend())); // same issue + // assertion because nested expressions are different + // std::sort(B.reshaped().begin(),B.reshaped().end()); + // VERIFY(std::is_sorted(B.reshaped().cbegin(),B.reshaped().cend())); + // B.setRandom(); } { @@ -149,6 +260,7 @@ EIGEN_DECLARE_TEST(stl_iterators) for(int i = 0; i < g_repeat; i++) { CALL_SUBTEST_1(( test_range_for_loop<double,2,3>() )); CALL_SUBTEST_1(( test_range_for_loop<float,7,5>() )); + CALL_SUBTEST_1(( test_range_for_loop<int,Dynamic,Dynamic>(internal::random<int>(5,10), internal::random<int>(5,10)) )); CALL_SUBTEST_1(( test_range_for_loop<int,Dynamic,Dynamic>(internal::random<int>(10,200), internal::random<int>(10,200)) )); } } |