[gcc(refs/vendors/ARM/heads/arm-struct-reorg-wip)] libstdc++: Add lightweight replacement for std::numeric_limits (PR 92546)

Tamar Christina tnfchris@gcc.gnu.org
Fri Jul 17 12:56:08 GMT 2020


https://gcc.gnu.org/g:c03b53da9129ae2d5ac9629c4b874d0981a7d418

commit c03b53da9129ae2d5ac9629c4b874d0981a7d418
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Feb 17 14:30:02 2020 +0000

    libstdc++: Add lightweight replacement for std::numeric_limits (PR 92546)
    
    Many uses of std::numeric_limits in C++17 and C++20 features only really
    need the min(), max() and digits constants for integral types. By adding
    __detail::__int_limits we can avoid including the whole <limits> header.
    
    The <limits> header isn't especially large, but avoiding it still gives
    small savings in compilation time and memory usage for the compiler.
    
    There are also C++11 features that could benefit from this change (e.g.
    <bits/hashtable_policy.h> and <bits/uniform_int_dist.h>) but I won't
    change those until stage 1.
    
    The implementation of __int_limits assumes two's complement integers,
    which is true for all targets supported by GCC.
    
            PR libstdc++/92546 (partial)
            * include/Makefile.am: Add new header.
            * include/Makefile.in: Regenerate.
            * include/bits/int_limits.h: New header.
            * include/bits/parse_numbers.h (__select_int::_Select_int): Replace
            numeric_limits with __detail::__int_limits.
            * include/std/bit (__rotl, __rotr, __countl_zero, __countl_one)
            (__countr_zero, __countr_one, __popcount, __ceil2, __floor2, __log2p1):
            Likewise.
            * 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 (in_range): Likewise.
            * testsuite/20_util/integer_comparisons/in_range_neg.cc: Adjust for
            extra error about incomplete type __int_limits<bool>.
            * testsuite/26_numerics/bit/bit.count/countl_one.cc: Include <limits>.
            * testsuite/26_numerics/bit/bit.count/countl_zero.cc: Likewise.
            * testsuite/26_numerics/bit/bit.count/countr_one.cc: Likewise.
            * testsuite/26_numerics/bit/bit.count/countr_zero.cc: Likewise.
            * testsuite/26_numerics/bit/bit.count/popcount.cc: Likewise.
            * testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc: Likewise.
            * testsuite/26_numerics/bit/bit.pow.two/ceil2.cc: Likewise.
            * testsuite/26_numerics/bit/bit.pow.two/floor2.cc: Likewise.
            * testsuite/26_numerics/bit/bit.pow.two/ispow2.cc: Likewise.
            * testsuite/26_numerics/bit/bit.pow.two/log2p1.cc: Likewise.
            * testsuite/26_numerics/bit/bit.rotate/rotl.cc: Likewise.
            * testsuite/26_numerics/bit/bit.rotate/rotr.cc: Likewise.

Diff:
---
 libstdc++-v3/ChangeLog                             | 30 +++++++++
 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          |  8 +--
 libstdc++-v3/include/std/bit                       | 56 ++++++++--------
 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                   | 11 ++--
 .../20_util/integer_comparisons/in_range_neg.cc    |  1 +
 .../26_numerics/bit/bit.count/countl_one.cc        |  1 +
 .../26_numerics/bit/bit.count/countl_zero.cc       |  1 +
 .../26_numerics/bit/bit.count/countr_one.cc        |  1 +
 .../26_numerics/bit/bit.count/countr_zero.cc       |  1 +
 .../26_numerics/bit/bit.count/popcount.cc          |  1 +
 .../testsuite/26_numerics/bit/bit.pow.two/ceil2.cc |  1 +
 .../26_numerics/bit/bit.pow.two/ceil2_neg.cc       |  1 +
 .../26_numerics/bit/bit.pow.two/floor2.cc          |  1 +
 .../26_numerics/bit/bit.pow.two/ispow2.cc          |  1 +
 .../26_numerics/bit/bit.pow.two/log2p1.cc          |  1 +
 .../testsuite/26_numerics/bit/bit.rotate/rotl.cc   |  1 +
 .../testsuite/26_numerics/bit/bit.rotate/rotr.cc   |  1 +
 23 files changed, 174 insertions(+), 50 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 9ae1e112aa8..954eb673184 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,35 @@
 2020-02-17  Jonathan Wakely  <jwakely@redhat.com>
 
+	PR libstdc++/92546 (partial)
+	* include/Makefile.am: Add new header.
+	* include/Makefile.in: Regenerate.
+	* include/bits/int_limits.h: New header.
+	* include/bits/parse_numbers.h (__select_int::_Select_int): Replace
+	numeric_limits with __detail::__int_limits.
+	* include/std/bit (__rotl, __rotr, __countl_zero, __countl_one)
+	(__countr_zero, __countr_one, __popcount, __ceil2, __floor2, __log2p1):
+	Likewise.
+	* 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 (in_range): Likewise.
+	* testsuite/20_util/integer_comparisons/in_range_neg.cc: Adjust for
+	extra error about incomplete type __int_limits<bool>.
+	* testsuite/26_numerics/bit/bit.count/countl_one.cc: Include <limits>.
+	* testsuite/26_numerics/bit/bit.count/countl_zero.cc: Likewise.
+	* testsuite/26_numerics/bit/bit.count/countr_one.cc: Likewise.
+	* testsuite/26_numerics/bit/bit.count/countr_zero.cc: Likewise.
+	* testsuite/26_numerics/bit/bit.count/popcount.cc: Likewise.
+	* testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc: Likewise.
+	* testsuite/26_numerics/bit/bit.pow.two/ceil2.cc: Likewise.
+	* testsuite/26_numerics/bit/bit.pow.two/floor2.cc: Likewise.
+	* testsuite/26_numerics/bit/bit.pow.two/ispow2.cc: Likewise.
+	* testsuite/26_numerics/bit/bit.pow.two/log2p1.cc: Likewise.
+	* testsuite/26_numerics/bit/bit.rotate/rotl.cc: Likewise.
+	* testsuite/26_numerics/bit/bit.rotate/rotr.cc: Likewise.
+
 	* python/libstdcxx/v6/printers.py (StdCmpCatPrinter.to_string): Update
 	value for partial_ordering::unordered.
 
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index e131ce04f8c..80aeb3f8959 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -129,6 +129,7 @@ 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 ae20f6b1d21..eb437ad8d8d 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -474,6 +474,7 @@ 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
new file mode 100644
index 00000000000..7ae34377331
--- /dev/null
+++ b/libstdc++-v3/include/bits/int_limits.h
@@ -0,0 +1,74 @@
+// 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
+// <http://www.gnu.org/licenses/>.
+
+/** @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 <bits/c++config.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+namespace __detail
+{
+  // This template is used for arbitrary signed and unsigned integer types
+  // (by headers <bit> and <charconv>) and for specific integer types
+  // (by <memory_resource> and <string_view>) but also for char (<charconv>).
+  // For simplicity's sake, all integral types except bool are supported.
+
+  // Lightweight alternative to numeric_limits<signed integer type>.
+  template<typename _Tp, bool = is_signed<_Tp>::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<unsigned integer type>.
+  template<typename _Tp>
+    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<bool>; // 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 d7a81e55182..6a75d002774 100644
--- a/libstdc++-v3/include/bits/parse_numbers.h
+++ b/libstdc++-v3/include/bits/parse_numbers.h
@@ -34,9 +34,9 @@
 
 // From n3642.pdf except I added binary literals and digit separator '\''.
 
-#if __cplusplus > 201103L
+#if __cplusplus >= 201402L
 
-#include <limits>
+#include <bits/int_limits.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -265,7 +265,7 @@ namespace __select_int
 
   template<unsigned long long _Val, typename _IntType, typename... _Ints>
     struct _Select_int_base<_Val, _IntType, _Ints...>
-    : conditional_t<(_Val <= std::numeric_limits<_IntType>::max()),
+    : conditional_t<(_Val <= __detail::__int_limits<_IntType>::max()),
 		    integral_constant<_IntType, _Val>,
 		    _Select_int_base<_Val, _Ints...>>
     { };
@@ -289,6 +289,6 @@ namespace __select_int
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
-#endif // __cplusplus > 201103L
+#endif // C++14
 
 #endif // _GLIBCXX_PARSE_NUMBERS_H
diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index 0203546d1d2..dc0a77e1a5f 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -34,7 +34,7 @@
 #if __cplusplus >= 201402L
 
 #include <type_traits>
-#include <limits>
+#include <bits/int_limits.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -55,7 +55,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr _Tp
     __rotl(_Tp __x, int __s) noexcept
     {
-      constexpr auto _Nd = numeric_limits<_Tp>::digits;
+      constexpr auto _Nd = __detail::__int_limits<_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 = numeric_limits<_Tp>::digits;
+      constexpr auto _Nd = __detail::__int_limits<_Tp>::digits;
       const int __r = __s % _Nd;
       if (__r == 0)
 	return __x;
@@ -83,14 +83,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr int
     __countl_zero(_Tp __x) noexcept
     {
-      constexpr auto _Nd = numeric_limits<_Tp>::digits;
+      using std::__detail::__int_limits;
+      constexpr auto _Nd = __int_limits<_Tp>::digits;
 
       if (__x == 0)
         return _Nd;
 
-      constexpr auto _Nd_ull = numeric_limits<unsigned long long>::digits;
-      constexpr auto _Nd_ul = numeric_limits<unsigned long>::digits;
-      constexpr auto _Nd_u = numeric_limits<unsigned>::digits;
+      constexpr auto _Nd_ull = __int_limits<unsigned long long>::digits;
+      constexpr auto _Nd_ul = __int_limits<unsigned long>::digits;
+      constexpr auto _Nd_u = __int_limits<unsigned>::digits;
 
       if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
 	{
@@ -118,7 +119,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	      constexpr int __diff = (2 * _Nd_ull) - _Nd;
 	      return __builtin_clzll(__high) - __diff;
 	    }
-	  constexpr auto __max_ull = numeric_limits<unsigned long long>::max();
+	  constexpr auto __max_ull = __int_limits<unsigned long long>::max();
 	  unsigned long long __low = __x & __max_ull;
 	  return (_Nd - _Nd_ull) + __builtin_clzll(__low);
 	}
@@ -128,8 +129,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr int
     __countl_one(_Tp __x) noexcept
     {
-      if (__x == numeric_limits<_Tp>::max())
-        return numeric_limits<_Tp>::digits;
+      if (__x == __detail::__int_limits<_Tp>::max())
+	return __detail::__int_limits<_Tp>::digits;
       return std::__countl_zero<_Tp>((_Tp)~__x);
     }
 
@@ -137,14 +138,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr int
     __countr_zero(_Tp __x) noexcept
     {
-      constexpr auto _Nd = numeric_limits<_Tp>::digits;
+      using std::__detail::__int_limits;
+      constexpr auto _Nd = __int_limits<_Tp>::digits;
 
       if (__x == 0)
         return _Nd;
 
-      constexpr auto _Nd_ull = numeric_limits<unsigned long long>::digits;
-      constexpr auto _Nd_ul = numeric_limits<unsigned long>::digits;
-      constexpr auto _Nd_u = numeric_limits<unsigned>::digits;
+      constexpr auto _Nd_ull = __int_limits<unsigned long long>::digits;
+      constexpr auto _Nd_ul = __int_limits<unsigned long>::digits;
+      constexpr auto _Nd_u = __int_limits<unsigned>::digits;
 
       if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
 	return __builtin_ctz(__x);
@@ -157,7 +159,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  static_assert(_Nd <= (2 * _Nd_ull),
 			"Maximum supported integer size is 128-bit");
 
-	  constexpr auto __max_ull = numeric_limits<unsigned long long>::max();
+	  constexpr auto __max_ull = __int_limits<unsigned long long>::max();
 	  unsigned long long __low = __x & __max_ull;
 	  if (__low != 0)
 	    return __builtin_ctzll(__low);
@@ -170,8 +172,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr int
     __countr_one(_Tp __x) noexcept
     {
-      if (__x == numeric_limits<_Tp>::max())
-        return numeric_limits<_Tp>::digits;
+      if (__x == __detail::__int_limits<_Tp>::max())
+	return __detail::__int_limits<_Tp>::digits;
       return std::__countr_zero((_Tp)~__x);
     }
 
@@ -179,14 +181,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr int
     __popcount(_Tp __x) noexcept
     {
-      constexpr auto _Nd = numeric_limits<_Tp>::digits;
+      using std::__detail::__int_limits;
+      constexpr auto _Nd = __int_limits<_Tp>::digits;
 
       if (__x == 0)
         return 0;
 
-      constexpr auto _Nd_ull = numeric_limits<unsigned long long>::digits;
-      constexpr auto _Nd_ul = numeric_limits<unsigned long>::digits;
-      constexpr auto _Nd_u = numeric_limits<unsigned>::digits;
+      constexpr auto _Nd_ull = __int_limits<unsigned long long>::digits;
+      constexpr auto _Nd_ul = __int_limits<unsigned long>::digits;
+      constexpr auto _Nd_u = __int_limits<unsigned>::digits;
 
       if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
 	return __builtin_popcount(__x);
@@ -199,7 +202,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  static_assert(_Nd <= (2 * _Nd_ull),
 			"Maximum supported integer size is 128-bit");
 
-	  constexpr auto __max_ull = numeric_limits<unsigned long long>::max();
+	  constexpr auto __max_ull = __int_limits<unsigned long long>::max();
 	  unsigned long long __low = __x & __max_ull;
 	  unsigned long long __high = __x >> _Nd_ull;
 	  return __builtin_popcountll(__low) + __builtin_popcountll(__high);
@@ -215,7 +218,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr _Tp
     __ceil2(_Tp __x) noexcept
     {
-      constexpr auto _Nd = numeric_limits<_Tp>::digits;
+      using std::__detail::__int_limits;
+      constexpr auto _Nd = __int_limits<_Tp>::digits;
       if (__x == 0 || __x == 1)
         return 1;
       auto __shift_exponent = _Nd - std::__countl_zero((_Tp)(__x - 1u));
@@ -226,7 +230,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
       if (!__builtin_is_constant_evaluated())
 	{
-	  __glibcxx_assert( __shift_exponent != numeric_limits<_Tp>::digits );
+	  __glibcxx_assert( __shift_exponent != __int_limits<_Tp>::digits );
 	}
 #endif
       using __promoted_type = decltype(__x << 1);
@@ -247,7 +251,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr _Tp
     __floor2(_Tp __x) noexcept
     {
-      constexpr auto _Nd = numeric_limits<_Tp>::digits;
+      constexpr auto _Nd = __detail::__int_limits<_Tp>::digits;
       if (__x == 0)
         return 0;
       return (_Tp)1u << (_Nd - std::__countl_zero((_Tp)(__x >> 1)));
@@ -257,7 +261,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr _Tp
     __log2p1(_Tp __x) noexcept
     {
-      constexpr auto _Nd = numeric_limits<_Tp>::digits;
+      constexpr auto _Nd = __detail::__int_limits<_Tp>::digits;
       return _Nd - std::__countl_zero(__x);
     }
 
diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv
index 1fd84a8f449..9b5a1f7cab8 100644
--- a/libstdc++-v3/include/std/charconv
+++ b/libstdc++-v3/include/std/charconv
@@ -34,11 +34,11 @@
 #if __cplusplus >= 201402L
 
 #include <type_traits>
-#include <limits>
 #include <bit>			// for __log2p1
 #include <cctype>		// for isdigit
 #include <bits/charconv.h>	// for __to_chars_len, __to_chars_10_impl
 #include <bits/error_constants.h> // for std::errc
+#include <bits/int_limits.h>
 
 // Define when floating point is supported: #define __cpp_lib_to_chars 201611L
 
@@ -222,7 +222,7 @@ namespace __detail
       to_chars_result __res;
       unsigned __len;
 
-      if _GLIBCXX17_CONSTEXPR (numeric_limits<_Tp>::digits <= 16)
+      if _GLIBCXX17_CONSTEXPR (__detail::__int_limits<_Tp>::digits <= 16)
 	{
 	  __len = __val > 077777u ? 6u
 	    : __val > 07777u ? 5u
@@ -410,7 +410,7 @@ namespace __detail
 	  __i++;
 	}
       __first += __i;
-      return __i <= numeric_limits<_Tp>::digits;
+      return __i <= __detail::__int_limits<_Tp>::digits;
     }
 
   /// std::from_chars implementation for integers in bases 3 to 10.
@@ -529,7 +529,7 @@ namespace __detail
     case 'Z':
       return 35;
     }
-    return std::numeric_limits<unsigned char>::max();
+    return __detail::__int_limits<unsigned char>::max();
   }
 
   /// std::from_chars implementation for integers in bases 11 to 26.
@@ -616,10 +616,10 @@ namespace __detail
 		}
 	      else
 		{
-		  if _GLIBCXX17_CONSTEXPR
-		    (numeric_limits<_Up>::max() > numeric_limits<_Tp>::max())
+		  if _GLIBCXX17_CONSTEXPR (__detail::__int_limits<_Up>::max()
+		      > __detail::__int_limits<_Tp>::max())
 		    {
-		      if (__val > numeric_limits<_Tp>::max())
+		      if (__val > __detail::__int_limits<_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 13be3e9dc75..70c56d1d7e6 100644
--- a/libstdc++-v3/include/std/memory_resource
+++ b/libstdc++-v3/include/std/memory_resource
@@ -33,13 +33,13 @@
 
 #if __cplusplus >= 201703L
 
-#include <limits>			// numeric_limits
 #include <memory>			// align, allocator_arg_t, __uses_alloc
 #include <utility>			// pair, index_sequence
 #include <vector>			// vector
 #include <cstddef>			// size_t, max_align_t, byte
 #include <shared_mutex>			// shared_mutex
 #include <bits/functexcept.h>
+#include <bits/int_limits.h>
 #include <debug/assertions.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -166,7 +166,7 @@ namespace pmr
       allocate(size_t __n)
       __attribute__((__returns_nonnull__))
       {
-	if (__n > (numeric_limits<size_t>::max() / sizeof(_Tp)))
+	if (__n > (__detail::__int_limits<size_t>::max() / sizeof(_Tp)))
 	  std::__throw_bad_alloc();
 	return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
 						       alignof(_Tp)));
@@ -192,7 +192,7 @@ namespace pmr
 	_Up*
 	allocate_object(size_t __n = 1)
 	{
-	  if ((std::numeric_limits<size_t>::max() / sizeof(_Up)) < __n)
+	  if ((__detail::__int_limits<size_t>::max() / sizeof(_Up)) < __n)
 	    __throw_length_error("polymorphic_allocator::allocate_object");
 	  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 798cb89a621..bedad24979e 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -37,10 +37,10 @@
 
 #if __cplusplus >= 201703L
 
-#include <limits>
 #include <iosfwd>
 #include <bits/char_traits.h>
 #include <bits/functional_hash.h>
+#include <bits/int_limits.h>
 #include <bits/range_access.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -456,10 +456,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _S_compare(size_type __n1, size_type __n2) noexcept
       {
 	const difference_type __diff = __n1 - __n2;
-	if (__diff > std::numeric_limits<int>::max())
-	  return std::numeric_limits<int>::max();
-	if (__diff < std::numeric_limits<int>::min())
-	  return std::numeric_limits<int>::min();
+	if (__diff > __detail::__int_limits<int>::max())
+	  return __detail::__int_limits<int>::max();
+	if (__diff < __detail::__int_limits<int>::min())
+	  return __detail::__int_limits<int>::min();
 	return static_cast<int>(__diff);
       }
 
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index 380c059395c..dc6e8468af5 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -76,7 +76,7 @@
 #include <initializer_list>
 
 #if __cplusplus > 201703L
-#include <limits>
+#include <bits/int_limits.h>
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -460,15 +460,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       static_assert(__is_standard_integer<_Up>::value);
       static_assert(__is_standard_integer<_Tp>::value);
+      using std::__detail::__int_limits;
 
       if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
-	return numeric_limits<_Up>::min() <= __t
-	  && __t <= numeric_limits<_Up>::max();
+	return __int_limits<_Up>::min() <= __t
+	  && __t <= __int_limits<_Up>::max();
       else if constexpr (is_signed_v<_Tp>)
 	return __t >= 0
-	  && make_unsigned_t<_Tp>(__t) <= numeric_limits<_Up>::max();
+	  && make_unsigned_t<_Tp>(__t) <= __int_limits<_Up>::max();
       else
-	return __t <= make_unsigned_t<_Up>(numeric_limits<_Up>::max());
+	return __t <= make_unsigned_t<_Up>(__int_limits<_Up>::max());
     }
 #endif // C++20
 #endif // C++17
diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/in_range_neg.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/in_range_neg.cc
index 13e2bf75a8a..077d9818dc8 100644
--- a/libstdc++-v3/testsuite/20_util/integer_comparisons/in_range_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/in_range_neg.cc
@@ -34,3 +34,4 @@ bool k = std::in_range<int>(U'a'); // { dg-error "here" }
 bool l = std::in_range<char32_t>(97); // { dg-error "here" }
 
 // { dg-error "static assertion failed" "" { target *-*-* } 0 }
+// { dg-prune-output "incomplete type" }
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_one.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_one.cc
index 7fdb6ed53bb..1e9b8983ed6 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_one.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_one.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename UInt>
 constexpr auto
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_zero.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_zero.cc
index 1a056bf7dd4..8e2f42ab6ba 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_zero.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_zero.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename UInt>
 constexpr auto
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_one.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_one.cc
index d6fffa95445..7f53b7116d1 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_one.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_one.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename UInt>
 constexpr auto
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_zero.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_zero.cc
index 004272c9cce..132722f037b 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_zero.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_zero.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename UInt>
 constexpr auto
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.count/popcount.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/popcount.cc
index e2f5e9829ea..62007ed6aeb 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.count/popcount.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/popcount.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename UInt>
 constexpr auto
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc
index e8bc0bba6f8..f917efb5ef3 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename T>
   constexpr T max = std::numeric_limits<T>::max();
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc
index 54b194bb9df..b5391936e3d 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc
@@ -20,6 +20,7 @@
 // { dg-xfail-run-if "__glibcxx_assert in ceil2 should fail" { *-*-* } }
 
 #include <bit>
+#include <limits>
 
 // P1355R2: not a constant expression if the result is not representable
 
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/floor2.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/floor2.cc
index 4d439bd2a19..7d2321d6acf 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/floor2.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/floor2.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename UInt>
 constexpr auto
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ispow2.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ispow2.cc
index 3362d40c6dc..a0a4d89a54f 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ispow2.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ispow2.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename UInt>
 constexpr auto
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/log2p1.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/log2p1.cc
index 4fea5805228..6f32d4afc1b 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/log2p1.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/log2p1.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename UInt>
 constexpr auto
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotl.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotl.cc
index 802495f20d8..b2525050e09 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotl.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotl.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename UInt>
 constexpr bool
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotr.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotr.cc
index 84a86c03149..bebf79d5d96 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotr.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotr.cc
@@ -19,6 +19,7 @@
 // { dg-do compile { target c++2a } }
 
 #include <bit>
+#include <limits>
 
 template<typename UInt>
 constexpr bool


More information about the Libstdc++-cvs mailing list