https://gcc.gnu.org/g:7135990e3b07d3f29de46e9ca7ddbb66c094d52e

commit r16-2130-g7135990e3b07d3f29de46e9ca7ddbb66c094d52e
Author: Mateusz Zych <mte.z...@gmail.com>
Date:   Tue Jul 8 10:51:07 2025 +0100

    libstdc++: Added missing members to numeric_limits specializations for 
integer-class types
    
    [iterator.concept.winc]/11 says that std::numeric_limits should be
    specialized for integer-class types, with each member defined
    appropriately.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/max_size_type.h (numeric_limits<__max_size_type>):
            New members.
            (numeric_limits<__max_diff_type>): Likewise.
            * testsuite/std/ranges/iota/max_size_type.cc: New test cases.
    
    Signed-off-by: Mateusz Zych <mte.z...@gmail.com>

Diff:
---
 libstdc++-v3/include/bits/max_size_type.h          | 83 ++++++++++++++++++++++
 .../testsuite/std/ranges/iota/max_size_type.cc     | 31 ++++++++
 2 files changed, 114 insertions(+)

diff --git a/libstdc++-v3/include/bits/max_size_type.h 
b/libstdc++-v3/include/bits/max_size_type.h
index 73a6d141d5bc..30c5b1247679 100644
--- a/libstdc++-v3/include/bits/max_size_type.h
+++ b/libstdc++-v3/include/bits/max_size_type.h
@@ -38,6 +38,7 @@
 #include <ext/numeric_traits.h>
 #include <bit> // __bit_width
 #include <numbers>
+#include <limits> // __glibcxx_integral_traps
 
 // This header implements unsigned and signed integer-class types (as per
 // [iterator.concept.winc]) that are one bit wider than the widest supported
@@ -775,10 +776,27 @@ namespace ranges
       static constexpr bool is_signed = false;
       static constexpr bool is_integer = true;
       static constexpr bool is_exact = true;
+      static constexpr bool is_bounded = true;
+      static constexpr bool is_modulo = true;
+      static constexpr bool traps = __glibcxx_integral_traps;
+      static constexpr int radix = 2;
       static constexpr int digits
        = __gnu_cxx::__int_traits<_Sp::__rep>::__digits + 1;
       static constexpr int digits10
        = static_cast<int>(digits * numbers::ln2 / numbers::ln10);
+      static constexpr int max_digits10 = 0;
+      static constexpr int min_exponent = 0;
+      static constexpr int min_exponent10 = 0;
+      static constexpr int max_exponent = 0;
+      static constexpr int max_exponent10 = 0;
+      static constexpr bool is_iec559 = false;
+      static constexpr bool has_infinity = false;
+      static constexpr bool has_quiet_NaN = false;
+      static constexpr bool has_signaling_NaN = false;
+      static constexpr bool has_denorm_loss = false;
+      static constexpr bool tinyness_before = false;
+      static constexpr float_denorm_style has_denorm = denorm_absent;
+      static constexpr float_round_style round_style = round_toward_zero;
 
       static constexpr _Sp
       min() noexcept
@@ -791,6 +809,30 @@ namespace ranges
       static constexpr _Sp
       lowest() noexcept
       { return min(); }
+
+      static constexpr _Sp
+      denorm_min() noexcept
+      { return 0; }
+
+      static constexpr _Sp
+      epsilon() noexcept
+      { return 0; }
+
+      static constexpr _Sp
+      round_error() noexcept
+      { return 0; }
+
+      static constexpr _Sp
+      infinity() noexcept
+      { return 0; }
+
+      static constexpr _Sp
+      quiet_NaN() noexcept
+      { return 0; }
+
+      static constexpr _Sp
+      signaling_NaN() noexcept
+      { return 0; }
     };
 
   template<>
@@ -802,9 +844,26 @@ namespace ranges
       static constexpr bool is_signed = true;
       static constexpr bool is_integer = true;
       static constexpr bool is_exact = true;
+      static constexpr bool is_bounded = true;
+      static constexpr bool is_modulo = false;
+      static constexpr bool traps = __glibcxx_integral_traps;
+      static constexpr int radix = 2;
       static constexpr int digits = numeric_limits<_Sp>::digits - 1;
       static constexpr int digits10
        = static_cast<int>(digits * numbers::ln2 / numbers::ln10);
+      static constexpr int max_digits10 = 0;
+      static constexpr int min_exponent = 0;
+      static constexpr int min_exponent10 = 0;
+      static constexpr int max_exponent = 0;
+      static constexpr int max_exponent10 = 0;
+      static constexpr bool is_iec559 = false;
+      static constexpr bool has_infinity = false;
+      static constexpr bool has_quiet_NaN = false;
+      static constexpr bool has_signaling_NaN = false;
+      static constexpr bool has_denorm_loss = false;
+      static constexpr bool tinyness_before = false;
+      static constexpr float_denorm_style has_denorm = denorm_absent;
+      static constexpr float_round_style round_style = round_toward_zero;
 
       static constexpr _Dp
       min() noexcept
@@ -817,6 +876,30 @@ namespace ranges
       static constexpr _Dp
       lowest() noexcept
       { return min(); }
+
+      static constexpr _Dp
+      denorm_min() noexcept
+      { return 0; }
+
+      static constexpr _Dp
+      epsilon() noexcept
+      { return 0; }
+
+      static constexpr _Dp
+      round_error() noexcept
+      { return 0; }
+
+      static constexpr _Dp
+      infinity() noexcept
+      { return 0; }
+
+      static constexpr _Dp
+      quiet_NaN() noexcept
+      { return 0; }
+
+      static constexpr _Dp
+      signaling_NaN() noexcept
+      { return 0; }
     };
 
   template<>
diff --git a/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc 
b/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc
index 4739d9e2f790..fbd783bdf1a6 100644
--- a/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc
+++ b/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc
@@ -352,6 +352,9 @@ static_assert(numeric_limits<max_size_t>::is_specialized);
 static_assert(!numeric_limits<max_size_t>::is_signed);
 static_assert(numeric_limits<max_size_t>::is_integer);
 static_assert(numeric_limits<max_size_t>::is_exact);
+static_assert(numeric_limits<max_size_t>::is_bounded);
+static_assert(numeric_limits<max_size_t>::is_modulo);
+static_assert(numeric_limits<max_size_t>::radix == 2);
 // We can't unconditionally use numeric_limits here because __int128 is an
 // integral type only in GNU mode.
 #if __SIZEOF_INT128__
@@ -379,6 +382,9 @@ static_assert(numeric_limits<max_diff_t>::is_specialized);
 static_assert(numeric_limits<max_diff_t>::is_signed);
 static_assert(numeric_limits<max_diff_t>::is_integer);
 static_assert(numeric_limits<max_diff_t>::is_exact);
+static_assert(numeric_limits<max_diff_t>::is_bounded);
+static_assert(!numeric_limits<max_diff_t>::is_modulo);
+static_assert(numeric_limits<max_diff_t>::radix == 2);
 static_assert(numeric_limits<max_diff_t>::digits
              == numeric_limits<max_size_t>::digits - 1);
 static_assert(numeric_limits<max_diff_t>::digits10
@@ -400,6 +406,31 @@ static_assert(max_diff_t(max_size_t(1)
                         << (numeric_limits<max_size_t>::digits-1))
              == numeric_limits<max_diff_t>::min());
 
+template <typename integer_class>
+constexpr bool verify_numeric_limits_values_not_meaningful_for = true
+       && (numeric_limits<integer_class>::max_digits10 == 0)
+       && (numeric_limits<integer_class>::min_exponent == 0)
+       && (numeric_limits<integer_class>::min_exponent10 == 0)
+       && (numeric_limits<integer_class>::max_exponent == 0)
+       && (numeric_limits<integer_class>::max_exponent10 == 0)
+       && !numeric_limits<integer_class>::is_iec559
+       && !numeric_limits<integer_class>::has_infinity
+       && !numeric_limits<integer_class>::has_quiet_NaN
+       && !numeric_limits<integer_class>::has_signaling_NaN
+       && !numeric_limits<integer_class>::has_denorm_loss
+       && !numeric_limits<integer_class>::tinyness_before
+       && (numeric_limits<integer_class>::has_denorm == std::denorm_absent)
+       && (numeric_limits<integer_class>::round_style == 
std::round_toward_zero)
+       && (numeric_limits<integer_class>::denorm_min() == 0)
+       && (numeric_limits<integer_class>::epsilon() == 0)
+       && (numeric_limits<integer_class>::round_error() == 0)
+       && (numeric_limits<integer_class>::infinity() == 0)
+       && (numeric_limits<integer_class>::quiet_NaN() == 0)
+       && (numeric_limits<integer_class>::signaling_NaN() == 0);
+
+static_assert(verify_numeric_limits_values_not_meaningful_for<max_size_t>);
+static_assert(verify_numeric_limits_values_not_meaningful_for<max_diff_t>);
+
 // Verify that the types are structural types and can therefore be used
 // as NTTP types.
 template<max_size_t V> struct Su { static_assert(V*V == V+132); };

Reply via email to