aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2023-08-17 13:02:27 +0100
committerJonathan Wakely <jwakely@redhat.com>2023-08-17 13:12:39 +0100
commitd07bce478f9d770de5acb0480a3f0cec2f8b72d8 (patch)
tree6770aee86653d1ffe2d94dfc66d8b7e0569fa611 /libstdc++-v3
parentb10dfbb54efb7f5ed48eaa11c79f112a85676f24 (diff)
downloadgcc-d07bce478f9d770de5acb0480a3f0cec2f8b72d8.zip
gcc-d07bce478f9d770de5acb0480a3f0cec2f8b72d8.tar.gz
gcc-d07bce478f9d770de5acb0480a3f0cec2f8b72d8.tar.bz2
libstdc++: Fix std::format("{:F}", inf) to use uppercase
std::format was treating {:f} and {:F} identically on the basis that for the fixed 1.234567 format there are no alphabetical characters that need to be in uppercase. But that's wrong for infinities and NaNs, which should be formatted as "INF" and "NAN" for {:F}. libstdc++-v3/ChangeLog: * include/std/format (__format::_Pres_type): Add _Pres_F. (__formatter_fp::parse): Use _Pres_F for 'F'. (__formatter_fp::format): Set __upper for _Pres_F. * testsuite/std/format/functions/format.cc: Check formatting of infinity and NaN for each presentation type.
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/include/std/format10
-rw-r--r--libstdc++-v3/testsuite/std/format/functions/format.cc12
2 files changed, 20 insertions, 2 deletions
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index a8db10d..40c7d61 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -309,7 +309,7 @@ namespace __format
// Presentation types for integral types (including bool and charT).
_Pres_d = 1, _Pres_b, _Pres_B, _Pres_o, _Pres_x, _Pres_X, _Pres_c,
// Presentation types for floating-point types.
- _Pres_a = 1, _Pres_A, _Pres_e, _Pres_E, _Pres_f, _Pres_g, _Pres_G,
+ _Pres_a = 1, _Pres_A, _Pres_e, _Pres_E, _Pres_f, _Pres_F, _Pres_g, _Pres_G,
_Pres_p = 0, _Pres_P, // For pointers.
_Pres_s = 0, // For strings and bool.
_Pres_esc = 0xf, // For strings and charT.
@@ -1382,10 +1382,13 @@ namespace __format
++__first;
break;
case 'f':
- case 'F':
__spec._M_type = _Pres_f;
++__first;
break;
+ case 'F':
+ __spec._M_type = _Pres_F;
+ ++__first;
+ break;
case 'g':
__spec._M_type = _Pres_g;
++__first;
@@ -1442,6 +1445,9 @@ namespace __format
__use_prec = true;
__fmt = chars_format::scientific;
break;
+ case _Pres_F:
+ __upper = true;
+ [[fallthrough]];
case _Pres_f:
__use_prec = true;
__fmt = chars_format::fixed;
diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc b/libstdc++-v3/testsuite/std/format/functions/format.cc
index 4db5202..59ed3be 100644
--- a/libstdc++-v3/testsuite/std/format/functions/format.cc
+++ b/libstdc++-v3/testsuite/std/format/functions/format.cc
@@ -159,6 +159,18 @@ test_alternate_forms()
VERIFY( s == "1.e+01 1.e+01 1.e+01" );
}
+void
+test_infnan()
+{
+ double inf = std::numeric_limits<double>::infinity();
+ double nan = std::numeric_limits<double>::quiet_NaN();
+ std::string s;
+ s = std::format("{0} {0:e} {0:E} {0:f} {0:F} {0:g} {0:G} {0:a} {0:A}", inf);
+ VERIFY( s == "inf inf INF inf INF inf INF inf INF" );
+ s = std::format("{0} {0:e} {0:E} {0:f} {0:F} {0:g} {0:G} {0:a} {0:A}", nan);
+ VERIFY( s == "nan nan NAN nan NAN nan NAN nan NAN" );
+}
+
struct euro_punc : std::numpunct<char>
{
std::string do_grouping() const override { return "\3\3"; }