Index: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -832,13 +832,15 @@ namespace __is_convertible_imp { -template char __test(_Tp); -template __two __test(...); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template _Tp&& __source(); -#else -template typename remove_reference<_Tp>::type& __source(); -#endif +// Test derived from definition of is_convertible predicate in [meta.rel]p4. +// declval() is used instead adding a new create() function because the +// definitions are identical. +template char __helper(_Tp); + +template +typename enable_if(declval<_Tf>())) == 1, char>::type + __test(int); +template __two __test(...); template ::value, bool _IsFunction = is_function<_Tp>::value, @@ -868,9 +870,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 +885,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, typename add_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, typename add_const<_T1>::type&&, 1, 0> : true_type {}; +template struct __is_convertible<_T1, typename add_volatile<_T1>::type&&, 1, 0> : true_type {}; +template struct __is_convertible<_T1, typename add_cv<_T1>::type&&, 1, 0> : true_type {}; #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template struct __is_convertible<_T1, _T2*, 1, 0> @@ -913,18 +915,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 {};