diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -505,10 +505,16 @@ __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 @@ __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 @@ __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 @@ __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 @@ __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 --- 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 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__format/formatter_integer.h b/libcxx/include/__format/formatter_integer.h --- 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 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__functional/invoke.h b/libcxx/include/__functional/invoke.h --- 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 @@ __any(...); }; -struct __nat -{ -#ifndef _LIBCPP_CXX03_LANG - __nat() = delete; - __nat(const __nat&) = delete; - __nat& operator=(const __nat&) = delete; - ~__nat() = delete; -#endif -}; - template struct __member_pointer_traits_imp { diff --git a/libcxx/include/__iterator/incrementable_traits.h b/libcxx/include/__iterator/incrementable_traits.h --- 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 #include diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h --- 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 #include diff --git a/libcxx/include/__type_traits/aligned_storage.h b/libcxx/include/__type_traits/aligned_storage.h new file mode 100644 --- /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 + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +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, + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type<__struct_double>, + __type_list<__align_type<__struct_double4>, + __type_list<__align_type, + __nat + > > > > > > > > > > __all_types; + +template +struct _ALIGNAS(_Align) __fallback_overaligned {}; + +template struct __find_pod; + +template +struct __find_pod<__type_list<_Hp, __nat>, _Align> +{ + typedef typename conditional< + _Align == _Hp::value, + typename _Hp::type, + __fallback_overaligned<_Align> + >::type type; +}; + +template +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 struct __find_max_align; + +template +struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant {}; + +template +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 +struct __find_max_align<__type_list<_Hp, _Tp>, _Len> + : public integral_constant::value>::value> {}; + +template ::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 ::value> + using aligned_storage_t = typename aligned_storage<_Len, _Align>::type; +#endif + +#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \ +template \ +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 --- /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 + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __static_max; + +template +struct __static_max<_I0> +{ + static const size_t value = _I0; +}; + +template +struct __static_max<_I0, _I1, _In...> +{ + static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value : + __static_max<_I1, _In...>::value; +}; + +template +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 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 --- /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 +using __cond_res = + decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()()); + +// Let `XREF(A)` denote a unary alias template `T` such that `T` 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::template __apply`] +template +struct __xref { + template + using __apply = __copy_cvref_t<_Tp, _Up>; +}; + +// Given types A and B, let X be remove_reference_t, let Y be remove_reference_t, +// and let COMMON-REF(A, B) be: +template, class _Yp = remove_reference_t<_Bp>> +struct __common_ref; + +template +using __common_ref_t = typename __common_ref<_Xp, _Yp>::__type; + +template +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 +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&&. ... +template +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 && is_convertible_v is true, then COMMON-REF(A, B) is C. +template +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 +using __common_ref_D = __common_ref_t; + +// ... If A is an rvalue reference and B is an lvalue reference and D is well-formed and +// is_convertible_v is true, then COMMON-REF(A, B) is D. +template +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 +struct __common_ref<_Ap&, _Bp&&, _Xp, _Yp> : __common_ref<_Bp&&, _Ap&> {}; + +// Otherwise, COMMON-REF(A, B) is ill-formed. +template +struct __common_ref {}; + +// Note C: For the common_reference trait applied to a parameter pack [...] + +template +struct common_reference; + +template +using common_reference_t = typename common_reference<_Types...>::type; + +// bullet 1 - sizeof...(T) == 0 +template<> +struct common_reference<> {}; + +// bullet 2 - sizeof...(T) == 1 +template +struct common_reference<_Tp> +{ + using type = _Tp; +}; + +// bullet 3 - sizeof...(T) == 2 +template struct __common_reference_sub_bullet3; +template struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {}; +template 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 struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {}; + +template +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, XREF(T1), XREF(T2)>::type +// is well-formed, then the member typedef `type` denotes that type. +template class, template class> struct basic_common_reference {}; + +template +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 +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 +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 is well-formed, +// then the member typedef `type` denotes that type. +// - Otherwise, there shall be no member `type`. +template 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`. +template +requires requires { typename common_reference_t<_Tp, _Up>; } +struct common_reference<_Tp, _Up, _Vp, _Rest...> + : common_reference, _Vp, _Rest...> +{}; + +// bullet 5 - Otherwise, there shall be no member `type`. +template 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 --- /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 +using __cond_type = decltype(false ? declval<_Tp>() : declval<_Up>()); + +template +struct __common_type3 {}; + +// sub-bullet 4 - "if COND_RES(CREF(D1), CREF(D2)) denotes a type..." +template +struct __common_type3<_Tp, _Up, void_t<__cond_type>> +{ + using type = remove_cvref_t<__cond_type>; +}; + +template +struct __common_type2_imp : __common_type3<_Tp, _Up> {}; +#else +template +struct __common_type2_imp {}; +#endif + +// sub-bullet 3 - "if decay_t() : declval())> ..." +template +struct __common_type2_imp<_Tp, _Up, + typename __void_t() : declval<_Up>() + )>::type> +{ + typedef _LIBCPP_NODEBUG typename decay() : declval<_Up>() + )>::type type; +}; + +template +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 +struct __common_types; +template +struct _LIBCPP_TEMPLATE_VIS common_type; +#else +# define _LIBCPP_OPTIONAL_PACK(...) +struct __no_arg; +template +struct __common_types; +template +struct common_type { + static_assert(sizeof(_Unused) == 0, + "common_type accepts at most 3 arguments in C++03"); +}; +#endif // _LIBCPP_CXX03_LANG + +template +struct __common_type_impl< + __common_types<_Tp, _Up>, + typename __void_t::type>::type> +{ + typedef typename common_type<_Tp, _Up>::type type; +}; + +template +struct __common_type_impl< + __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)>, + typename __void_t::type>::type> + : __common_type_impl<__common_types::type, + _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > { +}; + +// bullet 1 - sizeof...(Tp) == 0 + +template <> +struct _LIBCPP_TEMPLATE_VIS common_type<> {}; + +// bullet 2 - sizeof...(Tp) == 1 + +template +struct _LIBCPP_TEMPLATE_VIS common_type<_Tp> + : public common_type<_Tp, _Tp> {}; + +// bullet 3 - sizeof...(Tp) == 2 + +// sub-bullet 1 - "If is_same_v is false or ..." +template +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::type, typename decay<_Up>::type> + >::type +{}; + +// bullet 4 - sizeof...(Tp) > 2 + +template +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 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 --- /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 +struct __copy_cv +{ + using type = _To; +}; + +template +struct __copy_cv +{ + using type = typename add_const<_To>::type; +}; + +template +struct __copy_cv +{ + using type = typename add_volatile<_To>::type; +}; + +template +struct __copy_cv +{ + using type = typename add_cv<_To>::type; +}; + +template +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 --- /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 +struct __copy_cvref +{ + using type = __copy_cv_t<_From, _To>; +}; + +template +struct __copy_cvref<_From&, _To> +{ + using type = typename add_lvalue_reference<__copy_cv_t<_From, _To> >::type; +}; + +template +struct __copy_cvref<_From&&, _To> +{ + using type = typename add_rvalue_reference<__copy_cv_t<_From, _To> >::type; +}; + +template +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 --- /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 +static void __test_noexcept(_Tp) noexcept; + +template +static bool_constant(declval<_Fm>()))> +__is_nothrow_convertible_test(); + +template +struct __is_nothrow_convertible_helper: decltype(__is_nothrow_convertible_test<_Fm, _To>()) +{ }; + +template +struct is_nothrow_convertible : _Or< + _And, is_void<_Fm>>, + _Lazy<_And, is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To>> +>::type { }; + +template +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 --- /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 +using __test_for_primary_template = __enable_if_t< + _IsSame<_Tp, typename _Tp::__primary_template>::value + >; +template +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 --- /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 struct __libcpp_is_signed_integer : public false_type {}; +template <> struct __libcpp_is_signed_integer : public true_type {}; +template <> struct __libcpp_is_signed_integer : public true_type {}; +template <> struct __libcpp_is_signed_integer : public true_type {}; +template <> struct __libcpp_is_signed_integer : public true_type {}; +template <> struct __libcpp_is_signed_integer : 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 --- /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 struct __libcpp_is_unsigned_integer : public false_type {}; +template <> struct __libcpp_is_unsigned_integer : public true_type {}; +template <> struct __libcpp_is_unsigned_integer : public true_type {}; +template <> struct __libcpp_is_unsigned_integer : public true_type {}; +template <> struct __libcpp_is_unsigned_integer : public true_type {}; +template <> struct __libcpp_is_unsigned_integer : 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 --- /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