]> gcc.gnu.org Git - gcc.git/commitdiff
libstdc++: Fix std::format("{:F}", inf) to use uppercase
authorJonathan Wakely <jwakely@redhat.com>
Thu, 17 Aug 2023 12:02:27 +0000 (13:02 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 17 Aug 2023 12:12:39 +0000 (13:12 +0100)
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.

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

index a8db10d6460c089dc4912aa4b3050d8879165411..40c7d6128f6065e88547f5e09bfe16ad160dc8ac 100644 (file)
@@ -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;
index 4db5202815d6262e83d50ea60818e2a4e7669e44..59ed3be8baa36052ba569d963d9496e0692646da 100644 (file)
@@ -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"; }
This page took 0.067654 seconds and 5 git commands to generate.