[PATCH] [libcxx] Correct SFINAE version of is_convertible to match spec and avoid triggering unnecessary compiler diagnostics
Eric Fiselier
eric at efcs.ca
Thu Aug 21 03:59:17 PDT 2014
The actual change looks great, and I think its almost ready to land. I would like to see more complete test coverage in `meta.rel/is_convertible.pass.cpp` . I understand its demonstrated by the other tests passing but I would like a localized test case for the changes.
================
Comment at: include/type_traits:834-844
@@ -833,11 +833,13 @@
namespace __is_convertible_imp
{
-template <class _Tp> char __test(_Tp);
-template <class _Tp> __two __test(...);
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-template <class _Tp> _Tp&& __source();
-#else
-template <class _Tp> 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 <class _Tp> char __helper(_Tp);
+
+template <class _Tp, class _Tf>
+typename enable_if<sizeof(__helper<_Tp>(declval<_Tf>())) == 1, char>::type
+ __test(int);
+template <class _Tp, class _Tf> __two __test(...);
template <class _Tp, bool _IsArray = is_array<_Tp>::value,
----------------
Can you add a test to `meta.rel/is_convertible.pass.cpp` to test this change?
================
Comment at: include/type_traits:887-894
@@ -884,10 +886,10 @@
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 0> : false_type {};
-template <class _T1> struct __is_convertible<_T1, const _T1&, 1, 0> : true_type {};
+template <class _T1> struct __is_convertible<_T1, typename add_const<_T1>::type&, 1, 0> : true_type {};
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _T1> struct __is_convertible<_T1, _T1&&, 1, 0> : true_type {};
-template <class _T1> struct __is_convertible<_T1, const _T1&&, 1, 0> : true_type {};
-template <class _T1> struct __is_convertible<_T1, volatile _T1&&, 1, 0> : true_type {};
-template <class _T1> struct __is_convertible<_T1, const volatile _T1&&, 1, 0> : true_type {};
+template <class _T1> struct __is_convertible<_T1, typename add_const<_T1>::type&&, 1, 0> : true_type {};
+template <class _T1> struct __is_convertible<_T1, typename add_volatile<_T1>::type&&, 1, 0> : true_type {};
+template <class _T1> struct __is_convertible<_T1, typename add_cv<_T1>::type&&, 1, 0> : true_type {};
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
----------------
I can get `meta.rel/is_convertible.pass.cpp` passing w/ GCC-TOT if I only apply this part of the change.
http://reviews.llvm.org/D4341
More information about the cfe-commits
mailing list