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 falsy statisfying 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. --- Testing on x86_64-linux, std/time/format tests passed. OK for trunk? libstdc++-v3/include/bits/chrono_io.h | 448 +++++++++--------- .../testsuite/std/time/format/pr119517.cc | 44 ++ 2 files changed, 262 insertions(+), 230 deletions(-) create mode 100644 libstdc++-v3/testsuite/std/time/format/pr119517.cc diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index c55b651d049..3a5bc5695fb 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -1785,277 +1785,272 @@ namespace __format __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::day, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Day); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Day); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::day& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::day& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::month, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Month); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Month); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::month& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::month& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::year, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Year); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Year); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::year& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::year& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::weekday, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Weekday); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Weekday); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::weekday& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::weekday& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::weekday_indexed, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Weekday); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Weekday); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::weekday_indexed& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::weekday_indexed& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::weekday_last, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Weekday); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Weekday); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::weekday_last& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::weekday_last& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::month_day, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::month_day& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::month_day& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::month_day_last, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::month_day_last& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::month_day_last& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::month_weekday, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::month_weekday& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::month_weekday& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::month_weekday_last, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); } - template<typename _FormatContext> - typename _FormatContext::iterator + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator format(const chrono::month_weekday_last& __t, - _FormatContext& __fc) const + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::year_month, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Year|__format::_Month); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Year|__format::_Month); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::year_month& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::year_month& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::year_month_day, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Date); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Date); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::year_month_day& __t, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::year_month_day& __t, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::year_month_day_last, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Date); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Date); } - template<typename _FormatContext> - typename _FormatContext::iterator + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator format(const chrono::year_month_day_last& __t, - _FormatContext& __fc) const + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::year_month_weekday, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Date); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Date); } - template<typename _FormatContext> - typename _FormatContext::iterator + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator format(const chrono::year_month_weekday& __t, - _FormatContext& __fc) const + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::year_month_weekday_last, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_Date); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_Date); } - template<typename _FormatContext> - typename _FormatContext::iterator + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator format(const chrono::year_month_weekday_last& __t, - _FormatContext& __fc) const - { return _M_f._M_format(__t, __fc); } + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _Rep, typename _Period, typename _CharT> + template<typename _Rep, typename _Period, __format::__char _CharT> struct formatter<chrono::hh_mm_ss<chrono::duration<_Rep, _Period>>, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_TimeOfDay); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_TimeOfDay); } - template<typename _FormatContext> - typename _FormatContext::iterator + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator format(const chrono::hh_mm_ss<chrono::duration<_Rep, _Period>>& __t, - _FormatContext& __fc) const + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__t, __fc); } private: @@ -2063,34 +2058,34 @@ namespace __format }; #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::sys_info, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_ChronoParts{}); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_ChronoParts{}); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::sys_info& __i, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::sys_info& __i, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__i, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _CharT> + template<__format::__char _CharT> struct formatter<chrono::local_info, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_ChronoParts{}); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_ChronoParts{}); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::local_info& __i, _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::local_info& __i, + basic_format_context<_Out, _CharT>& __fc) const { return _M_f._M_format(__i, __fc); } private: @@ -2098,25 +2093,24 @@ namespace __format }; #endif - template<typename _Duration, typename _CharT> + template<typename _Duration, __format::__char _CharT> struct formatter<chrono::sys_time<_Duration>, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { - auto __next = _M_f._M_parse(__pc, __format::_ZonedDateTime); - if constexpr (!__stream_insertable) - if (_M_f._M_spec._M_chrono_specs.empty()) - __format::__invalid_chrono_spec(); // chrono-specs can't be empty - return __next; - } - - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::sys_time<_Duration>& __t, - _FormatContext& __fc) const - { return _M_f._M_format(__t, __fc); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { + auto __next = _M_f._M_parse(__pc, __format::_ZonedDateTime); + if constexpr (!__stream_insertable) + if (_M_f._M_spec._M_chrono_specs.empty()) + __format::__invalid_chrono_spec(); // chrono-specs can't be empty + return __next; + } + + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::sys_time<_Duration>& __t, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f._M_format(__t, __fc); } private: static constexpr bool __stream_insertable @@ -2126,19 +2120,18 @@ namespace __format __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _Duration, typename _CharT> + template<typename _Duration, __format::__char _CharT> struct formatter<chrono::utc_time<_Duration>, _CharT> : __format::__formatter_chrono<_CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::utc_time<_Duration>& __t, - _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::utc_time<_Duration>& __t, + basic_format_context<_Out, _CharT>& __fc) const { // Adjust by removing leap seconds to get equivalent sys_time. // We can't just use clock_cast because we want to know if the time @@ -2161,19 +2154,18 @@ namespace __format __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _Duration, typename _CharT> + template<typename _Duration, __format::__char _CharT> struct formatter<chrono::tai_time<_Duration>, _CharT> : __format::__formatter_chrono<_CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::tai_time<_Duration>& __t, - _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::tai_time<_Duration>& __t, + basic_format_context<_Out, _CharT>& __fc) const { // Convert to __local_time_fmt with abbrev "TAI" and offset 0s. // We use __local_time_fmt and not sys_time (as the standard implies) @@ -2193,19 +2185,18 @@ namespace __format __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _Duration, typename _CharT> + template<typename _Duration, __format::__char _CharT> struct formatter<chrono::gps_time<_Duration>, _CharT> : __format::__formatter_chrono<_CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::gps_time<_Duration>& __t, - _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::gps_time<_Duration>& __t, + basic_format_context<_Out, _CharT>& __fc) const { // Convert to __local_time_fmt with abbrev "GPS" and offset 0s. // We use __local_time_fmt and not sys_time (as the standard implies) @@ -2225,72 +2216,69 @@ namespace __format __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _Duration, typename _CharT> + template<typename _Duration, __format::__char _CharT> struct formatter<chrono::file_time<_Duration>, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::file_time<_Duration>& __t, - _FormatContext& __ctx) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::file_time<_Duration>& __t, + basic_format_context<_Out, _CharT>& __fc) const { using namespace chrono; - return _M_f._M_format(chrono::clock_cast<system_clock>(__t), __ctx); + return _M_f._M_format(chrono::clock_cast<system_clock>(__t), __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _Duration, typename _CharT> + template<typename _Duration, __format::__char _CharT> struct formatter<chrono::local_time<_Duration>, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_DateTime); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_DateTime); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::local_time<_Duration>& __t, - _FormatContext& __ctx) const - { return _M_f._M_format(__t, __ctx); } + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::local_time<_Duration>& __t, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f._M_format(__t, __fc); } private: __format::__formatter_chrono<_CharT> _M_f; }; - template<typename _Duration, typename _CharT> + template<typename _Duration, __format::__char _CharT> struct formatter<chrono::__detail::__local_time_fmt<_Duration>, _CharT> { - template<typename _ParseContext> - constexpr typename _ParseContext::iterator - parse(_ParseContext& __pc) - { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::__detail::__local_time_fmt<_Duration>& __t, - _FormatContext& __ctx) const - { return _M_f._M_format(__t, __ctx, /* use %Z for {} */ true); } + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::__detail::__local_time_fmt<_Duration>& __t, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f._M_format(__t, __fc, /* use %Z for {} */ true); } private: __format::__formatter_chrono<_CharT> _M_f; }; #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI - template<typename _Duration, typename _TimeZonePtr, typename _CharT> + template<typename _Duration, typename _TimeZonePtr, __format::__char _CharT> struct formatter<chrono::zoned_time<_Duration, _TimeZonePtr>, _CharT> : formatter<chrono::__detail::__local_time_fmt_for<_Duration>, _CharT> { - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::zoned_time<_Duration, _TimeZonePtr>& __tp, - _FormatContext& __ctx) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::zoned_time<_Duration, _TimeZonePtr>& __tp, + basic_format_context<_Out, _CharT>& __fc) const { using _Ltf = chrono::__detail::__local_time_fmt_for<_Duration>; using _Base = formatter<_Ltf, _CharT>; @@ -2298,20 +2286,20 @@ namespace __format const auto __lf = chrono::local_time_format(__tp.get_local_time(), &__info.abbrev, &__info.offset); - return _Base::format(__lf, __ctx); + return _Base::format(__lf, __fc); } }; #endif // Partial specialization needed for %c formatting of __utc_leap_second. - template<typename _Duration, typename _CharT> + template<typename _Duration, __format::__char _CharT> struct formatter<chrono::__detail::__utc_leap_second<_Duration>, _CharT> : formatter<chrono::utc_time<_Duration>, _CharT> { - template<typename _FormatContext> - typename _FormatContext::iterator - format(const chrono::__detail::__utc_leap_second<_Duration>& __t, - _FormatContext& __fc) const + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const chrono::__detail::__utc_leap_second<_Duration>& __t, + basic_format_context<_Out, _CharT>& __fc) const { return this->_M_f._M_format(__t, __fc); } }; diff --git a/libstdc++-v3/testsuite/std/time/format/pr119517.cc b/libstdc++-v3/testsuite/std/time/format/pr119517.cc new file mode 100644 index 00000000000..d1fc466eaab --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/format/pr119517.cc @@ -0,0 +1,44 @@ +// { dg-do compile { target c++23 } } + +#include <chrono> +#include <format> +#include <testsuite_hooks.h> + +static_assert( std::formattable<std::chrono::weekday, char> ); +static_assert( std::formattable<std::chrono::weekday, wchar_t> ); +static_assert( !std::formattable<std::chrono::weekday, char16_t> ); + +static_assert( std::formattable<std::chrono::sys_days, char> ); +static_assert( std::formattable<std::chrono::sys_days, wchar_t> ); +static_assert( !std::formattable<std::chrono::sys_days, char16_t> ); + +static_assert( !std::formattable<std::chrono::seconds, int> ); + +static_assert( !std::formattable<std::chrono::day, int> ); +static_assert( !std::formattable<std::chrono::month, int> ); +static_assert( !std::formattable<std::chrono::year, int> ); +static_assert( !std::formattable<std::chrono::weekday, int> ); +static_assert( !std::formattable<std::chrono::weekday_indexed, int> ); +static_assert( !std::formattable<std::chrono::weekday_last, int> ); +static_assert( !std::formattable<std::chrono::month_day, int> ); +static_assert( !std::formattable<std::chrono::month_day_last, int> ); +static_assert( !std::formattable<std::chrono::month_weekday, int> ); +static_assert( !std::formattable<std::chrono::month_weekday_last, int> ); +static_assert( !std::formattable<std::chrono::year_month_day, int> ); +static_assert( !std::formattable<std::chrono::year_month_day_last, int> ); +static_assert( !std::formattable<std::chrono::year_month_weekday, int> ); +static_assert( !std::formattable<std::chrono::year_month_weekday_last, int> ); +static_assert( !std::formattable<std::chrono::hh_mm_ss<std::chrono::seconds>, int> ); + +static_assert( !std::formattable<std::chrono::sys_seconds, int> ); +static_assert( !std::formattable<std::chrono::utc_seconds, int> ); +static_assert( !std::formattable<std::chrono::tai_seconds, int> ); +static_assert( !std::formattable<std::chrono::gps_seconds, int> ); +static_assert( !std::formattable<std::chrono::local_seconds, int> ); +static_assert( !std::formattable<std::chrono::file_time<std::chrono::seconds>, int> ); +#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI +static_assert( !std::formattable<std::chrono::zoned_seconds, int> ); + +static_assert( !std::formattable<std::chrono::sys_info, int> ); +static_assert( !std::formattable<std::chrono::local_info, int> ); +#endif -- 2.48.1