https://gcc.gnu.org/g:6dcba678030181527c6010551387917b8d734904

commit r16-1205-g6dcba678030181527c6010551387917b8d734904
Author: Tomasz Kamiński <tkami...@redhat.com>
Date:   Fri Jun 6 09:07:49 2025 +0200

    libstdc++: Support wide characters output for sys_info and local_info 
[PR120565]
    
    Formatting sys_info as wchar_t require widening of the abbrev (zone) member.
    To support that we reuse the existing code in support for '%Z' specifier, 
for
    local_time_format, and produce output using singe format call with
    "[{0:%F %T},{1:%F %T},{2:%T},{3:%Q%q},{0:%Z}]" format string. As noted in 
the
    comment, produced output is locale independed, as it does not contain 
decimal
    separtors.
    
    For sys_info, the outputed literals are widended using _GLIBCXX_WIDEN, 
except
    opening and closing brackets, that are fetched from __format::_Separators.
    
            PR libstdc++/120565
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/chrono_io.h
            (operator<<(basic_ostream<_CharT, _Traits>&, const sys_info&))
            (operator<<(basic_ostream<_CharT, _Traits>&, const local_info&)):
            Support wchar_t as _CharT.
            * testsuite/std/time/format/empty_spec.cc: Instantiated test_infos 
for
            wchar_t and increase timeout.
    
    Reviewed-by: Jonathan Wakely <jwak...@redhat.com>
    Signed-off-by: Tomasz Kamiński <tkami...@redhat.com>

Diff:
---
 libstdc++-v3/include/bits/chrono_io.h              | 23 +++++++++++++---------
 .../testsuite/std/time/format/empty_spec.cc        |  8 ++++----
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index 9711a83cebed..c5c5e4bae53d 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -2944,9 +2944,14 @@ namespace __detail
     basic_ostream<_CharT, _Traits>&
     operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __i)
     {
-      __os << '[' << __i.begin << ',' << __i.end
-          << ',' << hh_mm_ss(__i.offset) << ',' << __i.save
-          << ',' << __i.abbrev << ']';
+      // n.b. only decimal separator is locale dependent for specifiers
+      // used below, as sys_info uses seconds and minutes duration, the
+      // output is locale-independent.
+      constexpr auto* __fs 
+       = _GLIBCXX_WIDEN("[{0:%F %T},{1:%F %T},{2:%T},{3:%Q%q},{0:%Z}]");
+      local_seconds __lb(__i.begin.time_since_epoch());
+      __os << std::format(__fs, local_time_format(__lb, &__i.abbrev),
+                         __i.end, __i.offset, __i.save);
       return __os;
     }
 
@@ -2955,19 +2960,19 @@ namespace __detail
     basic_ostream<_CharT, _Traits>&
     operator<<(basic_ostream<_CharT, _Traits>& __os, const local_info& __li)
     {
-      __os << '[';
+      __os << __format::_Separators<_CharT>::_S_squares()[0];
       if (__li.result == local_info::unique)
        __os << __li.first;
       else
        {
          if (__li.result == local_info::nonexistent)
-           __os << "nonexistent";
+           __os << _GLIBCXX_WIDEN("nonexistent");
          else
-           __os << "ambiguous";
-         __os << " local time between " << __li.first;
-         __os << " and " << __li.second;
+           __os << _GLIBCXX_WIDEN("ambiguous");
+         __os << _GLIBCXX_WIDEN(" local time between ") << __li.first;
+         __os << _GLIBCXX_WIDEN(" and ") << __li.second;
        }
-      __os << ']';
+      __os << __format::_Separators<_CharT>::_S_squares()[1];
       return __os;
     }
 
diff --git a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc 
b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
index 661712f1238b..99cbd740d5f5 100644
--- a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
+++ b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
@@ -1,6 +1,6 @@
 // { dg-do run { target c++20 } }
 // { dg-require-effective-target hosted }
-// { dg-timeout-factor 4 }
+// { dg-timeout-factor 5 }
 
 #include <chrono>
 #include <ranges>
@@ -842,14 +842,14 @@ test_all()
   test_durations<CharT>();
   test_calendar<CharT>();
   test_time_points<CharT>();
+#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI
+  test_infos<CharT>();
+#endif
 }
 
 int main()
 {
   test_all<char>();
-#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI
-  test_infos<char>();
-#endif
 
 #ifdef _GLIBCXX_USE_WCHAR_T
   test_all<wchar_t>();

Reply via email to