From eb04805be4029716e76532babc0fa9ecb18de96e Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 7 Jul 2020 23:26:38 +0100 Subject: [PATCH] libstdc++: Replace __int_limits with __numeric_traits_integer I recently added std::__detail::__int_limits as a lightweight alternative to std::numeric_limits, forgetting that the values it provides (digits, min and max) are already provided by __gnu_cxx::__numeric_traits. This change adds __int_traits as an alias for __numeric_traits_integer. This avoids instantiating __numeric_traits to decide whether to use __numeric_traits_integer or __numeric_traits_floating. Then all uses of __int_limits can be replaced with __int_traits, and __int_limits can be removed. libstdc++-v3/ChangeLog: * include/Makefile.am: Remove bits/int_limits.h. * include/Makefile.in: Regenerate. * include/bits/int_limits.h: Removed. * include/bits/parse_numbers.h (_Select_int_base): Replace __int_limits with __int_traits. * include/bits/range_access.h (_SSize::operator()): Likewise. * include/ext/numeric_traits.h (__numeric_traits_integer): Add static assertion. (__int_traits): New alias template. * include/std/bit (__rotl, __rotr, __countl_zero, __countl_one) (__countr_zero, __countr_one, __popcount, __bit_ceil) (__bit_floor, __bit_width) Replace __int_limits with __int_traits. * include/std/charconv (__to_chars_8, __from_chars_binary) (__from_chars_alpha_to_num, from_chars): Likewise. * include/std/memory_resource (polymorphic_allocator::allocate) (polymorphic_allocator::allocate_object): Likewise. * include/std/string_view (basic_string_view::_S_compare): Likewise. * include/std/utility (cmp_equal, cmp_less, in_range): Likewise. --- libstdc++-v3/include/Makefile.am | 1 - libstdc++-v3/include/Makefile.in | 1 - libstdc++-v3/include/bits/int_limits.h | 74 ----------------------- libstdc++-v3/include/bits/parse_numbers.h | 4 +- libstdc++-v3/include/bits/range_access.h | 8 +-- libstdc++-v3/include/ext/numeric_traits.h | 10 +++ libstdc++-v3/include/std/bit | 60 +++++++++--------- libstdc++-v3/include/std/charconv | 14 ++--- libstdc++-v3/include/std/memory_resource | 6 +- libstdc++-v3/include/std/string_view | 10 +-- libstdc++-v3/include/std/utility | 12 ++-- 11 files changed, 67 insertions(+), 133 deletions(-) delete mode 100644 libstdc++-v3/include/bits/int_limits.h diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 80aeb3f8959..e131ce04f8c 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -129,7 +129,6 @@ bits_headers = \ ${bits_srcdir}/hashtable.h \ ${bits_srcdir}/hashtable_policy.h \ ${bits_srcdir}/indirect_array.h \ - ${bits_srcdir}/int_limits.h \ ${bits_srcdir}/invoke.h \ ${bits_srcdir}/ios_base.h \ ${bits_srcdir}/istream.tcc \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 269645e14e1..c0b71e13a32 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -475,7 +475,6 @@ bits_headers = \ ${bits_srcdir}/hashtable.h \ ${bits_srcdir}/hashtable_policy.h \ ${bits_srcdir}/indirect_array.h \ - ${bits_srcdir}/int_limits.h \ ${bits_srcdir}/invoke.h \ ${bits_srcdir}/ios_base.h \ ${bits_srcdir}/istream.tcc \ diff --git a/libstdc++-v3/include/bits/int_limits.h b/libstdc++-v3/include/bits/int_limits.h deleted file mode 100644 index 7ae34377331..00000000000 --- a/libstdc++-v3/include/bits/int_limits.h +++ /dev/null @@ -1,74 +0,0 @@ -// Minimal replacement for numeric_limits of integers. -*- C++ -*- - -// Copyright (C) 2020 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 3, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// Under Section 7 of GPL version 3, you are granted additional -// permissions described in the GCC Runtime Library Exception, version -// 3.1, as published by the Free Software Foundation. - -// You should have received a copy of the GNU General Public License and -// a copy of the GCC Runtime Library Exception along with this program; -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -// . - -/** @file bits/int_limits.h - * This is an internal header file, included by other library headers. - * Do not attempt to use it directly. @headername{limits} - */ - -#ifndef _GLIBCXX_INT_LIMITS_H -#define _GLIBCXX_INT_LIMITS_H 1 - -#pragma GCC system_header - -#if __cplusplus >= 201103L -#include - -namespace std _GLIBCXX_VISIBILITY(default) -{ -_GLIBCXX_BEGIN_NAMESPACE_VERSION -namespace __detail -{ - // This template is used for arbitrary signed and unsigned integer types - // (by headers and ) and for specific integer types - // (by and ) but also for char (). - // For simplicity's sake, all integral types except bool are supported. - - // Lightweight alternative to numeric_limits. - template::value> - struct __int_limits - { - static_assert(is_integral<_Tp>::value, "unsupported specialization"); - using _Up = typename make_unsigned<_Tp>::type; - static constexpr int digits = sizeof(_Tp) * __CHAR_BIT__ - 1; - static constexpr _Tp min() noexcept { return _Tp(_Up(1) << digits); } - static constexpr _Tp max() noexcept { return _Tp(_Up(~_Up(0)) >> 1); } - }; - - // Lightweight alternative to numeric_limits. - template - struct __int_limits<_Tp, false> - { - static_assert(is_integral<_Tp>::value, "unsupported specialization"); - static constexpr int digits = sizeof(_Tp) * __CHAR_BIT__; - static constexpr _Tp min() noexcept { return 0; } - static constexpr _Tp max() noexcept { return _Tp(-1); } - }; - - template<> struct __int_limits; // not defined -} -_GLIBCXX_END_NAMESPACE_VERSION -} // namespace -#endif // C++11 -#endif // _GLIBCXX_INT_LIMITS_H diff --git a/libstdc++-v3/include/bits/parse_numbers.h b/libstdc++-v3/include/bits/parse_numbers.h index 6a75d002774..5e80907af09 100644 --- a/libstdc++-v3/include/bits/parse_numbers.h +++ b/libstdc++-v3/include/bits/parse_numbers.h @@ -36,7 +36,7 @@ #if __cplusplus >= 201402L -#include +#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -265,7 +265,7 @@ namespace __select_int template struct _Select_int_base<_Val, _IntType, _Ints...> - : conditional_t<(_Val <= __detail::__int_limits<_IntType>::max()), + : conditional_t<(_Val <= __gnu_cxx::__int_traits<_IntType>::__max), integral_constant<_IntType, _Val>, _Select_int_base<_Val, _Ints...>> { }; diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h index 82d9e2180c5..3919183c5b4 100644 --- a/libstdc++-v3/include/bits/range_access.h +++ b/libstdc++-v3/include/bits/range_access.h @@ -35,7 +35,7 @@ #if __cplusplus >= 201103L #include #include -#include +#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -727,12 +727,12 @@ namespace ranges { using __iter_type = decltype(_Begin{}(std::forward<_Tp>(__e))); using __diff_type = iter_difference_t<__iter_type>; - using std::__detail::__int_limits; + using __gnu_cxx::__int_traits; auto __size = _Size{}(std::forward<_Tp>(__e)); if constexpr (integral<__diff_type>) { - if constexpr (__int_limits<__diff_type>::digits - < __int_limits::digits) + if constexpr (__int_traits<__diff_type>::__digits + < __int_traits::__digits) return static_cast(__size); } return static_cast<__diff_type>(__size); diff --git a/libstdc++-v3/include/ext/numeric_traits.h b/libstdc++-v3/include/ext/numeric_traits.h index 4c74d7ea092..69f286d7be7 100644 --- a/libstdc++-v3/include/ext/numeric_traits.h +++ b/libstdc++-v3/include/ext/numeric_traits.h @@ -54,6 +54,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct __numeric_traits_integer { +#if __cplusplus >= 201103L + static_assert(std::__is_integer<_Value>::__value, + "invalid specialization"); +#endif + // Only integers for initialization of member constant. static const _Value __min = __glibcxx_min(_Value); static const _Value __max = __glibcxx_max(_Value); @@ -76,6 +81,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template const int __numeric_traits_integer<_Value>::__digits; +#if __cplusplus >= 201103L + template + using __int_traits = __numeric_traits_integer<_Tp>; +#endif + #undef __glibcxx_signed #undef __glibcxx_digits #undef __glibcxx_min diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit index 69e955458f3..f4344820d52 100644 --- a/libstdc++-v3/include/std/bit +++ b/libstdc++-v3/include/std/bit @@ -34,7 +34,7 @@ #if __cplusplus >= 201402L #include -#include +#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -55,7 +55,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tp __rotl(_Tp __x, int __s) noexcept { - constexpr auto _Nd = __detail::__int_limits<_Tp>::digits; + constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits; const int __r = __s % _Nd; if (__r == 0) return __x; @@ -69,7 +69,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tp __rotr(_Tp __x, int __s) noexcept { - constexpr auto _Nd = __detail::__int_limits<_Tp>::digits; + constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits; const int __r = __s % _Nd; if (__r == 0) return __x; @@ -83,15 +83,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr int __countl_zero(_Tp __x) noexcept { - using std::__detail::__int_limits; - constexpr auto _Nd = __int_limits<_Tp>::digits; + using __gnu_cxx::__int_traits; + constexpr auto _Nd = __int_traits<_Tp>::__digits; if (__x == 0) return _Nd; - constexpr auto _Nd_ull = __int_limits::digits; - constexpr auto _Nd_ul = __int_limits::digits; - constexpr auto _Nd_u = __int_limits::digits; + constexpr auto _Nd_ull = __int_traits::__digits; + constexpr auto _Nd_ul = __int_traits::__digits; + constexpr auto _Nd_u = __int_traits::__digits; if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u) { @@ -119,7 +119,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr int __diff = (2 * _Nd_ull) - _Nd; return __builtin_clzll(__high) - __diff; } - constexpr auto __max_ull = __int_limits::max(); + constexpr auto __max_ull = __int_traits::__max; unsigned long long __low = __x & __max_ull; return (_Nd - _Nd_ull) + __builtin_clzll(__low); } @@ -129,8 +129,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr int __countl_one(_Tp __x) noexcept { - if (__x == __detail::__int_limits<_Tp>::max()) - return __detail::__int_limits<_Tp>::digits; + if (__x == __gnu_cxx::__int_traits<_Tp>::__max) + return __gnu_cxx::__int_traits<_Tp>::__digits; return std::__countl_zero<_Tp>((_Tp)~__x); } @@ -138,15 +138,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr int __countr_zero(_Tp __x) noexcept { - using std::__detail::__int_limits; - constexpr auto _Nd = __int_limits<_Tp>::digits; + using __gnu_cxx::__int_traits; + constexpr auto _Nd = __int_traits<_Tp>::__digits; if (__x == 0) return _Nd; - constexpr auto _Nd_ull = __int_limits::digits; - constexpr auto _Nd_ul = __int_limits::digits; - constexpr auto _Nd_u = __int_limits::digits; + constexpr auto _Nd_ull = __int_traits::__digits; + constexpr auto _Nd_ul = __int_traits::__digits; + constexpr auto _Nd_u = __int_traits::__digits; if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u) return __builtin_ctz(__x); @@ -159,7 +159,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(_Nd <= (2 * _Nd_ull), "Maximum supported integer size is 128-bit"); - constexpr auto __max_ull = __int_limits::max(); + constexpr auto __max_ull = __int_traits::__max; unsigned long long __low = __x & __max_ull; if (__low != 0) return __builtin_ctzll(__low); @@ -172,8 +172,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr int __countr_one(_Tp __x) noexcept { - if (__x == __detail::__int_limits<_Tp>::max()) - return __detail::__int_limits<_Tp>::digits; + if (__x == __gnu_cxx::__int_traits<_Tp>::__max) + return __gnu_cxx::__int_traits<_Tp>::__digits; return std::__countr_zero((_Tp)~__x); } @@ -181,15 +181,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr int __popcount(_Tp __x) noexcept { - using std::__detail::__int_limits; - constexpr auto _Nd = __int_limits<_Tp>::digits; + using __gnu_cxx::__int_traits; + constexpr auto _Nd = __int_traits<_Tp>::__digits; if (__x == 0) return 0; - constexpr auto _Nd_ull = __int_limits::digits; - constexpr auto _Nd_ul = __int_limits::digits; - constexpr auto _Nd_u = __int_limits::digits; + constexpr auto _Nd_ull = __int_traits::__digits; + constexpr auto _Nd_ul = __int_traits::__digits; + constexpr auto _Nd_u = __int_traits::__digits; if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u) return __builtin_popcount(__x); @@ -202,7 +202,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(_Nd <= (2 * _Nd_ull), "Maximum supported integer size is 128-bit"); - constexpr auto __max_ull = __int_limits::max(); + constexpr auto __max_ull = __int_traits::__max; unsigned long long __low = __x & __max_ull; unsigned long long __high = __x >> _Nd_ull; return __builtin_popcountll(__low) + __builtin_popcountll(__high); @@ -218,8 +218,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tp __bit_ceil(_Tp __x) noexcept { - using std::__detail::__int_limits; - constexpr auto _Nd = __int_limits<_Tp>::digits; + using __gnu_cxx::__int_traits; + constexpr auto _Nd = __int_traits<_Tp>::__digits; if (__x == 0 || __x == 1) return 1; auto __shift_exponent = _Nd - std::__countl_zero((_Tp)(__x - 1u)); @@ -230,7 +230,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED if (!__builtin_is_constant_evaluated()) { - __glibcxx_assert( __shift_exponent != __int_limits<_Tp>::digits ); + __glibcxx_assert( __shift_exponent != __int_traits<_Tp>::__digits ); } #endif using __promoted_type = decltype(__x << 1); @@ -251,7 +251,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tp __bit_floor(_Tp __x) noexcept { - constexpr auto _Nd = __detail::__int_limits<_Tp>::digits; + constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits; if (__x == 0) return 0; return (_Tp)1u << (_Nd - std::__countl_zero((_Tp)(__x >> 1))); @@ -261,7 +261,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tp __bit_width(_Tp __x) noexcept { - constexpr auto _Nd = __detail::__int_limits<_Tp>::digits; + constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits; return _Nd - std::__countl_zero(__x); } diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv index b725e5d2afd..cc7dd0e3758 100644 --- a/libstdc++-v3/include/std/charconv +++ b/libstdc++-v3/include/std/charconv @@ -42,7 +42,7 @@ #include // for isdigit #include // for __to_chars_len, __to_chars_10_impl #include // for std::errc -#include +#include // FIXME: Define when floating point is supported: // #define __cpp_lib_to_chars 201611L @@ -237,7 +237,7 @@ namespace __detail to_chars_result __res; unsigned __len; - if _GLIBCXX17_CONSTEXPR (__detail::__int_limits<_Tp>::digits <= 16) + if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Tp>::__digits <= 16) { __len = __val > 077777u ? 6u : __val > 07777u ? 5u @@ -432,7 +432,7 @@ namespace __detail __i++; } __first += __i; - return (__i - __leading_zeroes) <= __detail::__int_limits<_Tp>::digits; + return (__i - __leading_zeroes) <= __gnu_cxx::__int_traits<_Tp>::__digits; } /// std::from_chars implementation for integers in bases 3 to 10. @@ -551,7 +551,7 @@ namespace __detail case 'Z': return 35; } - return __detail::__int_limits::max(); + return __gnu_cxx::__int_traits::__max; } /// std::from_chars implementation for integers in bases 11 to 26. @@ -638,10 +638,10 @@ namespace __detail } else { - if _GLIBCXX17_CONSTEXPR (__detail::__int_limits<_Up>::max() - > __detail::__int_limits<_Tp>::max()) + if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Up>::__max + > __gnu_cxx::__int_traits<_Tp>::__max) { - if (__val > __detail::__int_limits<_Tp>::max()) + if (__val > __gnu_cxx::__int_traits<_Tp>::__max) __res.ec = errc::result_out_of_range; else __value = __val; diff --git a/libstdc++-v3/include/std/memory_resource b/libstdc++-v3/include/std/memory_resource index 514c9888e7a..2b8735b8c39 100644 --- a/libstdc++-v3/include/std/memory_resource +++ b/libstdc++-v3/include/std/memory_resource @@ -39,7 +39,7 @@ #include // size_t, max_align_t, byte #include // shared_mutex #include -#include +#include #include namespace std _GLIBCXX_VISIBILITY(default) @@ -168,7 +168,7 @@ namespace pmr allocate(size_t __n) __attribute__((__returns_nonnull__)) { - if (__n > (__detail::__int_limits::max() / sizeof(_Tp))) + if (__n > (__gnu_cxx::__int_traits::__max / sizeof(_Tp))) _GLIBCXX_THROW_OR_ABORT(bad_array_new_length()); return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp), alignof(_Tp))); @@ -194,7 +194,7 @@ namespace pmr [[nodiscard]] _Up* allocate_object(size_t __n = 1) { - if ((__detail::__int_limits::max() / sizeof(_Up)) < __n) + if ((__gnu_cxx::__int_traits::__max / sizeof(_Up)) < __n) _GLIBCXX_THROW_OR_ABORT(bad_array_new_length()); return static_cast<_Up*>(allocate_bytes(__n * sizeof(_Up), alignof(_Up))); diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view index 7c7c1b3b5dd..ca0d6265098 100644 --- a/libstdc++-v3/include/std/string_view +++ b/libstdc++-v3/include/std/string_view @@ -40,9 +40,9 @@ #include #include #include -#include #include #include +#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -462,10 +462,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_compare(size_type __n1, size_type __n2) noexcept { const difference_type __diff = __n1 - __n2; - if (__diff > __detail::__int_limits::max()) - return __detail::__int_limits::max(); - if (__diff < __detail::__int_limits::min()) - return __detail::__int_limits::min(); + if (__diff > __gnu_cxx::__int_traits::__max) + return __gnu_cxx::__int_traits::__max; + if (__diff < __gnu_cxx::__int_traits::__min) + return __gnu_cxx::__int_traits::__min; return static_cast(__diff); } diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index cde375259f7..4a9ad604cbc 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -76,7 +76,7 @@ #include #if __cplusplus > 201703L -#include +#include #endif namespace std _GLIBCXX_VISIBILITY(default) @@ -456,16 +456,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { static_assert(__is_standard_integer<_Up>::value); static_assert(__is_standard_integer<_Tp>::value); - using std::__detail::__int_limits; + using __gnu_cxx::__int_traits; if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) - return __int_limits<_Up>::min() <= __t - && __t <= __int_limits<_Up>::max(); + return __int_traits<_Up>::__min <= __t + && __t <= __int_traits<_Up>::__max; else if constexpr (is_signed_v<_Tp>) return __t >= 0 - && make_unsigned_t<_Tp>(__t) <= __int_limits<_Up>::max(); + && make_unsigned_t<_Tp>(__t) <= __int_traits<_Up>::__max; else - return __t <= make_unsigned_t<_Up>(__int_limits<_Up>::max()); + return __t <= make_unsigned_t<_Up>(__int_traits<_Up>::__max); } #endif // C++20 #endif // C++17 -- 2.30.2