bug #826: fix is_convertible for MSVC and add minimalistic unit test for is_convertible

This commit is contained in:
Gael Guennebaud 2014-07-16 13:17:06 +02:00
parent 0a945687b7
commit 338d2ec42b
2 changed files with 40 additions and 7 deletions

View File

@ -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.

View File

@ -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);