On Wed, 2 Jul 2025 at 14:45, Mateusz Zych <mte.z...@gmail.com> wrote: > > > Oh actually the radix members should be of type int, not bool. I can fix > > that. > > Yes - thank you very much Jonathan for catching that! > It was my honest oversight - I am so used to using auto, that I have > accidentally copied the wrong type. > Also, thank you for adding tests - I should have added them myself in the > first place. > > > Thanks, I don't think there was any reason to omit these members, > > and I agree we should add them. > > Regarding adding missing members, > I am wondering whether template specializations of std::numeric_limits<> for > integer-class types > should define remaining static data members and static member functions, that > is: > - max_digits10 > - traps > - is_iec559 > - round_style > - has_infinity > - has_quiet_NaN > - has_signaling_NaN > - has_denorm > - has_denorm_loss > - min_exponent > - min_exponent10 > - max_exponent > - max_exponent10 > - tinyness_before > - epsilon() > - round_error() > - infinity() > - quiet_NaN() > - signaling_NaN() > - denorm_min() > > Here are reading relevant sections of the C++ standard: > > 25.3.4.4 Concept weakly_incrementable [iterator.concept.winc] > > (5) For every integer-class type I, > let B(I) be a unique hypothetical extended integer type > of the same signedness with the same width as I. > > [Note 2: The corresponding > hypothetical specialization numeric_limits<B(I)> > meets the requirements on > numeric_limits specializations for integral types.] > > (11) For every (possibly cv-qualified) integer-class type I, > numeric_limits<I> is specialized such that: > > - each static data member m > has the same value as numeric_limits<B(I)>::m, and > > - each static member function f > returns I(numeric_limits<B(I)>::f()). > > In short, std::numeric_limits<> specializations for integer-class types > should be defined > identically to std::numeric_limits<> specializations for extended integer > types, > and thus define all static data members and static member functions. > Am I reading this correctly?
Ah yes, if we're missing those ones too then we need to add them. > > Thank you, Mateusz Zych > > On Wed, Jul 2, 2025 at 1:59 PM Jonathan Wakely <jwak...@redhat.com> wrote: >> >> On 02/07/25 11:52 +0100, Jonathan Wakely wrote: >> >On Wed, 2 Jul 2025 at 10:50, Jonathan Wakely <jwak...@redhat.com> wrote: >> >> >> >> On 02/07/25 03:36 +0300, Mateusz Zych wrote: >> >> >Hello libstdc++ Team! >> >> > >> >> >I have recently found a bug in libstdc++, that is, >> >> >the std::numeric_limits<> template specializations for integer-class >> >> >types >> >> >are missing some of static data members, >> >> >which results in compilation errors of valid C++ code: >> >> > >> >> > - Compiler Explorer: https://godbolt.org/z/E7z4WYfj4 >> >> > >> >> >Since adding missing member constants, which are the most relevant to >> >> >integer-like types, >> >> >was not a lot of code, I have prepared a Git patch with relevant changes. >> >> > >> >> >I hope this patch is useful, Mateusz Zych >> >> >> >> Thanks, I don't think there was any reason to omit these members, and I >> >> agree we should add them. >> >> >> >> The patch is simple and obvious enough that I don't think we need a >> >> copyright assignment or DCO sign-off, so I'll push this to the >> >> relevant branches. Thanks! >> > >> >Oh actually the radix members should be of type int, not bool. I can fix >> >that. >> >> Here's what I'm testing: >> >> >> commit ddd5b88db4fe99166835fe1b94beca451bc1ce30 >> Author: Mateusz Zych <mte.z...@gmail.com> >> AuthorDate: Tue Jul 1 23:51:40 2025 >> Commit: Jonathan Wakely <r...@gcc.gnu.org> >> CommitDate: Wed Jul 2 11:57:45 2025 >> >> libstdc++: Add 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 static data members. >> (numeric_limits<__max_diff_type>): Likewise. >> * testsuite/std/ranges/iota/max_size_type.cc: Check new members. >> >> Co-authored-by: Jonathan Wakely <jwak...@redhat.com> >> >> diff --git a/libstdc++-v3/include/bits/max_size_type.h >> b/libstdc++-v3/include/bits/max_size_type.h >> index 73a6d141d5bc..3ac2b8e6b878 100644 >> --- a/libstdc++-v3/include/bits/max_size_type.h >> +++ b/libstdc++-v3/include/bits/max_size_type.h >> @@ -775,6 +775,9 @@ 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 int radix = 2; >> static constexpr int digits >> = __gnu_cxx::__int_traits<_Sp::__rep>::__digits + 1; >> static constexpr int digits10 >> @@ -802,6 +805,9 @@ 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 int radix = 2; >> static constexpr int digits = numeric_limits<_Sp>::digits - 1; >> static constexpr int digits10 >> = static_cast<int>(digits * numbers::ln2 / numbers::ln10); >> 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..fc5284594c7e 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 >>