Index: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -832,14 +832,20 @@ namespace __is_convertible_imp { -template char __test(_Tp); -template __two __test(...); +// Test taken directly from definition of is_convertible predicate in [meta.rel]p4. #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template _Tp&& __source(); +template typename add_rvalue_reference<_Tp>::type __create(); #else -template typename remove_reference<_Tp>::type& __source(); +template typename remove_reference<_Tp>::type& __create(); #endif +template char helper(_Tp); + +template +typename enable_if(__create<_Tf>())) == 1, char>::type + __test(int); +template __two __test(...); + template ::value, bool _IsFunction = is_function<_Tp>::value, bool _IsVoid = is_void<_Tp>::value> @@ -868,9 +874,9 @@ struct __is_convertible : public integral_constant(__is_convertible_imp::__source<_T1>())) == 1 + sizeof(__is_convertible_imp::__test<_T2, _T1>(1)) == 1 #else - sizeof(__is_convertible_imp::__test<_T2>(__is_convertible_imp::__source<_T1>())) == 1 + sizeof(__is_convertible_imp::__test<_T2, _T1>(1)) == 1 && !(!is_function<_T1>::value && !is_reference<_T1>::value && is_reference<_T2>::value && (!is_const::type>::value || is_volatile::type>::value) @@ -883,12 +889,12 @@ template struct __is_convertible<_T1, _T2, 1, 0> : false_type {}; -template struct __is_convertible<_T1, const _T1&, 1, 0> : true_type {}; +template struct __is_convertible<_T1, const typename remove_const<_T1>::type&, 1, 0> : true_type {}; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template struct __is_convertible<_T1, _T1&&, 1, 0> : true_type {}; -template struct __is_convertible<_T1, const _T1&&, 1, 0> : true_type {}; -template struct __is_convertible<_T1, volatile _T1&&, 1, 0> : true_type {}; -template struct __is_convertible<_T1, const volatile _T1&&, 1, 0> : true_type {}; +template struct __is_convertible<_T1, const typename remove_const<_T1>::type&&, 1, 0> : true_type {}; +template struct __is_convertible<_T1, volatile typename remove_volatile<_T1>::type&&, 1, 0> : true_type {}; +template struct __is_convertible<_T1, const volatile typename remove_cv<_T1>::type&&, 1, 0> : true_type {}; #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template struct __is_convertible<_T1, _T2*, 1, 0> @@ -913,18 +919,22 @@ template struct __is_convertible<_T1, _T1*volatile, 2, 0> : public true_type {}; template struct __is_convertible<_T1, _T1*const volatile, 2, 0> : public true_type {}; +// Per N2255 on is_convertible, void -> !void is not convertible. template struct __is_convertible<_T1, _T2, 3, 0> : public false_type {}; +// Per N2255 on is_convertible, * -> array is not converitble. template struct __is_convertible<_T1, _T2, 0, 1> : public false_type {}; template struct __is_convertible<_T1, _T2, 1, 1> : public false_type {}; template struct __is_convertible<_T1, _T2, 2, 1> : public false_type {}; template struct __is_convertible<_T1, _T2, 3, 1> : public false_type {}; +// Per N2255 on is_convertible, * -> function is not converitble. template struct __is_convertible<_T1, _T2, 0, 2> : public false_type {}; template struct __is_convertible<_T1, _T2, 1, 2> : public false_type {}; template struct __is_convertible<_T1, _T2, 2, 2> : public false_type {}; template struct __is_convertible<_T1, _T2, 3, 2> : public false_type {}; +// Per N2255 on is_convertible, only void -> void is convertible. template struct __is_convertible<_T1, _T2, 0, 3> : public false_type {}; template struct __is_convertible<_T1, _T2, 1, 3> : public false_type {}; template struct __is_convertible<_T1, _T2, 2, 3> : public false_type {};