[PATCH] libstdc++: Fix std::format thousands separators when sign present [PR120548]
Tomasz Kaminski
tkaminsk@redhat.com
Thu Jun 5 07:48:10 GMT 2025
On Wed, Jun 4, 2025 at 8:47 PM Jonathan Wakely <jwakely@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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250605/5a8a81f5/attachment.htm>
More information about the Libstdc++
mailing list