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
>
>

Reply via email to