[libcxx-commits] [libcxx] [libc++][RFC] Use type traits builtins directly in <type_traits> and <concepts> (PR #114840)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Mon Nov 4 09:57:49 PST 2024


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/114840

Using the builtins directly is quite a bit faster in my tests (at least 2x) and avoids some transitive includes. The main reason to not use them throughout the library is that GCC doesn't mangle the builtins, which means that they can't be used unconditionally.


>From bc134c005bd55bce97c854b2054b443ec191ed05 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 4 Nov 2024 18:55:52 +0100
Subject: [PATCH] [libc++][RFC] Use type traits builtins directly in
 <type_traits> and <concepts>

---
 libcxx/include/__concepts/class_or_enum.h      |  6 +-----
 libcxx/include/__concepts/constructible.h      |  3 +--
 libcxx/include/__concepts/convertible_to.h     |  2 +-
 libcxx/include/__concepts/derived_from.h       |  4 +---
 libcxx/include/__concepts/different_from.h     |  3 +--
 libcxx/include/__concepts/movable.h            |  3 +--
 libcxx/include/__concepts/same_as.h            |  3 +--
 libcxx/include/__concepts/swappable.h          |  3 +--
 libcxx/include/__type_traits/can_extract_key.h | 10 ++++------
 .../include/__type_traits/common_reference.h   | 18 +++++++-----------
 libcxx/include/__type_traits/common_type.h     |  6 ++----
 libcxx/include/__type_traits/datasizeof.h      |  2 --
 libcxx/include/__type_traits/decay.h           | 13 +++++--------
 .../__type_traits/is_always_bitcastable.h      | 12 ++++--------
 libcxx/include/__type_traits/is_destructible.h |  6 ++----
 .../__type_traits/is_equality_comparable.h     |  6 ++----
 .../__type_traits/is_execution_policy.h        |  6 ++----
 .../include/__type_traits/is_floating_point.h  |  3 +--
 libcxx/include/__type_traits/is_integral.h     |  3 +--
 libcxx/include/__type_traits/is_pointer.h      |  3 +--
 .../__type_traits/is_reference_wrapper.h       |  3 +--
 .../include/__type_traits/is_referenceable.h   |  4 +---
 libcxx/include/__type_traits/is_scalar.h       |  6 ++----
 .../__type_traits/is_trivially_assignable.h    |  1 -
 ...is_trivially_lexicographically_comparable.h |  4 +---
 .../__type_traits/is_trivially_relocatable.h   |  4 +---
 .../__type_traits/make_32_64_or_128_bit.h      |  3 +--
 libcxx/include/__type_traits/make_signed.h     |  6 ++----
 libcxx/include/__type_traits/make_unsigned.h   |  6 ++----
 libcxx/include/__type_traits/remove_cvref.h    |  2 --
 libcxx/include/__type_traits/underlying_type.h |  5 ++---
 libcxx/include/type_traits                     |  1 +
 32 files changed, 53 insertions(+), 107 deletions(-)

diff --git a/libcxx/include/__concepts/class_or_enum.h b/libcxx/include/__concepts/class_or_enum.h
index 2739e31e14ba65..053aff09bfcbdf 100644
--- a/libcxx/include/__concepts/class_or_enum.h
+++ b/libcxx/include/__concepts/class_or_enum.h
@@ -10,10 +10,6 @@
 #define _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H
 
 #include <__config>
-#include <__type_traits/is_class.h>
-#include <__type_traits/is_enum.h>
-#include <__type_traits/is_union.h>
-#include <__type_traits/remove_cvref.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -26,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // Whether a type is a class type or enumeration type according to the Core wording.
 
 template <class _Tp>
-concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>;
+concept __class_or_enum = __is_class(_Tp) || __is_union(_Tp) || __is_enum(_Tp);
 
 #endif // _LIBCPP_STD_VER >= 20
 
diff --git a/libcxx/include/__concepts/constructible.h b/libcxx/include/__concepts/constructible.h
index 835a44429c092f..395d5cb31592e5 100644
--- a/libcxx/include/__concepts/constructible.h
+++ b/libcxx/include/__concepts/constructible.h
@@ -12,7 +12,6 @@
 #include <__concepts/convertible_to.h>
 #include <__concepts/destructible.h>
 #include <__config>
-#include <__type_traits/is_constructible.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -24,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 // [concept.constructible]
 template <class _Tp, class... _Args>
-concept constructible_from = destructible<_Tp> && is_constructible_v<_Tp, _Args...>;
+concept constructible_from = destructible<_Tp> && __is_constructible(_Tp, _Args...);
 
 // [concept.default.init]
 
diff --git a/libcxx/include/__concepts/convertible_to.h b/libcxx/include/__concepts/convertible_to.h
index 6d5b6c1268d5d2..9646789d8a1eaa 100644
--- a/libcxx/include/__concepts/convertible_to.h
+++ b/libcxx/include/__concepts/convertible_to.h
@@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // [concept.convertible]
 
 template <class _From, class _To>
-concept convertible_to = is_convertible_v<_From, _To> && requires { static_cast<_To>(std::declval<_From>()); };
+concept convertible_to = __is_convertible(_From, _To) && requires { static_cast<_To>(std::declval<_From>()); };
 
 #endif // _LIBCPP_STD_VER >= 20
 
diff --git a/libcxx/include/__concepts/derived_from.h b/libcxx/include/__concepts/derived_from.h
index 9875faee81b901..d3775c5eb13915 100644
--- a/libcxx/include/__concepts/derived_from.h
+++ b/libcxx/include/__concepts/derived_from.h
@@ -10,8 +10,6 @@
 #define _LIBCPP___CONCEPTS_DERIVED_FROM_H
 
 #include <__config>
-#include <__type_traits/is_base_of.h>
-#include <__type_traits/is_convertible.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -24,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // [concept.derived]
 
 template <class _Dp, class _Bp>
-concept derived_from = is_base_of_v<_Bp, _Dp> && is_convertible_v<const volatile _Dp*, const volatile _Bp*>;
+concept derived_from = __is_base_of(_Bp, _Dp) && __is_convertible(const volatile _Dp*, const volatile _Bp*);
 
 #endif // _LIBCPP_STD_VER >= 20
 
diff --git a/libcxx/include/__concepts/different_from.h b/libcxx/include/__concepts/different_from.h
index fd31f6e25805d3..abf56f46e8e6bf 100644
--- a/libcxx/include/__concepts/different_from.h
+++ b/libcxx/include/__concepts/different_from.h
@@ -11,7 +11,6 @@
 
 #include <__concepts/same_as.h>
 #include <__config>
-#include <__type_traits/remove_cvref.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -22,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if _LIBCPP_STD_VER >= 20
 
 template <class _Tp, class _Up>
-concept __different_from = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
+concept __different_from = !same_as<__remove_cvref(_Tp), __remove_cvref(_Up)>;
 
 #endif // _LIBCPP_STD_VER >= 20
 
diff --git a/libcxx/include/__concepts/movable.h b/libcxx/include/__concepts/movable.h
index bc5b9d767c6a51..584e7196e90112 100644
--- a/libcxx/include/__concepts/movable.h
+++ b/libcxx/include/__concepts/movable.h
@@ -13,7 +13,6 @@
 #include <__concepts/constructible.h>
 #include <__concepts/swappable.h>
 #include <__config>
-#include <__type_traits/is_object.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -26,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // [concepts.object]
 
 template <class _Tp>
-concept movable = is_object_v<_Tp> && move_constructible<_Tp> && assignable_from<_Tp&, _Tp> && swappable<_Tp>;
+concept movable = __is_object(_Tp) && move_constructible<_Tp> && assignable_from<_Tp&, _Tp> && swappable<_Tp>;
 
 #endif // _LIBCPP_STD_VER >= 20
 
diff --git a/libcxx/include/__concepts/same_as.h b/libcxx/include/__concepts/same_as.h
index 4241131c70c1f4..e0d055cb1844ae 100644
--- a/libcxx/include/__concepts/same_as.h
+++ b/libcxx/include/__concepts/same_as.h
@@ -10,7 +10,6 @@
 #define _LIBCPP___CONCEPTS_SAME_AS_H
 
 #include <__config>
-#include <__type_traits/is_same.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -23,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // [concept.same]
 
 template <class _Tp, class _Up>
-concept __same_as_impl = _IsSame<_Tp, _Up>::value;
+concept __same_as_impl = __is_same(_Tp, _Up);
 
 template <class _Tp, class _Up>
 concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>;
diff --git a/libcxx/include/__concepts/swappable.h b/libcxx/include/__concepts/swappable.h
index 985c733021a0d7..a62fcd473a7e1c 100644
--- a/libcxx/include/__concepts/swappable.h
+++ b/libcxx/include/__concepts/swappable.h
@@ -18,7 +18,6 @@
 #include <__type_traits/extent.h>
 #include <__type_traits/is_nothrow_assignable.h>
 #include <__type_traits/is_nothrow_constructible.h>
-#include <__type_traits/remove_cvref.h>
 #include <__utility/exchange.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
@@ -46,7 +45,7 @@ void swap(_Tp&, _Tp&) = delete;
 // clang-format off
 template <class _Tp, class _Up>
 concept __unqualified_swappable_with =
-    (__class_or_enum<remove_cvref_t<_Tp>> || __class_or_enum<remove_cvref_t<_Up>>) &&
+    (__class_or_enum<__remove_cvref(_Tp)> || __class_or_enum<__remove_cvref(_Up)>) &&
     requires(_Tp&& __t, _Up&& __u) {
         swap(std::forward<_Tp>(__t), std::forward<_Up>(__u));
     };
diff --git a/libcxx/include/__type_traits/can_extract_key.h b/libcxx/include/__type_traits/can_extract_key.h
index b8359d07088104..0685a674311e2b 100644
--- a/libcxx/include/__type_traits/can_extract_key.h
+++ b/libcxx/include/__type_traits/can_extract_key.h
@@ -13,7 +13,6 @@
 #include <__fwd/pair.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/integral_constant.h>
-#include <__type_traits/is_same.h>
 #include <__type_traits/remove_const.h>
 #include <__type_traits/remove_const_ref.h>
 
@@ -29,19 +28,18 @@ struct __extract_key_self_tag {};
 struct __extract_key_first_tag {};
 
 template <class _ValTy, class _Key, class _RawValTy = __remove_const_ref_t<_ValTy> >
-struct __can_extract_key
-    : __conditional_t<_IsSame<_RawValTy, _Key>::value, __extract_key_self_tag, __extract_key_fail_tag> {};
+struct __can_extract_key : __conditional_t<__is_same(_RawValTy, _Key), __extract_key_self_tag, __extract_key_fail_tag> {
+};
 
 template <class _Pair, class _Key, class _First, class _Second>
 struct __can_extract_key<_Pair, _Key, pair<_First, _Second> >
-    : __conditional_t<_IsSame<__remove_const_t<_First>, _Key>::value, __extract_key_first_tag, __extract_key_fail_tag> {
-};
+    : __conditional_t<__is_same(__remove_const_t<_First>, _Key), __extract_key_first_tag, __extract_key_fail_tag> {};
 
 // __can_extract_map_key uses true_type/false_type instead of the tags.
 // It returns true if _Key != _ContainerValueTy (the container is a map not a set)
 // and _ValTy == _Key.
 template <class _ValTy, class _Key, class _ContainerValueTy, class _RawValTy = __remove_const_ref_t<_ValTy> >
-struct __can_extract_map_key : integral_constant<bool, _IsSame<_RawValTy, _Key>::value> {};
+struct __can_extract_map_key : integral_constant<bool, __is_same(_RawValTy, _Key)> {};
 
 // This specialization returns __extract_key_fail_tag for non-map containers
 // because _Key == _ContainerValueTy
diff --git a/libcxx/include/__type_traits/common_reference.h b/libcxx/include/__type_traits/common_reference.h
index c802902eb19fc3..bb09070d363105 100644
--- a/libcxx/include/__type_traits/common_reference.h
+++ b/libcxx/include/__type_traits/common_reference.h
@@ -13,10 +13,6 @@
 #include <__type_traits/common_type.h>
 #include <__type_traits/copy_cv.h>
 #include <__type_traits/copy_cvref.h>
-#include <__type_traits/is_convertible.h>
-#include <__type_traits/is_reference.h>
-#include <__type_traits/remove_cv.h>
-#include <__type_traits/remove_cvref.h>
 #include <__type_traits/remove_reference.h>
 #include <__utility/declval.h>
 
@@ -59,7 +55,7 @@ using __cv_cond_res = __cond_res<__copy_cv_t<_Xp, _Yp>&, __copy_cv_t<_Yp, _Xp>&>
 template <class _Ap, class _Bp, class _Xp, class _Yp>
   requires
     requires { typename __cv_cond_res<_Xp, _Yp>; } &&
-    is_reference_v<__cv_cond_res<_Xp, _Yp>>
+    __is_reference(__cv_cond_res<_Xp, _Yp>)
 struct __common_ref<_Ap&, _Bp&, _Xp, _Yp> {
   using __type = __cv_cond_res<_Xp, _Yp>;
 };
@@ -75,8 +71,8 @@ using __common_ref_C = remove_reference_t<__common_ref_t<_Xp&, _Yp&>>&&;
 template <class _Ap, class _Bp, class _Xp, class _Yp>
   requires
     requires { typename __common_ref_C<_Xp, _Yp>; } &&
-    is_convertible_v<_Ap&&, __common_ref_C<_Xp, _Yp>> &&
-    is_convertible_v<_Bp&&, __common_ref_C<_Xp, _Yp>>
+    __is_convertible(_Ap&&, __common_ref_C<_Xp, _Yp>) &&
+    __is_convertible(_Bp&&, __common_ref_C<_Xp, _Yp>)
 struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp> {
   using __type = __common_ref_C<_Xp, _Yp>;
 };
@@ -92,7 +88,7 @@ using __common_ref_D = __common_ref_t<const _Tp&, _Up&>;
 template <class _Ap, class _Bp, class _Xp, class _Yp>
   requires
     requires { typename __common_ref_D<_Xp, _Yp>; } &&
-    is_convertible_v<_Ap&&, __common_ref_D<_Xp, _Yp>>
+    __is_convertible(_Ap&&, __common_ref_D<_Xp, _Yp>)
 struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp> {
   using __type = __common_ref_D<_Xp, _Yp>;
 };
@@ -139,7 +135,7 @@ template <class _Tp, class _Up>
 struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {};
 
 template <class _Tp, class _Up>
-  requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; }
+  requires(__is_reference(_Tp) && __is_reference(_Up) && requires { typename __common_ref_t<_Tp, _Up>; })
 struct __common_reference_sub_bullet1<_Tp, _Up> {
   using type = __common_ref_t<_Tp, _Up>;
 };
@@ -151,8 +147,8 @@ struct basic_common_reference {};
 
 template <class _Tp, class _Up>
 using __basic_common_reference_t =
-    typename basic_common_reference<remove_cvref_t<_Tp>,
-                                    remove_cvref_t<_Up>,
+    typename basic_common_reference<__remove_cvref(_Tp),
+                                    __remove_cvref(_Up),
                                     __xref<_Tp>::template __apply,
                                     __xref<_Up>::template __apply>::type;
 
diff --git a/libcxx/include/__type_traits/common_type.h b/libcxx/include/__type_traits/common_type.h
index ef542f8bccfe02..1962331573fe18 100644
--- a/libcxx/include/__type_traits/common_type.h
+++ b/libcxx/include/__type_traits/common_type.h
@@ -12,8 +12,6 @@
 #include <__config>
 #include <__type_traits/conditional.h>
 #include <__type_traits/decay.h>
-#include <__type_traits/is_same.h>
-#include <__type_traits/remove_cvref.h>
 #include <__type_traits/type_identity.h>
 #include <__type_traits/void_t.h>
 #include <__utility/declval.h>
@@ -48,7 +46,7 @@ struct __common_type3 {};
 // sub-bullet 4 - "if COND_RES(CREF(D1), CREF(D2)) denotes a type..."
 template <class _Tp, class _Up>
 struct __common_type3<_Tp, _Up, void_t<__cond_type<const _Tp&, const _Up&>>> {
-  using type = remove_cvref_t<__cond_type<const _Tp&, const _Up&>>;
+  using type = __remove_cvref(__cond_type<const _Tp&, const _Up&>);
 };
 
 template <class _Tp, class _Up, class = void>
@@ -96,7 +94,7 @@ struct _LIBCPP_TEMPLATE_VIS common_type<_Tp> : public common_type<_Tp, _Tp> {};
 // sub-bullet 1 - "If is_same_v<T1, D1> is false or ..."
 template <class _Tp, class _Up>
 struct _LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up>
-    : __conditional_t<_IsSame<_Tp, __decay_t<_Tp> >::value && _IsSame<_Up, __decay_t<_Up> >::value,
+    : __conditional_t<__is_same(_Tp, __decay_t<_Tp>) && __is_same(_Up, __decay_t<_Up>),
                       __common_type2_imp<_Tp, _Up>,
                       common_type<__decay_t<_Tp>, __decay_t<_Up> > > {};
 
diff --git a/libcxx/include/__type_traits/datasizeof.h b/libcxx/include/__type_traits/datasizeof.h
index 0c1ed94f840294..54735cd52fdb59 100644
--- a/libcxx/include/__type_traits/datasizeof.h
+++ b/libcxx/include/__type_traits/datasizeof.h
@@ -11,8 +11,6 @@
 
 #include <__config>
 #include <__cstddef/size_t.h>
-#include <__type_traits/is_class.h>
-#include <__type_traits/is_final.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__type_traits/decay.h b/libcxx/include/__type_traits/decay.h
index 7412044f931796..dff6ecfc1d9ddf 100644
--- a/libcxx/include/__type_traits/decay.h
+++ b/libcxx/include/__type_traits/decay.h
@@ -12,12 +12,8 @@
 #include <__config>
 #include <__type_traits/add_pointer.h>
 #include <__type_traits/conditional.h>
-#include <__type_traits/is_array.h>
-#include <__type_traits/is_function.h>
 #include <__type_traits/is_referenceable.h>
-#include <__type_traits/remove_cv.h>
 #include <__type_traits/remove_extent.h>
-#include <__type_traits/remove_reference.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -35,25 +31,26 @@ struct decay {
 };
 
 #else
+// This implementation is only used with GCC, so we can use __remove_reference and __is_array directly
 template <class _Up, bool>
 struct __decay {
-  typedef _LIBCPP_NODEBUG __remove_cv_t<_Up> type;
+  typedef _LIBCPP_NODEBUG __remove_cv(_Up) type;
 };
 
 template <class _Up>
 struct __decay<_Up, true> {
 public:
   typedef _LIBCPP_NODEBUG
-      __conditional_t<is_array<_Up>::value,
+      __conditional_t<__is_array(_Up),
                       __add_pointer_t<__remove_extent_t<_Up> >,
-                      __conditional_t<is_function<_Up>::value, typename add_pointer<_Up>::type, __remove_cv_t<_Up> > >
+                      __conditional_t<__is_function(_Up), typename add_pointer<_Up>::type, __remove_cv(_Up)> >
           type;
 };
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS decay {
 private:
-  typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp> _Up;
+  typedef _LIBCPP_NODEBUG __remove_reference(_Tp) _Up;
 
 public:
   typedef _LIBCPP_NODEBUG typename __decay<_Up, __libcpp_is_referenceable<_Up>::value>::type type;
diff --git a/libcxx/include/__type_traits/is_always_bitcastable.h b/libcxx/include/__type_traits/is_always_bitcastable.h
index 5bc650b41358a8..76c4e8b99af350 100644
--- a/libcxx/include/__type_traits/is_always_bitcastable.h
+++ b/libcxx/include/__type_traits/is_always_bitcastable.h
@@ -12,10 +12,6 @@
 #include <__config>
 #include <__type_traits/integral_constant.h>
 #include <__type_traits/is_integral.h>
-#include <__type_traits/is_object.h>
-#include <__type_traits/is_same.h>
-#include <__type_traits/is_trivially_copyable.h>
-#include <__type_traits/remove_cv.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -31,13 +27,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // considered bit-castable.
 template <class _From, class _To>
 struct __is_always_bitcastable {
-  using _UnqualFrom = __remove_cv_t<_From>;
-  using _UnqualTo   = __remove_cv_t<_To>;
+  using _UnqualFrom = __remove_cv(_From);
+  using _UnqualTo   = __remove_cv(_To);
 
   // clang-format off
   static const bool value =
       // First, the simple case -- `From` and `To` are the same object type.
-      (is_same<_UnqualFrom, _UnqualTo>::value && is_trivially_copyable<_UnqualFrom>::value) ||
+      (__is_same(_UnqualFrom, _UnqualTo) && __is_trivially_copyable(_UnqualFrom)) ||
 
       // Beyond the simple case, we say that one type is "always bit-castable" to another if:
       // - (1) `From` and `To` have the same value representation, and in addition every possible value of `From` has
@@ -75,7 +71,7 @@ struct __is_always_bitcastable {
         sizeof(_From) == sizeof(_To) &&
         is_integral<_From>::value &&
         is_integral<_To>::value &&
-        !is_same<_UnqualTo, bool>::value
+        !__is_same(_UnqualTo, bool)
       );
   // clang-format on
 };
diff --git a/libcxx/include/__type_traits/is_destructible.h b/libcxx/include/__type_traits/is_destructible.h
index 3248b07d36ee67..650132854b438f 100644
--- a/libcxx/include/__type_traits/is_destructible.h
+++ b/libcxx/include/__type_traits/is_destructible.h
@@ -11,8 +11,6 @@
 
 #include <__config>
 #include <__type_traits/integral_constant.h>
-#include <__type_traits/is_function.h>
-#include <__type_traits/is_reference.h>
 #include <__type_traits/remove_all_extents.h>
 #include <__utility/declval.h>
 
@@ -71,13 +69,13 @@ template <class _Tp, bool>
 struct __destructible_false;
 
 template <class _Tp>
-struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, is_reference<_Tp>::value> {};
+struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, __is_reference(_Tp)> {};
 
 template <class _Tp>
 struct __destructible_false<_Tp, true> : public false_type {};
 
 template <class _Tp>
-struct is_destructible : public __destructible_false<_Tp, is_function<_Tp>::value> {};
+struct is_destructible : public __destructible_false<_Tp, __is_function(_Tp)> {};
 
 template <class _Tp>
 struct is_destructible<_Tp[]> : public false_type {};
diff --git a/libcxx/include/__type_traits/is_equality_comparable.h b/libcxx/include/__type_traits/is_equality_comparable.h
index 4397f743e5ee95..892e848da49760 100644
--- a/libcxx/include/__type_traits/is_equality_comparable.h
+++ b/libcxx/include/__type_traits/is_equality_comparable.h
@@ -13,7 +13,6 @@
 #include <__type_traits/enable_if.h>
 #include <__type_traits/integral_constant.h>
 #include <__type_traits/is_integral.h>
-#include <__type_traits/is_same.h>
 #include <__type_traits/is_signed.h>
 #include <__type_traits/is_void.h>
 #include <__type_traits/remove_cv.h>
@@ -64,7 +63,7 @@ template <class _Tp, class _Up>
 struct __libcpp_is_trivially_equality_comparable_impl<
     _Tp,
     _Up,
-    __enable_if_t<is_integral<_Tp>::value && is_integral<_Up>::value && !is_same<_Tp, _Up>::value &&
+    __enable_if_t<is_integral<_Tp>::value && is_integral<_Up>::value && !__is_same(_Tp, _Up) &&
                   is_signed<_Tp>::value == is_signed<_Up>::value && sizeof(_Tp) == sizeof(_Up)> > : true_type {};
 
 template <class _Tp>
@@ -76,8 +75,7 @@ struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Up*>
     : integral_constant<
           bool,
           __is_equality_comparable<_Tp*, _Up*>::value &&
-              (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value || is_void<_Tp>::value || is_void<_Up>::value)> {
-};
+              (__is_same(__remove_cv(_Tp), __remove_cv(_Up)) || is_void<_Tp>::value || is_void<_Up>::value)> {};
 
 template <class _Tp, class _Up>
 using __libcpp_is_trivially_equality_comparable =
diff --git a/libcxx/include/__type_traits/is_execution_policy.h b/libcxx/include/__type_traits/is_execution_policy.h
index 6884f17ba16c88..15103165122616 100644
--- a/libcxx/include/__type_traits/is_execution_policy.h
+++ b/libcxx/include/__type_traits/is_execution_policy.h
@@ -10,7 +10,6 @@
 #define _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H
 
 #include <__config>
-#include <__type_traits/remove_cvref.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -27,14 +26,13 @@ template <class>
 inline constexpr bool __is_unsequenced_execution_policy_impl = false;
 
 template <class _Tp>
-inline constexpr bool __is_unsequenced_execution_policy_v =
-    __is_unsequenced_execution_policy_impl<__remove_cvref_t<_Tp>>;
+inline constexpr bool __is_unsequenced_execution_policy_v = __is_unsequenced_execution_policy_impl<__remove_cvref(_Tp)>;
 
 template <class>
 inline constexpr bool __is_parallel_execution_policy_impl = false;
 
 template <class _Tp>
-inline constexpr bool __is_parallel_execution_policy_v = __is_parallel_execution_policy_impl<__remove_cvref_t<_Tp>>;
+inline constexpr bool __is_parallel_execution_policy_v = __is_parallel_execution_policy_impl<__remove_cvref(_Tp)>;
 
 namespace execution {
 struct __disable_user_instantiations_tag {
diff --git a/libcxx/include/__type_traits/is_floating_point.h b/libcxx/include/__type_traits/is_floating_point.h
index add34782dfa099..f2cda337b5b272 100644
--- a/libcxx/include/__type_traits/is_floating_point.h
+++ b/libcxx/include/__type_traits/is_floating_point.h
@@ -11,7 +11,6 @@
 
 #include <__config>
 #include <__type_traits/integral_constant.h>
-#include <__type_traits/remove_cv.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -27,7 +26,7 @@ template <>          struct __libcpp_is_floating_point<long double> : public tru
 // clang-format on
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_floating_point : public __libcpp_is_floating_point<__remove_cv_t<_Tp> > {};
+struct _LIBCPP_TEMPLATE_VIS is_floating_point : public __libcpp_is_floating_point<__remove_cv(_Tp)> {};
 
 #if _LIBCPP_STD_VER >= 17
 template <class _Tp>
diff --git a/libcxx/include/__type_traits/is_integral.h b/libcxx/include/__type_traits/is_integral.h
index 61178720a5938c..1a7070ed7fefd4 100644
--- a/libcxx/include/__type_traits/is_integral.h
+++ b/libcxx/include/__type_traits/is_integral.h
@@ -11,7 +11,6 @@
 
 #include <__config>
 #include <__type_traits/integral_constant.h>
-#include <__type_traits/remove_cv.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -60,7 +59,7 @@ inline constexpr bool is_integral_v = __is_integral(_Tp);
 #else
 
 template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS is_integral : public _BoolConstant<__libcpp_is_integral<__remove_cv_t<_Tp> >::value> {};
+struct _LIBCPP_TEMPLATE_VIS is_integral : public _BoolConstant<__libcpp_is_integral<__remove_cv(_Tp)>::value> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
diff --git a/libcxx/include/__type_traits/is_pointer.h b/libcxx/include/__type_traits/is_pointer.h
index 9701e57807cf6f..cf2cd3937e5150 100644
--- a/libcxx/include/__type_traits/is_pointer.h
+++ b/libcxx/include/__type_traits/is_pointer.h
@@ -11,7 +11,6 @@
 
 #include <__config>
 #include <__type_traits/integral_constant.h>
-#include <__type_traits/remove_cv.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -51,7 +50,7 @@ template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretai
 
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_pointer
-    : public __libcpp_is_pointer<typename __libcpp_remove_objc_qualifiers<__remove_cv_t<_Tp> >::type> {};
+    : public __libcpp_is_pointer<typename __libcpp_remove_objc_qualifiers<__remove_cv(_Tp)>::type> {};
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _Tp>
diff --git a/libcxx/include/__type_traits/is_reference_wrapper.h b/libcxx/include/__type_traits/is_reference_wrapper.h
index 310a910040e8be..4016548a65aaf9 100644
--- a/libcxx/include/__type_traits/is_reference_wrapper.h
+++ b/libcxx/include/__type_traits/is_reference_wrapper.h
@@ -12,7 +12,6 @@
 #include <__config>
 #include <__fwd/functional.h>
 #include <__type_traits/integral_constant.h>
-#include <__type_traits/remove_cv.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -25,7 +24,7 @@ struct __is_reference_wrapper_impl : public false_type {};
 template <class _Tp>
 struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
 template <class _Tp>
-struct __is_reference_wrapper : public __is_reference_wrapper_impl<__remove_cv_t<_Tp> > {};
+struct __is_reference_wrapper : public __is_reference_wrapper_impl<__remove_cv(_Tp)> {};
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/libcxx/include/__type_traits/is_referenceable.h b/libcxx/include/__type_traits/is_referenceable.h
index 4b34ec25723173..c5b17c5c30e750 100644
--- a/libcxx/include/__type_traits/is_referenceable.h
+++ b/libcxx/include/__type_traits/is_referenceable.h
@@ -11,7 +11,6 @@
 
 #include <__config>
 #include <__type_traits/integral_constant.h>
-#include <__type_traits/is_same.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -32,8 +31,7 @@ struct __libcpp_is_referenceable_impl {
 
 template <class _Tp>
 struct __libcpp_is_referenceable
-    : integral_constant<bool, _IsNotSame<decltype(__libcpp_is_referenceable_impl::__test<_Tp>(0)), false_type>::value> {
-};
+    : integral_constant<bool, !__is_same(decltype(__libcpp_is_referenceable_impl::__test<_Tp>(0)), false_type)> {};
 #endif // __has_builtin(__is_referenceable)
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/is_scalar.h b/libcxx/include/__type_traits/is_scalar.h
index 242023a6877c94..80d70ca539c07f 100644
--- a/libcxx/include/__type_traits/is_scalar.h
+++ b/libcxx/include/__type_traits/is_scalar.h
@@ -12,8 +12,6 @@
 #include <__config>
 #include <__type_traits/integral_constant.h>
 #include <__type_traits/is_arithmetic.h>
-#include <__type_traits/is_enum.h>
-#include <__type_traits/is_member_pointer.h>
 #include <__type_traits/is_null_pointer.h>
 #include <__type_traits/is_pointer.h>
 
@@ -47,11 +45,11 @@ template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS is_scalar
     : public integral_constant<
           bool, is_arithmetic<_Tp>::value ||
-                is_member_pointer<_Tp>::value ||
+                __is_member_pointer(_Tp) ||
                 is_pointer<_Tp>::value ||
                 __is_null_pointer_v<_Tp> ||
                 __is_block<_Tp>::value ||
-                is_enum<_Tp>::value> {};
+                __is_enum(_Tp)> {};
 // clang-format on
 
 template <>
diff --git a/libcxx/include/__type_traits/is_trivially_assignable.h b/libcxx/include/__type_traits/is_trivially_assignable.h
index 201333b0fa0b33..7720c3e637506a 100644
--- a/libcxx/include/__type_traits/is_trivially_assignable.h
+++ b/libcxx/include/__type_traits/is_trivially_assignable.h
@@ -10,7 +10,6 @@
 #define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_ASSIGNABLE_H
 
 #include <__config>
-#include <__type_traits/add_const.h>
 #include <__type_traits/add_lvalue_reference.h>
 #include <__type_traits/add_rvalue_reference.h>
 #include <__type_traits/integral_constant.h>
diff --git a/libcxx/include/__type_traits/is_trivially_lexicographically_comparable.h b/libcxx/include/__type_traits/is_trivially_lexicographically_comparable.h
index 15dda5824a3623..d61dd315faa0f1 100644
--- a/libcxx/include/__type_traits/is_trivially_lexicographically_comparable.h
+++ b/libcxx/include/__type_traits/is_trivially_lexicographically_comparable.h
@@ -12,9 +12,7 @@
 #include <__config>
 #include <__fwd/byte.h>
 #include <__type_traits/integral_constant.h>
-#include <__type_traits/is_same.h>
 #include <__type_traits/is_unsigned.h>
-#include <__type_traits/remove_cv.h>
 #include <__type_traits/void_t.h>
 #include <__utility/declval.h>
 
@@ -52,7 +50,7 @@ inline const bool __is_std_byte_v<byte> = true;
 
 template <class _Tp, class _Up>
 inline const bool __is_trivially_lexicographically_comparable_v =
-    is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value &&
+    __is_same(__remove_cv(_Tp), __remove_cv(_Up)) &&
 #ifdef _LIBCPP_LITTLE_ENDIAN
     sizeof(_Tp) == 1 &&
 #endif
diff --git a/libcxx/include/__type_traits/is_trivially_relocatable.h b/libcxx/include/__type_traits/is_trivially_relocatable.h
index c0871731cc0016..7559da2019c755 100644
--- a/libcxx/include/__type_traits/is_trivially_relocatable.h
+++ b/libcxx/include/__type_traits/is_trivially_relocatable.h
@@ -12,7 +12,6 @@
 #include <__config>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/integral_constant.h>
-#include <__type_traits/is_same.h>
 #include <__type_traits/is_trivially_copyable.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -33,8 +32,7 @@ struct __libcpp_is_trivially_relocatable : is_trivially_copyable<_Tp> {};
 #endif
 
 template <class _Tp>
-struct __libcpp_is_trivially_relocatable<_Tp,
-                                         __enable_if_t<is_same<_Tp, typename _Tp::__trivially_relocatable>::value> >
+struct __libcpp_is_trivially_relocatable<_Tp, __enable_if_t<__is_same(_Tp, typename _Tp::__trivially_relocatable)> >
     : true_type {};
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__type_traits/make_32_64_or_128_bit.h b/libcxx/include/__type_traits/make_32_64_or_128_bit.h
index 70f84fcd18686c..f75126f1036ced 100644
--- a/libcxx/include/__type_traits/make_32_64_or_128_bit.h
+++ b/libcxx/include/__type_traits/make_32_64_or_128_bit.h
@@ -11,7 +11,6 @@
 
 #include <__config>
 #include <__type_traits/conditional.h>
-#include <__type_traits/is_same.h>
 #include <__type_traits/is_signed.h>
 #include <__type_traits/is_unsigned.h>
 #include <__type_traits/make_unsigned.h>
@@ -28,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 /// The restriction is the same as the integral version of to_char.
 template <class _Tp>
 #if _LIBCPP_STD_VER >= 20
-  requires(is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>)
+  requires(is_signed_v<_Tp> || is_unsigned_v<_Tp> || __is_same(_Tp, char))
 #endif
 // clang-format off
 using __make_32_64_or_128_bit_t =
diff --git a/libcxx/include/__type_traits/make_signed.h b/libcxx/include/__type_traits/make_signed.h
index 8070690b3a7a90..6363a79e222432 100644
--- a/libcxx/include/__type_traits/make_signed.h
+++ b/libcxx/include/__type_traits/make_signed.h
@@ -11,10 +11,8 @@
 
 #include <__config>
 #include <__type_traits/copy_cv.h>
-#include <__type_traits/is_enum.h>
 #include <__type_traits/is_integral.h>
 #include <__type_traits/nat.h>
-#include <__type_traits/remove_cv.h>
 #include <__type_traits/type_list.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -45,7 +43,7 @@ typedef __type_list<signed char,
         > > > > > __signed_types;
 // clang-format on
 
-template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
+template <class _Tp, bool = is_integral<_Tp>::value || __is_enum(_Tp)>
 struct __make_signed{};
 
 template <class _Tp>
@@ -70,7 +68,7 @@ template <> struct __make_signed<__uint128_t,        true> {typedef __int128_t t
 // clang-format on
 
 template <class _Tp>
-using __make_signed_t = __copy_cv_t<_Tp, typename __make_signed<__remove_cv_t<_Tp> >::type>;
+using __make_signed_t = __copy_cv_t<_Tp, typename __make_signed<__remove_cv(_Tp)>::type>;
 
 #endif // __has_builtin(__make_signed)
 
diff --git a/libcxx/include/__type_traits/make_unsigned.h b/libcxx/include/__type_traits/make_unsigned.h
index 562f7bab8a7fbf..cfdacb4a7258e6 100644
--- a/libcxx/include/__type_traits/make_unsigned.h
+++ b/libcxx/include/__type_traits/make_unsigned.h
@@ -12,11 +12,9 @@
 #include <__config>
 #include <__type_traits/conditional.h>
 #include <__type_traits/copy_cv.h>
-#include <__type_traits/is_enum.h>
 #include <__type_traits/is_integral.h>
 #include <__type_traits/is_unsigned.h>
 #include <__type_traits/nat.h>
-#include <__type_traits/remove_cv.h>
 #include <__type_traits/type_list.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -47,7 +45,7 @@ typedef __type_list<unsigned char,
         > > > > > __unsigned_types;
 // clang-format on
 
-template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
+template <class _Tp, bool = is_integral<_Tp>::value || __is_enum(_Tp)>
 struct __make_unsigned{};
 
 template <class _Tp>
@@ -72,7 +70,7 @@ template <> struct __make_unsigned<__uint128_t,        true> {typedef __uint128_
 // clang-format on
 
 template <class _Tp>
-using __make_unsigned_t = __copy_cv_t<_Tp, typename __make_unsigned<__remove_cv_t<_Tp> >::type>;
+using __make_unsigned_t = __copy_cv_t<_Tp, typename __make_unsigned<__remove_cv(_Tp)>::type>;
 
 #endif // __has_builtin(__make_unsigned)
 
diff --git a/libcxx/include/__type_traits/remove_cvref.h b/libcxx/include/__type_traits/remove_cvref.h
index 55f894dbd1d815..5bcdea05e4beb6 100644
--- a/libcxx/include/__type_traits/remove_cvref.h
+++ b/libcxx/include/__type_traits/remove_cvref.h
@@ -11,8 +11,6 @@
 
 #include <__config>
 #include <__type_traits/is_same.h>
-#include <__type_traits/remove_cv.h>
-#include <__type_traits/remove_reference.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__type_traits/underlying_type.h b/libcxx/include/__type_traits/underlying_type.h
index 16e7501dee17df..0b53fb934da644 100644
--- a/libcxx/include/__type_traits/underlying_type.h
+++ b/libcxx/include/__type_traits/underlying_type.h
@@ -10,7 +10,6 @@
 #define _LIBCPP___TYPE_TRAITS_UNDERLYING_TYPE_H
 
 #include <__config>
-#include <__type_traits/is_enum.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -18,7 +17,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp, bool = is_enum<_Tp>::value>
+template <class _Tp, bool = __is_enum(_Tp)>
 struct __underlying_type_impl;
 
 template <class _Tp>
@@ -30,7 +29,7 @@ struct __underlying_type_impl<_Tp, true> {
 };
 
 template <class _Tp>
-struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
+struct underlying_type : __underlying_type_impl<_Tp> {};
 
 #if _LIBCPP_STD_VER >= 14
 template <class _Tp>
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index baeed35ca8508b..3f2c5e11790d43 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -516,6 +516,7 @@ namespace std
 #  include <__type_traits/is_constant_evaluated.h>
 #  include <__type_traits/is_nothrow_convertible.h>
 #  include <__type_traits/is_unbounded_array.h>
+#  include <__type_traits/remove_cvref.h>
 #  include <__type_traits/type_identity.h>
 #  include <__type_traits/unwrap_ref.h>
 #endif



More information about the libcxx-commits mailing list