]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Added missing members to numeric_limits specializations for integer-class...
authorMateusz Zych <mte.zych@gmail.com>
Tue, 8 Jul 2025 09:51:07 +0000 (10:51 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 9 Jul 2025 11:14:40 +0000 (12:14 +0100)
[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.zych@gmail.com>
libstdc++-v3/include/bits/max_size_type.h
libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc

index 73a6d141d5bc735a61d290633de6b96c2c17b412..30c5b1247679c2971d708604138d28d020adda39 100644 (file)
@@ -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<>
index 4739d9e2f7904027964953f320582e5535f3e73b..fbd783bdf1a6133ad2c9d5c97d81dd462d5f57ab 100644 (file)
@@ -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); };