diff options
-rw-r--r-- | Eigen/src/Core/util/Meta.h | 23 | ||||
-rw-r--r-- | 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<typename T> struct add_const_on_value_type<T const* const> { typedef T template<typename From, typename To> -struct is_convertible +struct is_convertible_impl { private: + struct any_conversion + { + template <typename T> any_conversion(const volatile T&); + template <typename T> any_conversion(T&); + }; struct yes {int a[1];}; struct no {int a[2];}; - - template<typename T> - static yes test (const T&) {} - - template<typename> static no test (...) {} + + static yes test(const To&, int); + static no test(any_conversion, ...); public: static From ms_from; - enum { value = sizeof(test<To>(ms_from))==sizeof(yes) }; + enum { value = sizeof(test(ms_from, 0))==sizeof(yes) }; }; +template<typename From, typename To> +struct is_convertible +{ + enum { value = is_convertible_impl<typename remove_all<From>::type, + typename remove_all<To >::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<typename From, typename To> +bool check_is_convertible(const From&, const To&) +{ + return internal::is_convertible<From,To>::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<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 )); +// 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 )); + { + 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<X>::ret == int(std::sqrt(double(X)))) VERIFY_META_SQRT(2); |