]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: Implement correct locale-specific chrono formatting [PR110719]
authorJonathan Wakely <jwakely@redhat.com>
Tue, 18 Jul 2023 11:46:07 +0000 (12:46 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Wed, 19 Jul 2023 11:36:59 +0000 (12:36 +0100)
commitf4bce119f617dc4663fb43f55784908daf16b4b6
treec5a250c2346089e4f97a4824d69de83f001efdb1
parentc1e420549f2305efb70ed37e693d380724eb7540
libstdc++: Implement correct locale-specific chrono formatting [PR110719]

This fixes some TODOs in the C++20 <chrono> format support, where the
locale-specific output was incorrect or unimplemented. The approach
taken here is to either use the formatting locale's std::time_put facet
to do the formatting, or to remove subsecond precision from time points
so that locale-specific formats don't print fractional seconds. This
ensures that we are consistent with what the std::time_put facet would
print (which never includes fractional seconds) even if we actually
reimplement the formatting by hand instead of using the facet.

This also fixes a misplaced statement that allowed modifiers for %Z
which should have been on %z instead. There was also some ill-formed
code in an untested branch for formatting time zone names to wide
characters. A new test for zoned_time I/O has been added to exercise
that code properly.

libstdc++-v3/ChangeLog:

PR libstdc++/110719
* include/bits/chrono_io.h (__formatter_chrono::_M_parse): Fix
allowed modifiers for %z and %Z. Fix -Wparentheses and
-Wnarrowing warnings.
(__formatter_chrono::_M_format): Call new functions for %d, %e,
%H, %I, %m and %M.
(__formatter_chrono::_M_c): Use _S_floor_seconds to remove
subsecond precision.
(__formatter_chrono::_M_C_y_Y): Use _M_locale_fmt to handle
modifiers.
(__formatter_chrono::_M_e): Replace with _M_d_e and use
_M_locale_fmt.
(__formatter_chrono::_M_I): Replace with _M_H_I and use
_M_locale_fmt.
(__formatter_chrono::_M_m): New function.
(__formatter_chrono::_M_M): New function.
(__formatter_chrono::_M_r): Use _M_locale_fmt.
(__formatter_chrono::_M_S): Likewise.
(__formatter_chrono::_M_u_w): Likewise.
(__formatter_chrono::_M_U_V_W): Likewise.
(__formatter_chrono::_M_X): Use _S_floor_seconds.
(__formatter_chrono::_M_Z): Fix untested branch for wchar_t.
(__formatter_chrono::_S_altnum): Remove function.
(__formatter_chrono::_S_dd_zero_fill): Remove function.
(__formatter_chrono::_S_floor_seconds): New function.
(__formatter_chrono::_M_locale_fmt): New function.
* testsuite/std/time/clock/system/io.cc: Adjust expected output
for locale-specific formats and check modified formats.
* testsuite/std/time/clock/utc/io.cc: Likewise.
* testsuite/std/time/zoned_time/io.cc: New test.
libstdc++-v3/include/bits/chrono_io.h
libstdc++-v3/testsuite/std/time/clock/system/io.cc
libstdc++-v3/testsuite/std/time/clock/utc/io.cc
libstdc++-v3/testsuite/std/time/zoned_time/io.cc [new file with mode: 0644]