diff --git a/libcxx/include/__type_traits/is_convertible.h b/libcxx/include/__type_traits/is_convertible.h --- a/libcxx/include/__type_traits/is_convertible.h +++ b/libcxx/include/__type_traits/is_convertible.h @@ -24,89 +24,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__is_convertible) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) - template struct _LIBCPP_TEMPLATE_VIS is_convertible : public integral_constant {}; -#elif __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) - -template -struct _LIBCPP_TEMPLATE_VIS is_convertible : public integral_constant {}; - -// TODO: Remove this fallback when GCC < 13 support is no longer required. -// GCC 13 has the __is_convertible built-in. -#else // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) - -namespace __is_convertible_imp { -template -void __test_convert(_Tp); - -template -struct __is_convertible_test : public false_type {}; - -template -struct __is_convertible_test<_From, _To, decltype(__is_convertible_imp::__test_convert<_To>(std::declval<_From>()))> - : public true_type {}; - -// clang-format off -template ::value, - bool _IsFunction = is_function<_Tp>::value, - bool _IsVoid = is_void<_Tp>::value> - struct __is_array_function_or_void { enum { value = 0 }; }; -template struct __is_array_function_or_void<_Tp, true, false, false> { enum { value = 1 }; }; -template struct __is_array_function_or_void<_Tp, false, true, false> { enum { value = 2 }; }; -template struct __is_array_function_or_void<_Tp, false, false, true> { enum { value = 3 }; }; -// clang-format on -} // namespace __is_convertible_imp - -template >::value> -struct __is_convertible_check { - static const size_t __v = 0; -}; - -template -struct __is_convertible_check<_Tp, 0> { - static const size_t __v = sizeof(_Tp); -}; - -template ::value, - unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value> -struct __is_convertible - : public integral_constant::value >{}; - -// clang-format off -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{}; - -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{}; - -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{}; -template struct __is_convertible<_T1, _T2, 3, 3> : public true_type{}; -// clang-format on - -template -struct _LIBCPP_TEMPLATE_VIS is_convertible : public __is_convertible<_T1, _T2> { - static const size_t __complete_check1 = __is_convertible_check<_T1>::__v; - static const size_t __complete_check2 = __is_convertible_check<_T2>::__v; -}; - -#endif // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) - #if _LIBCPP_STD_VER >= 17 template -inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value; +inline constexpr bool is_convertible_v = __is_convertible(_From, _To); #endif _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp b/libcxx/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp deleted file mode 100644 --- a/libcxx/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03 - -// ADDITIONAL_COMPILE_FLAGS: -D _LIBCPP_USE_IS_CONVERTIBLE_FALLBACK - -// UNSUPPORTED: gcc-13 - -// type_traits - -// is_convertible - -// Test the fallback implementation. - -// libc++ provides a fallback implementation of the compiler trait -// `__is_convertible` with the same name when clang doesn't. -// Because this test forces the use of the fallback even when clang provides -// it causing a keyword incompatibility. - -#include "test_macros.h" -TEST_CLANG_DIAGNOSTIC_IGNORED("-Wkeyword-compat") - -#include "is_convertible.pass.cpp"