aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/std/time
AgeCommit message (Collapse)AuthorFilesLines
6 dayslibstdc++: Fix test when dual abi disabledFrançois Dumont1-2/+2
When !_GLIBCXX_USE_DUAL_ABI the old COW std::string implementation is being used which do not generate the expected error diagnostics. libstdc++-v3/ChangeLog: * testsuite/std/time/format/data_not_present_neg.cc: Remove _GLIBCXX_USE_DUAL_ABI check. Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-07-18libstdc++: Fixed localized empty-spec formatting for months/weekdays [PR121154]Tomasz Kamiński2-0/+9
Previously for localized output, if _M_debug option was set, the _M_check_ok completed succesfully and _M_locale_fmt was called for months/weekdays that are !ok(). This patch lifts debug checks from each conversion function into _M_check_ok, that in case of !ok() values return a string_view containing the kind of calendar data, to be included after "is not a valid" string. The localized output (_M_locale_fmt) is not used if string is non-empty. Emitting of this message is now handled in _M_format_to, further reducing each specifier function. To handle weekday (%a,%A) and month (%b,%B), _M_check_ok now accepts a mutable reference to conversion specifier, and updates it to corresponding numeric value (%w, %m). Extra care needs to be taken to handle a month(0) that needs to be printed as single digit in debug format. Finally, the _M_time_point is replaced with _M_needs_ok_check member, that indicates if input contains any user-suplied values that are checked for being ok() and these values are referenced in chrono-specs. PR libstdc++/121154 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (_ChronoSpec::_M_time_point): Remove. (_ChronoSpec::_M_needs_ok_check): Define (__formatter_chrono::_M_parse): Set _M_needs_ok_check. (__formatter_chrono::_M_check_ok): Check values also for debug mode, and return __string_view. (__formatter_chrono::_M_format_to): Handle results of _M_check_ok. (__formatter_chrono::_M_wi, __formatter_chrono::_M_a_A) (__formatter_chrono::_M_b_B, __formatter_chrono::_M_C_y_Y) (__formatter_chrono::_M_d_e, __formatter_chrono::_M_F): Removed handling of _M_debug. (__formatter_chrono::__M_m): Print zero unpadded in _M_debug mode. (__formatter_duration::_S_spec_for): Remove _M_time_point refernce. (__formatter_duration::_M_parse): Override _M_needs_ok_check. * testsuite/std/time/month/io.cc: Test for localized !ok() values. * testsuite/std/time/weekday/io.cc: Test for localized !ok() values.
2025-07-07libstdc++: Format chrono %a/%A/%b/%h/%B/%p using locale's time_put [PR117214]XU Kailiang2-0/+44
C++ formatting locale could have a custom time_put that performs differently from the C locale, so do not use __timepunct directly, instead all of above specifiers use _M_locale_fmt. For %a/%A/%b/%h/%B, the code handling the exception is now moved to the _M_check_ok function, that is invoked before handling of the conversion specifier. For time_points the values of months/weekday are computed, and thus are always ok(), this information is indicated by new _M_time_point member of the _ChronoSpec. The different behavior of j specifier for durations and time_points/calendar types, is now handled using only _ChronoParts, and _M_time_only in _ChronoSpec is no longer needed, thus it was removed. PR libstdc++/117214 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (_ChronoSpec::_M_time_only): Remove. (_ChronoSpec::_M_time_point): Define. (__formatter_chrono::_M_parse): Use __parts to determine interpretation of j. (__formatter_chrono::_M_check_ok): Define. (__formatter_chrono::_M_format_to): Invoke _M_check_ok. (__formatter_chrono::_M_a_A, __formatter_chrono::_M_b_B): Move exception throwing to _M_check_ok. (__formatter_chrono::_M_j): Use _M_needs to define interpretation. (__formatter_duration::_S_spec_for): Set _M_time_point. * testsuite/std/time/format/format.cc: Test for exception for !ok() months/weekday. * testsuite/std/time/format/pr117214_custom_timeput.cc: New test. Co-authored-by: Tomasz Kaminski <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: XU Kailiang <xu2k3l4@outlook.com> Signed-off-by: Tomasz Kaminski <tkaminsk@redhat.com>
2025-06-27libstdc++: Fix warnings introduced by type-erasing for chrono commits [PR110739]Tomasz Kamiński1-17/+26
The r16-1709-g4b3cefed1a08344495fedec4982d85168bd8173f caused `-Woverflow` in empty_spec.cc file. This warning is not cause by any issue in shipping code, and results in taking to much shortcut when implementing a test-only custom representation type Rep, where long was always used to store a value. In particular common type for Rep and long long int, was de-facto long. This is addressed by adding Under template parameter, that controls the type of stored value, and handling it properly in common_type specializations. No changes to shipping code are necessary. Secondly, extracting _M_locale_fmt calls in r16-1712-gcaac94, resulted in __ctx format parameter no longer being used. This patch removes such parameter entirely, and replace _FormatContext template parameter, with _OutIter parameter for __out. For consistency type of the __out is decoupled from _FormatContext, for functions that still need context: * to extract locale (_M_A_a, _M_B_b, _M_c, _M_p, _M_r, _M_subsecs) * perform formatting for duration/subseconds (_M_Q, _M_T, _M_S, _M_subsecs) PR libstdc++/110739 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono::_M_format_to): Rename _Out to _OutIter for consistency, and update calls to specifier functions. (__formatter_chrono::_M_wi, __formatter_chrono::_M_C_y_Y) (__formatter_chrono::_M_D_x, __formatter_chrono::_M_d_e) (__formatter_chrono::_M_F, __formatter_chrono::_M_g_G) (__formatter_chrono::_M_H_I, __formatter_chrono::_M_j) (__formatter_chrono::_M_m, __formatter_chrono::_M_M) (__formatter_chrono::_M_q, __formatter_chrono::_M_R_X) (__formatter_chrono::_M_u_w, __formatter_chrono::_M_U_V_W) (__formatter_chrono::_M_z, __formatter_chrono::_M_z): Remove _FormatContext parameter, and introduce _OutIter for __out type. (__formatter_chrono::_M_a_A, __formatter_chrono::_M_B_b) (__formatter_chrono::_M_p, __formatter_chrono::_M_Q) (__formatter_chrono::_M_r, __formatter_chrono::_M_S) (__formatter_chrono::_M_subsecs, __formatter_chrono::_M_T): Introduce separate _OutIter template parameter for __out. (__formatter_chrono::_M_c, __formatter_chrono::_M_T): Likewise, and adjust calls to specifiers functions. * testsuite/std/time/format/empty_spec.cc: Make underlying type for Rep configurable.
2025-06-26libstdc++: Type-erase chrono-data for formatting [PR110739]Tomasz Kamiński1-8/+8
This patch reworks the formatting for the chrono types, such that they are all formatted in terms of _ChronoData class, that includes all required fields. Populating each required field is performed in formatter for specific type, based on the chrono-spec used. To facilitate above, the _ChronoSpec now includes additional _M_needed field, that represnts the chrono data that is referenced by format spec (this value is also configured for __defSpec). This value differs from the value of __parts passed to _M_parse, which does include all fields that can be computed from input (e.g. weekday_indexed can be computed for year_month_day). Later it is used to fill _ChronoData, in particular _M_fill_* family of functions, to determine if given field needs to be set, and thus its value needs to be computed. In consequence _ChronoParts enum was extended with additional values, that allows more fine grained identification: * _TimeOfDay is separated into _HoursMinutesSeconds and _Subseconds, * _TimeZone is separated into _ZoneAbbrev and _ZoneOffset, * _LocalDays, _WeekdayIndex are defined and in included in _Date, * _Duration is removed, and instead _EpochUnits and _UnitSuffix are introduced. Furthermore, to avoid name conflicts _ChonoParts is now defined as enum class, with additional operators that simplify uses. In addition to fields that can be printed using chrono-spec, _ChronoData stores: * Total days in wall time (_M_ldays), day of year (_M_day_of_year) - used by struct tm construction, and for ISO calendar computation. * Total seconds in wall time (_M_lseconds) - this value may be different from sum of days, hours, minutes, seconds (e.g. see utc_time below). Included to allow future extension, like printing total minutes. * Total seconds since epoch - due offset different from above. Again to be used with future extension (e.g. %s as proposed in P2945R1). * Subseconds - count of attoseconds (10^(-18)), in addition to printing can be used to compute fractional hours, minutes. The both total seconds fields use single _TotalSeconds enumerator in _ChronoParts, that when present in combination with _EpochUnits or _LocalDays indicates that _M_eseconds (_EpochSeconds) or _M_lseconds (_LocalSeconds) are provided/required. To handle type formatting of time since epoch ('%Q'|_EpochUnits), we use the format_args mechanism, where the result of +d.count() (see LWG4118) is erased into make_format_args to local __arg_store, that is later referenced by _M_ereps (_M_ereps.get(0)). To handle precision values, and in prepartion to allow user to configure ones, we store the precision as third element of _M_ereps (_M_ereps.get(2)), this allows duration with precision to be printed using "{0:{2}}". For subseconds the precision is handled differently depending on the representation: * for integral reps, _M_subseconds value is used to determine fractional value, precision is trimmed to 18 digits; * for floating-points, _M_ereps stores duration<Rep> initialized with only fractional seconds, that is later formatted with precision. Always using _M_subseconds fields for integral duration, means that we do not use formattter for user-defined durations that are considered to be integral (see empty_spec.cc file change). To avoid potentially expensive computation of _M_subseconds, we make sure that _ChronoParts::_Subseconds is set only if _Subseconds are needed. In particular we remove this flag for localized ouput in _M_parse. Construction of the _M_ereps as described above is handled by __formatter_duration, that is then used to format duration, hh_mm_ss and time_points specializations. This class also handles _UnitSuffix, the _M_units_suffix field is populated either with predefined suffix (chrono::__detail::__units_suffix) or one produced locally. Finally, formatters for types listed below contains type specific logic: * hh_mm_ss - we do not compute total duration and seconds, unless explicitly requested, as such computation may overflow; * utc_time - for time during leap second insertion, the _M_seconds field is increased to 60; * __local_time_fmt - exception is thrown if zone offset (_ZoneOffset) or abbrevation (_ZoneAbbrev) is requsted, but corresponding pointer is null, futhermore conversion from `char` to `wchar_t` for abbreviation is performed if needed. PR libstdc++/110739 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__format::__no_timezone_available): Removed, replaced with separate throws in formatter for __local_time_fmt (__format::_ChronoParts): Defined additional enumertors and declared as enum class. (__format::operator&(_ChronoParts, _ChronoParts)) (__format::operator&=(_ChronoParts&, _ChronoParts)) (__format::operator-(_ChronoParts, _ChronoParts)) (__format::operator-=(_ChronoParts&, _ChronoParts)) (__format::operator==(_ChronoParts, decltype(nullptr))) (_ChronoSpec::_M_time_only, _ChronoSpec::_M_floating_point_rep) (_ChronoSpec::_M_custom_rep, _ChronoSpec::_M_needed) (_ChronoSpec::_M_needs, __format::_ChronoData): Define. (__format::__formatter_chrono): Redefine to accept _ChronoData. (__formatter_chrono::_M_format_to_ostream): Moved to __formatter_duration. (__format::__formatter_duration): Define. (__formatter_chrono_info::format): Pass value-constructed _ChronoData. (std::formatter<chrono::day, _CharT>) (std::formatter<chrono::month, _CharT>) (std::formatter<chrono::year, _CharT>) (std::formatter<chrono::weekday, _CharT>) (std::formatter<chrono::weekday_indexed, _CharT>) (std::formatter<chrono::weekday_last, _CharT>) (std::formatter<chrono::month_day, _CharT>) (std::formatter<chrono::month_day_last, _CharT>) (std::formatter<chrono::month_weekday, _CharT>) (std::formatter<chrono::month_weekday_indexed, _CharT>) (std::formatter<chrono::month_weekday_last, _CharT>) (std::formatter<chrono::year_month, _CharT>) (std::formatter<chrono::year_month_day, _CharT>) (std::formatter<chrono::year_month_day_last, _CharT>) (std::formatter<chrono::year_month_weekday, _CharT>) (std::formatter<chrono::year_month_weekday_indexed, _CharT>) (std::formatter<chrono::year_month_weekday_last, _CharT>): Construct _ChronoData in format, and configure _M_needed in _ChronoSpec. (std::formatter<chrono::duration<_Rep, _Period>, _CharT>) (std::formatter<chrono::hh_mm_ss<_Duration>, _CharT>) (std::formatter<chrono::sys_time<_Duration>, _CharT>) (std::formatter<chrono::utc_time<_Duration>, _CharT>) (std::formatter<chrono::tai_time<_Duration>, _CharT>) (std::formatter<chrono::gps_time<_Duration>, _CharT>) (std::formatter<chrono::file_time<_Duration>, _CharT>) (std::formatter<chrono::local_time<_Duration>, _CharT>) (std::formatter<chrono::_detail::__local_time_fmt<_Duration>, _CharT>): Reworked in terms of __formatter_duration and _ChronoData. (std::formatter<chrono::_detail::__utc_leap_second<_Duration>, _CharT>): Removed. (_Parser<_Duration>::operator()): Adjusted for _ChronoParts being enum class. * include/std/chrono (__detail::__utc_leap_second): Removed, replaced with simply bumping _M_seconds in _ChronoData. * testsuite/std/time/format/empty_spec.cc: Updated %S integral ouput. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-06-25libstdc++: Test for %S precision for durations with integral representation.Tomasz Kamiński1-5/+99
Existing test are extented to cover cases where not precision is specified, or it is specified to zero. The precision value is ignored in all cases. libstdc++-v3/ChangeLog: * testsuite/std/time/format/precision.cc: New tests.
2025-06-25libstdc++: Report compilation error on formatting "%d" from month_last ↵Tomasz Kamiński1-0/+164
[PR120650] For month_day we incorrectly reported day information to be available, which lead to format_error being thrown from the call to formatter::format at runtime, instead of making call to format ill-formed. The included test cover most of the combinations of _ChronoParts and format specifiers. PR libstdc++/120650 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (formatter<chrono::month_day_last,_CharT>::parse): Call _M_parse with only Month being available. * testsuite/std/time/format/data_not_present_neg.cc: New test.
2025-06-13libstdc++: Format %r, %x and %X using locale's time_put facet [PR120648]Tomasz Kamiński1-5/+38
Similarly to issue reported for %c in PR117214, the format string for locale specific time (%r, %X) and date (%x) representations may contain specifiers not accepted by chrono-spec, leading to exception being thrown. This happened for following conversion specifier and locale combinations: * %r, %X for aa_DJ.UTF-8, ar_SA.UTF-8 * %x for ca_AD.UTF-8, my_MM.UTF-8 This fix follows approach from r15-8490-gc24a1d5, and uses time_put to emit localized date format. The existing _M_c is reworked to handle all locale dependent conversion specifies, by accepting them as argument. It is also renamed to _M_c_r_x_X. PR libstdc++/120648 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono::_M_format_to): Handle %c, %r, %x and %X by passing them to _M_c_r_x_X. (__formatter_chrono::_M_c_r_x_X): Reworked from _M_c. (__formatter_chrono::_M_c): Renamed into above. (__formatter_chrono::_M_r, __formatter_chrono::_M_x) (__formatter_chrono::_M_X): Removed. * testsuite/std/time/format/pr117214.cc: New tests for %r, %x, %X with date, time and durations.
2025-06-13libstdc++: Replace _CharT template parameter with CharT in format tests.Tomasz Kamiński4-86/+86
As pointed out by Daniel Krügler we do not need to use reserved name in tests. libstdc++-v3/ChangeLog: * testsuite/23_containers/vector/bool/format.cc: Replaced _CharT with CharT. * testsuite/std/format/debug.cc: Likewise. * testsuite/std/format/ranges/adaptors.cc: Likewise. * testsuite/std/format/ranges/formatter.cc: Likewise. * testsuite/std/format/ranges/map.cc: Likewise. * testsuite/std/format/ranges/sequence.cc: Likewise. * testsuite/std/format/ranges/string.cc: Likewise. * testsuite/std/format/tuple.cc: Likewise. * testsuite/std/time/format/empty_spec.cc: Likewise. * testsuite/std/time/format/pr120114.cc: Likewise. * testsuite/std/time/format/pr120481.cc: Likewise. * testsuite/std/time/format/precision.cc: Likewise.
2025-06-13libstdc++: Test chrono-spec containing only whitespaces.Tomasz Kamiński1-0/+56
libstdc++-v3/ChangeLog: * testsuite/std/time/format/whitespace.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-06-11libstdc++: Test for precision and floting point durations.Tomasz Kamiński2-0/+158
libstdc++-v3/ChangeLog: * testsuite/std/time/format/empty_spec.cc: New tests. * testsuite/std/time/format/precision.cc: New test.
2025-06-06libstdc++: Support wide characters output for sys_info and local_info [PR120565]Tomasz Kamiński1-4/+4
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 <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-06-06libstdc++: Test for formatting with empty spec for local_info and sys_info.Tomasz Kamiński1-3/+108
We do not test with wchar_t currently, as operator<< (and format) are ill-formed in such case, because we do not widen abbrev member of local_info. Adding a tests for behavior of the ostream operator and the formatting with empty chrono-spec for the chrono types. The coverage is now complete: * sys_info, local_info in this commit, * time point, zoned_time and local_time_format in r16-1107-g3cfa53aa95a19c, * duration and hh_mm_ss in r16-1099-gac0a04b7a254fb, * calendar types in r16-1016-g28a17985dd34b7. Finally, the timeout for the test was increased again and preprocessor checks for zoned_time where changed to _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI to match ones from bits/chrono_io.h file. libstdc++-v3/ChangeLog: * testsuite/std/time/format/empty_spec.cc: New tests and increased timeout. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-06-05libstdc++: Fix formatting of 3-digits months,day,weekday and hour [PR120481]Tomasz Kamiński2-8/+328
This patch fixes the handle multiple digits values for the month, day, weekday and hour, when used with the %m, %d, %e, %m, %u, %w, %H, and %D, %F specifiers. The values are now printed unmodified. This patch also fixes printing negative year with %F, where the values was not padded to four digits. Furthemore, the %I,%p are adjusted to handle input with hours values set to over 24 hours. In the case the values is interpretd modulo 24. This was already the case for %r (locale's 12-hour clock), as we convert the input into seconds. In case of %u, %w we print values unchanged, this makes the behavior of this specifiers equivalent to printing the iso_encoding and c_encoding respectively. As constructing weekday from value 7, initializes it with 0, the !ok() weekdays values are always greater of equal eight, so they are clearly distinguishable. The months, weekday, day values that can have 3 decimal digit as maximum (range [0, 255]), we are using new _S_str_d1, _S_str_d2 that return string_view containing textual representation, without padding or padded to two digits. This function accepts are 3 character buffer, that are used for 3 digits number. In other cases, we return _S_digit and _S_two_digits result directly. The former is changed to return string_view to facilitate this. For %F and %D when at least one component have more digits that expected (2 for month and day, 4 for year), we produce output using format_to with appropriate format string. Otherwise the representation is produced in local char buffer. Two simply fill this buffer, _S_fill_two_digits function was added. We also make sure that minus is not included in year width for %F. The handling of %C, %Y, %y was adjusted to use similar pattern, for years with more than two digits. To support that the order of characters in _S_chars was adjusted so it contain "-{}" string. For handling of %H, we print 3 or more digits values using format_to. The handling for large hours values in %T and %R was changed, so they printed using format_to, and otherwise we use same stack buffer as for minutes to print them. PR libstdc++/120481 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__format::_S_chars): Reorder so it contains "-{}". (__format::_S_colon, __format::_S_slash, __format::_S_space) (__format::_S_plus_minus): Updated starting indicies. (__format::_S_minus_empty_spec): Define. (__formatter_chrono::_M_C_y_Y, __formatter_chrono::_M_R_T): Rework implementation. (__formatter_chrono::_M_d_e, __formatter_chrono::_M_F) (__formatter_chrono::_M_m, __formatter_chrono::_M_u_w) (__formatter_chrono::_M_H_I, __formatter_chrono::_M_p): Handle multi digits values. (__formatter_chrono::_S_digit): Return string view. (__formatter_chrono::_S_str_d1, __formatter_chrono::_S_str_d2) (__formatter_chrono::_S_fill_two_digits): Define. * testsuite/std/time/format/empty_spec.cc: Update test for year_month_day, that uses '%F'. * testsuite/std/time/format/pr120481.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-06-04libstdc++: Skip time zone format testing for COW std::stringJonathan Wakely1-0/+4
This is needed when testing with -D_GLIBCXX_USE_CXX11_ABI=0 to fix: FAIL: std/time/format/empty_spec.cc -std=gnu++20 (test for excess errors) libstdc++-v3/ChangeLog: * testsuite/std/time/format/empty_spec.cc: Only test time zones for cxx11 string ABI.
2025-06-04libstdc++: Test for formatting with empty spec for time points.Tomasz Kamiński1-14/+194
Adding a tests for behavior of the ostream operator and the formatting with empty chrono-spec for the chrono types. Current coverage is: * time point, zoned_time and local_time_format in this commit, * duration and hh_mm_ss in r16-1099-gac0a04b7a254fb, * calendar types in r16-1016-g28a17985dd34b7. libstdc++-v3/ChangeLog: * testsuite/std/time/format/empty_spec.cc: New tests. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-06-04libstdc++: Fix format call and test formatting with empty specs for durations.Tomasz Kamiński1-0/+271
This patches fixes an obvious error, where the output iterator argument was missing for call to format_to, when duration with custom representation types are used. It's also adding the test for behavior of ostream operator and the formatting with empty chron-spec for the chrono types. Current coverage is: * duration and hh_mm_ss in this commit, * calendar types in r16-1016-g28a17985dd34b7. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono:_M_s): Add missing __out argument to format_to call. * testsuite/std/time/format/empty_spec.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-30libstdc++: Test for formatting with empty spec for calendar types.Tomasz Kamiński1-0/+301
Adding a test for behavior of the ostream operator and the formatting with empty chron-spec for the chrono types. This commit covers calendar types. libstdc++-v3/ChangeLog: * testsuite/std/time/format/empty_spec.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-19libstdc++: Fix std::format of chrono::local_days with {} [PR120293]Jonathan Wakely1-0/+3
Formatting of chrono::local_days with an empty chrono-specs should be equivalent to inserting it into an ostream, which should use the overload for inserting chrono::sys_days into an ostream. The implementation of empty chrono-specs in _M_format_to_ostream takes some short cuts, and that wasn't being done correctly for chrono::local_days. libstdc++-v3/ChangeLog: PR libstdc++/120293 * include/bits/chrono_io.h (_M_format_to_ostream): Add special case for local_time convertible to local_days. * testsuite/std/time/clock/local/io.cc: Check formatting of chrono::local_days. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-07libstdc++: Fix width computation for the chrono formatting [PR120114]Tomasz Kamiński1-0/+125
Use `__unicode::_field_width` to compute the field width of the output when writting the formatted output for std::chrono::types. This applies both to characters copied from format string, and one produced by localized formatting. We also use _Str_sink::view() instead of get(), which avoids copying the content of the buffer to std::string in case of small output. PR libstdc++/120114 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono::_M_format): Use __field_width. * testsuite/std/time/format/pr120114.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-31libstdc++: Constrain formatters for chrono types [PR119517]Tomasz Kamiński1-0/+43
The formatters for chrono types defined the parse/format methods as accepting unconstrained types, this in combination with lack of constrain on _CharT lead to them falsely satisfying formattable requirements for any type used as character. This patch adjust the fromatter<T, CharT>::parse signature to: constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc); And formatter<T, CharT>::format to: template<typename _Out> typename basic_format_context<_Out, _CharT>::iterator format(const T& __t, basic_format_context<_Out, _CharT>& __fc) const; Furthermore we _CharT with __format::__char (char or wchar_t), PR libstdc++/119517 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (formatter): Add __format::__char for _CharT and adjust parse and format method signatures. * testsuite/std/time/format/pr119517.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-27libstdc++-v3 testsuite: fix malformed dg-require-static-libstdcxx directivesDavid Malcolm1-1/+1
I believe these don't get detected by DejaGnu's regexp. Found by dg-lint. libstdc++-v3/ChangeLog: * testsuite/17_intro/shared_with_static_deps.cc: Fix malformed dg-require-static-libstdcxx directive. * testsuite/17_intro/static.cc: Likewise. * testsuite/18_support/type_info/110572.cc: Likewise. * testsuite/20_util/to_chars/4.cc: Likewise. * testsuite/std/time/tzdb_list/pr118811.cc: Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2025-03-21libstdc++: Fix localized %c formatting for non-UTC times [PR117214]Jonathan Wakely1-0/+65
The previous commit fixed most cases of %c formatting, but it incorrectly prints times using the system's local time zone. This only matters if the locale's %c format includes %Z, but some do. To print a correct value for %Z we can set tm.tm_zone to either "UTC" or the abbreviation passed to the formatter in the local-time-format-t structure. For local times with no info and for systems that don't support tm_zone (which is new in POSIX.1-2024) we just set tm_isdst = -1 so that no zone name is printed. In theory, a locale's %c format could use %z which should print a +hhmm offset from UTC. I'm unsure how to control that though. The new tm_gmtoff field in combination with tm_isdst != -1 seems like it should work, but using that without also setting tm_zone causes the system zone to be used for %Z again. That means local_time_format(lt, nullptr, &off) might work for a locale that uses %z but prints the wrong thing for %Z. This commit doesn't set tm_gmtoff even if _M_offset_sec is provided for a local-time-format-t value. libstdc++-v3/ChangeLog: PR libstdc++/117214 * configure.ac: Use AC_STRUCT_TIMEZONE. * config.h.in: Regenerate. * configure: Regenerate. * include/bits/chrono_io.h (__formatter_chrono::_M_c): Set tm_isdst and tm_zone. * testsuite/std/time/format/pr117214.cc: Check %c formatting of zoned_time and local time.
2025-03-21libstdc++: Fix localized D_T_FMT %c formatting for <chrono> [PR117214]XU Kailiang1-0/+34
Formatting a time point with %c was implemented by calling std::vprint_to with format string constructed from locale's D_T_FMT string, but in some locales this string contains strftime specifiers which are not valid for chrono-specs, e.g. %l. So just use _M_locale_fmt to avoid this problem. libstdc++-v3/ChangeLog: PR libstdc++/117214 * include/bits/chrono_io.h (__formatter_chrono::_M_c): Use _M_locale_fmt to format %c time point. * testsuite/std/time/format/pr117214.cc: New test. Signed-off-by: XU Kailiang <xu2k3l4@outlook.com> Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
2025-03-21libstdc++: Use formatting locale for std::time_put formatsJonathan Wakely1-0/+33
When using std::time_put to format a chrono value, we should imbue the formatting locale into the stream. This ensures that when std::time_put::do_put uses a ctype or __timepunct facet from the locale, it gets the correct facets. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono::_M_locale_fmt): Imbue locale into ostringstream. * testsuite/std/time/format/localized.cc: Check that correct locale is used for call to time_put::put. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-02-20libstdc++: Use init_priority attribute for tzdb globals [PR118811]Jonathan Wakely1-0/+25
When linking statically to libstdc++.a (or to libstdc++_nonshared.a in the RHEL devtoolset compiler) there's a static initialization order problem where user code might be constructed before the std::chrono::tzdb_list globals, and so might try to use them after they've already been destroyed. Use the init_priority attribute on those globals so that they are initialized early. Since r15-7511-g4e7f74225116e7 we can disable the warnings for using a reserved priority using a diagnostic pragma. libstdc++-v3/ChangeLog: PR libstdc++/118811 * src/c++20/tzdb.cc (tzdb_list::_Node): Use init_priority attribute on static data members. * testsuite/std/time/tzdb_list/pr118811.cc: New test.
2025-01-02Update copyright years.Jakub Jelinek33-33/+33
2024-12-29libstdc++-v3/testsuite/.../year_month_day/3.cc, 4.cc: Cut down for simulatorsHans-Peter Nilsson2-2/+19
These two long-running tests happened to fail for me when run in parallel (nprocs - 1) compared to a serial run, for target mmix on my laptop. The runtime is 3m40s for 3.cc before this change, and 0.9s afterwards. * testsuite/std/time/year_month_day/3.cc (test01): Add ifdeffery to limit the tested dates. For simulators, pass start and end dates limiting the tested range to 100000 days, centered on days (0). * testsuite/std/time/year_month_day/4.cc: Ditto.
2024-10-11libstdc++: Fix localized %c formatting for <chrono> [PR117085]Jonathan Wakely3-0/+19
When formatting a time point with %c we call std::vformat_to using the formatting locale's D_T_FMT string, but we weren't adding the L option to the format string. This meant we always interpreted D_T_FMT in the C locale, instead of using the formatting locale as obviously intended when %c is used. libstdc++-v3/ChangeLog: PR libstdc++/117085 * include/bits/chrono_io.h (__formatter_chrono::_M_c): Add L option to format string. * testsuite/std/time/format.cc: Move to... * testsuite/std/time/format/format.cc: ...here. * testsuite/std/time/format_localized.cc: Move to... * testsuite/std/time/format/localized.cc: ...here. * testsuite/std/time/format/pr117085.cc: New test.
2024-10-02libstdc++: Fix rounding in chrono::parseJonathan Wakely2-1/+40
I noticed that chrono::parse was using duration_cast and time_point_cast to convert the parsed value to the result. Those functions truncate towards zero, which is not generally what you want. Especially for negative times before the epoch, where truncating towards zero rounds "up" towards the next duration/time_point. Using chrono::round is typically better, as that rounds to nearest. However, while testing the fix I realised that rounding to the nearest can give surprising results in some cases. For example if we parse a chrono::sys_days using chrono::parse("F %T", "2024-09-22 18:34:56", tp) then we will round up to the next day, i.e. sys_days(2024y/09/23). That seems surprising, and I think 2024-09-22 is what most users would expect. This change attempts to provide a hybrid rounding heuristic where we use chrono::round for the general case, but when the result has a period that is one of minutes, hours, days, weeks, or years then we truncate towards negative infinity using chrono::floor. This means that we truncate "2024-09-22 18:34:56" to the start of the current minute/hour/day/week/year, instead of rounding up to 2024-09-23, or to 18:35, or 17:00. For a period of months chrono::round is used, because the months duration is defined as a twelfth of a year, which is not actually the length of any calendar month. We don't want to truncate to a whole number of "months" if that can actually go from e.g. 2023-03-01 to 2023-01-31, because February is shorter than chrono::months(1). libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__detail::__use_floor): New function. (__detail::__round): New function. (from_stream): Use __detail::__round. * testsuite/std/time/clock/file/io.cc: Check for expected rounding in parse. * testsuite/std/time/clock/gps/io.cc: Likewise.
2024-09-15libstdc++: Enable most of <chrono> for freestandingJonathan Wakely1-0/+52
This makes durations, time points and calendrical types available for freestanding. The clocks and time zone utilities are disabled for freestanding, as they require functions in the hosted lib. Add support for a new macro _GLIBCXX_NO_FREESTANDING_CHRONO which can be used to explicitly disable <chrono> for freestanding. libstdc++-v3/ChangeLog: * doc/xml/manual/using.xml (_GLIBCXX_NO_FREESTANDING_CHRONO): Document macro. * doc/html/*: Regenerate. * include/bits/chrono.h [_GLIBCXX_NO_FREESTANDING_CHRONO]: Only include <bits/require_hosted.h> when this macro is defined. [_GLIBCXX_HOSTED]: Only define clocks for hosted. * include/bits/version.def (chrono_udls): Remove hosted=yes. * include/bits/version.h: Regenerate. * include/std/chrono [_GLIBCXX_HOSTED]: Only define clocks and time zone utilities for hosted. * testsuite/std/time/freestanding.cc: New test.
2024-09-06libstdc++: Fix std::chrono::parse for TAI and GPS clocksJonathan Wakely5-2/+121
Howard Hinnant brought to my attention that chrono::parse was giving incorrect values for chrono::gps_clock, because it was applying the offset between the GPS clock and UTC. That's incorrect, because when we parse HH::MM::SS as a GPS time, the result should be that time, not HH:MM:SS+offset. The problem was that I was using clock_cast to convert from sys_time to utc_time and then using clock_time again to convert to gps_time. The solution is to convert the parsed time into an duration representing the time since the GPS clock's epoch, then construct a gps_time directly from that duration. As well as adding tests for correct round tripping of times for all clocks, this also adds some more tests for correct results with std::format. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (from_stream): Fix conversions in overloads for gps_time and tai_time. * testsuite/std/time/clock/file/io.cc: Test round tripping using chrono::parse. Add additional std::format tests. * testsuite/std/time/clock/gps/io.cc: Likewise. * testsuite/std/time/clock/local/io.cc: Likewise. * testsuite/std/time/clock/tai/io.cc: Likewise. * testsuite/std/time/clock/utc/io.cc: Likewise.
2024-07-31libstdc++: Fix src/c++20/format.cc for non-gthreads targetsJonathan Wakely1-1/+1
libstdc++-v3/ChangeLog: * src/c++20/format.cc [!_GLIBCXX_HAS_GTHREADS] (mutex): Define dummy mutex type. * testsuite/std/time/format_localized.cc: Use loop variable instead of creating the same locale on every iteration.
2024-07-31libstdc++: Handle encodings in localized chrono formatting [PR109162]Jonathan Wakely1-0/+90
This implements the C++23 paper P2419R2 (Clarify handling of encodings in localized formatting of chrono types). The requirement is that when the literal encoding is "a Unicode encoding form" and the formatting locale uses a different encoding, any locale-specific strings such as "août" for std::chrono::August should be converted to the literal encoding. Using the recently-added std::locale::encoding() function we can check the locale's encoding and then use iconv if a conversion is needed. Because nl_langinfo_l and iconv_open both allocate memory, a naive implementation would perform multiple allocations and deallocations for every snippet of locale-specific text that needs to be converted to UTF-8. To avoid that, a new internal locale::facet is defined to store the text_encoding and an iconv_t descriptor, which are then cached in the formatting locale. This requires access to the internals of a std::locale object in src/c++20/format.cc, so that new file needs to be compiled with -fno-access-control, as well as -std=gnu++26 in order to use std::text_encoding. Because the new std::text_encoding and std::locale::encoding() symbols are only in the libstdc++exp.a archive, we need to include src/c++26/text_encoding.cc in the main library, but not export its symbols yet. This means they can be used by the two new functions which are exported from the main library. The encoding conversions are done for C++20, treating it as a DR that resolves LWG 3656. With this change we can increase the value of the __cpp_lib_format macro for C++23. The value should be 202207 for P2419R2, but we already implement P2510R3 (Formatting pointers) so can use the value 202304. libstdc++-v3/ChangeLog: PR libstdc++/109162 * acinclude.m4 (libtool_VERSION): Update to 6:34:0. * config/abi/pre/gnu.ver: Disambiguate old patters. Add new GLIBCXX_3.4.34 symbol version and new exports. * configure: Regenerate. * include/bits/chrono_io.h (_ChronoSpec::_M_locale_specific): Add new accessor functions to use a reserved bit in _Spec. (__formatter_chrono::_M_parse): Use _M_locale_specific(true) when chrono-specs contains locale-dependent conversion specifiers. (__formatter_chrono::_M_format): Open iconv descriptor if conversion to UTF-8 will be needed. (__formatter_chrono::_M_write): New function to write a localized string with possible character conversion. (__formatter_chrono::_M_a_A, __formatter_chrono::_M_b_B) (__formatter_chrono::_M_p, __formatter_chrono::_M_r) (__formatter_chrono::_M_x, __formatter_chrono::_M_X) (__formatter_chrono::_M_locale_fmt): Use _M_write. * include/bits/version.def (format): Update value. * include/bits/version.h: Regenerate. * include/std/format (_GLIBCXX_P2518R3): Check feature test macro instead of __cplusplus. (basic_format_context): Declare __formatter_chrono as friend. * src/c++20/Makefile.am: Add new file. * src/c++20/Makefile.in: Regenerate. * src/c++20/format.cc: New file. * testsuite/std/time/format_localized.cc: New test. * testsuite/util/testsuite_abi.cc: Add new symbol version.
2024-07-30libstdc++: Fix formatter for low-resolution chrono::zoned_time (LWG 4124)Jonathan Wakely1-0/+4
This implements the proposed resolution of LWG 4124, so that low-resolution chrono::zoned_time objects can be formatted. The formatter for zoned_time<D, P> needs to account for get_local_time returning local_time<common_type_t<D, seconds>> not local_time<D>. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__local_time_fmt_for): New alias template. (formatter<zoned_time<D, P>>): Use __local_time_fmt_for. * testsuite/std/time/zoned_time/io.cc: Check zoned_time<minutes> can be formatted.
2024-07-30libstdc++: Fix std::format output for std::chrono::zoned_timeJonathan Wakely5-6/+95
When formatting a chrono::zoned_time with an empty chrono-specs, we were only formatting its _M_time member, but the ostream insertion operator uses the format "{:L%F %T %Z}" which includes the time zone abbreviation. The %Z should also be used when formatting with an empty chrono-specs. This commit makes _M_format_to_ostream handle __local_time_fmt specializations directly, rather than calling itself recursively to format the _M_time member. We need to be able to customize the output of _M_format_to_ostream for __local_time_fmt, because we use that type for gps_time and tai_time as well as for zoned_time and __local_time_fmt. When formatting gps_time and tai_time we don't want to include the time zone abbreviation in the "{}" output, but for zoned_time we do want to. We can reuse the __is_neg flag passed to _M_format_to_ostream (via _M_format) to say that we want the time zone abbreviation. Currently the __is_neg flag is only used for duration specializations, so it's available for __local_time_fmt to use. In addition to fixing the zoned_time output to use %Z, this commit also changes the __local_time_fmt output to use %Z. Previously it didn't use it, just like zoned_time. The standard doesn't actually say how to format local-time-format-t for an empty chrono-specs, but this behaviour seems sensible and is what I'm proposing as part of LWG 4124. While testing this I noticed that some chrono types were not being tested with empty chrono-specs, so this adds more tests. I also noticed that std/time/clock/local/io.cc was testing tai_time instead of local_time, which was completely wrong. That's fixed now too. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__local_fmt_t): Remove unused declaration. (__formatter_chrono::_M_format_to_ostream): Add explicit handling for specializations of __local_time_fmt, including the time zone abbreviation in the output if __is_neg is true. (formatter<chrono::tai_time<D>>::format): Add comment. (formatter<chrono::gps_time<D>>::format): Likewise. (formatter<chrono::__detail::__local_time_fmt::format): Call _M_format with true for the __is_neg flag. * testsuite/std/time/clock/gps/io.cc: Remove unused variable. * testsuite/std/time/clock/local/io.cc: Fix test error that checked tai_time instead of local_time. Add tests for local-time-format-t formatting. * testsuite/std/time/clock/system/io.cc: Check empty chrono-specs. * testsuite/std/time/clock/tai/io.cc: Likewise. * testsuite/std/time/zoned_time/io.cc: Likewise.
2024-06-26libstdc++: Fix std::chrono::tzdb to work with vanguard formatJonathan Wakely2-1/+111
I found some issues in the std::chrono::tzdb parser by testing the tzdata "vanguard" format, which uses new features that aren't enabled in the "main" and "rearguard" data formats. Since 2024a the keyword "minimum" is no longer valid for the FROM and TO fields in a Rule line, which means that "m" is now a valid abbreviation for "maximum". Previously we expected either "mi" or "ma". For backwards compatibility, a FROM field beginning with "mi" is still supported and is treated as 1900. The "maximum" keyword is only allowed in TO now, because it makes no sense in FROM. To support these changes the minmax_year and minmax_year2 classes for parsing FROM and TO are replaced with a single years_from_to class that reads both fields. The vanguard format makes use of %z in Zone FORMAT fields, which caused an exception to be thrown from ZoneInfo::set_abbrev because no % or / characters were expected when a Zone doesn't use a named Rule. The ZoneInfo::to(sys_info&) function now uses format_abbrev_str to replace any %z with the current offset. Although format_abbrev_str also checks for %s and STD/DST formats, those only make sense when a named Rule is in effect, so won't occur when ZoneInfo::to(sys_info&) is used. This change also implements a feature that has always been missing from time_zone::_M_get_sys_info: finding the Rule that is active before the specified time point, so that we can correctly handle %s in the FORMAT for the first new sys_info that gets created. This requires implementing a poorly documented feature of zic, to get the LETTERS field from a later transition, as described at https://mm.icann.org/pipermail/tz/2024-April/058891.html In order for this to work we need to be able to distinguish an empty letters field (as used by CE%sT where the variable part is either empty or "S") from "the letters field is not known for this transition". The tzdata file uses "-" for an empty letters field, which libstdc++ was previously replacing with "" when the Rule was parsed. Instead, we now preserve the "-" in the Rule object, so that "" can be used for the case where we don't know the letters (and so need to decide it). libstdc++-v3/ChangeLog: * src/c++20/tzdb.cc (minmax_year, minmax_year2): Remove. (years_from_to): New class replacing minmax_year and minmax_year2. (format_abbrev_str, select_std_or_dst_abbrev): Move earlier in the file. Handle "-" for letters. (ZoneInfo::to): Use format_abbrev_str to expand %z. (ZoneInfo::set_abbrev): Remove exception. Change parameter from reference to value. (operator>>(istream&, Rule&)): Do not clear letters when it contains "-". (time_zone::_M_get_sys_info): Add missing logic to find the Rule in effect before the time point. * testsuite/std/time/tzdb/1.cc: Adjust for vanguard format using "GMT" as the Zone name, not as a Link to "Etc/GMT". * testsuite/std/time/time_zone/sys_info_abbrev.cc: New test.
2024-06-21libstdc++: Fix __cpp_lib_chrono for old std::string ABIJonathan Wakely1-2/+9
The <chrono> header is incomplete for the old std::string ABI, because std::chrono::tzdb is only defined for the new ABI. The feature test macro advertising full C++20 support should not be defined for the old ABI. libstdc++-v3/ChangeLog: * include/bits/version.def (chrono): Add cxx11abi = yes. * include/bits/version.h: Regenerate. * testsuite/std/time/syn_c++20.cc: Adjust expected value for the feature test macro.
2024-06-11libstdc++: Add test for chrono::leap_seconds ostream insertionJonathan Wakely1-0/+56
Also add a comment to the three-way comparison oeprator for chrono::leap_seconds, noting the deviation from the spec (which is functionally equivalent). What we implement is the originally proposed resolution to LWG 3383, which should compile slightly more efficiently than the final accepted resolution. libstdc++-v3/ChangeLog: * include/std/chrono (leap_seconds): Add comment. * testsuite/std/time/leap_seconds/io.cc: New test.
2024-04-19libstdc++: Support link chains in std::chrono::tzdb::locate_zone [PR114770]Jonathan Wakely2-0/+227
Since 2022 the TZif format defined in the zic(8) man page has said that links can refer to other links, rather than only referring to a zone. This isn't supported by the C++20 spec, which assumes that the target() for a chrono::time_zone_link always names a chrono::time_zone, not another chrono::time_zone_link. This hasn't been a problem until now, because there are no entries in the tzdata file that chain links together. However, Debian Sid has changed the target of the Asia/Chungking link from the Asia/Shanghai zone to the Asia/Chongqing link, creating a link chain. The libstdc++ code is unable to handle this, so chrono::locate_zone("Asia/Chungking") will fail with the tzdata.zi file from Debian Sid. It seems likely that the C++ spec will need a change to allow link chains, so that the original structure of the IANA database can be fully represented by chrono::tzdb. The alternative would be for chrono::tzdb to flatten all chains when loading the data, so that a link's target is always a zone, but this means throwing away information present in the tzdata.zi input file. In anticipation of a change to the spec, this commit adds support for chained links to libstdc++. When a name is found to be a link, we try to find its target in the list of zones as before, but now if the target isn't the name of a zone we don't fail. Instead we look for another link with that name, and keep doing that until we reach the end of the chain of links, and then look up the last target as a zone. This new logic would get stuck in a loop if the tzdata.zi file is buggy and defines a link chain that contains a cycle, e.g. two links that refer to each other. To deal with that unlikely case, we use the tortoise and hare algorithm to detect cycles in link chains, and throw an exception if we detect a cycle. Cycles in links should never happen, and it is expected that link chains will be short (if they occur at all) and so the code is optimized for short chains without cycles. Longer chains (four or more links) and cycles will do more work, but won't fail to resolve a chain or get stuck in a loop. The new test file checks various forms of broken links and cycles. Also add a new check in the testsuite that every element in the get_tzdb().zones and get_tzdb().links sequences can be successfully found using locate_zone. libstdc++-v3/ChangeLog: PR libstdc++/114770 * src/c++20/tzdb.cc (do_locate_zone): Support links that have another link as their target. * testsuite/std/time/tzdb/1.cc: Check that all zones and links can be found by locate_zone. * testsuite/std/time/tzdb/links.cc: New test.
2024-04-10libstdc++: Adjust expected locale-dependent date formats in testsJonathan Wakely1-1/+1
The std/time/year_month_day/io.cc test assumes that %x in the fr_FR locale is %d/%m/%Y but on FreeBSD it is %d.%m.%Y instead. Make the test PASS for either format. Similarly, 27_io/manipulators/extended/get_time/char/2.cc expects that %a in the de_DE locale is "Di" but on FreeBSD it's "Di." with a trailing period. Adjust the input string to be "1971 Di." instead of "Di 1971" and that way if %a doesn't expect the trailing '.' it simply won't extract it from the stream. This fixes: FAIL: std/time/year_month_day/io.cc -std=gnu++20 execution test FAIL: 27_io/manipulators/extended/get_time/char/2.cc -std=gnu++17 execution test libstdc++-v3/ChangeLog: * testsuite/27_io/manipulators/extended/get_time/char/2.cc: Adjust input string so that it matches %a with or without a trailing period. * testsuite/std/time/year_month_day/io.cc: Adjust expected format for %x in the fr_FR locale.
2024-03-09libstdc++: Do not require a time-of-day when parsing sys_days [PR114240]Jonathan Wakely1-0/+36
When parsing a std::chrono::sys_days (or a sys_time with an even longer period) we should not require a time-of-day to be present in the input, because we can't represent that in the result type anyway. Rather than trying to decide which specializations should require a time-of-date and which should not, follow the direction of Howard Hinnant's date library, which allows extracting a sys_time of any period from input that only contains a date, defaulting the time-of-day part to 00:00:00. This seems consistent with the intent of the standard, which says it's an error "If the parse fails to decode a valid date" (i.e., it doesn't care about decoding a valid time, only a date). libstdc++-v3/ChangeLog: PR libstdc++/114240 * include/bits/chrono_io.h (_Parser::operator()): Assume hours(0) for a time_point, so that a time is not required to be present. * testsuite/std/time/parse/114240.cc: New test.
2024-03-09libstdc++: Fix parsing of leap seconds as chrono::utc_time [PR114279]Jonathan Wakely2-0/+53
Implementing all chrono::from_stream overloads in terms of chrono::sys_time meant that a leap second time like 23:59:60.001 cannot be parsed, because that cannot be represented in a sys_time. The fix to support parsing leap seconds as utc_time is to convert the parsed date to utc_time<days> and then add the parsed time to that, which allows the result to land in a leap second, rather than doing all the arithmetic with sys_time which doesn't have leap seconds. For local_time we also allow %S to parse a 60s value, because doing otherwise might disallow some valid uses. We can't know all use cases users have for treating times as local_time. For all other clocks, we can reject times that have 60 or 60.nnn as the seconds part, because that cannot occur in a valid UNIX, GPS, or TAI time. Since our chrono::file_clock uses sys_time, it can't occur for that clock either. In order to support this a new _M_is_leap_second member is needed in the _Parser type. This can be added at the end, where most targets currently have padding bytes. Similar to what I did recently for formatter _Spec structs, we can also reserve additional padding bits for future expansion. This also fixes bugs in the from_stream overloads for utc_time, tai_time, gps_time, and file_time, which were not using time_point_cast to explicitly convert to the result type. That's needed because the result type might have lower precision than the value returned from from_sys or from_utc, which has a precision no lower than seconds. libstdc++-v3/ChangeLog: PR libstdc++/114279 * include/bits/chrono_io.h (_Parser::_M_is_leap_second): New data member. (_Parser::_M_reserved): Reserve padding bits for future use. (_Parser::operator()): Set _M_is_leap_second if %S reads 60s. (from_stream): Only allow _M_is_leap_second for utc_time and local_time. Adjust arithmetic for utc_time so that leap seconds are preserved. Use time_point_cast to convert to a possibly lower-precision result type. * testsuite/std/time/parse.cc: Move to ... * testsuite/std/time/parse/parse.cc: ... here. * testsuite/std/time/parse/114279.cc: New test.
2024-03-07libstdc++: Update expiry times for leap seconds listsJonathan Wakely1-1/+1
The list in tzdb.cc isn't the only hardcoded list of leap seconds in the library, there's the one defined inline in <chrono> (to avoid loading the tzdb for the common case) and another in a testcase. This updates them to note that there are no new leap seconds in 2024 either, until at least 2024-12-28. libstdc++-v3/ChangeLog: * include/std/chrono (__get_leap_second_info): Update expiry time for hardcoded list of leap seconds. * testsuite/std/time/tzdb/leap_seconds.cc: Update comment.
2024-01-30libstdc++: Fix check in testsuite/std/time/clock/gps/io.ccJonathan Wakely1-1/+2
The test_format() function contained an incorrect assertion but wasn't actually being called from main. libstdc++-v3/ChangeLog: * testsuite/std/time/clock/gps/io.cc: Fix expected result in assertion and call test_format() from main.
2024-01-22libstdc++: Fix check in testsuite/std/time/clock/file/io.ccJonathan Wakely1-1/+2
The test_format() function contained an incorrect assertion but wasn't actually being called from main. libstdc++-v3/ChangeLog: * testsuite/std/time/clock/file/io.cc: Fix expected result in assertion and call test_format() from main.
2024-01-21libstdc++: Fix std::format for floating-point chrono::time_point [PR113500]Jonathan Wakely4-3/+73
Currently trying to use std::format with certain specializations of std::chrono::time_point is ill-formed, due to one member function of the __formatter_chrono type which tries to write a time_point to an ostream. For sys_time<floating-point> or sys_time with a period greater than days there is no operator<< that can be used. That operator<< is only needed when using an empty chrono-specs in the format string, like "{}", but the ill-formed expression gives an error even if not actually used. This means it's not possible to format some other specializations of chrono::time_point, even when using a non-empty chrono-specs. This fixes it by avoiding using 'os << t' for all chrono::time_point specializations, and instead using std::format("{:L%F %T}", t). So that we continue to reject std::format("{}", sys_time{1.0s}) a check for empty chrono-specs is added to the formatter<sys_time<D>, C> specialization. While testing this I noticed that the output for %S with a floating-point duration was incorrect, as the subseconds part was being appended to the seconds without a decimal point, and without the correct number of leading zeros. libstdc++-v3/ChangeLog: PR libstdc++/113500 * include/bits/chrono_io.h (__formatter_chrono::_M_S): Fix printing of subseconds with floating-point rep. (__formatter_chrono::_M_format_to_ostream): Do not write time_point specializations directly to the ostream. (formatter<chrono::sys_time<D>, C>::parse): Do not allow an empty chrono-spec if the type fails to meet the constraints for writing to an ostream with operator<<. * testsuite/std/time/clock/file/io.cc: Check formatting non-integral times with empty chrono-specs. * testsuite/std/time/clock/gps/io.cc: Likewise. * testsuite/std/time/clock/utc/io.cc: Likewise. * testsuite/std/time/hh_mm_ss/io.cc: Likewise.
2024-01-21libstdc++: Fix std::chrono::file_clock conversions for low-precision timesJonathan Wakely1-0/+9
THe std::chrono::file_clock conversions were not using common_type and so failed to compile when converting anything that should have increased precision after arithmetic with a std::chrono::seconds value. libstdc++-v3/ChangeLog: * include/bits/chrono.h (__file_clock::from_sys) (__file_clock::to_sys, __file_clock::_S_from_sys) (__file_clock::_S_to_sys): Use common_type for return type. * testsuite/std/time/clock/file/members.cc: Check round trip conversion for time with lower precision that seconds.
2024-01-08libstdc++: Implement P2905R2 "Runtime format strings" for C++20Jonathan Wakely5-10/+10
This change makes std::make_format_args refuse to create dangling references to temporaries. This makes the std::vformat API safer. This was approved in Kona 2023 as a DR for C++20 so the change is implemented unconditionally. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono): Always use lvalue arguments to make_format_args. * include/std/format (make_format_args): Change parameter pack from forwarding references to lvalue references. Remove use of remove_reference_t which is now unnecessary. (format_to, formatted_size): Remove incorrect forwarding of arguments. * include/std/ostream (print): Remove forwarding of arguments. * include/std/print (print): Likewise. * testsuite/20_util/duration/io.cc: Use lvalues as arguments to make_format_args. * testsuite/std/format/arguments/args.cc: Likewise. * testsuite/std/format/arguments/lwg3810.cc: Likewise. * testsuite/std/format/functions/format.cc: Likewise. * testsuite/std/format/functions/vformat_to.cc: Likewise. * testsuite/std/format/string.cc: Likewise. * testsuite/std/time/day/io.cc: Likewise. * testsuite/std/time/month/io.cc: Likewise. * testsuite/std/time/weekday/io.cc: Likewise. * testsuite/std/time/year/io.cc: Likewise. * testsuite/std/time/year_month_day/io.cc: Likewise. * testsuite/std/format/arguments/args_neg.cc: New test.
2024-01-05libstdc++: Remove UB from month and weekday additions and subtractions.Cassio Neri4-2/+97
The following invoke signed integer overflow (UB) [1]: month + months{MAX} // where MAX is the maximum value of months::rep month + months{MIN} // where MIN is the maximum value of months::rep month - months{MIN} // where MIN is the minimum value of months::rep weekday + days {MAX} // where MAX is the maximum value of days::rep weekday - days {MIN} // where MIN is the minimum value of days::rep For the additions to MAX, the crux of the problem is that, in libstdc++, months::rep and days::rep are int64_t. Other implementations use int32_t, cast operands to int64_t and perform arithmetic operations without risk of overflowing. For month + months{MIN}, the implementation follows the Standard's "returns clause" and evaluates: modulo(static_cast<long long>(unsigned{__x}) + (__y.count() - 1), 12); Overflow occurs when MIN - 1 is evaluated. Casting to a larger type could help but, unfortunately again, this is not possible for libstdc++. For the subtraction of MIN, the problem is that -MIN is not representable. It's fair to say that the intention is for these additions/subtractions to be performed in modulus (12 or 7) arithmetic so that no overflow is expected. To fix these UB, this patch implements: template <unsigned __d, typename _T> unsigned __add_modulo(unsigned __x, _T __y); template <unsigned __d, typename _T> unsigned __sub_modulo(unsigned __x, _T __y); which respectively, returns the remainder of Euclidean division of, __x + __y and __x - __y by __d without overflowing. These functions replace constexpr unsigned __modulo(long long __n, unsigned __d); which also calculates the reminder of __n, where __n is the result of the addition or subtraction. Hence, these operations might invoke UB before __modulo is called and thus, __modulo can't do anything to remediate the issue. In addition to solve the UB issues, __add_modulo and __sub_modulo allow better codegen (shorter and branchless) on x86-64 and ARM [2]. [1] https://godbolt.org/z/a9YfWdn57 [2] https://godbolt.org/z/Gh36cr7E4 libstdc++-v3/ChangeLog: * include/std/chrono: Fix + and - for months and weekdays. * testsuite/std/time/month/1.cc: Add constexpr tests against overflow. * testsuite/std/time/month/2.cc: New test for extreme values. * testsuite/std/time/weekday/1.cc: Add constexpr tests against overflow. * testsuite/std/time/weekday/2.cc: New test for extreme values.