From 338d2ec42b99a17f4fa1759f27bf8735b4aea974 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 16 Jul 2014 13:17:06 +0200 Subject: [PATCH] bug #826: fix is_convertible for MSVC and add minimalistic unit test for is_convertible --- Eigen/src/Core/util/Meta.h | 23 ++++++++++++++++------- test/meta.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/Eigen/src/Core/util/Meta.h b/Eigen/src/Core/util/Meta.h index 795197f59..b99b8849e 100644 --- a/Eigen/src/Core/util/Meta.h +++ b/Eigen/src/Core/util/Meta.h @@ -82,22 +82,31 @@ template struct add_const_on_value_type { typedef T template -struct is_convertible +struct is_convertible_impl { private: + struct any_conversion + { + template any_conversion(const volatile T&); + template any_conversion(T&); + }; struct yes {int a[1];}; struct no {int a[2];}; - - template - static yes test (const T&) {} - - template static no test (...) {} + + static yes test(const To&, int); + static no test(any_conversion, ...); public: static From ms_from; - enum { value = sizeof(test(ms_from))==sizeof(yes) }; + enum { value = sizeof(test(ms_from, 0))==sizeof(yes) }; }; +template +struct is_convertible +{ + enum { value = is_convertible_impl::type, + typename remove_all::type>::value }; +}; /** \internal Allows to enable/disable an overload * according to a compile time condition. diff --git a/test/meta.cpp b/test/meta.cpp index 3302c5887..b8dea68e8 100644 --- a/test/meta.cpp +++ b/test/meta.cpp @@ -9,6 +9,12 @@ #include "main.h" +template +bool check_is_convertible(const From&, const To&) +{ + return internal::is_convertible::value; +} + void test_meta() { VERIFY((internal::conditional<(3<4),internal::true_type, internal::false_type>::type::value)); @@ -52,6 +58,24 @@ void test_meta() VERIFY(( internal::is_same::type >::value)); VERIFY(( internal::is_same::type >::value)); + VERIFY(( internal::is_convertible::value )); + VERIFY(( internal::is_convertible::value )); + VERIFY(( internal::is_convertible::value )); + VERIFY((!internal::is_convertible,double>::value )); + VERIFY(( internal::is_convertible::value )); +// VERIFY((!internal::is_convertible::value )); //does not work because the conversion is prevented by a static assertion + VERIFY((!internal::is_convertible::value )); + VERIFY((!internal::is_convertible::value )); + { + float f; + MatrixXf A, B; + VectorXf a, b; + VERIFY(( check_is_convertible(a.dot(b), f) )); + VERIFY(( check_is_convertible(a.transpose()*b, f) )); + VERIFY((!check_is_convertible(A*B, f) )); + VERIFY(( check_is_convertible(A*B, A) )); + } + VERIFY(internal::meta_sqrt<1>::ret == 1); #define VERIFY_META_SQRT(X) VERIFY(internal::meta_sqrt::ret == int(std::sqrt(double(X)))) VERIFY_META_SQRT(2);