aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-08-05 20:26:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-10-23 18:26:44 +0000
commit2f2ebe758bea201830bd021525424813f7fc6c6b (patch)
tree8da7da203241e5935403d0b9c0612ef0fe970a06
parente8847079df1b7998ce84fd87c845d9eeef0567fb (diff)
libcxx-compat: revert llvmorg-19-init-17473-g69fecaa1a455:
[libc++] Clean up some now dead code with the upgrade to GCC 14 (#97746) PR: 280562 MFC after: 1 month
-rw-r--r--contrib/llvm-project/libcxx/include/__config58
-rw-r--r--contrib/llvm-project/libcxx/include/__tuple/tuple_element.h26
-rw-r--r--contrib/llvm-project/libcxx/include/__type_traits/is_function.h14
-rw-r--r--contrib/llvm-project/libcxx/include/__type_traits/is_member_function_pointer.h31
-rw-r--r--contrib/llvm-project/libcxx/include/__type_traits/is_member_object_pointer.h15
-rw-r--r--contrib/llvm-project/libcxx/include/__type_traits/is_member_pointer.h16
-rw-r--r--contrib/llvm-project/libcxx/include/__type_traits/is_nothrow_constructible.h61
-rw-r--r--contrib/llvm-project/libcxx/include/__type_traits/is_object.h25
-rw-r--r--contrib/llvm-project/libcxx/include/__type_traits/is_reference.h29
-rw-r--r--contrib/llvm-project/libcxx/include/__type_traits/is_scoped_enum.h22
10 files changed, 266 insertions, 31 deletions
diff --git a/contrib/llvm-project/libcxx/include/__config b/contrib/llvm-project/libcxx/include/__config
index 2010e45ba13c..f44f18d52099 100644
--- a/contrib/llvm-project/libcxx/include/__config
+++ b/contrib/llvm-project/libcxx/include/__config
@@ -162,6 +162,16 @@ _LIBCPP_HARDENING_MODE_DEBUG
# define _LIBCPP_CXX03_LANG
# endif
+// TODO: Remove once we switch to GCC 14
+# ifndef __has_extension
+# define __has_extension(__x) 0
+# endif
+
+// TODO: Remove once we switch to GCC 14
+# ifndef __has_feature
+# define __has_feature(__x) 0
+# endif
+
# ifndef __has_constexpr_builtin
# define __has_constexpr_builtin(x) 0
# endif
@@ -338,30 +348,44 @@ typedef __char32_t char32_t;
# define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
+# if defined(_LIBCPP_COMPILER_CLANG_BASED)
+
// Objective-C++ features (opt-in)
-# if __has_feature(objc_arc)
-# define _LIBCPP_HAS_OBJC_ARC
-# endif
+# if __has_feature(objc_arc)
+# define _LIBCPP_HAS_OBJC_ARC
+# endif
-# if __has_feature(objc_arc_weak)
-# define _LIBCPP_HAS_OBJC_ARC_WEAK
-# endif
+# if __has_feature(objc_arc_weak)
+# define _LIBCPP_HAS_OBJC_ARC_WEAK
+# endif
-# if __has_extension(blocks)
-# define _LIBCPP_HAS_EXTENSION_BLOCKS
-# endif
+# if __has_extension(blocks)
+# define _LIBCPP_HAS_EXTENSION_BLOCKS
+# endif
-# if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__)
-# define _LIBCPP_HAS_BLOCKS_RUNTIME
-# endif
+# if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__)
+# define _LIBCPP_HAS_BLOCKS_RUNTIME
+# endif
-# if !__has_feature(address_sanitizer)
-# define _LIBCPP_HAS_NO_ASAN
-# endif
+# if !__has_feature(address_sanitizer)
+# define _LIBCPP_HAS_NO_ASAN
+# endif
+
+# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__))
+
+# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
+
+# elif defined(_LIBCPP_COMPILER_GCC)
+
+# if !defined(__SANITIZE_ADDRESS__)
+# define _LIBCPP_HAS_NO_ASAN
+# endif
+
+# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__))
-# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__))
+# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
-# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
+# endif // _LIBCPP_COMPILER_[CLANG|GCC]
# if defined(_LIBCPP_OBJECT_FORMAT_COFF)
diff --git a/contrib/llvm-project/libcxx/include/__tuple/tuple_element.h b/contrib/llvm-project/libcxx/include/__tuple/tuple_element.h
index 9127c47dc8f1..55b3b47619f6 100644
--- a/contrib/llvm-project/libcxx/include/__tuple/tuple_element.h
+++ b/contrib/llvm-project/libcxx/include/__tuple/tuple_element.h
@@ -40,6 +40,32 @@ struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp> {
#ifndef _LIBCPP_CXX03_LANG
+# if !__has_builtin(__type_pack_element)
+
+namespace __indexer_detail {
+
+template <size_t _Idx, class _Tp>
+struct __indexed {
+ using type _LIBCPP_NODEBUG = _Tp;
+};
+
+template <class _Types, class _Indexes>
+struct __indexer;
+
+template <class... _Types, size_t... _Idx>
+struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>> : __indexed<_Idx, _Types>... {};
+
+template <size_t _Idx, class _Tp>
+__indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&);
+
+} // namespace __indexer_detail
+
+template <size_t _Idx, class... _Types>
+using __type_pack_element _LIBCPP_NODEBUG = typename decltype(__indexer_detail::__at_index<_Idx>(
+ __indexer_detail::__indexer< __tuple_types<_Types...>,
+ typename __make_tuple_indices<sizeof...(_Types)>::type >{}))::type;
+# endif
+
template <size_t _Ip, class... _Types>
struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...> > {
static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range");
diff --git a/contrib/llvm-project/libcxx/include/__type_traits/is_function.h b/contrib/llvm-project/libcxx/include/__type_traits/is_function.h
index 98fedd0ad96d..f09f19adf4aa 100644
--- a/contrib/llvm-project/libcxx/include/__type_traits/is_function.h
+++ b/contrib/llvm-project/libcxx/include/__type_traits/is_function.h
@@ -11,6 +11,8 @@
#include <__config>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_reference.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -18,12 +20,22 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+#if __has_builtin(__is_function)
+
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_function : integral_constant<bool, __is_function(_Tp)> {};
+#else
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_function
+ : public integral_constant<bool, !(is_reference<_Tp>::value || is_const<const _Tp>::value)> {};
+
+#endif // __has_builtin(__is_function)
+
#if _LIBCPP_STD_VER >= 17
template <class _Tp>
-inline constexpr bool is_function_v = __is_function(_Tp);
+inline constexpr bool is_function_v = is_function<_Tp>::value;
#endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/llvm-project/libcxx/include/__type_traits/is_member_function_pointer.h b/contrib/llvm-project/libcxx/include/__type_traits/is_member_function_pointer.h
index 037d5ca04ab0..11c8a00c9975 100644
--- a/contrib/llvm-project/libcxx/include/__type_traits/is_member_function_pointer.h
+++ b/contrib/llvm-project/libcxx/include/__type_traits/is_member_function_pointer.h
@@ -11,6 +11,9 @@
#include <__config>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_function.h>
+#include <__type_traits/remove_cv.h>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -19,6 +22,21 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
+struct __libcpp_is_member_pointer {
+ enum { __is_member = false, __is_func = false, __is_obj = false };
+};
+template <class _Tp, class _Up>
+struct __libcpp_is_member_pointer<_Tp _Up::*> {
+ enum {
+ __is_member = true,
+ __is_func = is_function<_Tp>::value,
+ __is_obj = !__is_func,
+ };
+};
+
+#if __has_builtin(__is_member_function_pointer)
+
+template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer : _BoolConstant<__is_member_function_pointer(_Tp)> {};
# if _LIBCPP_STD_VER >= 17
@@ -26,6 +44,19 @@ template <class _Tp>
inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp);
# endif
+#else // __has_builtin(__is_member_function_pointer)
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
+ : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_func> {};
+
+# if _LIBCPP_STD_VER >= 17
+template <class _Tp>
+inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value;
+# endif
+
+#endif // __has_builtin(__is_member_function_pointer)
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___TYPE_TRAITS_IS_MEMBER_FUNCTION_POINTER_H
diff --git a/contrib/llvm-project/libcxx/include/__type_traits/is_member_object_pointer.h b/contrib/llvm-project/libcxx/include/__type_traits/is_member_object_pointer.h
index 555794bfe038..9141f9da530f 100644
--- a/contrib/llvm-project/libcxx/include/__type_traits/is_member_object_pointer.h
+++ b/contrib/llvm-project/libcxx/include/__type_traits/is_member_object_pointer.h
@@ -18,6 +18,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+#if __has_builtin(__is_member_object_pointer)
+
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer : _BoolConstant<__is_member_object_pointer(_Tp)> {};
@@ -26,6 +28,19 @@ template <class _Tp>
inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp);
# endif
+#else // __has_builtin(__is_member_object_pointer)
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
+ : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_obj> {};
+
+# if _LIBCPP_STD_VER >= 17
+template <class _Tp>
+inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value;
+# endif
+
+#endif // __has_builtin(__is_member_object_pointer)
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___TYPE_TRAITS_IS_MEMBER_FUNCTION_POINTER_H
diff --git a/contrib/llvm-project/libcxx/include/__type_traits/is_member_pointer.h b/contrib/llvm-project/libcxx/include/__type_traits/is_member_pointer.h
index 149634fde758..4ca01d1c2fc8 100644
--- a/contrib/llvm-project/libcxx/include/__type_traits/is_member_pointer.h
+++ b/contrib/llvm-project/libcxx/include/__type_traits/is_member_pointer.h
@@ -11,6 +11,7 @@
#include <__config>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_member_function_pointer.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -18,6 +19,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+#if __has_builtin(__is_member_pointer)
+
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> {};
@@ -26,6 +29,19 @@ template <class _Tp>
inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
# endif
+#else // __has_builtin(__is_member_pointer)
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_member_pointer
+ : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_member> {};
+
+# if _LIBCPP_STD_VER >= 17
+template <class _Tp>
+inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+# endif
+
+#endif // __has_builtin(__is_member_pointer)
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___TYPE_TRAITS_IS_MEMBER_POINTER_H
diff --git a/contrib/llvm-project/libcxx/include/__type_traits/is_nothrow_constructible.h b/contrib/llvm-project/libcxx/include/__type_traits/is_nothrow_constructible.h
index 58d2b2475140..2f7ed8487e76 100644
--- a/contrib/llvm-project/libcxx/include/__type_traits/is_nothrow_constructible.h
+++ b/contrib/llvm-project/libcxx/include/__type_traits/is_nothrow_constructible.h
@@ -13,6 +13,10 @@
#include <__type_traits/add_lvalue_reference.h>
#include <__type_traits/add_rvalue_reference.h>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_constructible.h>
+#include <__type_traits/is_reference.h>
+#include <__utility/declval.h>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -20,28 +24,85 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+// GCC is disabled due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611
+#if __has_builtin(__is_nothrow_constructible) && !defined(_LIBCPP_COMPILER_GCC)
+
template < class _Tp, class... _Args>
struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
: public integral_constant<bool, __is_nothrow_constructible(_Tp, _Args...)> {};
+#else
+
+template <bool, bool, class _Tp, class... _Args>
+struct __libcpp_is_nothrow_constructible;
+
+template <class _Tp, class... _Args>
+struct __libcpp_is_nothrow_constructible</*is constructible*/ true, /*is reference*/ false, _Tp, _Args...>
+ : public integral_constant<bool, noexcept(_Tp(std::declval<_Args>()...))> {};
+
+template <class _Tp>
+void __implicit_conversion_to(_Tp) noexcept {}
+
+template <class _Tp, class _Arg>
+struct __libcpp_is_nothrow_constructible</*is constructible*/ true, /*is reference*/ true, _Tp, _Arg>
+ : public integral_constant<bool, noexcept(std::__implicit_conversion_to<_Tp>(std::declval<_Arg>()))> {};
+
+template <class _Tp, bool _IsReference, class... _Args>
+struct __libcpp_is_nothrow_constructible</*is constructible*/ false, _IsReference, _Tp, _Args...> : public false_type {
+};
+
+template <class _Tp, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible
+ : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value,
+ is_reference<_Tp>::value,
+ _Tp,
+ _Args...> {};
+
+template <class _Tp, size_t _Ns>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]>
+ : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp> {};
+
+#endif // __has_builtin(__is_nothrow_constructible)
#if _LIBCPP_STD_VER >= 17
template <class _Tp, class... _Args>
inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, _Args...>::value;
#endif
+// TODO: remove this implementation once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 is fixed
+#ifdef _LIBCPP_COMPILER_GCC
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
+ : public is_nothrow_constructible<_Tp, __add_lvalue_reference_t<const _Tp> > {};
+
+#else // _LIBCPP_COMPILER_GCC
+
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible
: public integral_constant< bool, __is_nothrow_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> {};
+#endif // _LIBCPP_COMPILER_GCC
+
#if _LIBCPP_STD_VER >= 17
template <class _Tp>
inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<_Tp>::value;
#endif
+// TODO: remove this implementation once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 is fixed
+#ifndef _LIBCPP_COMPILER_GCC
+
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
: public integral_constant<bool, __is_nothrow_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
+#else // _LIBCPP_COMPILER_GCC
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible
+ : public is_nothrow_constructible<_Tp, __add_rvalue_reference_t<_Tp> > {};
+
+#endif // _LIBCPP_COMPILER_GCC
+
#if _LIBCPP_STD_VER >= 17
template <class _Tp>
inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<_Tp>::value;
diff --git a/contrib/llvm-project/libcxx/include/__type_traits/is_object.h b/contrib/llvm-project/libcxx/include/__type_traits/is_object.h
index ec04508402ce..5ac1d854a695 100644
--- a/contrib/llvm-project/libcxx/include/__type_traits/is_object.h
+++ b/contrib/llvm-project/libcxx/include/__type_traits/is_object.h
@@ -11,6 +11,10 @@
#include <__config>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_scalar.h>
+#include <__type_traits/is_union.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -18,13 +22,30 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+#if __has_builtin(__is_object)
+
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> {};
-#if _LIBCPP_STD_VER >= 17
+# if _LIBCPP_STD_VER >= 17
template <class _Tp>
inline constexpr bool is_object_v = __is_object(_Tp);
-#endif
+# endif
+
+#else // __has_builtin(__is_object)
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_object
+ : public integral_constant<bool,
+ is_scalar<_Tp>::value || is_array<_Tp>::value || is_union<_Tp>::value ||
+ is_class<_Tp>::value > {};
+
+# if _LIBCPP_STD_VER >= 17
+template <class _Tp>
+inline constexpr bool is_object_v = is_object<_Tp>::value;
+# endif
+
+#endif // __has_builtin(__is_object)
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/llvm-project/libcxx/include/__type_traits/is_reference.h b/contrib/llvm-project/libcxx/include/__type_traits/is_reference.h
index cc157a438e49..42853d479039 100644
--- a/contrib/llvm-project/libcxx/include/__type_traits/is_reference.h
+++ b/contrib/llvm-project/libcxx/include/__type_traits/is_reference.h
@@ -18,15 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> {};
-
-#if _LIBCPP_STD_VER >= 17
-template <class _Tp>
-inline constexpr bool is_reference_v = __is_reference(_Tp);
-#endif
-
-#if __has_builtin(__is_lvalue_reference) && __has_builtin(__is_rvalue_reference)
+#if __has_builtin(__is_lvalue_reference) && __has_builtin(__is_rvalue_reference) && __has_builtin(__is_reference)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> {};
@@ -34,14 +26,19 @@ struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_refe
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> {};
+
# if _LIBCPP_STD_VER >= 17
template <class _Tp>
+inline constexpr bool is_reference_v = __is_reference(_Tp);
+template <class _Tp>
inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(_Tp);
template <class _Tp>
inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp);
# endif
-#else // __has_builtin(__is_lvalue_reference)
+#else // __has_builtin(__is_lvalue_reference) && etc...
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {};
@@ -53,15 +50,25 @@ struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {};
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_reference : public false_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {};
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {};
+
# if _LIBCPP_STD_VER >= 17
template <class _Tp>
+inline constexpr bool is_reference_v = is_reference<_Tp>::value;
+
+template <class _Tp>
inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value;
template <class _Tp>
inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value;
# endif
-#endif // __has_builtin(__is_lvalue_reference)
+#endif // __has_builtin(__is_lvalue_reference) && etc...
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/llvm-project/libcxx/include/__type_traits/is_scoped_enum.h b/contrib/llvm-project/libcxx/include/__type_traits/is_scoped_enum.h
index cb3e25cf5733..1db88e13356e 100644
--- a/contrib/llvm-project/libcxx/include/__type_traits/is_scoped_enum.h
+++ b/contrib/llvm-project/libcxx/include/__type_traits/is_scoped_enum.h
@@ -11,6 +11,9 @@
#include <__config>
#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_enum.h>
+#include <__type_traits/underlying_type.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -20,12 +23,31 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 23
+// TODO: GCC and Clang both have this builtin. Remove the false case once we've updated to GCC 14.
+# if __has_builtin(__is_scoped_enum)
+
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_scoped_enum : bool_constant<__is_scoped_enum(_Tp)> {};
template <class _Tp>
inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp);
+# else
+
+template <class _Tp, bool = is_enum_v<_Tp> >
+struct __is_scoped_enum_helper : false_type {};
+
+template <class _Tp>
+struct __is_scoped_enum_helper<_Tp, true> : public bool_constant<!is_convertible_v<_Tp, underlying_type_t<_Tp> > > {};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_scoped_enum : public __is_scoped_enum_helper<_Tp> {};
+
+template <class _Tp>
+inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
+
+# endif // __has_builtin(__is_scoped_enum)
+
#endif // _LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD