diff --git a/Eigen/src/Core/Ref.h b/Eigen/src/Core/Ref.h index 11866f7e6..e347a0fde 100644 --- a/Eigen/src/Core/Ref.h +++ b/Eigen/src/Core/Ref.h @@ -363,6 +363,15 @@ template class Ref< // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy } + EIGEN_DEVICE_FUNC inline Ref(Ref&& other) { + if (other.data() == other.m_object.data()) { + m_object = std::move(other.m_object); + Base::construct(m_object); + } + else + Base::construct(other); + } + template EIGEN_DEVICE_FUNC inline Ref(const RefBase& other) { EIGEN_STATIC_ASSERT(Traits::template match::type::value || may_map_m_object_successfully, diff --git a/test/ref.cpp b/test/ref.cpp index 252bacd4b..f28353735 100644 --- a/test/ref.cpp +++ b/test/ref.cpp @@ -317,6 +317,30 @@ void test_ref_overloads() test_ref_ambiguous(A, B); } +template +struct RefDerived + : Ref_ +{ + using Ref_::m_object; +}; + +template void test_cref_move_ctor(const DenseBase &expr) { + typedef Ref CRef; + typedef RefDerived CRefDerived; + + const bool owns_data = !bool(internal::traits::template match::type::value); + CRef cref1(expr); + const double *data1 = cref1.data(), + *obj_data1 = static_cast(cref1).m_object.data(); + VERIFY(test_is_equal(data1, obj_data1, owns_data)); + CRef cref2(std::move(cref1)); + VERIFY_IS_EQUAL(data1, cref1.data()); + const double *data2 = cref2.data(), + *obj_data2 = static_cast(cref2).m_object.data(); + VERIFY(test_is_equal(data1, data2, MatrixType::MaxSizeAtCompileTime == Dynamic || !owns_data)); + VERIFY(test_is_equal(data1, obj_data2, MatrixType::MaxSizeAtCompileTime == Dynamic && owns_data)); +} + EIGEN_DECLARE_TEST(ref) { for(int i = 0; i < g_repeat; i++) { @@ -342,4 +366,13 @@ EIGEN_DECLARE_TEST(ref) } CALL_SUBTEST_7( test_ref_overloads() ); + + CALL_SUBTEST_9( test_cref_move_ctor(VectorXd::Ones(9)) ); + CALL_SUBTEST_9( test_cref_move_ctor(VectorXd(9)) ); + CALL_SUBTEST_9( test_cref_move_ctor(Vector3d::Ones()) ); + CALL_SUBTEST_9( test_cref_move_ctor(Vector3d()) ); + CALL_SUBTEST_9( test_cref_move_ctor(MatrixXd::Ones(9, 5)) ); + CALL_SUBTEST_9( test_cref_move_ctor(MatrixXd(9, 5)) ); + CALL_SUBTEST_9( test_cref_move_ctor(Matrix3d::Ones()) ); + CALL_SUBTEST_9( test_cref_move_ctor(Matrix3d()) ); }