diff mbox series

libstdc++: Check ios::uppercase for ios::fixed floating-point output [PR114862]

Message ID 20240801213927.388966-4-jwakely@redhat.com
State New
Headers show
Series libstdc++: Check ios::uppercase for ios::fixed floating-point output [PR114862] | expand

Commit Message

Jonathan Wakely Aug. 1, 2024, 9:32 p.m. UTC
Tested x86_64-linux.

-- >8 --

This is LWG 4084 which I filed recently. LWG seems to support making the
change, so that std::num_put can use the %F format for floating-point
numbers.

libstdc++-v3/ChangeLog:

	PR libstdc++/114862
	* src/c++98/locale_facets.cc (__num_base::_S_format_float):
	Check uppercase flag for fixed format.
	* testsuite/22_locale/num_put/put/char/lwg4084.cc: New test.
---
 libstdc++-v3/src/c++98/locale_facets.cc       | 13 ++++--
 .../22_locale/num_put/put/char/lwg4084.cc     | 46 +++++++++++++++++++
 2 files changed, 54 insertions(+), 5 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc

Comments

Jonathan Wakely Aug. 21, 2024, 11:01 a.m. UTC | #1
This is still pending a decision by LEWG, but I've pushed it to trunk anyway.

We can always revert it before GCC 15 is released if the committee
decides against it, but this way we might get user feedback on it.

On Thu, 1 Aug 2024 at 22:41, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> Tested x86_64-linux.
>
> -- >8 --
>
> This is LWG 4084 which I filed recently. LWG seems to support making the
> change, so that std::num_put can use the %F format for floating-point
> numbers.
>
> libstdc++-v3/ChangeLog:
>
>         PR libstdc++/114862
>         * src/c++98/locale_facets.cc (__num_base::_S_format_float):
>         Check uppercase flag for fixed format.
>         * testsuite/22_locale/num_put/put/char/lwg4084.cc: New test.
> ---
>  libstdc++-v3/src/c++98/locale_facets.cc       | 13 ++++--
>  .../22_locale/num_put/put/char/lwg4084.cc     | 46 +++++++++++++++++++
>  2 files changed, 54 insertions(+), 5 deletions(-)
>  create mode 100644 libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc
>
> diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc
> index fa469b1b872..02f53fd5ec1 100644
> --- a/libstdc++-v3/src/c++98/locale_facets.cc
> +++ b/libstdc++-v3/src/c++98/locale_facets.cc
> @@ -84,17 +84,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
>      if (__mod)
>        *__fptr++ = __mod;
> -    // [22.2.2.2.2] Table 58
> +    // C++11 [facet.num.put.virtuals] Table 88
> +    // _GLIBCXX_RESOLVE_LIB_DEFECTS
> +    // 4084. std::fixed ignores std::uppercase
> +    bool __upper = __flags & ios_base::uppercase;
>      if (__fltfield == ios_base::fixed)
> -      *__fptr++ = 'f';
> +      *__fptr++ = __upper ? 'F' : 'f';
>      else if (__fltfield == ios_base::scientific)
> -      *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e';
> +      *__fptr++ = __upper ? 'E' : 'e';
>  #if _GLIBCXX_USE_C99_STDIO
>      else if (__fltfield == (ios_base::fixed | ios_base::scientific))
> -      *__fptr++ = (__flags & ios_base::uppercase) ? 'A' : 'a';
> +      *__fptr++ = __upper ? 'A' : 'a';
>  #endif
>      else
> -      *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
> +      *__fptr++ = __upper ? 'G' : 'g';
>      *__fptr = '\0';
>    }
>
> diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc
> new file mode 100644
> index 00000000000..b7c7da11f86
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc
> @@ -0,0 +1,46 @@
> +// { dg-do run }
> +// LWG 4084. std::fixed ignores std::uppercase
> +// PR libstdc++/114862 std::uppercase not applying to nan's and inf's
> +
> +#include <sstream>
> +#include <limits>
> +#include <iomanip>
> +#include <testsuite_hooks.h>
> +
> +void
> +test_nan()
> +{
> +  std::ostringstream out;
> +  double nan = std::numeric_limits<double>::quiet_NaN();
> +  out << std::fixed;
> +  out << ' ' << nan << ' ' << -nan;
> +  out << std::uppercase;
> +  out << ' ' << nan << ' ' << -nan;
> +  out << std::showpoint;
> +  out << ' ' << nan << ' ' << -nan;
> +  out << std::showpos;
> +  out << ' ' << nan << ' ' << -nan;
> +  VERIFY( out.str() == " nan -nan NAN -NAN NAN -NAN +NAN -NAN" );
> +}
> +
> +void
> +test_inf()
> +{
> +  std::ostringstream out;
> +  double inf = std::numeric_limits<double>::infinity();
> +  out << std::fixed;
> +  out << ' ' << inf << ' ' << -inf;
> +  out << std::uppercase;
> +  out << ' ' << inf << ' ' << -inf;
> +  out << std::showpoint;
> +  out << ' ' << inf << ' ' << -inf;
> +  out << std::showpos;
> +  out << ' ' << inf << ' ' << -inf;
> +  VERIFY( out.str() == " inf -inf INF -INF INF -INF +INF -INF" );
> +}
> +
> +int main()
> +{
> +  test_nan();
> +  test_inf();
> +}
> --
> 2.45.2
>
diff mbox series

Patch

diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc
index fa469b1b872..02f53fd5ec1 100644
--- a/libstdc++-v3/src/c++98/locale_facets.cc
+++ b/libstdc++-v3/src/c++98/locale_facets.cc
@@ -84,17 +84,20 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     if (__mod)
       *__fptr++ = __mod;
-    // [22.2.2.2.2] Table 58
+    // C++11 [facet.num.put.virtuals] Table 88
+    // _GLIBCXX_RESOLVE_LIB_DEFECTS
+    // 4084. std::fixed ignores std::uppercase
+    bool __upper = __flags & ios_base::uppercase;
     if (__fltfield == ios_base::fixed)
-      *__fptr++ = 'f';
+      *__fptr++ = __upper ? 'F' : 'f';
     else if (__fltfield == ios_base::scientific)
-      *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e';
+      *__fptr++ = __upper ? 'E' : 'e';
 #if _GLIBCXX_USE_C99_STDIO
     else if (__fltfield == (ios_base::fixed | ios_base::scientific))
-      *__fptr++ = (__flags & ios_base::uppercase) ? 'A' : 'a';
+      *__fptr++ = __upper ? 'A' : 'a';
 #endif
     else
-      *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
+      *__fptr++ = __upper ? 'G' : 'g';
     *__fptr = '\0';
   }
 
diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc
new file mode 100644
index 00000000000..b7c7da11f86
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc
@@ -0,0 +1,46 @@ 
+// { dg-do run }
+// LWG 4084. std::fixed ignores std::uppercase
+// PR libstdc++/114862 std::uppercase not applying to nan's and inf's
+
+#include <sstream>
+#include <limits>
+#include <iomanip>
+#include <testsuite_hooks.h>
+
+void
+test_nan()
+{
+  std::ostringstream out;
+  double nan = std::numeric_limits<double>::quiet_NaN();
+  out << std::fixed;
+  out << ' ' << nan << ' ' << -nan;
+  out << std::uppercase;
+  out << ' ' << nan << ' ' << -nan;
+  out << std::showpoint;
+  out << ' ' << nan << ' ' << -nan;
+  out << std::showpos;
+  out << ' ' << nan << ' ' << -nan;
+  VERIFY( out.str() == " nan -nan NAN -NAN NAN -NAN +NAN -NAN" );
+}
+
+void
+test_inf()
+{
+  std::ostringstream out;
+  double inf = std::numeric_limits<double>::infinity();
+  out << std::fixed;
+  out << ' ' << inf << ' ' << -inf;
+  out << std::uppercase;
+  out << ' ' << inf << ' ' << -inf;
+  out << std::showpoint;
+  out << ' ' << inf << ' ' << -inf;
+  out << std::showpos;
+  out << ' ' << inf << ' ' << -inf;
+  VERIFY( out.str() == " inf -inf INF -INF INF -INF +INF -INF" );
+}
+
+int main()
+{
+  test_nan();
+  test_inf();
+}