From 0481900e25764f16e8723d2588f818d3a610cfad Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Tue, 2 Oct 2018 23:44:36 +0200 Subject: Add pointer-based iterator for direct-access expressions --- test/stl_iterators.cpp | 118 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 3 deletions(-) (limited to 'test/stl_iterators.cpp') 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 #include "main.h" template< class Iterator > @@ -16,6 +17,12 @@ make_reverse_iterator( Iterator i ) return std::reverse_iterator(i); } +template +bool is_PointerBasedStlIterator(const PointerBasedStlIterator &) { return true; } + +template +bool is_DenseStlIterator(const DenseStlIterator &) { return true; } + template 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 ColMatrixType; typedef Matrix 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(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(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().begin()) ); + VERIFY( is_DenseStlIterator(A.template reshaped().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(0,A.rows()-1); + for(auto x : cA.row(i)) { VERIFY_IS_EQUAL(x,A(i,j++)); } + } + Matrix 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(0,A.cols()-1); + auto it = A.col(j).begin(); + for(i=0;i(0,A.rows()-1); + auto it = A.row(i).begin(); + for(j=0;j(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(0,A.cols()-1); + // auto it = (A+2*A).col(j).begin(); + // for(i=0;i=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(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(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() )); CALL_SUBTEST_1(( test_range_for_loop() )); + CALL_SUBTEST_1(( test_range_for_loop(internal::random(5,10), internal::random(5,10)) )); CALL_SUBTEST_1(( test_range_for_loop(internal::random(10,200), internal::random(10,200)) )); } } -- cgit v1.2.3