[libcxx-commits] [libcxx] b7aa9c4 - [libc++] Granularize some more type_traits

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jul 24 13:22:18 PDT 2022


Author: Nikolas Klauser
Date: 2022-07-24T22:22:12+02:00
New Revision: b7aa9c4ac8e7a2736125109deeb0be8b1f41f852

URL: https://github.com/llvm/llvm-project/commit/b7aa9c4ac8e7a2736125109deeb0be8b1f41f852
DIFF: https://github.com/llvm/llvm-project/commit/b7aa9c4ac8e7a2736125109deeb0be8b1f41f852.diff

LOG: [libc++] Granularize some more type_traits

Reviewed By: ldionne, #libc

Spies: libcxx-commits, mgorny

Differential Revision: https://reviews.llvm.org/D128948

Added: 
    libcxx/include/__type_traits/aligned_storage.h
    libcxx/include/__type_traits/aligned_union.h
    libcxx/include/__type_traits/common_reference.h
    libcxx/include/__type_traits/common_type.h
    libcxx/include/__type_traits/copy_cv.h
    libcxx/include/__type_traits/copy_cvref.h
    libcxx/include/__type_traits/is_nothrow_convertible.h
    libcxx/include/__type_traits/is_primary_template.h
    libcxx/include/__type_traits/is_signed_integer.h
    libcxx/include/__type_traits/is_unsigned_integer.h
    libcxx/include/__type_traits/is_valid_expansion.h
    libcxx/include/__type_traits/lazy.h
    libcxx/include/__type_traits/make_32_64_or_128_bit.h
    libcxx/include/__type_traits/make_signed.h
    libcxx/include/__type_traits/make_unsigned.h
    libcxx/include/__type_traits/nat.h
    libcxx/include/__type_traits/promote.h
    libcxx/include/__type_traits/remove_cvref.h
    libcxx/include/__type_traits/type_list.h

Modified: 
    libcxx/include/CMakeLists.txt
    libcxx/include/__concepts/arithmetic.h
    libcxx/include/__format/formatter_integer.h
    libcxx/include/__functional/invoke.h
    libcxx/include/__iterator/incrementable_traits.h
    libcxx/include/__memory/temporary_buffer.h
    libcxx/include/charconv
    libcxx/include/math.h
    libcxx/include/module.modulemap.in
    libcxx/include/type_traits
    libcxx/test/libcxx/private_headers.verify.cpp
    libcxx/test/libcxx/utilities/meta/meta_base.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 71c30e73b5ba7..354a86931fb11 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -505,10 +505,16 @@ set(files
   __type_traits/add_pointer.h
   __type_traits/add_rvalue_reference.h
   __type_traits/add_volatile.h
+  __type_traits/aligned_storage.h
+  __type_traits/aligned_union.h
   __type_traits/alignment_of.h
   __type_traits/apply_cv.h
+  __type_traits/common_reference.h
+  __type_traits/common_type.h
   __type_traits/conditional.h
   __type_traits/conjunction.h
+  __type_traits/copy_cv.h
+  __type_traits/copy_cvref.h
   __type_traits/decay.h
   __type_traits/disjunction.h
   __type_traits/enable_if.h
@@ -550,6 +556,7 @@ set(files
   __type_traits/is_move_constructible.h
   __type_traits/is_nothrow_assignable.h
   __type_traits/is_nothrow_constructible.h
+  __type_traits/is_nothrow_convertible.h
   __type_traits/is_nothrow_copy_assignable.h
   __type_traits/is_nothrow_copy_constructible.h
   __type_traits/is_nothrow_default_constructible.h
@@ -561,6 +568,7 @@ set(files
   __type_traits/is_pod.h
   __type_traits/is_pointer.h
   __type_traits/is_polymorphic.h
+  __type_traits/is_primary_template.h
   __type_traits/is_reference.h
   __type_traits/is_reference_wrapper.h
   __type_traits/is_referenceable.h
@@ -568,6 +576,7 @@ set(files
   __type_traits/is_scalar.h
   __type_traits/is_scoped_enum.h
   __type_traits/is_signed.h
+  __type_traits/is_signed_integer.h
   __type_traits/is_standard_layout.h
   __type_traits/is_trivial.h
   __type_traits/is_trivially_assignable.h
@@ -582,18 +591,28 @@ set(files
   __type_traits/is_unbounded_array.h
   __type_traits/is_union.h
   __type_traits/is_unsigned.h
+  __type_traits/is_unsigned_integer.h
+  __type_traits/is_valid_expansion.h
   __type_traits/is_void.h
   __type_traits/is_volatile.h
+  __type_traits/lazy.h
+  __type_traits/make_32_64_or_128_bit.h
+  __type_traits/make_signed.h
+  __type_traits/make_unsigned.h
+  __type_traits/nat.h
   __type_traits/negation.h
+  __type_traits/promote.h
   __type_traits/rank.h
   __type_traits/remove_all_extents.h
   __type_traits/remove_const.h
   __type_traits/remove_cv.h
+  __type_traits/remove_cvref.h
   __type_traits/remove_extent.h
   __type_traits/remove_pointer.h
   __type_traits/remove_reference.h
   __type_traits/remove_volatile.h
   __type_traits/type_identity.h
+  __type_traits/type_list.h
   __type_traits/underlying_type.h
   __type_traits/void_t.h
   __undef_macros

diff  --git a/libcxx/include/__concepts/arithmetic.h b/libcxx/include/__concepts/arithmetic.h
index 023f031e7e07a..d91570f02b8bb 100644
--- a/libcxx/include/__concepts/arithmetic.h
+++ b/libcxx/include/__concepts/arithmetic.h
@@ -10,6 +10,8 @@
 #define _LIBCPP___CONCEPTS_ARITHMETIC_H
 
 #include <__config>
+#include <__type_traits/is_signed_integer.h>
+#include <__type_traits/is_unsigned_integer.h>
 #include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

diff  --git a/libcxx/include/__format/formatter_integer.h b/libcxx/include/__format/formatter_integer.h
index 0281b4f2fa679..3139c9efdf807 100644
--- a/libcxx/include/__format/formatter_integer.h
+++ b/libcxx/include/__format/formatter_integer.h
@@ -19,6 +19,7 @@
 #include <__format/formatter_integral.h>
 #include <__format/formatter_output.h>
 #include <__format/parser_std_format_spec.h>
+#include <__type_traits/make_32_64_or_128_bit.h>
 #include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

diff  --git a/libcxx/include/__functional/invoke.h b/libcxx/include/__functional/invoke.h
index 7381462ffca59..d56a0accdbcef 100644
--- a/libcxx/include/__functional/invoke.h
+++ b/libcxx/include/__functional/invoke.h
@@ -24,6 +24,7 @@
 #include <__type_traits/is_reference_wrapper.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/is_void.h>
+#include <__type_traits/nat.h>
 #include <__type_traits/remove_cv.h>
 #include <__utility/declval.h>
 #include <__utility/forward.h>
@@ -41,16 +42,6 @@ struct __any
     __any(...);
 };
 
-struct __nat
-{
-#ifndef _LIBCPP_CXX03_LANG
-    __nat() = delete;
-    __nat(const __nat&) = delete;
-    __nat& operator=(const __nat&) = delete;
-    ~__nat() = delete;
-#endif
-};
-
 template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
 struct __member_pointer_traits_imp
 {

diff  --git a/libcxx/include/__iterator/incrementable_traits.h b/libcxx/include/__iterator/incrementable_traits.h
index ef5f5110a30ec..4109b58d46a9e 100644
--- a/libcxx/include/__iterator/incrementable_traits.h
+++ b/libcxx/include/__iterator/incrementable_traits.h
@@ -11,6 +11,7 @@
 #define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H
 
 #include <__config>
+#include <__type_traits/is_primary_template.h>
 #include <concepts>
 #include <type_traits>
 

diff  --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index 9822bd30c826e..b1f7a126299f6 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -11,6 +11,7 @@
 #define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H
 
 #include <__config>
+#include <__type_traits/alignment_of.h>
 #include <__utility/pair.h>
 #include <cstddef>
 #include <new>

diff  --git a/libcxx/include/__type_traits/aligned_storage.h b/libcxx/include/__type_traits/aligned_storage.h
new file mode 100644
index 0000000000000..9659a90ae50c1
--- /dev/null
+++ b/libcxx/include/__type_traits/aligned_storage.h
@@ -0,0 +1,142 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H
+#define _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H
+
+#include <__config>
+#include <__type_traits/conditional.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/nat.h>
+#include <__type_traits/type_list.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __align_type
+{
+    static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
+    typedef _Tp type;
+};
+
+struct __struct_double {long double __lx;};
+struct __struct_double4 {double __lx[4];};
+
+typedef
+    __type_list<__align_type<unsigned char>,
+    __type_list<__align_type<unsigned short>,
+    __type_list<__align_type<unsigned int>,
+    __type_list<__align_type<unsigned long>,
+    __type_list<__align_type<unsigned long long>,
+    __type_list<__align_type<double>,
+    __type_list<__align_type<long double>,
+    __type_list<__align_type<__struct_double>,
+    __type_list<__align_type<__struct_double4>,
+    __type_list<__align_type<int*>,
+    __nat
+    > > > > > > > > > > __all_types;
+
+template <size_t _Align>
+struct _ALIGNAS(_Align) __fallback_overaligned {};
+
+template <class _TL, size_t _Align> struct __find_pod;
+
+template <class _Hp, size_t _Align>
+struct __find_pod<__type_list<_Hp, __nat>, _Align>
+{
+    typedef typename conditional<
+                             _Align == _Hp::value,
+                             typename _Hp::type,
+                             __fallback_overaligned<_Align>
+                         >::type type;
+};
+
+template <class _Hp, class _Tp, size_t _Align>
+struct __find_pod<__type_list<_Hp, _Tp>, _Align>
+{
+    typedef typename conditional<
+                             _Align == _Hp::value,
+                             typename _Hp::type,
+                             typename __find_pod<_Tp, _Align>::type
+                         >::type type;
+};
+
+template <class _TL, size_t _Len> struct __find_max_align;
+
+template <class _Hp, size_t _Len>
+struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {};
+
+template <size_t _Len, size_t _A1, size_t _A2>
+struct __select_align
+{
+private:
+    static const size_t __min = _A2 < _A1 ? _A2 : _A1;
+    static const size_t __max = _A1 < _A2 ? _A2 : _A1;
+public:
+    static const size_t value = _Len < __max ? __min : __max;
+};
+
+template <class _Hp, class _Tp, size_t _Len>
+struct __find_max_align<__type_list<_Hp, _Tp>, _Len>
+    : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};
+
+template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+struct _LIBCPP_TEMPLATE_VIS aligned_storage
+{
+    typedef typename __find_pod<__all_types, _Align>::type _Aligner;
+    union type
+    {
+        _Aligner __align;
+        unsigned char __data[(_Len + _Align - 1)/_Align * _Align];
+    };
+};
+
+#if _LIBCPP_STD_VER > 11
+template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+    using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;
+#endif
+
+#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
+template <size_t _Len>\
+struct _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\
+{\
+    struct _ALIGNAS(n) type\
+    {\
+        unsigned char __lx[(_Len + n - 1)/n * n];\
+    };\
+}
+
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x8);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x10);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x20);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x40);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x80);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x100);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x200);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x400);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x800);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000);
+// PE/COFF does not support alignment beyond 8192 (=0x2000)
+#if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000);
+#endif // !defined(_LIBCPP_OBJECT_FORMAT_COFF)
+
+#undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H

diff  --git a/libcxx/include/__type_traits/aligned_union.h b/libcxx/include/__type_traits/aligned_union.h
new file mode 100644
index 0000000000000..31eb9353a9e22
--- /dev/null
+++ b/libcxx/include/__type_traits/aligned_union.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_ALIGNED_UNION_H
+#define _LIBCPP___TYPE_TRAITS_ALIGNED_UNION_H
+
+#include <__config>
+#include <__type_traits/aligned_storage.h>
+#include <__type_traits/integral_constant.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <size_t _I0, size_t ..._In>
+struct __static_max;
+
+template <size_t _I0>
+struct __static_max<_I0>
+{
+    static const size_t value = _I0;
+};
+
+template <size_t _I0, size_t _I1, size_t ..._In>
+struct __static_max<_I0, _I1, _In...>
+{
+    static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value :
+                                             __static_max<_I1, _In...>::value;
+};
+
+template <size_t _Len, class _Type0, class ..._Types>
+struct aligned_union
+{
+    static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0),
+                                                       _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
+    static const size_t __len = __static_max<_Len, sizeof(_Type0),
+                                             sizeof(_Types)...>::value;
+    typedef typename aligned_storage<__len, alignment_value>::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <size_t _Len, class ..._Types> using aligned_union_t = typename aligned_union<_Len, _Types...>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_ALIGNED_UNION_H

diff  --git a/libcxx/include/__type_traits/common_reference.h b/libcxx/include/__type_traits/common_reference.h
new file mode 100644
index 0000000000000..559d39858ec88
--- /dev/null
+++ b/libcxx/include/__type_traits/common_reference.h
@@ -0,0 +1,188 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_COMMON_REFERENCE_H
+#define _LIBCPP___TYPE_TRAITS_COMMON_REFERENCE_H
+
+#include <__config>
+#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>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// common_reference
+#if _LIBCPP_STD_VER > 17
+// Let COND_RES(X, Y) be:
+template <class _Xp, class _Yp>
+using __cond_res =
+    decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()());
+
+// Let `XREF(A)` denote a unary alias template `T` such that `T<U>` denotes the same type as `U`
+// with the addition of `A`'s cv and reference qualifiers, for a non-reference cv-unqualified type
+// `U`.
+// [Note: `XREF(A)` is `__xref<A>::template __apply`]
+template <class _Tp>
+struct __xref {
+  template<class _Up>
+  using __apply = __copy_cvref_t<_Tp, _Up>;
+};
+
+// Given types A and B, let X be remove_reference_t<A>, let Y be remove_reference_t<B>,
+// and let COMMON-REF(A, B) be:
+template<class _Ap, class _Bp, class _Xp = remove_reference_t<_Ap>, class _Yp = remove_reference_t<_Bp>>
+struct __common_ref;
+
+template<class _Xp, class _Yp>
+using __common_ref_t = typename __common_ref<_Xp, _Yp>::__type;
+
+template<class _Xp, class _Yp>
+using __cv_cond_res = __cond_res<__copy_cv_t<_Xp, _Yp>&, __copy_cv_t<_Yp, _Xp>&>;
+
+
+//    If A and B are both lvalue reference types, COMMON-REF(A, B) is
+//    COND-RES(COPYCV(X, Y)&, COPYCV(Y, X)&) if that type exists and is a reference type.
+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>>
+struct __common_ref<_Ap&, _Bp&, _Xp, _Yp>
+{
+    using __type = __cv_cond_res<_Xp, _Yp>;
+};
+
+//    Otherwise, let C be remove_reference_t<COMMON-REF(X&, Y&)>&&. ...
+template <class _Xp, class _Yp>
+using __common_ref_C = remove_reference_t<__common_ref_t<_Xp&, _Yp&>>&&;
+
+
+//    .... If A and B are both rvalue reference types, C is well-formed, and
+//    is_convertible_v<A, C> && is_convertible_v<B, C> is true, then COMMON-REF(A, B) is C.
+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>>
+struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp>
+{
+    using __type = __common_ref_C<_Xp, _Yp>;
+};
+
+//    Otherwise, let D be COMMON-REF(const X&, Y&). ...
+template <class _Tp, class _Up>
+using __common_ref_D = __common_ref_t<const _Tp&, _Up&>;
+
+//    ... If A is an rvalue reference and B is an lvalue reference and D is well-formed and
+//    is_convertible_v<A, D> is true, then COMMON-REF(A, B) is D.
+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>>
+struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp>
+{
+    using __type = __common_ref_D<_Xp, _Yp>;
+};
+
+//    Otherwise, if A is an lvalue reference and B is an rvalue reference, then
+//    COMMON-REF(A, B) is COMMON-REF(B, A).
+template<class _Ap, class _Bp, class _Xp, class _Yp>
+struct __common_ref<_Ap&, _Bp&&, _Xp, _Yp> : __common_ref<_Bp&&, _Ap&> {};
+
+//    Otherwise, COMMON-REF(A, B) is ill-formed.
+template<class _Ap, class _Bp, class _Xp, class _Yp>
+struct __common_ref {};
+
+// Note C: For the common_reference trait applied to a parameter pack [...]
+
+template <class...>
+struct common_reference;
+
+template <class... _Types>
+using common_reference_t = typename common_reference<_Types...>::type;
+
+// bullet 1 - sizeof...(T) == 0
+template<>
+struct common_reference<> {};
+
+// bullet 2 - sizeof...(T) == 1
+template <class _Tp>
+struct common_reference<_Tp>
+{
+    using type = _Tp;
+};
+
+// bullet 3 - sizeof...(T) == 2
+template <class _Tp, class _Up> struct __common_reference_sub_bullet3;
+template <class _Tp, class _Up> struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {};
+template <class _Tp, class _Up> struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {};
+
+// sub-bullet 1 - If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, then
+// the member typedef `type` denotes that type.
+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>; }
+struct __common_reference_sub_bullet1<_Tp, _Up>
+{
+    using type = __common_ref_t<_Tp, _Up>;
+};
+
+// sub-bullet 2 - Otherwise, if basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>, XREF(T1), XREF(T2)>::type
+// is well-formed, then the member typedef `type` denotes that type.
+template <class, class, template <class> class, template <class> class> 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>,
+    __xref<_Tp>::template __apply, __xref<_Up>::template __apply>::type;
+
+template <class _Tp, class _Up>
+requires requires { typename __basic_common_reference_t<_Tp, _Up>; }
+struct __common_reference_sub_bullet2<_Tp, _Up>
+{
+    using type = __basic_common_reference_t<_Tp, _Up>;
+};
+
+// sub-bullet 3 - Otherwise, if COND-RES(T1, T2) is well-formed,
+// then the member typedef `type` denotes that type.
+template <class _Tp, class _Up>
+requires requires { typename __cond_res<_Tp, _Up>; }
+struct __common_reference_sub_bullet3<_Tp, _Up>
+{
+    using type = __cond_res<_Tp, _Up>;
+};
+
+
+// sub-bullet 4 & 5 - Otherwise, if common_type_t<T1, T2> is well-formed,
+//                    then the member typedef `type` denotes that type.
+//                  - Otherwise, there shall be no member `type`.
+template <class _Tp, class _Up> struct __common_reference_sub_bullet3 : common_type<_Tp, _Up> {};
+
+// bullet 4 - If there is such a type `C`, the member typedef type shall denote the same type, if
+//            any, as `common_reference_t<C, Rest...>`.
+template <class _Tp, class _Up, class _Vp, class... _Rest>
+requires requires { typename common_reference_t<_Tp, _Up>; }
+struct common_reference<_Tp, _Up, _Vp, _Rest...>
+    : common_reference<common_reference_t<_Tp, _Up>, _Vp, _Rest...>
+{};
+
+// bullet 5 - Otherwise, there shall be no member `type`.
+template <class...> struct common_reference {};
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_COMMON_REFERENCE_H

diff  --git a/libcxx/include/__type_traits/common_type.h b/libcxx/include/__type_traits/common_type.h
new file mode 100644
index 0000000000000..55321e9936dd4
--- /dev/null
+++ b/libcxx/include/__type_traits/common_type.h
@@ -0,0 +1,138 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_COMMON_TYPE_H
+#define _LIBCPP___TYPE_TRAITS_COMMON_TYPE_H
+
+#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/void_t.h>
+#include <__utility/declval.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+// Let COND_RES(X, Y) be:
+template <class _Tp, class _Up>
+using __cond_type = decltype(false ? declval<_Tp>() : declval<_Up>());
+
+template <class _Tp, class _Up, class = void>
+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&>>;
+};
+
+template <class _Tp, class _Up, class = void>
+struct __common_type2_imp : __common_type3<_Tp, _Up> {};
+#else
+template <class _Tp, class _Up, class = void>
+struct __common_type2_imp {};
+#endif
+
+// sub-bullet 3 - "if decay_t<decltype(false ? declval<D1>() : declval<D2>())> ..."
+template <class _Tp, class _Up>
+struct __common_type2_imp<_Tp, _Up,
+                          typename __void_t<decltype(
+                                            true ? declval<_Tp>() : declval<_Up>()
+                                            )>::type>
+{
+  typedef _LIBCPP_NODEBUG typename decay<decltype(
+                         true ? declval<_Tp>() : declval<_Up>()
+                         )>::type type;
+};
+
+template <class, class = void>
+struct __common_type_impl {};
+
+// Clang provides variadic templates in C++03 as an extension.
+#if !defined(_LIBCPP_CXX03_LANG) || defined(__clang__)
+# define _LIBCPP_OPTIONAL_PACK(...) , __VA_ARGS__
+template <class... _Tp>
+struct __common_types;
+template <class... _Tp>
+struct _LIBCPP_TEMPLATE_VIS common_type;
+#else
+# define _LIBCPP_OPTIONAL_PACK(...)
+struct __no_arg;
+template <class _Tp, class _Up, class = __no_arg>
+struct __common_types;
+template <class _Tp = __no_arg, class _Up = __no_arg, class _Vp = __no_arg,
+          class _Unused = __no_arg>
+struct common_type {
+  static_assert(sizeof(_Unused) == 0,
+                "common_type accepts at most 3 arguments in C++03");
+};
+#endif // _LIBCPP_CXX03_LANG
+
+template <class _Tp, class _Up>
+struct __common_type_impl<
+    __common_types<_Tp, _Up>,
+    typename __void_t<typename common_type<_Tp, _Up>::type>::type>
+{
+  typedef typename common_type<_Tp, _Up>::type type;
+};
+
+template <class _Tp, class _Up, class _Vp _LIBCPP_OPTIONAL_PACK(class... _Rest)>
+struct __common_type_impl<
+    __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)>,
+    typename __void_t<typename common_type<_Tp, _Up>::type>::type>
+    : __common_type_impl<__common_types<typename common_type<_Tp, _Up>::type,
+                                        _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {
+};
+
+// bullet 1 - sizeof...(Tp) == 0
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS common_type<> {};
+
+// bullet 2 - sizeof...(Tp) == 1
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS common_type<_Tp>
+    : public common_type<_Tp, _Tp> {};
+
+// bullet 3 - sizeof...(Tp) == 2
+
+// 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<
+        _IsSame<_Tp, typename decay<_Tp>::type>::value && _IsSame<_Up, typename decay<_Up>::type>::value,
+        __common_type2_imp<_Tp, _Up>,
+        common_type<typename decay<_Tp>::type, typename decay<_Up>::type>
+    >::type
+{};
+
+// bullet 4 - sizeof...(Tp) > 2
+
+template <class _Tp, class _Up, class _Vp _LIBCPP_OPTIONAL_PACK(class... _Rest)>
+struct _LIBCPP_TEMPLATE_VIS
+    common_type<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)>
+    : __common_type_impl<
+          __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {};
+
+#undef _LIBCPP_OPTIONAL_PACK
+
+#if _LIBCPP_STD_VER > 11
+template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_COMMON_TYPE_H

diff  --git a/libcxx/include/__type_traits/copy_cv.h b/libcxx/include/__type_traits/copy_cv.h
new file mode 100644
index 0000000000000..8e9bfe0a522f8
--- /dev/null
+++ b/libcxx/include/__type_traits/copy_cv.h
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_COPY_CV_H
+#define _LIBCPP___TYPE_TRAITS_COPY_CV_H
+
+#include <__config>
+#include <__type_traits/add_const.h>
+#include <__type_traits/add_cv.h>
+#include <__type_traits/add_volatile.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Let COPYCV(FROM, TO) be an alias for type TO with the addition of FROM's
+// top-level cv-qualifiers.
+template <class _From, class _To>
+struct __copy_cv
+{
+    using type = _To;
+};
+
+template <class _From, class _To>
+struct __copy_cv<const _From, _To>
+{
+    using type = typename add_const<_To>::type;
+};
+
+template <class _From, class _To>
+struct __copy_cv<volatile _From, _To>
+{
+    using type = typename add_volatile<_To>::type;
+};
+
+template <class _From, class _To>
+struct __copy_cv<const volatile _From, _To>
+{
+    using type = typename add_cv<_To>::type;
+};
+
+template <class _From, class _To>
+using __copy_cv_t = typename __copy_cv<_From, _To>::type;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_COPY_CV_H

diff  --git a/libcxx/include/__type_traits/copy_cvref.h b/libcxx/include/__type_traits/copy_cvref.h
new file mode 100644
index 0000000000000..69b97ac1cb17b
--- /dev/null
+++ b/libcxx/include/__type_traits/copy_cvref.h
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_COPY_CVREF_H
+#define _LIBCPP___TYPE_TRAITS_COPY_CVREF_H
+
+#include <__config>
+#include <__type_traits/add_lvalue_reference.h>
+#include <__type_traits/add_rvalue_reference.h>
+#include <__type_traits/copy_cv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _From, class _To>
+struct __copy_cvref
+{
+    using type = __copy_cv_t<_From, _To>;
+};
+
+template <class _From, class _To>
+struct __copy_cvref<_From&, _To>
+{
+    using type = typename add_lvalue_reference<__copy_cv_t<_From, _To> >::type;
+};
+
+template <class _From, class _To>
+struct __copy_cvref<_From&&, _To>
+{
+    using type = typename add_rvalue_reference<__copy_cv_t<_From, _To> >::type;
+};
+
+template <class _From, class _To>
+using __copy_cvref_t = typename __copy_cvref<_From, _To>::type;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_COPY_CVREF_H

diff  --git a/libcxx/include/__type_traits/is_nothrow_convertible.h b/libcxx/include/__type_traits/is_nothrow_convertible.h
new file mode 100644
index 0000000000000..712b6f2cf4b8c
--- /dev/null
+++ b/libcxx/include/__type_traits/is_nothrow_convertible.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_NOTHROW_CONVERTIBLE_H
+#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_CONVERTIBLE_H
+
+#include <__config>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/disjunction.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/lazy.h>
+#include <__utility/declval.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+template <typename _Tp>
+static void __test_noexcept(_Tp) noexcept;
+
+template<typename _Fm, typename _To>
+static bool_constant<noexcept(_VSTD::__test_noexcept<_To>(declval<_Fm>()))>
+__is_nothrow_convertible_test();
+
+template <typename _Fm, typename _To>
+struct __is_nothrow_convertible_helper: decltype(__is_nothrow_convertible_test<_Fm, _To>())
+{ };
+
+template <typename _Fm, typename _To>
+struct is_nothrow_convertible : _Or<
+    _And<is_void<_To>, is_void<_Fm>>,
+    _Lazy<_And, is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To>>
+>::type { };
+
+template <typename _Fm, typename _To>
+inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_Fm, _To>::value;
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_CONVERTIBLE_H

diff  --git a/libcxx/include/__type_traits/is_primary_template.h b/libcxx/include/__type_traits/is_primary_template.h
new file mode 100644
index 0000000000000..a9bebcf7e64c0
--- /dev/null
+++ b/libcxx/include/__type_traits/is_primary_template.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_PRIMARY_TEMPLATE_H
+#define _LIBCPP___TYPE_TRAITS_IS_PRIMARY_TEMPLATE_H
+
+#include <__config>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_valid_expansion.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+using __test_for_primary_template = __enable_if_t<
+    _IsSame<_Tp, typename _Tp::__primary_template>::value
+  >;
+template <class _Tp>
+using __is_primary_template = _IsValidExpansion<
+    __test_for_primary_template, _Tp
+  >;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_PRIMARY_TEMPLATE_H

diff  --git a/libcxx/include/__type_traits/is_signed_integer.h b/libcxx/include/__type_traits/is_signed_integer.h
new file mode 100644
index 0000000000000..95aa11bfa1b58
--- /dev/null
+++ b/libcxx/include/__type_traits/is_signed_integer.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_SIGNED_INTEGER_H
+#define _LIBCPP___TYPE_TRAITS_IS_SIGNED_INTEGER_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct __libcpp_is_signed_integer : public false_type {};
+template <> struct __libcpp_is_signed_integer<signed char>      : public true_type {};
+template <> struct __libcpp_is_signed_integer<signed short>     : public true_type {};
+template <> struct __libcpp_is_signed_integer<signed int>       : public true_type {};
+template <> struct __libcpp_is_signed_integer<signed long>      : public true_type {};
+template <> struct __libcpp_is_signed_integer<signed long long> : public true_type {};
+#ifndef _LIBCPP_HAS_NO_INT128
+template <> struct __libcpp_is_signed_integer<__int128_t>       : public true_type {};
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_SIGNED_INTEGER_H

diff  --git a/libcxx/include/__type_traits/is_unsigned_integer.h b/libcxx/include/__type_traits/is_unsigned_integer.h
new file mode 100644
index 0000000000000..54b29acd9ea38
--- /dev/null
+++ b/libcxx/include/__type_traits/is_unsigned_integer.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_UNSIGNED_INTEGER_H
+#define _LIBCPP___TYPE_TRAITS_IS_UNSIGNED_INTEGER_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> struct __libcpp_is_unsigned_integer : public false_type {};
+template <> struct __libcpp_is_unsigned_integer<unsigned char>      : public true_type {};
+template <> struct __libcpp_is_unsigned_integer<unsigned short>     : public true_type {};
+template <> struct __libcpp_is_unsigned_integer<unsigned int>       : public true_type {};
+template <> struct __libcpp_is_unsigned_integer<unsigned long>      : public true_type {};
+template <> struct __libcpp_is_unsigned_integer<unsigned long long> : public true_type {};
+#ifndef _LIBCPP_HAS_NO_INT128
+template <> struct __libcpp_is_unsigned_integer<__uint128_t>        : public true_type {};
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_UNSIGNED_INTEGER_H

diff  --git a/libcxx/include/__type_traits/is_valid_expansion.h b/libcxx/include/__type_traits/is_valid_expansion.h
new file mode 100644
index 0000000000000..c45db7509e41f
--- /dev/null
+++ b/libcxx/include/__type_traits/is_valid_expansion.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_IS_VALID_EXPANSION_H
+#define _LIBCPP___TYPE_TRAITS_IS_VALID_EXPANSION_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <template <class...> class _Templ, class ..._Args, class = _Templ<_Args...> >
+true_type __sfinae_test_impl(int);
+template <template <class...> class, class ...>
+false_type __sfinae_test_impl(...);
+
+template <template <class ...> class _Templ, class ..._Args>
+using _IsValidExpansion _LIBCPP_NODEBUG = decltype(__sfinae_test_impl<_Templ, _Args...>(0));
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_IS_VALID_EXPANSION_H

diff  --git a/libcxx/include/__type_traits/lazy.h b/libcxx/include/__type_traits/lazy.h
new file mode 100644
index 0000000000000..6874b06f3c5af
--- /dev/null
+++ b/libcxx/include/__type_traits/lazy.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_LAZY_H
+#define _LIBCPP___TYPE_TRAITS_LAZY_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <template <class...> class _Func, class ..._Args>
+struct _Lazy : _Func<_Args...> {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_LAZY_H

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
new file mode 100644
index 0000000000000..87340eac7fb1f
--- /dev/null
+++ b/libcxx/include/__type_traits/make_32_64_or_128_bit.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_MAKE_32_64_OR_128_BIT_H
+#define _LIBCPP___TYPE_TRAITS_MAKE_32_64_OR_128_BIT_H
+
+#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>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+/// Helper to promote an integral to smallest 32, 64, or 128 bit representation.
+///
+/// The restriction is the same as the integral version of to_char.
+template <class _Tp>
+#if _LIBCPP_STD_VER > 17
+  requires (is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>)
+#endif
+using __make_32_64_or_128_bit_t =
+  __copy_unsigned_t<_Tp,
+    __conditional_t<sizeof(_Tp) <= sizeof(int32_t),    int32_t,
+    __conditional_t<sizeof(_Tp) <= sizeof(int64_t),    int64_t,
+#ifndef _LIBCPP_HAS_NO_INT128
+    __conditional_t<sizeof(_Tp) <= sizeof(__int128_t), __int128_t,
+    /* else */                                         void>
+#else
+    /* else */                                         void
+#endif
+    > >
+  >;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_MAKE_32_64_OR_128_BIT_H

diff  --git a/libcxx/include/__type_traits/make_signed.h b/libcxx/include/__type_traits/make_signed.h
new file mode 100644
index 0000000000000..fbc31172a9785
--- /dev/null
+++ b/libcxx/include/__type_traits/make_signed.h
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_MAKE_SIGNED_H
+#define _LIBCPP___TYPE_TRAITS_MAKE_SIGNED_H
+
+#include <__config>
+#include <__type_traits/apply_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)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+typedef
+    __type_list<signed char,
+    __type_list<signed short,
+    __type_list<signed int,
+    __type_list<signed long,
+    __type_list<signed long long,
+#ifndef _LIBCPP_HAS_NO_INT128
+    __type_list<__int128_t,
+#endif
+    __nat
+#ifndef _LIBCPP_HAS_NO_INT128
+    >
+#endif
+    > > > > > __signed_types;
+
+template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
+struct __make_signed {};
+
+template <class _Tp>
+struct __make_signed<_Tp, true>
+{
+    typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type;
+};
+
+template <> struct __make_signed<bool,               true> {};
+template <> struct __make_signed<  signed short,     true> {typedef short     type;};
+template <> struct __make_signed<unsigned short,     true> {typedef short     type;};
+template <> struct __make_signed<  signed int,       true> {typedef int       type;};
+template <> struct __make_signed<unsigned int,       true> {typedef int       type;};
+template <> struct __make_signed<  signed long,      true> {typedef long      type;};
+template <> struct __make_signed<unsigned long,      true> {typedef long      type;};
+template <> struct __make_signed<  signed long long, true> {typedef long long type;};
+template <> struct __make_signed<unsigned long long, true> {typedef long long type;};
+#ifndef _LIBCPP_HAS_NO_INT128
+template <> struct __make_signed<__int128_t,         true> {typedef __int128_t type;};
+template <> struct __make_signed<__uint128_t,        true> {typedef __int128_t type;};
+#endif
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS make_signed
+{
+    typedef typename __apply_cv<_Tp, typename __make_signed<typename remove_cv<_Tp>::type>::type>::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using make_signed_t = typename make_signed<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_MAKE_SIGNED_H

diff  --git a/libcxx/include/__type_traits/make_unsigned.h b/libcxx/include/__type_traits/make_unsigned.h
new file mode 100644
index 0000000000000..8110a5ca96097
--- /dev/null
+++ b/libcxx/include/__type_traits/make_unsigned.h
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_MAKE_UNSIGNED_H
+#define _LIBCPP___TYPE_TRAITS_MAKE_UNSIGNED_H
+
+#include <__config>
+#include <__type_traits/apply_cv.h>
+#include <__type_traits/conditional.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)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+typedef
+    __type_list<unsigned char,
+    __type_list<unsigned short,
+    __type_list<unsigned int,
+    __type_list<unsigned long,
+    __type_list<unsigned long long,
+#ifndef _LIBCPP_HAS_NO_INT128
+    __type_list<__uint128_t,
+#endif
+    __nat
+#ifndef _LIBCPP_HAS_NO_INT128
+    >
+#endif
+    > > > > > __unsigned_types;
+
+template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
+struct __make_unsigned {};
+
+template <class _Tp>
+struct __make_unsigned<_Tp, true>
+{
+    typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type;
+};
+
+template <> struct __make_unsigned<bool,               true> {};
+template <> struct __make_unsigned<  signed short,     true> {typedef unsigned short     type;};
+template <> struct __make_unsigned<unsigned short,     true> {typedef unsigned short     type;};
+template <> struct __make_unsigned<  signed int,       true> {typedef unsigned int       type;};
+template <> struct __make_unsigned<unsigned int,       true> {typedef unsigned int       type;};
+template <> struct __make_unsigned<  signed long,      true> {typedef unsigned long      type;};
+template <> struct __make_unsigned<unsigned long,      true> {typedef unsigned long      type;};
+template <> struct __make_unsigned<  signed long long, true> {typedef unsigned long long type;};
+template <> struct __make_unsigned<unsigned long long, true> {typedef unsigned long long type;};
+#ifndef _LIBCPP_HAS_NO_INT128
+template <> struct __make_unsigned<__int128_t,         true> {typedef __uint128_t        type;};
+template <> struct __make_unsigned<__uint128_t,        true> {typedef __uint128_t        type;};
+#endif
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS make_unsigned
+{
+    typedef typename __apply_cv<_Tp, typename __make_unsigned<typename remove_cv<_Tp>::type>::type>::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using make_unsigned_t = typename make_unsigned<_Tp>::type;
+#endif
+
+#ifndef _LIBCPP_CXX03_LANG
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr
+typename make_unsigned<_Tp>::type __to_unsigned_like(_Tp __x) noexcept {
+    return static_cast<typename make_unsigned<_Tp>::type>(__x);
+}
+#endif
+
+template <class _Tp, class _Up>
+using __copy_unsigned_t = __conditional_t<is_unsigned<_Tp>::value, typename make_unsigned<_Up>::type, _Up>;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_MAKE_UNSIGNED_H

diff  --git a/libcxx/include/__type_traits/nat.h b/libcxx/include/__type_traits/nat.h
new file mode 100644
index 0000000000000..5216ef5204202
--- /dev/null
+++ b/libcxx/include/__type_traits/nat.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_NAT_H
+#define _LIBCPP___TYPE_TRAITS_NAT_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct __nat
+{
+#ifndef _LIBCPP_CXX03_LANG
+    __nat() = delete;
+    __nat(const __nat&) = delete;
+    __nat& operator=(const __nat&) = delete;
+    ~__nat() = delete;
+#endif
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_NAT_H

diff  --git a/libcxx/include/__type_traits/promote.h b/libcxx/include/__type_traits/promote.h
new file mode 100644
index 0000000000000..a9226a74b300d
--- /dev/null
+++ b/libcxx/include/__type_traits/promote.h
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_PROMOTE_H
+#define _LIBCPP___TYPE_TRAITS_PROMOTE_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/is_same.h>
+#include <__utility/declval.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct __numeric_type
+{
+   static void __test(...);
+   static float __test(float);
+   static double __test(char);
+   static double __test(int);
+   static double __test(unsigned);
+   static double __test(long);
+   static double __test(unsigned long);
+   static double __test(long long);
+   static double __test(unsigned long long);
+   static double __test(double);
+   static long double __test(long double);
+
+   typedef decltype(__test(declval<_Tp>())) type;
+   static const bool value = _IsNotSame<type, void>::value;
+};
+
+template <>
+struct __numeric_type<void>
+{
+   static const bool value = true;
+};
+
+template <class _A1, class _A2 = void, class _A3 = void,
+          bool = __numeric_type<_A1>::value &&
+                 __numeric_type<_A2>::value &&
+                 __numeric_type<_A3>::value>
+class __promote_imp
+{
+public:
+    static const bool value = false;
+};
+
+template <class _A1, class _A2, class _A3>
+class __promote_imp<_A1, _A2, _A3, true>
+{
+private:
+    typedef typename __promote_imp<_A1>::type __type1;
+    typedef typename __promote_imp<_A2>::type __type2;
+    typedef typename __promote_imp<_A3>::type __type3;
+public:
+    typedef decltype(__type1() + __type2() + __type3()) type;
+    static const bool value = true;
+};
+
+template <class _A1, class _A2>
+class __promote_imp<_A1, _A2, void, true>
+{
+private:
+    typedef typename __promote_imp<_A1>::type __type1;
+    typedef typename __promote_imp<_A2>::type __type2;
+public:
+    typedef decltype(__type1() + __type2()) type;
+    static const bool value = true;
+};
+
+template <class _A1>
+class __promote_imp<_A1, void, void, true>
+{
+public:
+    typedef typename __numeric_type<_A1>::type type;
+    static const bool value = true;
+};
+
+template <class _A1, class _A2 = void, class _A3 = void>
+class __promote : public __promote_imp<_A1, _A2, _A3> {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_PROMOTE_H

diff  --git a/libcxx/include/__type_traits/remove_cvref.h b/libcxx/include/__type_traits/remove_cvref.h
new file mode 100644
index 0000000000000..d937501fedcec
--- /dev/null
+++ b/libcxx/include/__type_traits/remove_cvref.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REMOVE_CVREF_H
+#define _LIBCPP___TYPE_TRAITS_REMOVE_CVREF_H
+
+#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
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+using __uncvref_t _LIBCPP_NODEBUG = typename remove_cv<typename remove_reference<_Tp>::type>::type;
+
+template <class _Tp, class _Up>
+struct __is_same_uncvref : _IsSame<__uncvref_t<_Tp>, __uncvref_t<_Up> > {};
+
+#if _LIBCPP_STD_VER > 17
+// remove_cvref - same as __uncvref
+template <class _Tp>
+struct remove_cvref {
+    using type _LIBCPP_NODEBUG = __uncvref_t<_Tp>;
+};
+
+template <class _Tp> using remove_cvref_t = typename remove_cvref<_Tp>::type;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REMOVE_CVREF_H

diff  --git a/libcxx/include/__type_traits/type_list.h b/libcxx/include/__type_traits/type_list.h
new file mode 100644
index 0000000000000..5a9e3319a1d46
--- /dev/null
+++ b/libcxx/include/__type_traits/type_list.h
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_TYPE_LIST_H
+#define _LIBCPP___TYPE_TRAITS_TYPE_LIST_H
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Hp, class _Tp>
+struct __type_list
+{
+    typedef _Hp _Head;
+    typedef _Tp _Tail;
+};
+
+template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)> struct __find_first;
+
+template <class _Hp, class _Tp, size_t _Size>
+struct __find_first<__type_list<_Hp, _Tp>, _Size, true>
+{
+    typedef _LIBCPP_NODEBUG _Hp type;
+};
+
+template <class _Hp, class _Tp, size_t _Size>
+struct __find_first<__type_list<_Hp, _Tp>, _Size, false>
+{
+    typedef _LIBCPP_NODEBUG typename __find_first<_Tp, _Size>::type type;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_TYPE_LIST_H

diff  --git a/libcxx/include/charconv b/libcxx/include/charconv
index 9f474ae711f3e..4f00755a83bbf 100644
--- a/libcxx/include/charconv
+++ b/libcxx/include/charconv
@@ -88,6 +88,7 @@ namespace std {
 #include <__config>
 #include <__debug>
 #include <__errc>
+#include <__type_traits/make_32_64_or_128_bit.h>
 #include <__utility/unreachable.h>
 #include <cmath> // for log2f
 #include <cstdint>

diff  --git a/libcxx/include/math.h b/libcxx/include/math.h
index 7d553e728d0fe..0ec584af9dbed 100644
--- a/libcxx/include/math.h
+++ b/libcxx/include/math.h
@@ -305,6 +305,7 @@ long double    truncl(long double x);
 // back to C++ linkage before including these C++ headers.
 extern "C++" {
 
+#include <__type_traits/promote.h>
 #include <limits>
 #include <stdlib.h>
 #include <type_traits>

diff  --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index cbf0b4f7f16d5..40f6d2da36263 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1090,10 +1090,16 @@ module std [system] {
     module add_pointer                        { private header "__type_traits/add_pointer.h" }
     module add_rvalue_reference               { private header "__type_traits/add_rvalue_reference.h" }
     module add_volatile                       { private header "__type_traits/add_volatile.h" }
+    module aligned_storage                    { private header "__type_traits/aligned_storage.h" }
+    module aligned_union                      { private header "__type_traits/aligned_union.h" }
     module alignment_of                       { private header "__type_traits/alignment_of.h" }
     module apply_cv                           { private header "__type_traits/apply_cv.h" }
+    module common_reference                   { private header "__type_traits/common_reference.h" }
+    module common_type                        { private header "__type_traits/common_type.h" }
     module conditional                        { private header "__type_traits/conditional.h" }
     module conjunction                        { private header "__type_traits/conjunction.h" }
+    module copy_cv                            { private header "__type_traits/copy_cv.h" }
+    module copy_cvref                         { private header "__type_traits/copy_cvref.h" }
     module decay                              { private header "__type_traits/decay.h" }
     module disjunction                        { private header "__type_traits/disjunction.h" }
     module enable_if                          { private header "__type_traits/enable_if.h" }
@@ -1135,6 +1141,7 @@ module std [system] {
     module is_move_constructible              { private header "__type_traits/is_move_constructible.h" }
     module is_nothrow_assignable              { private header "__type_traits/is_nothrow_assignable.h" }
     module is_nothrow_constructible           { private header "__type_traits/is_nothrow_constructible.h" }
+    module is_nothrow_convertible             { private header "__type_traits/is_nothrow_convertible.h" }
     module is_nothrow_copy_assignable         { private header "__type_traits/is_nothrow_copy_assignable.h" }
     module is_nothrow_copy_constructible      { private header "__type_traits/is_nothrow_copy_constructible.h" }
     module is_nothrow_default_constructible   { private header "__type_traits/is_nothrow_default_constructible.h" }
@@ -1146,6 +1153,7 @@ module std [system] {
     module is_pod                             { private header "__type_traits/is_pod.h" }
     module is_pointer                         { private header "__type_traits/is_pointer.h" }
     module is_polymorphic                     { private header "__type_traits/is_polymorphic.h" }
+    module is_primary_template                { private header "__type_traits/is_primary_template.h" }
     module is_reference                       { private header "__type_traits/is_reference.h" }
     module is_reference_wrapper               { private header "__type_traits/is_reference_wrapper.h" }
     module is_referenceable                   { private header "__type_traits/is_referenceable.h" }
@@ -1153,6 +1161,7 @@ module std [system] {
     module is_scalar                          { private header "__type_traits/is_scalar.h" }
     module is_scoped_enum                     { private header "__type_traits/is_scoped_enum.h" }
     module is_signed                          { private header "__type_traits/is_signed.h" }
+    module is_signed_integer                  { private header "__type_traits/is_signed_integer.h" }
     module is_standard_layout                 { private header "__type_traits/is_standard_layout.h" }
     module is_trivial                         { private header "__type_traits/is_trivial.h" }
     module is_trivially_assignable            { private header "__type_traits/is_trivially_assignable.h" }
@@ -1167,18 +1176,28 @@ module std [system] {
     module is_unbounded_array                 { private header "__type_traits/is_unbounded_array.h" }
     module is_union                           { private header "__type_traits/is_union.h" }
     module is_unsigned                        { private header "__type_traits/is_unsigned.h" }
+    module is_unsigned_integer                { private header "__type_traits/is_unsigned_integer.h" }
+    module is_valid_expansion                 { private header "__type_traits/is_valid_expansion.h" }
     module is_void                            { private header "__type_traits/is_void.h" }
     module is_volatile                        { private header "__type_traits/is_volatile.h" }
+    module lazy                               { private header "__type_traits/lazy.h" }
+    module make_32_64_or_128_bit              { private header "__type_traits/make_32_64_or_128_bit.h" }
+    module make_signed                        { private header "__type_traits/make_signed.h" }
+    module make_unsigned                      { private header "__type_traits/make_unsigned.h" }
+    module nat                                { private header "__type_traits/nat.h" }
     module negation                           { private header "__type_traits/negation.h" }
+    module promote                            { private header "__type_traits/promote.h" }
     module rank                               { private header "__type_traits/rank.h" }
     module remove_all_extents                 { private header "__type_traits/remove_all_extents.h" }
     module remove_const                       { private header "__type_traits/remove_const.h" }
     module remove_cv                          { private header "__type_traits/remove_cv.h" }
+    module remove_cvref                       { private header "__type_traits/remove_cvref.h" }
     module remove_extent                      { private header "__type_traits/remove_extent.h" }
     module remove_pointer                     { private header "__type_traits/remove_pointer.h" }
     module remove_reference                   { private header "__type_traits/remove_reference.h" }
     module remove_volatile                    { private header "__type_traits/remove_volatile.h" }
     module type_identity                      { private header "__type_traits/type_identity.h" }
+    module type_list                          { private header "__type_traits/type_list.h" }
     module underlying_type                    { private header "__type_traits/underlying_type.h" }
     module void_t                             { private header "__type_traits/void_t.h" }
   }

diff  --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index f7d81e65dd8e3..3a086c595f92f 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -425,8 +425,12 @@ namespace std
 #include <__type_traits/add_pointer.h>
 #include <__type_traits/add_rvalue_reference.h>
 #include <__type_traits/add_volatile.h>
+#include <__type_traits/aligned_storage.h>
+#include <__type_traits/aligned_union.h>
 #include <__type_traits/alignment_of.h>
 #include <__type_traits/apply_cv.h>
+#include <__type_traits/common_reference.h>
+#include <__type_traits/common_type.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/conjunction.h>
 #include <__type_traits/decay.h>
@@ -469,6 +473,7 @@ namespace std
 #include <__type_traits/is_move_constructible.h>
 #include <__type_traits/is_nothrow_assignable.h>
 #include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_nothrow_convertible.h>
 #include <__type_traits/is_nothrow_copy_assignable.h>
 #include <__type_traits/is_nothrow_copy_constructible.h>
 #include <__type_traits/is_nothrow_default_constructible.h>
@@ -503,6 +508,8 @@ namespace std
 #include <__type_traits/is_unsigned.h>
 #include <__type_traits/is_void.h>
 #include <__type_traits/is_volatile.h>
+#include <__type_traits/make_signed.h>
+#include <__type_traits/make_unsigned.h>
 #include <__type_traits/negation.h>
 #include <__type_traits/rank.h>
 #include <__type_traits/remove_all_extents.h>
@@ -529,798 +536,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS pair;
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
 
-template <template <class...> class _Func, class ..._Args>
-struct _Lazy : _Func<_Args...> {};
-
 // Member detector base
 
-template <template <class...> class _Templ, class ..._Args, class = _Templ<_Args...> >
-true_type __sfinae_test_impl(int);
-template <template <class...> class, class ...>
-false_type __sfinae_test_impl(...);
-
-template <template <class ...> class _Templ, class ..._Args>
-using _IsValidExpansion _LIBCPP_NODEBUG = decltype(__sfinae_test_impl<_Templ, _Args...>(0));
-
 template <class _Tp, bool>
 struct _LIBCPP_TEMPLATE_VIS __dependent_type : public _Tp {};
 
-// is_same
-
-template <class _Tp>
-using __test_for_primary_template = __enable_if_t<
-    _IsSame<_Tp, typename _Tp::__primary_template>::value
-  >;
-template <class _Tp>
-using __is_primary_template = _IsValidExpansion<
-    __test_for_primary_template, _Tp
-  >;
-
 // is_integral
 
-// [basic.fundamental] defines five standard signed integer types;
-// __int128_t is an extended signed integer type.
-// The signed and unsigned integer types, plus bool and the
-// five types with "char" in their name, compose the "integral" types.
-
-template <class _Tp> struct __libcpp_is_signed_integer : public false_type {};
-template <> struct __libcpp_is_signed_integer<signed char>      : public true_type {};
-template <> struct __libcpp_is_signed_integer<signed short>     : public true_type {};
-template <> struct __libcpp_is_signed_integer<signed int>       : public true_type {};
-template <> struct __libcpp_is_signed_integer<signed long>      : public true_type {};
-template <> struct __libcpp_is_signed_integer<signed long long> : public true_type {};
-#ifndef _LIBCPP_HAS_NO_INT128
-template <> struct __libcpp_is_signed_integer<__int128_t>       : public true_type {};
-#endif
-
-template <class _Tp> struct __libcpp_is_unsigned_integer : public false_type {};
-template <> struct __libcpp_is_unsigned_integer<unsigned char>      : public true_type {};
-template <> struct __libcpp_is_unsigned_integer<unsigned short>     : public true_type {};
-template <> struct __libcpp_is_unsigned_integer<unsigned int>       : public true_type {};
-template <> struct __libcpp_is_unsigned_integer<unsigned long>      : public true_type {};
-template <> struct __libcpp_is_unsigned_integer<unsigned long long> : public true_type {};
-#ifndef _LIBCPP_HAS_NO_INT128
-template <> struct __libcpp_is_unsigned_integer<__uint128_t>        : public true_type {};
-#endif
-
 template <class _Tp>
 struct __unconstref {
     typedef _LIBCPP_NODEBUG typename remove_const<typename remove_reference<_Tp>::type>::type type;
 };
 
-template <class _Tp>
-using __uncvref_t _LIBCPP_NODEBUG = typename remove_cv<typename remove_reference<_Tp>::type>::type;
-
-// __is_same_uncvref
-
-template <class _Tp, class _Up>
-struct __is_same_uncvref : _IsSame<__uncvref_t<_Tp>, __uncvref_t<_Up> > {};
-
-#if _LIBCPP_STD_VER > 17
-// remove_cvref - same as __uncvref
-template <class _Tp>
-struct remove_cvref {
-    using type _LIBCPP_NODEBUG = __uncvref_t<_Tp>;
-};
-
-template <class _Tp> using remove_cvref_t = typename remove_cvref<_Tp>::type;
-#endif
-
-// is_nothrow_convertible
-
-#if _LIBCPP_STD_VER > 17
-
-template <typename _Tp>
-static void __test_noexcept(_Tp) noexcept;
-
-template<typename _Fm, typename _To>
-static bool_constant<noexcept(_VSTD::__test_noexcept<_To>(declval<_Fm>()))>
-__is_nothrow_convertible_test();
-
-template <typename _Fm, typename _To>
-struct __is_nothrow_convertible_helper: decltype(__is_nothrow_convertible_test<_Fm, _To>())
-{ };
-
-template <typename _Fm, typename _To>
-struct is_nothrow_convertible : _Or<
-    _And<is_void<_To>, is_void<_Fm>>,
-    _Lazy<_And, is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To>>
->::type { };
-
-template <typename _Fm, typename _To>
-inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_Fm, _To>::value;
-
-#endif // _LIBCPP_STD_VER > 17
-
-// aligned_storage
-
-template <class _Hp, class _Tp>
-struct __type_list
-{
-    typedef _Hp _Head;
-    typedef _Tp _Tail;
-};
-
-template <class _Tp>
-struct __align_type
-{
-    static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
-    typedef _Tp type;
-};
-
-struct __struct_double {long double __lx;};
-struct __struct_double4 {double __lx[4];};
-
-typedef
-    __type_list<__align_type<unsigned char>,
-    __type_list<__align_type<unsigned short>,
-    __type_list<__align_type<unsigned int>,
-    __type_list<__align_type<unsigned long>,
-    __type_list<__align_type<unsigned long long>,
-    __type_list<__align_type<double>,
-    __type_list<__align_type<long double>,
-    __type_list<__align_type<__struct_double>,
-    __type_list<__align_type<__struct_double4>,
-    __type_list<__align_type<int*>,
-    __nat
-    > > > > > > > > > > __all_types;
-
-template <size_t _Align>
-struct _ALIGNAS(_Align) __fallback_overaligned {};
-
-template <class _TL, size_t _Align> struct __find_pod;
-
-template <class _Hp, size_t _Align>
-struct __find_pod<__type_list<_Hp, __nat>, _Align>
-{
-    typedef typename conditional<
-                             _Align == _Hp::value,
-                             typename _Hp::type,
-                             __fallback_overaligned<_Align>
-                         >::type type;
-};
-
-template <class _Hp, class _Tp, size_t _Align>
-struct __find_pod<__type_list<_Hp, _Tp>, _Align>
-{
-    typedef typename conditional<
-                             _Align == _Hp::value,
-                             typename _Hp::type,
-                             typename __find_pod<_Tp, _Align>::type
-                         >::type type;
-};
-
-template <class _TL, size_t _Len> struct __find_max_align;
-
-template <class _Hp, size_t _Len>
-struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {};
-
-template <size_t _Len, size_t _A1, size_t _A2>
-struct __select_align
-{
-private:
-    static const size_t __min = _A2 < _A1 ? _A2 : _A1;
-    static const size_t __max = _A1 < _A2 ? _A2 : _A1;
-public:
-    static const size_t value = _Len < __max ? __min : __max;
-};
-
-template <class _Hp, class _Tp, size_t _Len>
-struct __find_max_align<__type_list<_Hp, _Tp>, _Len>
-    : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};
-
-template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
-struct _LIBCPP_TEMPLATE_VIS aligned_storage
-{
-    typedef typename __find_pod<__all_types, _Align>::type _Aligner;
-    union type
-    {
-        _Aligner __align;
-        unsigned char __data[(_Len + _Align - 1)/_Align * _Align];
-    };
-};
-
-#if _LIBCPP_STD_VER > 11
-template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
-    using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;
-#endif
-
-#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
-template <size_t _Len>\
-struct _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\
-{\
-    struct _ALIGNAS(n) type\
-    {\
-        unsigned char __lx[(_Len + n - 1)/n * n];\
-    };\
-}
-
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x8);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x10);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x20);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x40);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x80);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x100);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x200);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x400);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x800);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000);
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000);
-// PE/COFF does not support alignment beyond 8192 (=0x2000)
-#if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
-_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000);
-#endif // !defined(_LIBCPP_OBJECT_FORMAT_COFF)
-
-#undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION
-
-
-// aligned_union
-
-template <size_t _I0, size_t ..._In>
-struct __static_max;
-
-template <size_t _I0>
-struct __static_max<_I0>
-{
-    static const size_t value = _I0;
-};
-
-template <size_t _I0, size_t _I1, size_t ..._In>
-struct __static_max<_I0, _I1, _In...>
-{
-    static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value :
-                                             __static_max<_I1, _In...>::value;
-};
-
-template <size_t _Len, class _Type0, class ..._Types>
-struct aligned_union
-{
-    static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0),
-                                                       _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
-    static const size_t __len = __static_max<_Len, sizeof(_Type0),
-                                             sizeof(_Types)...>::value;
-    typedef typename aligned_storage<__len, alignment_value>::type type;
-};
-
-#if _LIBCPP_STD_VER > 11
-template <size_t _Len, class ..._Types> using aligned_union_t = typename aligned_union<_Len, _Types...>::type;
-#endif
-
-template <class _Tp>
-struct __numeric_type
-{
-   static void __test(...);
-   static float __test(float);
-   static double __test(char);
-   static double __test(int);
-   static double __test(unsigned);
-   static double __test(long);
-   static double __test(unsigned long);
-   static double __test(long long);
-   static double __test(unsigned long long);
-   static double __test(double);
-   static long double __test(long double);
-
-   typedef decltype(__test(declval<_Tp>())) type;
-   static const bool value = _IsNotSame<type, void>::value;
-};
-
-template <>
-struct __numeric_type<void>
-{
-   static const bool value = true;
-};
-
-// __promote
-
-template <class _A1, class _A2 = void, class _A3 = void,
-          bool = __numeric_type<_A1>::value &&
-                 __numeric_type<_A2>::value &&
-                 __numeric_type<_A3>::value>
-class __promote_imp
-{
-public:
-    static const bool value = false;
-};
-
-template <class _A1, class _A2, class _A3>
-class __promote_imp<_A1, _A2, _A3, true>
-{
-private:
-    typedef typename __promote_imp<_A1>::type __type1;
-    typedef typename __promote_imp<_A2>::type __type2;
-    typedef typename __promote_imp<_A3>::type __type3;
-public:
-    typedef decltype(__type1() + __type2() + __type3()) type;
-    static const bool value = true;
-};
-
-template <class _A1, class _A2>
-class __promote_imp<_A1, _A2, void, true>
-{
-private:
-    typedef typename __promote_imp<_A1>::type __type1;
-    typedef typename __promote_imp<_A2>::type __type2;
-public:
-    typedef decltype(__type1() + __type2()) type;
-    static const bool value = true;
-};
-
-template <class _A1>
-class __promote_imp<_A1, void, void, true>
-{
-public:
-    typedef typename __numeric_type<_A1>::type type;
-    static const bool value = true;
-};
-
-template <class _A1, class _A2 = void, class _A3 = void>
-class __promote : public __promote_imp<_A1, _A2, _A3> {};
-
-// make_signed / make_unsigned
-
-typedef
-    __type_list<signed char,
-    __type_list<signed short,
-    __type_list<signed int,
-    __type_list<signed long,
-    __type_list<signed long long,
-#ifndef _LIBCPP_HAS_NO_INT128
-    __type_list<__int128_t,
-#endif
-    __nat
-#ifndef _LIBCPP_HAS_NO_INT128
-    >
-#endif
-    > > > > > __signed_types;
-
-typedef
-    __type_list<unsigned char,
-    __type_list<unsigned short,
-    __type_list<unsigned int,
-    __type_list<unsigned long,
-    __type_list<unsigned long long,
-#ifndef _LIBCPP_HAS_NO_INT128
-    __type_list<__uint128_t,
-#endif
-    __nat
-#ifndef _LIBCPP_HAS_NO_INT128
-    >
-#endif
-    > > > > > __unsigned_types;
-
-template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)> struct __find_first;
-
-template <class _Hp, class _Tp, size_t _Size>
-struct __find_first<__type_list<_Hp, _Tp>, _Size, true>
-{
-    typedef _LIBCPP_NODEBUG _Hp type;
-};
-
-template <class _Hp, class _Tp, size_t _Size>
-struct __find_first<__type_list<_Hp, _Tp>, _Size, false>
-{
-    typedef _LIBCPP_NODEBUG typename __find_first<_Tp, _Size>::type type;
-};
-
-template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
-struct __make_signed {};
-
-template <class _Tp>
-struct __make_signed<_Tp, true>
-{
-    typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type;
-};
-
-template <> struct __make_signed<bool,               true> {};
-template <> struct __make_signed<  signed short,     true> {typedef short     type;};
-template <> struct __make_signed<unsigned short,     true> {typedef short     type;};
-template <> struct __make_signed<  signed int,       true> {typedef int       type;};
-template <> struct __make_signed<unsigned int,       true> {typedef int       type;};
-template <> struct __make_signed<  signed long,      true> {typedef long      type;};
-template <> struct __make_signed<unsigned long,      true> {typedef long      type;};
-template <> struct __make_signed<  signed long long, true> {typedef long long type;};
-template <> struct __make_signed<unsigned long long, true> {typedef long long type;};
-#ifndef _LIBCPP_HAS_NO_INT128
-template <> struct __make_signed<__int128_t,         true> {typedef __int128_t type;};
-template <> struct __make_signed<__uint128_t,        true> {typedef __int128_t type;};
-#endif
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS make_signed
-{
-    typedef typename __apply_cv<_Tp, typename __make_signed<typename remove_cv<_Tp>::type>::type>::type type;
-};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using make_signed_t = typename make_signed<_Tp>::type;
-#endif
-
-template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
-struct __make_unsigned {};
-
-template <class _Tp>
-struct __make_unsigned<_Tp, true>
-{
-    typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type;
-};
-
-template <> struct __make_unsigned<bool,               true> {};
-template <> struct __make_unsigned<  signed short,     true> {typedef unsigned short     type;};
-template <> struct __make_unsigned<unsigned short,     true> {typedef unsigned short     type;};
-template <> struct __make_unsigned<  signed int,       true> {typedef unsigned int       type;};
-template <> struct __make_unsigned<unsigned int,       true> {typedef unsigned int       type;};
-template <> struct __make_unsigned<  signed long,      true> {typedef unsigned long      type;};
-template <> struct __make_unsigned<unsigned long,      true> {typedef unsigned long      type;};
-template <> struct __make_unsigned<  signed long long, true> {typedef unsigned long long type;};
-template <> struct __make_unsigned<unsigned long long, true> {typedef unsigned long long type;};
-#ifndef _LIBCPP_HAS_NO_INT128
-template <> struct __make_unsigned<__int128_t,         true> {typedef __uint128_t        type;};
-template <> struct __make_unsigned<__uint128_t,        true> {typedef __uint128_t        type;};
-#endif
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS make_unsigned
-{
-    typedef typename __apply_cv<_Tp, typename __make_unsigned<typename remove_cv<_Tp>::type>::type>::type type;
-};
-
-#if _LIBCPP_STD_VER > 11
-template <class _Tp> using make_unsigned_t = typename make_unsigned<_Tp>::type;
-#endif
-
-#ifndef _LIBCPP_CXX03_LANG
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr
-typename make_unsigned<_Tp>::type __to_unsigned_like(_Tp __x) noexcept {
-    return static_cast<typename make_unsigned<_Tp>::type>(__x);
-}
-#endif
-
-template <class _Tp, class _Up>
-using __copy_unsigned_t = __conditional_t<is_unsigned<_Tp>::value, typename make_unsigned<_Up>::type, _Up>;
-
-/// Helper to promote an integral to smallest 32, 64, or 128 bit representation.
-///
-/// The restriction is the same as the integral version of to_char.
-template <class _Tp>
-#if _LIBCPP_STD_VER > 17
-  requires (is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>)
-#endif
-using __make_32_64_or_128_bit_t =
-  __copy_unsigned_t<_Tp,
-    __conditional_t<sizeof(_Tp) <= sizeof(int32_t),    int32_t,
-    __conditional_t<sizeof(_Tp) <= sizeof(int64_t),    int64_t,
-#ifndef _LIBCPP_HAS_NO_INT128
-    __conditional_t<sizeof(_Tp) <= sizeof(__int128_t), __int128_t,
-    /* else */                                         void>
-#else
-    /* else */                                         void
-#endif
-    > >
-  >;
-
-#if _LIBCPP_STD_VER > 17
-// Let COND_RES(X, Y) be:
-template <class _Tp, class _Up>
-using __cond_type = decltype(false ? declval<_Tp>() : declval<_Up>());
-
-template <class _Tp, class _Up, class = void>
-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&>>;
-};
-
-template <class _Tp, class _Up, class = void>
-struct __common_type2_imp : __common_type3<_Tp, _Up> {};
-#else
-template <class _Tp, class _Up, class = void>
-struct __common_type2_imp {};
-#endif
-
-// sub-bullet 3 - "if decay_t<decltype(false ? declval<D1>() : declval<D2>())> ..."
-template <class _Tp, class _Up>
-struct __common_type2_imp<_Tp, _Up,
-                          typename __void_t<decltype(
-                                            true ? declval<_Tp>() : declval<_Up>()
-                                            )>::type>
-{
-  typedef _LIBCPP_NODEBUG typename decay<decltype(
-                         true ? declval<_Tp>() : declval<_Up>()
-                         )>::type type;
-};
-
-template <class, class = void>
-struct __common_type_impl {};
-
-// Clang provides variadic templates in C++03 as an extension.
-#if !defined(_LIBCPP_CXX03_LANG) || defined(__clang__)
-# define _LIBCPP_OPTIONAL_PACK(...) , __VA_ARGS__
-template <class... _Tp>
-struct __common_types;
-template <class... _Tp>
-struct _LIBCPP_TEMPLATE_VIS common_type;
-#else
-# define _LIBCPP_OPTIONAL_PACK(...)
-struct __no_arg;
-template <class _Tp, class _Up, class = __no_arg>
-struct __common_types;
-template <class _Tp = __no_arg, class _Up = __no_arg, class _Vp = __no_arg,
-          class _Unused = __no_arg>
-struct common_type {
-  static_assert(sizeof(_Unused) == 0,
-                "common_type accepts at most 3 arguments in C++03");
-};
-#endif // _LIBCPP_CXX03_LANG
-
-template <class _Tp, class _Up>
-struct __common_type_impl<
-    __common_types<_Tp, _Up>,
-    typename __void_t<typename common_type<_Tp, _Up>::type>::type>
-{
-  typedef typename common_type<_Tp, _Up>::type type;
-};
-
-template <class _Tp, class _Up, class _Vp _LIBCPP_OPTIONAL_PACK(class... _Rest)>
-struct __common_type_impl<
-    __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)>,
-    typename __void_t<typename common_type<_Tp, _Up>::type>::type>
-    : __common_type_impl<__common_types<typename common_type<_Tp, _Up>::type,
-                                        _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {
-};
-
-// bullet 1 - sizeof...(Tp) == 0
-
-template <>
-struct _LIBCPP_TEMPLATE_VIS common_type<> {};
-
-// bullet 2 - sizeof...(Tp) == 1
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS common_type<_Tp>
-    : public common_type<_Tp, _Tp> {};
-
-// bullet 3 - sizeof...(Tp) == 2
-
-// 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<
-        _IsSame<_Tp, typename decay<_Tp>::type>::value && _IsSame<_Up, typename decay<_Up>::type>::value,
-        __common_type2_imp<_Tp, _Up>,
-        common_type<typename decay<_Tp>::type, typename decay<_Up>::type>
-    >::type
-{};
-
-// bullet 4 - sizeof...(Tp) > 2
-
-template <class _Tp, class _Up, class _Vp _LIBCPP_OPTIONAL_PACK(class... _Rest)>
-struct _LIBCPP_TEMPLATE_VIS
-    common_type<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)>
-    : __common_type_impl<
-          __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {};
-
-#undef _LIBCPP_OPTIONAL_PACK
-
-#if _LIBCPP_STD_VER > 11
-template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type;
-#endif
-
-// Let COPYCV(FROM, TO) be an alias for type TO with the addition of FROM's
-// top-level cv-qualifiers.
-template <class _From, class _To>
-struct __copy_cv
-{
-    using type = _To;
-};
-
-template <class _From, class _To>
-struct __copy_cv<const _From, _To>
-{
-    using type = typename add_const<_To>::type;
-};
-
-template <class _From, class _To>
-struct __copy_cv<volatile _From, _To>
-{
-    using type = typename add_volatile<_To>::type;
-};
-
-template <class _From, class _To>
-struct __copy_cv<const volatile _From, _To>
-{
-    using type = typename add_cv<_To>::type;
-};
-
-template <class _From, class _To>
-using __copy_cv_t = typename __copy_cv<_From, _To>::type;
-
-template <class _From, class _To>
-struct __copy_cvref
-{
-    using type = __copy_cv_t<_From, _To>;
-};
-
-template <class _From, class _To>
-struct __copy_cvref<_From&, _To>
-{
-    using type = typename add_lvalue_reference<__copy_cv_t<_From, _To> >::type;
-};
-
-template <class _From, class _To>
-struct __copy_cvref<_From&&, _To>
-{
-    using type = typename add_rvalue_reference<__copy_cv_t<_From, _To> >::type;
-};
-
-template <class _From, class _To>
-using __copy_cvref_t = typename __copy_cvref<_From, _To>::type;
-
-
-// common_reference
-#if _LIBCPP_STD_VER > 17
-// Let COND_RES(X, Y) be:
-template <class _Xp, class _Yp>
-using __cond_res =
-    decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()());
-
-// Let `XREF(A)` denote a unary alias template `T` such that `T<U>` denotes the same type as `U`
-// with the addition of `A`'s cv and reference qualifiers, for a non-reference cv-unqualified type
-// `U`.
-// [Note: `XREF(A)` is `__xref<A>::template __apply`]
-template <class _Tp>
-struct __xref {
-  template<class _Up>
-  using __apply = __copy_cvref_t<_Tp, _Up>;
-};
-
-// Given types A and B, let X be remove_reference_t<A>, let Y be remove_reference_t<B>,
-// and let COMMON-REF(A, B) be:
-template<class _Ap, class _Bp, class _Xp = remove_reference_t<_Ap>, class _Yp = remove_reference_t<_Bp>>
-struct __common_ref;
-
-template<class _Xp, class _Yp>
-using __common_ref_t = typename __common_ref<_Xp, _Yp>::__type;
-
-template<class _Xp, class _Yp>
-using __cv_cond_res = __cond_res<__copy_cv_t<_Xp, _Yp>&, __copy_cv_t<_Yp, _Xp>&>;
-
-
-//    If A and B are both lvalue reference types, COMMON-REF(A, B) is
-//    COND-RES(COPYCV(X, Y)&, COPYCV(Y, X)&) if that type exists and is a reference type.
-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>>
-struct __common_ref<_Ap&, _Bp&, _Xp, _Yp>
-{
-    using __type = __cv_cond_res<_Xp, _Yp>;
-};
-
-//    Otherwise, let C be remove_reference_t<COMMON-REF(X&, Y&)>&&. ...
-template <class _Xp, class _Yp>
-using __common_ref_C = remove_reference_t<__common_ref_t<_Xp&, _Yp&>>&&;
-
-
-//    .... If A and B are both rvalue reference types, C is well-formed, and
-//    is_convertible_v<A, C> && is_convertible_v<B, C> is true, then COMMON-REF(A, B) is C.
-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>>
-struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp>
-{
-    using __type = __common_ref_C<_Xp, _Yp>;
-};
-
-//    Otherwise, let D be COMMON-REF(const X&, Y&). ...
-template <class _Tp, class _Up>
-using __common_ref_D = __common_ref_t<const _Tp&, _Up&>;
-
-//    ... If A is an rvalue reference and B is an lvalue reference and D is well-formed and
-//    is_convertible_v<A, D> is true, then COMMON-REF(A, B) is D.
-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>>
-struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp>
-{
-    using __type = __common_ref_D<_Xp, _Yp>;
-};
-
-//    Otherwise, if A is an lvalue reference and B is an rvalue reference, then
-//    COMMON-REF(A, B) is COMMON-REF(B, A).
-template<class _Ap, class _Bp, class _Xp, class _Yp>
-struct __common_ref<_Ap&, _Bp&&, _Xp, _Yp> : __common_ref<_Bp&&, _Ap&> {};
-
-//    Otherwise, COMMON-REF(A, B) is ill-formed.
-template<class _Ap, class _Bp, class _Xp, class _Yp>
-struct __common_ref {};
-
-// Note C: For the common_reference trait applied to a parameter pack [...]
-
-template <class...>
-struct common_reference;
-
-template <class... _Types>
-using common_reference_t = typename common_reference<_Types...>::type;
-
-// bullet 1 - sizeof...(T) == 0
-template<>
-struct common_reference<> {};
-
-// bullet 2 - sizeof...(T) == 1
-template <class _Tp>
-struct common_reference<_Tp>
-{
-    using type = _Tp;
-};
-
-// bullet 3 - sizeof...(T) == 2
-template <class _Tp, class _Up> struct __common_reference_sub_bullet3;
-template <class _Tp, class _Up> struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {};
-template <class _Tp, class _Up> struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {};
-
-// sub-bullet 1 - If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, then
-// the member typedef `type` denotes that type.
-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>; }
-struct __common_reference_sub_bullet1<_Tp, _Up>
-{
-    using type = __common_ref_t<_Tp, _Up>;
-};
-
-// sub-bullet 2 - Otherwise, if basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>, XREF(T1), XREF(T2)>::type
-// is well-formed, then the member typedef `type` denotes that type.
-template <class, class, template <class> class, template <class> class> 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>,
-    __xref<_Tp>::template __apply, __xref<_Up>::template __apply>::type;
-
-template <class _Tp, class _Up>
-requires requires { typename __basic_common_reference_t<_Tp, _Up>; }
-struct __common_reference_sub_bullet2<_Tp, _Up>
-{
-    using type = __basic_common_reference_t<_Tp, _Up>;
-};
-
-// sub-bullet 3 - Otherwise, if COND-RES(T1, T2) is well-formed,
-// then the member typedef `type` denotes that type.
-template <class _Tp, class _Up>
-requires requires { typename __cond_res<_Tp, _Up>; }
-struct __common_reference_sub_bullet3<_Tp, _Up>
-{
-    using type = __cond_res<_Tp, _Up>;
-};
-
-
-// sub-bullet 4 & 5 - Otherwise, if common_type_t<T1, T2> is well-formed,
-//                    then the member typedef `type` denotes that type.
-//                  - Otherwise, there shall be no member `type`.
-template <class _Tp, class _Up> struct __common_reference_sub_bullet3 : common_type<_Tp, _Up> {};
-
-// bullet 4 - If there is such a type `C`, the member typedef type shall denote the same type, if
-//            any, as `common_reference_t<C, Rest...>`.
-template <class _Tp, class _Up, class _Vp, class... _Rest>
-requires requires { typename common_reference_t<_Tp, _Up>; }
-struct common_reference<_Tp, _Up, _Vp, _Rest...>
-    : common_reference<common_reference_t<_Tp, _Up>, _Vp, _Rest...>
-{};
-
-// bullet 5 - Otherwise, there shall be no member `type`.
-template <class...> struct common_reference {};
-
-#endif // _LIBCPP_STD_VER > 17
-
 #ifndef _LIBCPP_CXX03_LANG
 // First of all, we can't implement this check in C++03 mode because the {}
 // default initialization syntax isn't valid.

diff  --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp
index 6c1b3b5e7bbfd..b21f5573b40bd 100644
--- a/libcxx/test/libcxx/private_headers.verify.cpp
+++ b/libcxx/test/libcxx/private_headers.verify.cpp
@@ -517,10 +517,16 @@ END-SCRIPT
 #include <__type_traits/add_pointer.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/add_pointer.h'}}
 #include <__type_traits/add_rvalue_reference.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/add_rvalue_reference.h'}}
 #include <__type_traits/add_volatile.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/add_volatile.h'}}
+#include <__type_traits/aligned_storage.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/aligned_storage.h'}}
+#include <__type_traits/aligned_union.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/aligned_union.h'}}
 #include <__type_traits/alignment_of.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/alignment_of.h'}}
 #include <__type_traits/apply_cv.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/apply_cv.h'}}
+#include <__type_traits/common_reference.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/common_reference.h'}}
+#include <__type_traits/common_type.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/common_type.h'}}
 #include <__type_traits/conditional.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/conditional.h'}}
 #include <__type_traits/conjunction.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/conjunction.h'}}
+#include <__type_traits/copy_cv.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/copy_cv.h'}}
+#include <__type_traits/copy_cvref.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/copy_cvref.h'}}
 #include <__type_traits/decay.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/decay.h'}}
 #include <__type_traits/disjunction.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/disjunction.h'}}
 #include <__type_traits/enable_if.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/enable_if.h'}}
@@ -562,6 +568,7 @@ END-SCRIPT
 #include <__type_traits/is_move_constructible.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_move_constructible.h'}}
 #include <__type_traits/is_nothrow_assignable.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_nothrow_assignable.h'}}
 #include <__type_traits/is_nothrow_constructible.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_nothrow_constructible.h'}}
+#include <__type_traits/is_nothrow_convertible.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_nothrow_convertible.h'}}
 #include <__type_traits/is_nothrow_copy_assignable.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_nothrow_copy_assignable.h'}}
 #include <__type_traits/is_nothrow_copy_constructible.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_nothrow_copy_constructible.h'}}
 #include <__type_traits/is_nothrow_default_constructible.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_nothrow_default_constructible.h'}}
@@ -573,6 +580,7 @@ END-SCRIPT
 #include <__type_traits/is_pod.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_pod.h'}}
 #include <__type_traits/is_pointer.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_pointer.h'}}
 #include <__type_traits/is_polymorphic.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_polymorphic.h'}}
+#include <__type_traits/is_primary_template.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_primary_template.h'}}
 #include <__type_traits/is_reference.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_reference.h'}}
 #include <__type_traits/is_reference_wrapper.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_reference_wrapper.h'}}
 #include <__type_traits/is_referenceable.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_referenceable.h'}}
@@ -580,6 +588,7 @@ END-SCRIPT
 #include <__type_traits/is_scalar.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_scalar.h'}}
 #include <__type_traits/is_scoped_enum.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_scoped_enum.h'}}
 #include <__type_traits/is_signed.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_signed.h'}}
+#include <__type_traits/is_signed_integer.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_signed_integer.h'}}
 #include <__type_traits/is_standard_layout.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_standard_layout.h'}}
 #include <__type_traits/is_trivial.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_trivial.h'}}
 #include <__type_traits/is_trivially_assignable.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_trivially_assignable.h'}}
@@ -594,18 +603,28 @@ END-SCRIPT
 #include <__type_traits/is_unbounded_array.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_unbounded_array.h'}}
 #include <__type_traits/is_union.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_union.h'}}
 #include <__type_traits/is_unsigned.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_unsigned.h'}}
+#include <__type_traits/is_unsigned_integer.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_unsigned_integer.h'}}
+#include <__type_traits/is_valid_expansion.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_valid_expansion.h'}}
 #include <__type_traits/is_void.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_void.h'}}
 #include <__type_traits/is_volatile.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_volatile.h'}}
+#include <__type_traits/lazy.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/lazy.h'}}
+#include <__type_traits/make_32_64_or_128_bit.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/make_32_64_or_128_bit.h'}}
+#include <__type_traits/make_signed.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/make_signed.h'}}
+#include <__type_traits/make_unsigned.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/make_unsigned.h'}}
+#include <__type_traits/nat.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/nat.h'}}
 #include <__type_traits/negation.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/negation.h'}}
+#include <__type_traits/promote.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/promote.h'}}
 #include <__type_traits/rank.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/rank.h'}}
 #include <__type_traits/remove_all_extents.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/remove_all_extents.h'}}
 #include <__type_traits/remove_const.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/remove_const.h'}}
 #include <__type_traits/remove_cv.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/remove_cv.h'}}
+#include <__type_traits/remove_cvref.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/remove_cvref.h'}}
 #include <__type_traits/remove_extent.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/remove_extent.h'}}
 #include <__type_traits/remove_pointer.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/remove_pointer.h'}}
 #include <__type_traits/remove_reference.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/remove_reference.h'}}
 #include <__type_traits/remove_volatile.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/remove_volatile.h'}}
 #include <__type_traits/type_identity.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/type_identity.h'}}
+#include <__type_traits/type_list.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/type_list.h'}}
 #include <__type_traits/underlying_type.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/underlying_type.h'}}
 #include <__type_traits/void_t.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/void_t.h'}}
 #include <__utility/as_const.h> // expected-error@*:* {{use of private header from outside its module: '__utility/as_const.h'}}

diff  --git a/libcxx/test/libcxx/utilities/meta/meta_base.pass.cpp b/libcxx/test/libcxx/utilities/meta/meta_base.pass.cpp
index 7357c222e17bc..4696e3f667830 100644
--- a/libcxx/test/libcxx/utilities/meta/meta_base.pass.cpp
+++ b/libcxx/test/libcxx/utilities/meta/meta_base.pass.cpp
@@ -7,11 +7,13 @@
 //===----------------------------------------------------------------------===//
 //
 
+#include "test_macros.h"
+
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#include <__type_traits/is_valid_expansion.h>
 #include <type_traits>
 #include <cassert>
 
-#include "test_macros.h"
-
 struct Bomb;
 template <int N, class T = Bomb >
 struct BOOM {


        


More information about the libcxx-commits mailing list