This patch removes the partial specialization for float16_t and bfloat16_t
that formatted the values by casting to float. In consequence an implicit
specialization of generic floating-point specialization is used, and
to_chars overloads for their types are used.
As explained in r13-3591-g0ae26533b3e268 (that adds corresponding to_chars
overload), the shortest string (produced when no precision is specified)
is shorter for above, than float.

As formatter specializations were defined under the same condition as
corresponding to_chars overloads, the __formattable_float constrain on
formatter floating-point specialization makes it enable in same cases.

This reverts parts of r14-3305-g6cf214b4fc97f5 (revereted partially
in r14-3329-g27d0cfcb2b33de), leading to (necessary for correctness)
increase of the number template specializations. It also depends on
preserving values of above types (instead of float) in basic_format_arg
introduced r16-616-g9c9a7316adb996.

The specializations for float32_t and float64_t are left unchanged,
as their to_chars overloads are also implemented in terms of casting
to float/double respectivelly.

libstdc++-v3/ChangeLog:

        PR libstdc++/126731
        * include/std/format (std::formatter<_Float16, _CharT>)
        (std::formatter<__format::__bflt16_t, _CharT>): Remove
        partial specializations.
        * testsuite/std/format/formatter/ext_float.cc: Test output
        for closest value to 1/10.
---
As far as I can tell this case will not be affected by P3505R4
"Fix the default floating-point representation in std::format",
as float(0.1f16) is 1.998p-4, while 0.1 f is 1.99999ap-4, so
only later could use 0.1 as shortest string.

Testing on x86_64-linux. *format* passed in all standard modes,
-m32, debug and assertions. OK for trunk and 16?
(We cannot backport it to eariel standards due dependency described
above).

 libstdc++-v3/include/std/format               | 44 -------------------
 .../std/format/formatter/ext_float.cc         | 22 ++++++----
 2 files changed, 13 insertions(+), 53 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 729cb89ec60..8d530e883c3 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3003,28 +3003,6 @@ namespace __format
     };
 #endif
 
-#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
-  // Reuse __formatter_fp<C>::format<float, Out> for _Float16.
-  template<__format::__char _CharT>
-    struct formatter<_Float16, _CharT>
-    {
-      formatter() = default;
-
-      [[__gnu__::__always_inline__]]
-      constexpr typename basic_format_parse_context<_CharT>::iterator
-      parse(basic_format_parse_context<_CharT>& __pc)
-      { return _M_f.parse(__pc); }
-
-      template<typename _Out>
-       typename basic_format_context<_Out, _CharT>::iterator
-       format(_Float16 __u, basic_format_context<_Out, _CharT>& __fc) const
-       { return _M_f.format((float)__u, __fc); }
-
-    private:
-      __format::__formatter_fp<_CharT> _M_f;
-    };
-#endif
-
 #if defined(__FLT32_DIG__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
   // Reuse __formatter_fp<C>::format<float, Out> for _Float32.
   template<__format::__char _CharT>
@@ -3114,28 +3092,6 @@ namespace __format
     };
 #endif
 
-#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
-  // Reuse __formatter_fp<C>::format<float, Out> for bfloat16_t.
-  template<__format::__char _CharT>
-    struct formatter<__format::__bflt16_t, _CharT>
-    {
-      formatter() = default;
-
-      [[__gnu__::__always_inline__]]
-      constexpr typename basic_format_parse_context<_CharT>::iterator
-      parse(basic_format_parse_context<_CharT>& __pc)
-      { return _M_f.parse(__pc); }
-
-      template<typename _Out>
-       typename basic_format_context<_Out, _CharT>::iterator
-       format(__gnu_cxx::__bfloat16_t __u,
-              basic_format_context<_Out, _CharT>& __fc) const
-       { return _M_f.format((float)__u, __fc); }
-
-    private:
-      __format::__formatter_fp<_CharT> _M_f;
-    };
-#endif
 #endif // __cpp_lib_to_chars
 
   /** Format a pointer.
diff --git a/libstdc++-v3/testsuite/std/format/formatter/ext_float.cc 
b/libstdc++-v3/testsuite/std/format/formatter/ext_float.cc
index 82e696fa797..7b231b07006 100644
--- a/libstdc++-v3/testsuite/std/format/formatter/ext_float.cc
+++ b/libstdc++-v3/testsuite/std/format/formatter/ext_float.cc
@@ -4,10 +4,14 @@
 #include <testsuite_hooks.h>
 
 template<typename T>
-bool format_float()
+void
+verify_output()
 {
-    auto s = std::format("{:#} != {:<+7.3f}", (T)-0.0, (T)0.5);
-    return s == "-0. != +0.500 ";
+  auto s = std::format("{:#} != {:<+7.3f}", T(-0.0), T(0.5));
+  VERIFY( s == "-0. != +0.500 ");
+
+  s = std::format("{}", T(1)/T(10));
+  VERIFY( s == "0.1");
 }
 
 #if __cplusplus > 202002L
@@ -23,7 +27,7 @@ test_float16()
 {
 #if __FLT16_DIG__
   if constexpr (formattable<_Float16>)
-    VERIFY( format_float<_Float16>() );
+    verify_output<_Float16>();
   else
     std::puts("Cannot format _Float16 on this target");
 #endif
@@ -34,7 +38,7 @@ test_float32()
 {
 #if __FLT32_DIG__
   if constexpr (formattable<_Float32>)
-    VERIFY( format_float<_Float32>() );
+    verify_output<_Float32>();
   else
     std::puts("Cannot format _Float32 on this target");
 #endif
@@ -45,7 +49,7 @@ test_float64()
 {
 #if __FLT64_DIG__
   if constexpr (formattable<_Float64>)
-    VERIFY( format_float<_Float64>() );
+    verify_output<_Float64>();
   else
     std::puts("Cannot format _Float64 on this target");
 #endif
@@ -56,13 +60,13 @@ test_float128()
 {
 #ifdef __SIZEOF_FLOAT128__
   if constexpr (formattable<__float128>)
-    VERIFY( format_float<__float128>() );
+    verify_output<__float128>();
   else
     std::puts("Cannot format __float128 on this target");
 #endif
 #if __FLT128_DIG__
   if constexpr (formattable<_Float128>)
-    VERIFY( format_float<_Float128>() );
+    verify_output<_Float128>();
   else
     std::puts("Cannot format _Float128 on this target");
 #endif
@@ -75,7 +79,7 @@ test_bfloat16()
   using bfloat16_t = decltype(0.0bf16);
 
   if constexpr (formattable<bfloat16_t>)
-    VERIFY( format_float<bfloat16_t>() );
+    verify_output<bfloat16_t>();
   else
     std::puts("Cannot format bfloat16_t on this target");
 #endif
-- 
2.55.0

Reply via email to