On Wed, Jun 4, 2025 at 8:47 PM Jonathan Wakely <jwak...@redhat.com> wrote:
> The leading sign character should be skipped when deciding whether to > insert thousands separators into a floating-point format. > > libstdc++-v3/ChangeLog: > > PR libstdc++/120548 > * include/std/format (__formatter_fp::_M_localize): Do not > * include a leading sign character in the string to be grouped. > * testsuite/std/format/functions/format.cc: Check grouping when > sign is present in the output. > --- > > I'm testing this now. Initial testing passed on x86_64-linux. > LGTM. > > libstdc++-v3/include/std/format | 11 +++++++++-- > libstdc++-v3/testsuite/std/format/functions/format.cc | 10 ++++++++++ > 2 files changed, 19 insertions(+), 2 deletions(-) > > diff --git a/libstdc++-v3/include/std/format > b/libstdc++-v3/include/std/format > index b4929d5ae59f..ec76ab0682e0 100644 > --- a/libstdc++-v3/include/std/format > +++ b/libstdc++-v3/include/std/format > @@ -2398,9 +2398,16 @@ namespace __format > const size_t __r = __str.size() - __e; // Length of remainder. > auto __overwrite = [&](_CharT* __p, size_t) { > // Apply grouping to the digits before the radix or exponent. > - auto __end = std::__add_grouping(__p, __np.thousands_sep(), > + int __off = 0; > + if (auto __c = __str.front(); __c == '-' || __c == '+' || __c == > ' ') > + { > + *__p = __c; > + __off = 1; > + } > + auto __end = std::__add_grouping(__p + __off, > __np.thousands_sep(), > __grp.data(), __grp.size(), > - __str.data(), __str.data() + > __e); > + __str.data() + __off, > + __str.data() + __e); > if (__r) // If there's a fractional part or exponent > { > if (__d != __str.npos) > diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc > b/libstdc++-v3/testsuite/std/format/functions/format.cc > index e4adf3aeb706..2af0bbeaa144 100644 > --- a/libstdc++-v3/testsuite/std/format/functions/format.cc > +++ b/libstdc++-v3/testsuite/std/format/functions/format.cc > @@ -261,6 +261,16 @@ test_locale() > s = std::format(eloc, "{0:Le} {0:Lf} {0:Lg}", -nan); > VERIFY( s == "-nan -nan -nan" ); > > + // PR libstdc++/120548 format confuses a negative sign for a thousands > digit > + s = std::format(bloc, "{:L}", -123.45); > + VERIFY( s == "-123.45" ); > + s = std::format(bloc, "{:-L}", -123.45); > + VERIFY( s == "-123.45" ); > + s = std::format(bloc, "{:+L}", 123.45); > + VERIFY( s == "+123.45" ); > + s = std::format(bloc, "{: L}", 123.45); > + VERIFY( s == " 123.45" ); > + > // Restore > std::locale::global(cloc); > } > -- > 2.49.0 > >