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>();