From: Tomasz Kamiński Date: Fri, 6 Jun 2025 07:07:49 +0000 (+0200) Subject: libstdc++: Support wide characters output for sys_info and local_info [PR120565] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6dcba678030181527c6010551387917b8d734904;p=thirdparty%2Fgcc.git 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 Signed-off-by: Tomasz Kamiński --- diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index 9711a83cebe..c5c5e4bae53 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 661712f1238..99cbd740d5f 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 #include @@ -842,14 +842,14 @@ test_all() test_durations(); test_calendar(); test_time_points(); +#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI + test_infos(); +#endif } int main() { test_all(); -#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI - test_infos(); -#endif #ifdef _GLIBCXX_USE_WCHAR_T test_all();