mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-01-06 14:14:46 +08:00
Big 853: replace enable_if in Ref<> ctor by static assertions and add failtests for Ref<>
This commit is contained in:
parent
739ed32222
commit
4577bafb91
@ -188,6 +188,8 @@ template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
||||
: public RefBase<Ref<PlainObjectType, Options, StrideType> >
|
||||
{
|
||||
typedef internal::traits<Ref> Traits;
|
||||
template<typename Derived>
|
||||
inline Ref(const PlainObjectBase<Derived>& expr);
|
||||
public:
|
||||
|
||||
typedef RefBase<Ref> Base;
|
||||
@ -196,20 +198,21 @@ template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename Derived>
|
||||
inline Ref(PlainObjectBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
|
||||
inline Ref(PlainObjectBase<Derived>& expr)
|
||||
{
|
||||
Base::construct(expr);
|
||||
EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
||||
Base::construct(expr.derived());
|
||||
}
|
||||
template<typename Derived>
|
||||
inline Ref(const DenseBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(internal::is_lvalue<Derived>::value&&bool(Traits::template match<Derived>::MatchAtCompileTime)),Derived>::type* = 0,
|
||||
int = Derived::ThisConstantIsPrivateInPlainObjectBase)
|
||||
inline Ref(const DenseBase<Derived>& expr)
|
||||
#else
|
||||
template<typename Derived>
|
||||
inline Ref(DenseBase<Derived>& expr)
|
||||
#endif
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(static_cast<bool>(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||
EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
||||
enum { THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY = Derived::ThisConstantIsPrivateInPlainObjectBase};
|
||||
Base::construct(expr.const_cast_derived());
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,9 @@
|
||||
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
|
||||
THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
|
||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
|
||||
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG
|
||||
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG,
|
||||
IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY,
|
||||
STORAGE_LAYOUT_DOES_NOT_MATCH
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -26,6 +26,12 @@ ei_add_failtest("block_on_const_type_actually_const_1")
|
||||
ei_add_failtest("transpose_on_const_type_actually_const")
|
||||
ei_add_failtest("diagonal_on_const_type_actually_const")
|
||||
|
||||
ei_add_failtest("ref_1")
|
||||
ei_add_failtest("ref_2")
|
||||
ei_add_failtest("ref_3")
|
||||
ei_add_failtest("ref_4")
|
||||
ei_add_failtest("ref_5")
|
||||
|
||||
if (EIGEN_FAILTEST_FAILURE_COUNT)
|
||||
message(FATAL_ERROR
|
||||
"${EIGEN_FAILTEST_FAILURE_COUNT} out of ${EIGEN_FAILTEST_COUNT} failtests FAILED. "
|
||||
|
18
failtest/ref_1.cpp
Normal file
18
failtest/ref_1.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "../Eigen/Core"
|
||||
|
||||
#ifdef EIGEN_SHOULD_FAIL_TO_BUILD
|
||||
#define CV_QUALIFIER const
|
||||
#else
|
||||
#define CV_QUALIFIER
|
||||
#endif
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
void call_ref(Ref<VectorXf> a) { }
|
||||
|
||||
int main()
|
||||
{
|
||||
VectorXf a(10);
|
||||
CV_QUALIFIER VectorXf& ac(a);
|
||||
call_ref(ac);
|
||||
}
|
15
failtest/ref_2.cpp
Normal file
15
failtest/ref_2.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "../Eigen/Core"
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
void call_ref(Ref<VectorXf> a) { }
|
||||
|
||||
int main()
|
||||
{
|
||||
MatrixXf A(10,10);
|
||||
#ifdef EIGEN_SHOULD_FAIL_TO_BUILD
|
||||
call_ref(A.row(3));
|
||||
#else
|
||||
call_ref(A.col(3));
|
||||
#endif
|
||||
}
|
15
failtest/ref_3.cpp
Normal file
15
failtest/ref_3.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "../Eigen/Core"
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
#ifdef EIGEN_SHOULD_FAIL_TO_BUILD
|
||||
void call_ref(Ref<VectorXf> a) { }
|
||||
#else
|
||||
void call_ref(const Ref<const VectorXf> &a) { }
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
VectorXf a(10);
|
||||
call_ref(a+a);
|
||||
}
|
15
failtest/ref_4.cpp
Normal file
15
failtest/ref_4.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "../Eigen/Core"
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
void call_ref(Ref<MatrixXf,0,OuterStride<> > a) {}
|
||||
|
||||
int main()
|
||||
{
|
||||
MatrixXf A(10,10);
|
||||
#ifdef EIGEN_SHOULD_FAIL_TO_BUILD
|
||||
call_ref(A.transpose());
|
||||
#else
|
||||
call_ref(A);
|
||||
#endif
|
||||
}
|
16
failtest/ref_5.cpp
Normal file
16
failtest/ref_5.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include "../Eigen/Core"
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
void call_ref(Ref<VectorXf> a) { }
|
||||
|
||||
int main()
|
||||
{
|
||||
VectorXf a(10);
|
||||
DenseBase<VectorXf> &ac(a);
|
||||
#ifdef EIGEN_SHOULD_FAIL_TO_BUILD
|
||||
call_ref(ac);
|
||||
#else
|
||||
call_ref(ac.derived());
|
||||
#endif
|
||||
}
|
@ -183,15 +183,15 @@ void call_ref()
|
||||
|
||||
VERIFY_EVALUATION_COUNT( call_ref_1(a,a), 0);
|
||||
VERIFY_EVALUATION_COUNT( call_ref_1(b,b.transpose()), 0);
|
||||
// call_ref_1(ac); // does not compile because ac is const
|
||||
// call_ref_1(ac,a<c); // does not compile because ac is const
|
||||
VERIFY_EVALUATION_COUNT( call_ref_1(ab,ab), 0);
|
||||
VERIFY_EVALUATION_COUNT( call_ref_1(a.head(4),a.head(4)), 0);
|
||||
VERIFY_EVALUATION_COUNT( call_ref_1(abc,abc), 0);
|
||||
VERIFY_EVALUATION_COUNT( call_ref_1(A.col(3),A.col(3)), 0);
|
||||
// call_ref_1(A.row(3)); // does not compile because innerstride!=1
|
||||
// call_ref_1(A.row(3),A.row(3)); // does not compile because innerstride!=1
|
||||
VERIFY_EVALUATION_COUNT( call_ref_3(A.row(3),A.row(3).transpose()), 0);
|
||||
VERIFY_EVALUATION_COUNT( call_ref_4(A.row(3),A.row(3).transpose()), 0);
|
||||
// call_ref_1(a+a); // does not compile for obvious reason
|
||||
// call_ref_1(a+a, a+a); // does not compile for obvious reason
|
||||
|
||||
MatrixXf tmp = A*A.col(1);
|
||||
VERIFY_EVALUATION_COUNT( call_ref_2(A*A.col(1), tmp), 1); // evaluated into a temp
|
||||
@ -212,7 +212,7 @@ void call_ref()
|
||||
VERIFY_EVALUATION_COUNT( call_ref_5(a,a), 0);
|
||||
VERIFY_EVALUATION_COUNT( call_ref_5(a.head(3),a.head(3)), 0);
|
||||
VERIFY_EVALUATION_COUNT( call_ref_5(A,A), 0);
|
||||
// call_ref_5(A.transpose()); // does not compile
|
||||
// call_ref_5(A.transpose(),A.transpose()); // does not compile because storage order does not match
|
||||
VERIFY_EVALUATION_COUNT( call_ref_5(A.block(1,1,2,2),A.block(1,1,2,2)), 0);
|
||||
VERIFY_EVALUATION_COUNT( call_ref_5(b,b), 0); // storage order do not match, but this is a degenerate case that should work
|
||||
VERIFY_EVALUATION_COUNT( call_ref_5(a.row(3),a.row(3)), 0);
|
||||
|
Loading…
Reference in New Issue
Block a user