aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2025-06-04 18:22:28 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2025-06-05 14:43:48 +0100
commit2c3559839d70df6311da18fd93237050405580c3 (patch)
treec543b8d76090868a4541f80ee1dfca31ee942745
parent9399a3b5f512af6dbbe05be076e726efc91413f1 (diff)
downloadgcc-2c3559839d70df6311da18fd93237050405580c3.zip
gcc-2c3559839d70df6311da18fd93237050405580c3.tar.gz
gcc-2c3559839d70df6311da18fd93237050405580c3.tar.bz2
libstdc++: Fix std::format thousands separators when sign present [PR120548]
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>
-rw-r--r--libstdc++-v3/include/std/format11
-rw-r--r--libstdc++-v3/testsuite/std/format/functions/format.cc10
2 files changed, 19 insertions, 2 deletions
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index b4929d5..ec76ab0 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 e4adf3a..d342114 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}", -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);
}