diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 52611e43968bc..8931a1b35f6d3 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -800,6 +800,7 @@ set(files __type_traits/extent.h __type_traits/has_unique_object_representation.h __type_traits/has_virtual_destructor.h + __type_traits/integer_traits.h __type_traits/integral_constant.h __type_traits/invoke.h __type_traits/is_abstract.h @@ -850,7 +851,6 @@ set(files __type_traits/is_same.h __type_traits/is_scalar.h __type_traits/is_signed.h - __type_traits/is_signed_integer.h __type_traits/is_specialization.h __type_traits/is_standard_layout.h __type_traits/is_swappable.h @@ -864,7 +864,6 @@ 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 diff --git a/libcxx/include/__bit/bit_ceil.h b/libcxx/include/__bit/bit_ceil.h index cfd792dc2e2ad..99881a8538290 100644 --- a/libcxx/include/__bit/bit_ceil.h +++ b/libcxx/include/__bit/bit_ceil.h @@ -11,8 +11,8 @@ #include <__assert> #include <__bit/countl.h> -#include <__concepts/arithmetic.h> #include <__config> +#include <__type_traits/integer_traits.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -41,7 +41,7 @@ template # if _LIBCPP_STD_VER >= 20 -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { return std::__bit_ceil(__t); } diff --git a/libcxx/include/__bit/bit_floor.h b/libcxx/include/__bit/bit_floor.h index 6bcbc53fb4972..799a064130b4b 100644 --- a/libcxx/include/__bit/bit_floor.h +++ b/libcxx/include/__bit/bit_floor.h @@ -10,8 +10,8 @@ #define _LIBCPP___BIT_BIT_FLOOR_H #include <__bit/bit_log2.h> -#include <__concepts/arithmetic.h> #include <__config> +#include <__type_traits/integer_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t); } diff --git a/libcxx/include/__bit/bit_log2.h b/libcxx/include/__bit/bit_log2.h index b22e1ce1f84e6..8077cd91d6fd7 100644 --- a/libcxx/include/__bit/bit_log2.h +++ b/libcxx/include/__bit/bit_log2.h @@ -11,7 +11,7 @@ #include <__bit/countl.h> #include <__config> -#include <__type_traits/is_unsigned_integer.h> +#include <__type_traits/integer_traits.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __bit_log2(_Tp __t) _NOEXCEPT { - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__bit_log2 requires an unsigned integer type"); + static_assert(__is_unsigned_integer_v<_Tp>, "__bit_log2 requires an unsigned integer type"); return numeric_limits<_Tp>::digits - 1 - std::__countl_zero(__t); } diff --git a/libcxx/include/__bit/bit_width.h b/libcxx/include/__bit/bit_width.h index 853e481776f7d..75050acabbe88 100644 --- a/libcxx/include/__bit/bit_width.h +++ b/libcxx/include/__bit/bit_width.h @@ -10,8 +10,8 @@ #define _LIBCPP___BIT_BIT_WIDTH_H #include <__bit/bit_log2.h> -#include <__concepts/arithmetic.h> #include <__config> +#include <__type_traits/integer_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { return __t == 0 ? 0 : std::__bit_log2(__t) + 1; } diff --git a/libcxx/include/__bit/countl.h b/libcxx/include/__bit/countl.h index 9499bf9b458ee..075914020879a 100644 --- a/libcxx/include/__bit/countl.h +++ b/libcxx/include/__bit/countl.h @@ -9,9 +9,8 @@ #ifndef _LIBCPP___BIT_COUNTL_H #define _LIBCPP___BIT_COUNTL_H -#include <__concepts/arithmetic.h> #include <__config> -#include <__type_traits/is_unsigned_integer.h> +#include <__type_traits/integer_traits.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -25,18 +24,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _NOEXCEPT { - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type"); + static_assert(__is_unsigned_integer_v<_Tp>, "__countl_zero requires an unsigned integer type"); return __builtin_clzg(__t, numeric_limits<_Tp>::digits); } #if _LIBCPP_STD_VER >= 20 -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { return std::__countl_zero(__t); } -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; } diff --git a/libcxx/include/__bit/countr.h b/libcxx/include/__bit/countr.h index 1589f57c47385..f6c98695d3d06 100644 --- a/libcxx/include/__bit/countr.h +++ b/libcxx/include/__bit/countr.h @@ -9,9 +9,8 @@ #ifndef _LIBCPP___BIT_COUNTR_H #define _LIBCPP___BIT_COUNTR_H -#include <__concepts/arithmetic.h> #include <__config> -#include <__type_traits/is_unsigned_integer.h> +#include <__type_traits/integer_traits.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -25,18 +24,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD template [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __countr_zero(_Tp __t) _NOEXCEPT { - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countr_zero only works with unsigned types"); + static_assert(__is_unsigned_integer_v<_Tp>, "__countr_zero only works with unsigned types"); return __builtin_ctzg(__t, numeric_limits<_Tp>::digits); } #if _LIBCPP_STD_VER >= 20 -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { return std::__countr_zero(__t); } -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; } diff --git a/libcxx/include/__bit/has_single_bit.h b/libcxx/include/__bit/has_single_bit.h index 52f5853a1bc8a..b43e69323e77b 100644 --- a/libcxx/include/__bit/has_single_bit.h +++ b/libcxx/include/__bit/has_single_bit.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___BIT_HAS_SINGLE_BIT_H #define _LIBCPP___BIT_HAS_SINGLE_BIT_H -#include <__concepts/arithmetic.h> #include <__config> +#include <__type_traits/integer_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -23,7 +23,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { return __t != 0 && (((__t & (__t - 1)) == 0)); } diff --git a/libcxx/include/__bit/popcount.h b/libcxx/include/__bit/popcount.h index 4be0e418e7aa6..8d9ba09938482 100644 --- a/libcxx/include/__bit/popcount.h +++ b/libcxx/include/__bit/popcount.h @@ -9,9 +9,8 @@ #ifndef _LIBCPP___BIT_POPCOUNT_H #define _LIBCPP___BIT_POPCOUNT_H -#include <__concepts/arithmetic.h> #include <__config> -#include <__type_traits/is_unsigned_integer.h> +#include <__type_traits/integer_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -24,13 +23,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD template [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __popcount(_Tp __t) _NOEXCEPT { - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__popcount only works with unsigned types"); + static_assert(__is_unsigned_integer_v<_Tp>, "__popcount only works with unsigned types"); return __builtin_popcountg(__t); } #if _LIBCPP_STD_VER >= 20 -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { return std::__popcount(__t); } diff --git a/libcxx/include/__bit/rotate.h b/libcxx/include/__bit/rotate.h index d79d98de296aa..c6f34bdaf6e63 100644 --- a/libcxx/include/__bit/rotate.h +++ b/libcxx/include/__bit/rotate.h @@ -9,9 +9,8 @@ #ifndef _LIBCPP___BIT_ROTATE_H #define _LIBCPP___BIT_ROTATE_H -#include <__concepts/arithmetic.h> #include <__config> -#include <__type_traits/is_unsigned_integer.h> +#include <__type_traits/integer_traits.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -25,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // the rotr function becomes the ROR instruction. template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __x, int __s) _NOEXCEPT { - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotl requires an unsigned integer type"); + static_assert(__is_unsigned_integer_v<_Tp>, "__rotl requires an unsigned integer type"); const int __n = numeric_limits<_Tp>::digits; int __r = __s % __n; @@ -40,7 +39,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __x, int __s) template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __x, int __s) _NOEXCEPT { - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type"); + static_assert(__is_unsigned_integer_v<_Tp>, "__rotr requires an unsigned integer type"); const int __n = numeric_limits<_Tp>::digits; int __r = __s % __n; @@ -55,12 +54,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __x, int __s) #if _LIBCPP_STD_VER >= 20 -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, int __cnt) noexcept { return std::__rotl(__t, __cnt); } -template <__libcpp_unsigned_integer _Tp> +template <__unsigned_integer _Tp> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, int __cnt) noexcept { return std::__rotr(__t, __cnt); } diff --git a/libcxx/include/__concepts/arithmetic.h b/libcxx/include/__concepts/arithmetic.h index 0c44f117805f3..64c0200783df7 100644 --- a/libcxx/include/__concepts/arithmetic.h +++ b/libcxx/include/__concepts/arithmetic.h @@ -13,8 +13,6 @@ #include <__type_traits/is_floating_point.h> #include <__type_traits/is_integral.h> #include <__type_traits/is_signed.h> -#include <__type_traits/is_signed_integer.h> -#include <__type_traits/is_unsigned_integer.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -38,17 +36,6 @@ concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; template concept floating_point = is_floating_point_v<_Tp>; -// Concept helpers for the internal type traits for the fundamental types. - -template -concept __libcpp_unsigned_integer = __libcpp_is_unsigned_integer<_Tp>::value; - -template -concept __libcpp_signed_integer = __libcpp_is_signed_integer<_Tp>::value; - -template -concept __libcpp_integer = __libcpp_unsigned_integer<_Tp> || __libcpp_signed_integer<_Tp>; - #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__format/format_arg_store.h b/libcxx/include/__format/format_arg_store.h index 87557aa4da7bb..fbb4cad21b232 100644 --- a/libcxx/include/__format/format_arg_store.h +++ b/libcxx/include/__format/format_arg_store.h @@ -14,7 +14,6 @@ # pragma GCC system_header #endif -#include <__concepts/arithmetic.h> #include <__concepts/same_as.h> #include <__config> #include <__cstddef/size_t.h> @@ -22,6 +21,7 @@ #include <__format/format_arg.h> #include <__type_traits/conditional.h> #include <__type_traits/extent.h> +#include <__type_traits/integer_traits.h> #include <__type_traits/remove_const.h> #include #include @@ -65,7 +65,7 @@ consteval __arg_t __determine_arg_t() { # endif // Signed integers -template +template consteval __arg_t __determine_arg_t() { if constexpr (sizeof(_Tp) <= sizeof(int)) return __arg_t::__int; @@ -80,7 +80,7 @@ consteval __arg_t __determine_arg_t() { } // Unsigned integers -template +template consteval __arg_t __determine_arg_t() { if constexpr (sizeof(_Tp) <= sizeof(unsigned)) return __arg_t::__unsigned; diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h index 00454004851d5..99b54badf893c 100644 --- a/libcxx/include/__mdspan/extents.h +++ b/libcxx/include/__mdspan/extents.h @@ -21,11 +21,10 @@ #include <__config> #include <__concepts/arithmetic.h> -#include <__cstddef/byte.h> #include <__type_traits/common_type.h> +#include <__type_traits/integer_traits.h> #include <__type_traits/is_convertible.h> #include <__type_traits/is_nothrow_constructible.h> -#include <__type_traits/is_same.h> #include <__type_traits/make_unsigned.h> #include <__utility/integer_sequence.h> #include <__utility/unreachable.h> @@ -283,7 +282,8 @@ class extents { using size_type = make_unsigned_t; using rank_type = size_t; - static_assert(__libcpp_integer, "extents::index_type must be a signed or unsigned integer type"); + static_assert(__signed_or_unsigned_integer, + "extents::index_type must be a signed or unsigned integer type"); static_assert(((__mdspan_detail::__is_representable_as(_Extents) || (_Extents == dynamic_extent)) && ...), "extents ctor: arguments must be representable as index_type and nonnegative"); diff --git a/libcxx/include/__numeric/saturation_arithmetic.h b/libcxx/include/__numeric/saturation_arithmetic.h index 4110a8cb142a5..9bd3af12c9572 100644 --- a/libcxx/include/__numeric/saturation_arithmetic.h +++ b/libcxx/include/__numeric/saturation_arithmetic.h @@ -11,9 +11,9 @@ #define _LIBCPP___NUMERIC_SATURATION_ARITHMETIC_H #include <__assert> -#include <__concepts/arithmetic.h> #include <__config> #include <__memory/addressof.h> +#include <__type_traits/integer_traits.h> #include <__utility/cmp.h> #include @@ -28,12 +28,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template <__libcpp_integer _Tp> +template <__signed_or_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr _Tp __add_sat(_Tp __x, _Tp __y) noexcept { if (_Tp __sum; !__builtin_add_overflow(__x, __y, std::addressof(__sum))) return __sum; // Handle overflow - if constexpr (__libcpp_unsigned_integer<_Tp>) { + if constexpr (__unsigned_integer<_Tp>) { return std::numeric_limits<_Tp>::max(); } else { // Signed addition overflow @@ -46,12 +46,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp __add_sat(_Tp __x, _Tp __y) noexcept { } } -template <__libcpp_integer _Tp> +template <__signed_or_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr _Tp __sub_sat(_Tp __x, _Tp __y) noexcept { if (_Tp __sub; !__builtin_sub_overflow(__x, __y, std::addressof(__sub))) return __sub; // Handle overflow - if constexpr (__libcpp_unsigned_integer<_Tp>) { + if constexpr (__unsigned_integer<_Tp>) { // Overflows if (x < y) return std::numeric_limits<_Tp>::min(); } else { @@ -65,12 +65,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp __sub_sat(_Tp __x, _Tp __y) noexcept { } } -template <__libcpp_integer _Tp> +template <__signed_or_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr _Tp __mul_sat(_Tp __x, _Tp __y) noexcept { if (_Tp __mul; !__builtin_mul_overflow(__x, __y, std::addressof(__mul))) return __mul; // Handle overflow - if constexpr (__libcpp_unsigned_integer<_Tp>) { + if constexpr (__unsigned_integer<_Tp>) { return std::numeric_limits<_Tp>::max(); } else { // Signed multiplication overflow @@ -81,10 +81,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp __mul_sat(_Tp __x, _Tp __y) noexcept { } } -template <__libcpp_integer _Tp> +template <__signed_or_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr _Tp __div_sat(_Tp __x, _Tp __y) noexcept { _LIBCPP_ASSERT_UNCATEGORIZED(__y != 0, "Division by 0 is undefined"); - if constexpr (__libcpp_unsigned_integer<_Tp>) { + if constexpr (__unsigned_integer<_Tp>) { return __x / __y; } else { // Handle signed division overflow @@ -94,7 +94,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp __div_sat(_Tp __x, _Tp __y) noexcept { } } -template <__libcpp_integer _Rp, __libcpp_integer _Tp> +template <__signed_or_unsigned_integer _Rp, __signed_or_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr _Rp __saturate_cast(_Tp __x) noexcept { // Saturation is impossible edge case when ((min _Rp) < (min _Tp) && (max _Rp) > (max _Tp)) and it is expected to be // optimized out by the compiler. @@ -112,27 +112,27 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Rp __saturate_cast(_Tp __x) noexcept { #if _LIBCPP_STD_VER >= 26 -template <__libcpp_integer _Tp> +template <__signed_or_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr _Tp add_sat(_Tp __x, _Tp __y) noexcept { return std::__add_sat(__x, __y); } -template <__libcpp_integer _Tp> +template <__signed_or_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr _Tp sub_sat(_Tp __x, _Tp __y) noexcept { return std::__sub_sat(__x, __y); } -template <__libcpp_integer _Tp> +template <__signed_or_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr _Tp mul_sat(_Tp __x, _Tp __y) noexcept { return std::__mul_sat(__x, __y); } -template <__libcpp_integer _Tp> +template <__signed_or_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr _Tp div_sat(_Tp __x, _Tp __y) noexcept { return std::__div_sat(__x, __y); } -template <__libcpp_integer _Rp, __libcpp_integer _Tp> +template <__signed_or_unsigned_integer _Rp, __signed_or_unsigned_integer _Tp> _LIBCPP_HIDE_FROM_ABI constexpr _Rp saturate_cast(_Tp __x) noexcept { return std::__saturate_cast<_Rp>(__x); } diff --git a/libcxx/include/__type_traits/integer_traits.h b/libcxx/include/__type_traits/integer_traits.h new file mode 100644 index 0000000000000..fad502c44e301 --- /dev/null +++ b/libcxx/include/__type_traits/integer_traits.h @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// 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_INTEGER_TRAITS_H +#define _LIBCPP___TYPE_TRAITS_INTEGER_TRAITS_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// This trait is to determine whether a type is a /signed integer type/ +// See [basic.fundamental]/p1 +template +inline const bool __is_signed_integer_v = false; +template <> +inline const bool __is_signed_integer_v = true; +template <> +inline const bool __is_signed_integer_v = true; +template <> +inline const bool __is_signed_integer_v = true; +template <> +inline const bool __is_signed_integer_v = true; +template <> +inline const bool __is_signed_integer_v = true; +#if _LIBCPP_HAS_INT128 +template <> +inline const bool __is_signed_integer_v<__int128_t> = true; +#endif + +// This trait is to determine whether a type is an /unsigned integer type/ +// See [basic.fundamental]/p2 +template +inline const bool __is_unsigned_integer_v = false; +template <> +inline const bool __is_unsigned_integer_v = true; +template <> +inline const bool __is_unsigned_integer_v = true; +template <> +inline const bool __is_unsigned_integer_v = true; +template <> +inline const bool __is_unsigned_integer_v = true; +template <> +inline const bool __is_unsigned_integer_v = true; +#if _LIBCPP_HAS_INT128 +template <> +inline const bool __is_unsigned_integer_v<__uint128_t> = true; +#endif + +#if _LIBCPP_STD_VER >= 20 +template +concept __signed_integer = __is_signed_integer_v<_Tp>; + +template +concept __unsigned_integer = __is_unsigned_integer_v<_Tp>; + +// This isn't called __integer, because an integer type according to [basic.fundamental]/p11 is the same as an integral +// type. An integral type is _not_ the same set of types as signed and unsigned integer types combined. +template +concept __signed_or_unsigned_integer = __signed_integer<_Tp> || __unsigned_integer<_Tp>; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_INTEGER_TRAITS_H diff --git a/libcxx/include/__type_traits/is_signed_integer.h b/libcxx/include/__type_traits/is_signed_integer.h deleted file mode 100644 index 62943902a1834..0000000000000 --- a/libcxx/include/__type_traits/is_signed_integer.h +++ /dev/null @@ -1,35 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// clang-format off -template struct __libcpp_is_signed_integer : false_type {}; -template <> struct __libcpp_is_signed_integer : true_type {}; -template <> struct __libcpp_is_signed_integer : true_type {}; -template <> struct __libcpp_is_signed_integer : true_type {}; -template <> struct __libcpp_is_signed_integer : true_type {}; -template <> struct __libcpp_is_signed_integer : true_type {}; -#if _LIBCPP_HAS_INT128 -template <> struct __libcpp_is_signed_integer<__int128_t> : true_type {}; -#endif -// clang-format on - -_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 deleted file mode 100644 index 74414a831e79a..0000000000000 --- a/libcxx/include/__type_traits/is_unsigned_integer.h +++ /dev/null @@ -1,35 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// clang-format off -template struct __libcpp_is_unsigned_integer : false_type {}; -template <> struct __libcpp_is_unsigned_integer : true_type {}; -template <> struct __libcpp_is_unsigned_integer : true_type {}; -template <> struct __libcpp_is_unsigned_integer : true_type {}; -template <> struct __libcpp_is_unsigned_integer : true_type {}; -template <> struct __libcpp_is_unsigned_integer : true_type {}; -#if _LIBCPP_HAS_INT128 -template <> struct __libcpp_is_unsigned_integer<__uint128_t> : true_type {}; -#endif -// clang-format on - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___TYPE_TRAITS_IS_UNSIGNED_INTEGER_H diff --git a/libcxx/include/__utility/cmp.h b/libcxx/include/__utility/cmp.h index b7c1ed614dfcb..14dc0c154c040 100644 --- a/libcxx/include/__utility/cmp.h +++ b/libcxx/include/__utility/cmp.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___UTILITY_CMP_H #define _LIBCPP___UTILITY_CMP_H -#include <__concepts/arithmetic.h> #include <__config> +#include <__type_traits/integer_traits.h> #include <__type_traits/is_signed.h> #include <__type_traits/make_unsigned.h> #include @@ -26,7 +26,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template <__libcpp_integer _Tp, __libcpp_integer _Up> +template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept { if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) return __t == __u; @@ -36,12 +36,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept { return __u < 0 ? false : __t == make_unsigned_t<_Up>(__u); } -template <__libcpp_integer _Tp, __libcpp_integer _Up> +template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept { return !std::cmp_equal(__t, __u); } -template <__libcpp_integer _Tp, __libcpp_integer _Up> +template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept { if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) return __t < __u; @@ -51,22 +51,22 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept { return __u < 0 ? false : __t < make_unsigned_t<_Up>(__u); } -template <__libcpp_integer _Tp, __libcpp_integer _Up> +template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept { return std::cmp_less(__u, __t); } -template <__libcpp_integer _Tp, __libcpp_integer _Up> +template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept { return !std::cmp_greater(__t, __u); } -template <__libcpp_integer _Tp, __libcpp_integer _Up> +template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept { return !std::cmp_less(__t, __u); } -template <__libcpp_integer _Tp, __libcpp_integer _Up> +template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up> _LIBCPP_HIDE_FROM_ABI constexpr bool in_range(_Up __u) noexcept { return std::cmp_less_equal(__u, numeric_limits<_Tp>::max()) && std::cmp_greater_equal(__u, numeric_limits<_Tp>::min()); diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 7f625cefed1c2..f5fd970934e9b 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -94,6 +94,7 @@ module std_core [system] { module extent { header "__type_traits/extent.h" } module has_unique_object_representation { header "__type_traits/has_unique_object_representation.h" } module has_virtual_destructor { header "__type_traits/has_virtual_destructor.h" } + module integer_traits { header "__type_traits/integer_traits.h" } module integral_constant { header "__type_traits/integral_constant.h" } module invoke { header "__type_traits/invoke.h" } module is_abstract { @@ -284,10 +285,6 @@ module std_core [system] { header "__type_traits/is_scalar.h" export std_core.type_traits.integral_constant } - module is_signed_integer { - header "__type_traits/is_signed_integer.h" - export std_core.type_traits.integral_constant - } module is_signed { header "__type_traits/is_signed.h" export std_core.type_traits.integral_constant @@ -340,10 +337,6 @@ module std_core [system] { header "__type_traits/is_union.h" export std_core.type_traits.integral_constant } - module is_unsigned_integer { - header "__type_traits/is_unsigned_integer.h" - export std_core.type_traits.integral_constant - } module is_unsigned { header "__type_traits/is_unsigned.h" export std_core.type_traits.integral_constant diff --git a/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_integer.compile.pass.cpp b/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_integer.compile.pass.cpp index 563580b687955..4958a258137a1 100644 --- a/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_integer.compile.pass.cpp +++ b/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_integer.compile.pass.cpp @@ -11,9 +11,9 @@ // Concept helpers for the internal type traits for the fundamental types. // template -// concept __libcpp_integer; +// concept __signed_or_unsigned_integer; -#include +#include <__type_traits/integer_traits.h> #include "test_macros.h" @@ -24,40 +24,40 @@ enum SomeEnum {}; enum class SomeScopedEnum {}; // Unsigned -static_assert(std::__libcpp_integer); -static_assert(std::__libcpp_integer); -static_assert(std::__libcpp_integer); -static_assert(std::__libcpp_integer); -static_assert(std::__libcpp_integer); -static_assert(std::__libcpp_integer); +static_assert(std::__signed_or_unsigned_integer); +static_assert(std::__signed_or_unsigned_integer); +static_assert(std::__signed_or_unsigned_integer); +static_assert(std::__signed_or_unsigned_integer); +static_assert(std::__signed_or_unsigned_integer); +static_assert(std::__signed_or_unsigned_integer); #if _LIBCPP_HAS_INT128 -static_assert(std::__libcpp_integer<__uint128_t>); +static_assert(std::__signed_or_unsigned_integer<__uint128_t>); #endif // Signed -static_assert(std::__libcpp_integer); -static_assert(std::__libcpp_integer); -static_assert(std::__libcpp_integer); -static_assert(std::__libcpp_integer); -static_assert(std::__libcpp_integer); -static_assert(std::__libcpp_integer); +static_assert(std::__signed_or_unsigned_integer); +static_assert(std::__signed_or_unsigned_integer); +static_assert(std::__signed_or_unsigned_integer); +static_assert(std::__signed_or_unsigned_integer); +static_assert(std::__signed_or_unsigned_integer); +static_assert(std::__signed_or_unsigned_integer); #if _LIBCPP_HAS_INT128 -static_assert(std::__libcpp_integer<__int128_t>); +static_assert(std::__signed_or_unsigned_integer<__int128_t>); #endif // Non-integer -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); #ifndef TEST_HAS_NO_WIDE_CHARACTERS -static_assert(!std::__libcpp_integer); +static_assert(!std::__signed_or_unsigned_integer); #endif -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); -static_assert(!std::__libcpp_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); +static_assert(!std::__signed_or_unsigned_integer); diff --git a/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_signed_integer.compile.pass.cpp b/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_signed_integer.compile.pass.cpp index d1e21ee96b073..3fa342685770c 100644 --- a/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_signed_integer.compile.pass.cpp +++ b/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_signed_integer.compile.pass.cpp @@ -11,9 +11,9 @@ // Concept helpers for the internal type traits for the fundamental types. // template -// concept __libcpp_signed_integer; +// concept __signed_integer; -#include +#include <__type_traits/integer_traits.h> #include "test_macros.h" @@ -24,40 +24,40 @@ enum SomeEnum {}; enum class SomeScopedEnum {}; // Unsigned -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); #if _LIBCPP_HAS_INT128 -static_assert(!std::__libcpp_signed_integer<__uint128_t>); +static_assert(!std::__signed_integer<__uint128_t>); #endif // Signed -static_assert(std::__libcpp_signed_integer); -static_assert(std::__libcpp_signed_integer); -static_assert(std::__libcpp_signed_integer); -static_assert(std::__libcpp_signed_integer); -static_assert(std::__libcpp_signed_integer); -static_assert(std::__libcpp_signed_integer); +static_assert(std::__signed_integer); +static_assert(std::__signed_integer); +static_assert(std::__signed_integer); +static_assert(std::__signed_integer); +static_assert(std::__signed_integer); +static_assert(std::__signed_integer); #if _LIBCPP_HAS_INT128 -static_assert(std::__libcpp_signed_integer<__int128_t>); +static_assert(std::__signed_integer<__int128_t>); #endif // Non-integer -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); #ifndef TEST_HAS_NO_WIDE_CHARACTERS -static_assert(!std::__libcpp_signed_integer); +static_assert(!std::__signed_integer); #endif -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); -static_assert(!std::__libcpp_signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); +static_assert(!std::__signed_integer); diff --git a/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_unsigned_integer.compile.pass.cpp b/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_unsigned_integer.compile.pass.cpp index c671f03cbfce4..ff60f32319171 100644 --- a/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_unsigned_integer.compile.pass.cpp +++ b/libcxx/test/libcxx/concepts/concepts.arithmetic/__libcpp_unsigned_integer.compile.pass.cpp @@ -11,9 +11,9 @@ // Concept helpers for the internal type traits for the fundamental types. // template -// concept __libcpp_unsigned_integer; +// concept __unsigned_integer; -#include +#include <__type_traits/integer_traits.h> #include "test_macros.h" @@ -24,40 +24,40 @@ enum SomeEnum {}; enum class SomeScopedEnum {}; // Unsigned -static_assert(std::__libcpp_unsigned_integer); -static_assert(std::__libcpp_unsigned_integer); -static_assert(std::__libcpp_unsigned_integer); -static_assert(std::__libcpp_unsigned_integer); -static_assert(std::__libcpp_unsigned_integer); -static_assert(std::__libcpp_unsigned_integer); +static_assert(std::__unsigned_integer); +static_assert(std::__unsigned_integer); +static_assert(std::__unsigned_integer); +static_assert(std::__unsigned_integer); +static_assert(std::__unsigned_integer); +static_assert(std::__unsigned_integer); #if _LIBCPP_HAS_INT128 -static_assert(std::__libcpp_unsigned_integer<__uint128_t>); +static_assert(std::__unsigned_integer<__uint128_t>); #endif // Signed -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); #if _LIBCPP_HAS_INT128 -static_assert(!std::__libcpp_unsigned_integer<__int128_t>); +static_assert(!std::__unsigned_integer<__int128_t>); #endif // Non-integer -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); #ifndef TEST_HAS_NO_WIDE_CHARACTERS -static_assert(!std::__libcpp_unsigned_integer); +static_assert(!std::__unsigned_integer); #endif -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); -static_assert(!std::__libcpp_unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer); +static_assert(!std::__unsigned_integer);