]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Fix std::format thousands separators when sign present [PR120548]
authorJonathan Wakely <jwakely@redhat.com>
Wed, 4 Jun 2025 17:22:28 +0000 (18:22 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 11 Jun 2025 08:01:02 +0000 (09:01 +0100)
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.

Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com>
(cherry picked from commit 2c3559839d70df6311da18fd93237050405580c3)

libstdc++-v3/include/std/format
libstdc++-v3/testsuite/std/format/functions/format.cc

index 84f21281387c1d2e519c6fcc0b4008054443e193..ada62c26bcab77110ce5278d935189c2a8084cd4 100644 (file)
@@ -1838,9 +1838,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)
index d6575dabb6bcf22fd88b30d4e12ff2804e9559eb..677c0d1fe9989cef335b236e65b71be0cb97223a 100644 (file)
@@ -256,6 +256,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}", -876543.21);
+  VERIFY( s == "-876,543.21" );
+  s = std::format(bloc, "{:+L}", 333.22);
+  VERIFY( s == "+333.22" );
+  s = std::format(bloc, "{: L}", 999.44);
+  VERIFY( s == " 999.44" );
+
   // Restore
   std::locale::global(cloc);
 }