[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