aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/ref.cpp
diff options
context:
space:
mode:
authorGravatar Antonio Sanchez <cantonios@google.com>2020-12-10 14:05:38 -0800
committerGravatar Antonio Sanchez <cantonios@google.com>2021-01-05 10:41:25 -0800
commitbb1de9dbdede6669c2c86c028a9deff637e3d1f6 (patch)
tree3d7936aeea85b1541c2ff8c5eece202aefe82c42 /test/ref.cpp
parent12dda34b15fe2ea4d994fafdba8c4666963e1a55 (diff)
Fix Ref Stride checks.
The existing `Ref` class failed to consider cases where the Ref's `Stride` setting *could* match the underlying referred object's stride, but **didn't** at runtime. This led to trying to set invalid stride values, causing runtime failures in some cases, and garbage due to mismatched strides in others. Here we add the missing runtime checks. This involves computing the strides necessary to align with the referred object's storage, and verifying we can actually set those strides at runtime. In the `const` case, if it *may* be possible to refer to the original storage at compile-time but fails at runtime, then we defer to the `construct(...)` method that makes a copy. Added more tests to check these cases. Fixes #2093.
Diffstat (limited to 'test/ref.cpp')
-rw-r--r--test/ref.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/test/ref.cpp b/test/ref.cpp
index c0b6ffdcf..ebfc70d3d 100644
--- a/test/ref.cpp
+++ b/test/ref.cpp
@@ -141,6 +141,69 @@ template<typename VectorType> void ref_vector(const VectorType& m)
VERIFY_IS_APPROX(mat1, mat2);
}
+template<typename Scalar, int Rows, int Cols>
+void ref_vector_fixed_sizes()
+{
+ typedef Matrix<Scalar,Rows,Cols,RowMajor> RowMajorMatrixType;
+ typedef Matrix<Scalar,Rows,Cols,ColMajor> ColMajorMatrixType;
+ typedef Matrix<Scalar,1,Cols> RowVectorType;
+ typedef Matrix<Scalar,Rows,1> ColVectorType;
+ typedef Matrix<Scalar,Cols,1> RowVectorTransposeType;
+ typedef Matrix<Scalar,1,Rows> ColVectorTransposeType;
+ typedef Stride<Dynamic, Dynamic> DynamicStride;
+
+ RowMajorMatrixType mr = RowMajorMatrixType::Random();
+ ColMajorMatrixType mc = ColMajorMatrixType::Random();
+
+ Index i = internal::random<Index>(0,Rows-1);
+ Index j = internal::random<Index>(0,Cols-1);
+
+ // Reference ith row.
+ Ref<RowVectorType, 0, DynamicStride> mr_ri = mr.row(i);
+ VERIFY_IS_EQUAL(mr_ri, mr.row(i));
+ Ref<RowVectorType, 0, DynamicStride> mc_ri = mc.row(i);
+ VERIFY_IS_EQUAL(mc_ri, mc.row(i));
+
+ // Reference jth col.
+ Ref<ColVectorType, 0, DynamicStride> mr_cj = mr.col(j);
+ VERIFY_IS_EQUAL(mr_cj, mr.col(j));
+ Ref<ColVectorType, 0, DynamicStride> mc_cj = mc.col(j);
+ VERIFY_IS_EQUAL(mc_cj, mc.col(j));
+
+ // Reference the transpose of row i.
+ Ref<RowVectorTransposeType, 0, DynamicStride> mr_rit = mr.row(i);
+ VERIFY_IS_EQUAL(mr_rit, mr.row(i).transpose());
+ Ref<RowVectorTransposeType, 0, DynamicStride> mc_rit = mc.row(i);
+ VERIFY_IS_EQUAL(mc_rit, mc.row(i).transpose());
+
+ // Reference the transpose of col j.
+ Ref<ColVectorTransposeType, 0, DynamicStride> mr_cjt = mr.col(j);
+ VERIFY_IS_EQUAL(mr_cjt, mr.col(j).transpose());
+ Ref<ColVectorTransposeType, 0, DynamicStride> mc_cjt = mc.col(j);
+ VERIFY_IS_EQUAL(mc_cjt, mc.col(j).transpose());
+
+ // Const references without strides.
+ Ref<const RowVectorType> cmr_ri = mr.row(i);
+ VERIFY_IS_EQUAL(cmr_ri, mr.row(i));
+ Ref<const RowVectorType> cmc_ri = mc.row(i);
+ VERIFY_IS_EQUAL(cmc_ri, mc.row(i));
+
+ Ref<const ColVectorType> cmr_cj = mr.col(j);
+ VERIFY_IS_EQUAL(cmr_cj, mr.col(j));
+ Ref<const ColVectorType> cmc_cj = mc.col(j);
+ VERIFY_IS_EQUAL(cmc_cj, mc.col(j));
+
+ Ref<const RowVectorTransposeType> cmr_rit = mr.row(i);
+ VERIFY_IS_EQUAL(cmr_rit, mr.row(i).transpose());
+ Ref<const RowVectorTransposeType> cmc_rit = mc.row(i);
+ VERIFY_IS_EQUAL(cmc_rit, mc.row(i).transpose());
+
+ Ref<const ColVectorTransposeType> cmr_cjt = mr.col(j);
+ VERIFY_IS_EQUAL(cmr_cjt, mr.col(j).transpose());
+ Ref<const ColVectorTransposeType> cmc_cjt = mc.col(j);
+ VERIFY_IS_EQUAL(cmc_cjt, mc.col(j).transpose());
+}
+
template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)
{
// verify that ref-to-const don't have LvalueBit
@@ -287,6 +350,9 @@ EIGEN_DECLARE_TEST(ref)
CALL_SUBTEST_4( ref_matrix(Matrix<std::complex<double>,10,15>()) );
CALL_SUBTEST_5( ref_matrix(MatrixXi(internal::random<int>(1,10),internal::random<int>(1,10))) );
CALL_SUBTEST_6( call_ref() );
+
+ CALL_SUBTEST_8( (ref_vector_fixed_sizes<float,3,5>()) );
+ CALL_SUBTEST_8( (ref_vector_fixed_sizes<float,15,10>()) );
}
CALL_SUBTEST_7( test_ref_overloads() );