aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2018-07-12 09:57:19 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2018-07-12 09:57:19 +0200
commit21cf4a1a8b0868b6dcb74aa4ebe6317d5316b2e1 (patch)
tree447fb61ad27dd4dec4707c031a8202a30d5f4778
parent8a5955a052f64fc32099b052a221e0b5a8e92cbd (diff)
Make is_convertible more robust and conformant to std::is_convertible
-rwxr-xr-xEigen/src/Core/util/Meta.h12
-rw-r--r--test/meta.cpp36
2 files changed, 36 insertions, 12 deletions
diff --git a/Eigen/src/Core/util/Meta.h b/Eigen/src/Core/util/Meta.h
index ef9860c4b..3d2bdd12e 100755
--- a/Eigen/src/Core/util/Meta.h
+++ b/Eigen/src/Core/util/Meta.h
@@ -145,16 +145,19 @@ private:
struct yes {int a[1];};
struct no {int a[2];};
- static yes test(const To&, int);
+ template<typename T>
+ static yes test(T, int);
+
+ template<typename T>
static no test(any_conversion, ...);
public:
- static From ms_from;
+ static From* ms_from;
#ifdef __INTEL_COMPILER
#pragma warning push
#pragma warning ( disable : 2259 )
#endif
- enum { value = sizeof(test(ms_from, 0))==sizeof(yes) };
+ enum { value = sizeof(test<To>(*ms_from, 0))==sizeof(yes) };
#ifdef __INTEL_COMPILER
#pragma warning pop
#endif
@@ -163,8 +166,7 @@ public:
template<typename From, typename To>
struct is_convertible
{
- enum { value = is_convertible_impl<typename remove_all<From>::type,
- typename remove_all<To >::type>::value };
+ enum { value = is_convertible_impl<From,To>::value };
};
/** \internal Allows to enable/disable an overload
diff --git a/test/meta.cpp b/test/meta.cpp
index bd505762e..4904f3ba4 100644
--- a/test/meta.cpp
+++ b/test/meta.cpp
@@ -19,6 +19,14 @@ struct FooReturnType {
typedef int ReturnType;
};
+struct MyInterface {
+ virtual void func() = 0;
+ virtual ~MyInterface() {}
+};
+struct MyImpl : public MyInterface {
+ void func() {}
+};
+
void test_meta()
{
VERIFY((internal::conditional<(3<4),internal::true_type, internal::false_type>::type::value));
@@ -62,14 +70,19 @@ void test_meta()
VERIFY(( internal::is_same<const float,internal::remove_pointer<const float*>::type >::value));
VERIFY(( internal::is_same<float,internal::remove_pointer<float* const >::type >::value));
- VERIFY(( internal::is_convertible<float,double>::value ));
- VERIFY(( internal::is_convertible<int,double>::value ));
- VERIFY(( internal::is_convertible<double,int>::value ));
- VERIFY((!internal::is_convertible<std::complex<double>,double>::value ));
- VERIFY(( internal::is_convertible<Array33f,Matrix3f>::value ));
+
+ // is_convertible
+ STATIC_CHECK(( internal::is_convertible<float,double>::value ));
+ STATIC_CHECK(( internal::is_convertible<int,double>::value ));
+ STATIC_CHECK(( internal::is_convertible<int, short>::value ));
+ STATIC_CHECK(( internal::is_convertible<short, int>::value ));
+ STATIC_CHECK(( internal::is_convertible<double,int>::value ));
+ STATIC_CHECK(( internal::is_convertible<double,std::complex<double> >::value ));
+ STATIC_CHECK((!internal::is_convertible<std::complex<double>,double>::value ));
+ STATIC_CHECK(( internal::is_convertible<Array33f,Matrix3f>::value ));
// VERIFY((!internal::is_convertible<Matrix3f,Matrix3d>::value )); //does not work because the conversion is prevented by a static assertion
- VERIFY((!internal::is_convertible<Array33f,int>::value ));
- VERIFY((!internal::is_convertible<MatrixXf,float>::value ));
+ STATIC_CHECK((!internal::is_convertible<Array33f,int>::value ));
+ STATIC_CHECK((!internal::is_convertible<MatrixXf,float>::value ));
{
float f;
MatrixXf A, B;
@@ -80,6 +93,15 @@ void test_meta()
VERIFY(( check_is_convertible(A*B, A) ));
}
+ STATIC_CHECK(( !internal::is_convertible<MyInterface, MyImpl>::value ));
+ STATIC_CHECK(( !internal::is_convertible<MyImpl, MyInterface>::value ));
+ STATIC_CHECK(( internal::is_convertible<MyImpl, const MyInterface&>::value ));
+ {
+ int i;
+ VERIFY(( check_is_convertible(fix<3>(), i) ));
+ VERIFY((!check_is_convertible(i, fix<DynamicIndex>()) ));
+ }
+
VERIFY(( internal::has_ReturnType<FooReturnType>::value ));
VERIFY(( internal::has_ReturnType<ScalarBinaryOpTraits<int,int> >::value ));
VERIFY(( !internal::has_ReturnType<MatrixXf>::value ));