30 #ifndef _GLIBCXX_CHRONO_IO_H 31 #define _GLIBCXX_CHRONO_IO_H 1 33 #pragma GCC system_header 35 #if __cplusplus >= 202002L 43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
60 template<
typename _CharT>
62 _Widen(
const char* __narrow,
const wchar_t* __wide)
64 if constexpr (is_same_v<_CharT, wchar_t>)
69 #define _GLIBCXX_WIDEN_(C, S) ::std::chrono::__detail::_Widen<C>(S, L##S) 70 #define _GLIBCXX_WIDEN(S) _GLIBCXX_WIDEN_(_CharT, S) 72 template<
typename _Period,
typename _CharT>
73 constexpr basic_string_view<_CharT>
74 __units_suffix() noexcept
79 #define _GLIBCXX_UNITS_SUFFIX(period, suffix) \ 80 if constexpr (is_same_v<_Period, period>) \ 81 return _GLIBCXX_WIDEN(suffix); \ 84 _GLIBCXX_UNITS_SUFFIX(atto,
"as")
85 _GLIBCXX_UNITS_SUFFIX(femto, "fs")
86 _GLIBCXX_UNITS_SUFFIX(pico, "ps")
87 _GLIBCXX_UNITS_SUFFIX(nano, "ns")
88 _GLIBCXX_UNITS_SUFFIX(milli, "ms")
89 #if _GLIBCXX_USE_ALT_MICROSECONDS_SUFFIX 92 _GLIBCXX_UNITS_SUFFIX(micro,
"\u00b5s")
94 _GLIBCXX_UNITS_SUFFIX(micro,
"us")
96 _GLIBCXX_UNITS_SUFFIX(centi,
"cs")
97 _GLIBCXX_UNITS_SUFFIX(deci, "ds")
98 _GLIBCXX_UNITS_SUFFIX(ratio<1>, "s")
99 _GLIBCXX_UNITS_SUFFIX(deca, "das")
100 _GLIBCXX_UNITS_SUFFIX(hecto, "hs")
101 _GLIBCXX_UNITS_SUFFIX(kilo, "ks")
102 _GLIBCXX_UNITS_SUFFIX(mega, "Ms")
103 _GLIBCXX_UNITS_SUFFIX(giga, "Gs")
104 _GLIBCXX_UNITS_SUFFIX(tera, "Ts")
105 _GLIBCXX_UNITS_SUFFIX(tera, "Ts")
106 _GLIBCXX_UNITS_SUFFIX(peta, "Ps")
107 _GLIBCXX_UNITS_SUFFIX(exa, "Es")
108 _GLIBCXX_UNITS_SUFFIX(ratio<60>, "
min")
109 _GLIBCXX_UNITS_SUFFIX(ratio<3600>, "h")
110 _GLIBCXX_UNITS_SUFFIX(ratio<86400>, "d")
111 #undef _GLIBCXX_UNITS_SUFFIX 115 template<
typename _Period,
typename _CharT,
typename _Out>
117 __fmt_units_suffix(_Out __out) noexcept
119 if (
auto __s = __detail::__units_suffix<_Period, _CharT>(); __s.size())
120 return __format::__write(
std::move(__out), __s);
121 else if constexpr (_Period::den == 1)
122 return
std::format_to(
std::
move(__out), _GLIBCXX_WIDEN("[{}]s
"), 123 (uintmax_t)_Period::num); 125 return std::format_to(std::move(__out), _GLIBCXX_WIDEN("[{}/{}]s
"), 126 (uintmax_t)_Period::num, 127 (uintmax_t)_Period::den); 129 } // namespace __detail 136 template<typename _CharT, typename _Traits,
137 typename _Rep, typename _Period>
138 inline basic_ostream<_CharT, _Traits>&
139 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
140 const duration<_Rep, _Period>& __d)
142 using _Out = ostreambuf_iterator<_CharT, _Traits>;
143 using period = typename _Period::type;
144 std::basic_ostringstream<_CharT, _Traits> __s;
145 __s.flags(__os.flags());
146 __s.imbue(__os.getloc());
147 __s.precision(__os.precision());
149 __detail::__fmt_units_suffix<period, _CharT>(_Out(__s));
150 __os << std::move(__s).str();
157 // An unspecified type returned by `chrono::local_time_format`.
158 template<typename _Duration>
159 struct __local_time_fmt
161 local_time<_Duration> _M_time;
162 const string* _M_abbrev;
163 const seconds* _M_offset_sec;
166 struct __local_fmt_t;
179 template<typename _Duration>
180 inline __detail::__local_time_fmt<_Duration>
181 local_time_format(local_time<_Duration> __time,
182 const string* __abbrev = nullptr,
183 const seconds* __offset_sec = nullptr)
184 { return {__time, __abbrev, __offset_sec}; }
187 } // namespace chrono
192 [[noreturn,__gnu__::__always_inline__]]
194 __no_timezone_available()
195 { __throw_format_error("format error: no timezone available
for %Z or %z
"); } 197 [[noreturn,__gnu__::__always_inline__]] 199 __not_valid_for_duration() 200 { __throw_format_error("format error: chrono-format-spec not valid
for " 203 [[noreturn,__gnu__::__always_inline__]] 205 __invalid_chrono_spec() 206 { __throw_format_error("format error: chrono-format-spec not valid
for " 209 template<typename _CharT> 210 struct _ChronoSpec : _Spec<_CharT> 212 basic_string_view<_CharT> _M_chrono_specs; 215 // Represents the information provided by a chrono type. 216 // e.g. month_weekday has month and weekday but no year or time of day, 217 // hh_mm_ss has time of day but no date, sys_time is time_point+timezone. 219 _Year = 1, _Month = 2, _Day = 4, _Weekday = 8, _TimeOfDay = 16, 221 _Date = _Year | _Month | _Day | _Weekday, 222 _DateTime = _Date | _TimeOfDay, 223 _ZonedDateTime = _DateTime | _TimeZone, 224 _Duration = 128 // special case 227 constexpr _ChronoParts 228 operator|(_ChronoParts __x, _ChronoParts __y) 229 { return static_cast<_ChronoParts>((int)__x | (int)__y); } 231 // TODO rename this to chrono::__formatter? or chrono::__detail::__formatter? 232 template<typename _CharT> 233 struct __formatter_chrono 235 using __string_view = basic_string_view<_CharT>; 236 using __string = basic_string<_CharT>; 238 template<typename _ParseContext> 239 constexpr typename _ParseContext::iterator 240 _M_parse(_ParseContext& __pc, _ChronoParts __parts) 242 auto __first = __pc.begin(); 243 auto __last = __pc.end(); 245 _ChronoSpec<_CharT> __spec{}; 247 auto __finalize = [this, &__spec] { 251 auto __finished = [&] { 252 if (__first == __last || *__first == '}') 263 __first = __spec._M_parse_fill_and_align(__first, __last); 267 __first = __spec._M_parse_width(__first, __last, __pc); 271 if (__parts & _ChronoParts::_Duration) 273 __first = __spec._M_parse_precision(__first, __last, __pc); 278 __first = __spec._M_parse_locale(__first, __last); 282 // Everything up to the end of the string or the first '}' is a 283 // chrono-specs string. Check it is valid. 285 __string_view __str(__first, __last - __first); 286 auto __end = __str.find('}'); 287 if (__end != __str.npos) 289 __str.remove_suffix(__str.length() - __end); 290 __last = __first + __end; 292 if (__str.find('{') != __str.npos) 293 __throw_format_error("chrono format error:
'{' in chrono-specs
"); 296 // Parse chrono-specs in [first,last), checking each conversion-spec 297 // against __parts (so fail for %Y if no year in parts). 298 // Save range in __spec._M_chrono_specs. 300 const auto __chrono_specs = __first++; // Skip leading '%' 301 if (*__chrono_specs != '%') 302 __throw_format_error("chrono format error: no
'%' at start of
" 309 while (__first != __last) 311 enum _Mods { _Mod_none, _Mod_E, _Mod_O, _Mod_E_O }; 312 _Mods __allowed_mods = _Mod_none; 314 _CharT __c = *__first++; 327 __needed = _DateTime; 328 __allowed_mods = _Mod_E; 332 __allowed_mods = _Mod_E; 337 __allowed_mods = _Mod_O; 349 __needed = _TimeOfDay; 350 __allowed_mods = _Mod_O; 353 if (!(__parts & _Duration)) 358 __allowed_mods = _Mod_O; 361 __needed = _TimeOfDay; 362 __allowed_mods = _Mod_O; 368 __needed = _TimeOfDay; 372 __needed = _Duration; 375 __needed = _TimeOfDay; 376 __allowed_mods = _Mod_O; 381 __allowed_mods = _Mod_O; 387 __allowed_mods = _Mod_O; 391 __allowed_mods = _Mod_E; 394 __needed = _TimeOfDay; 395 __allowed_mods = _Mod_E; 399 __allowed_mods = _Mod_E_O; 403 __allowed_mods = _Mod_E; 406 __needed = _TimeZone; 407 __allowed_mods = _Mod_E_O; 410 __needed = _TimeZone; 418 if (__mod) [[unlikely]] 420 __allowed_mods = _Mod_none; 426 __throw_format_error("chrono format error: invalid
" 427 " specifier in chrono-specs
"); 430 if ((__mod == 'E' && !(__allowed_mods & _Mod_E)) 431 || (__mod == 'O' && !(__allowed_mods & _Mod_O))) 432 __throw_format_error("chrono format error: invalid
" 433 " modifier in chrono-specs
"); 436 if ((__parts & __needed) != __needed) 437 __throw_format_error("chrono format error: format argument
" 438 "does not contain the information
" 439 "required by the chrono-specs
"); 441 // Scan for next '%', ignoring literal-chars before it. 442 size_t __pos = __string_view(__first, __last - __first).find('%'); 447 if (__pos == __string_view::npos) 453 __first += __pos + 1; 457 // Check for a '%' conversion-spec without a type. 458 if (__conv || __mod != _CharT()) 459 __throw_format_error("chrono format error: unescaped
'%' in
" 463 _M_spec._M_chrono_specs 464 = __string_view(__chrono_specs, __first - __chrono_specs); 469 // TODO this function template is instantiated for every different _Tp. 470 // Consider creating a polymorphic interface for calendar types so 471 // that we instantiate fewer different specializations. Similar to 472 // _Sink_iter for std::format. Replace each _S_year, _S_day etc. with 473 // member functions of that type. 474 template<typename _Tp, typename _FormatContext> 475 typename _FormatContext::iterator 476 _M_format(const _Tp& __t, _FormatContext& __fc, 477 bool __is_neg = false) const 479 auto __first = _M_spec._M_chrono_specs.begin(); 480 const auto __last = _M_spec._M_chrono_specs.end(); 481 if (__first == __last) 482 return _M_format_to_ostream(__t, __fc, __is_neg); 484 _Sink_iter<_CharT> __out; 485 __format::_Str_sink<_CharT> __sink; 486 bool __write_direct = false; 487 if constexpr (is_same_v<typename _FormatContext::iterator, 490 if (_M_spec._M_width_kind == __format::_WP_none) 493 __write_direct = true; 496 __out = __sink.out(); 499 __out = __sink.out(); 501 // formatter<duration> passes the correct value of __is_neg 502 // for durations but for hh_mm_ss we decide it here. 503 if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>) 504 __is_neg = __t.is_negative(); 506 auto __print_sign = [&__is_neg, &__out] { 507 if constexpr (chrono::__is_duration_v<_Tp> 508 || __is_specialization_of<_Tp, chrono::hh_mm_ss>) 511 *__out++ = _S_plus_minus[1]; 514 return std::move(__out); 517 // Characters to output for "%n
", "%t
" and "%%
" specifiers. 518 constexpr const _CharT* __literals = _GLIBCXX_WIDEN("\n\t%
"); 520 ++__first; // Skip leading '%' at start of chrono-specs. 525 _CharT __c = *__first++; 530 __out = _M_a_A(__t, std::move(__out), __fc, __c == 'A'); 535 __out = _M_b_B(__t, std::move(__out), __fc, __c == 'B'); 538 __out = _M_c(__t, std::move(__out), __fc, __mod == 'E'); 543 __out = _M_C_y_Y(__t, std::move(__out), __fc, __c, __mod); 547 __out = _M_d_e(__t, std::move(__out), __fc, __c, __mod == 'O'); 550 __out = _M_D(__t, std::move(__out), __fc); 553 __out = _M_F(__t, std::move(__out), __fc); 557 __out = _M_g_G(__t, std::move(__out), __fc, __c == 'G'); 561 __out = _M_H_I(__t, __print_sign(), __fc, __c, __mod == 'O'); 564 __out = _M_j(__t, __print_sign(), __fc); 567 __out = _M_m(__t, std::move(__out), __fc, __mod == 'O'); 570 __out = _M_M(__t, __print_sign(), __fc, __mod == 'O'); 573 __out = _M_p(__t, std::move(__out), __fc); 576 __out = _M_q(__t, std::move(__out), __fc); 579 // %Q The duration's numeric value. 580 if constexpr (chrono::__is_duration_v<_Tp>) 581 __out = std::format_to(__print_sign(), _S_empty_spec, 584 __throw_format_error("chrono format error: argument is
" 588 __out = _M_r(__t, __print_sign(), __fc); 592 __out = _M_R_T(__t, __print_sign(), __fc, __c == 'T'); 595 __out = _M_S(__t, __print_sign(), __fc, __mod == 'O'); 599 __out = _M_u_w(__t, std::move(__out), __fc, __c, __mod == 'O'); 604 __out = _M_U_V_W(__t, std::move(__out), __fc, __c, 608 __out = _M_x(__t, std::move(__out), __fc, __mod == 'E'); 611 __out = _M_X(__t, __print_sign(), __fc, __mod == 'E'); 614 __out = _M_z(__t, std::move(__out), __fc, (bool)__mod); 617 __out = _M_Z(__t, std::move(__out), __fc); 620 *__out++ = __literals[0]; 623 *__out++ = __literals[1]; 626 *__out++ = __literals[2]; 637 // Scan for next '%' and write out everything before it. 638 __string_view __str(__first, __last - __first); 639 size_t __pos = __str.find('%'); 644 if (__pos == __str.npos) 648 __str.remove_suffix(__str.length() - __pos); 649 __first += __pos + 1; 651 __out = __format::__write(std::move(__out), __str); 654 while (__first != __last); 656 if constexpr (is_same_v<typename _FormatContext::iterator, 661 auto __str = std::move(__sink).get(); 662 return __format::__write_padded_as_spec(__str, __str.size(), 666 _ChronoSpec<_CharT> _M_spec; 669 // Return the formatting locale. 670 template<typename _FormatContext> 672 _M_locale(_FormatContext& __fc) const 674 if (!_M_spec._M_localized) 675 return std::locale::classic(); 677 return __fc.locale(); 680 // Format for empty chrono-specs, e.g. "{}
" (C++20 [time.format] p6). 681 // TODO: consider moving body of every operator<< into this function 682 // and use std::format("{}
", t) to implement those operators. That 683 // would avoid std::format("{}
", t) calling operator<< which calls 684 // std::format again. 685 template<typename _Tp, typename _FormatContext> 686 typename _FormatContext::iterator 687 _M_format_to_ostream(const _Tp& __t, _FormatContext& __fc, 690 using ::std::chrono::__detail::__utc_leap_second; 691 using ::std::chrono::__detail::__local_time_fmt; 693 if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) 694 return _M_format_to_ostream(__t._M_time, __fc, false); 697 basic_ostringstream<_CharT> __os; 698 __os.imbue(_M_locale(__fc)); 700 if constexpr (__is_specialization_of<_Tp, __utc_leap_second>) 701 __os << __t._M_date << ' ' << __t._M_time; 702 else if constexpr (chrono::__is_time_point_v<_Tp>) 704 // Need to be careful here because not all specializations 705 // of chrono::sys_time can be written to an ostream. 706 // For the specializations of time_point that can be 707 // formatted with an empty chrono-specs, either it's a 708 // sys_time with period greater or equal to days: 709 if constexpr (is_convertible_v<_Tp, chrono::sys_days>) 710 __os << _S_date(__t); 711 else // Or it's formatted as "{:L%F %T}
": 713 auto __days = chrono::floor<chrono::days>(__t); 714 __os << chrono::year_month_day(__days) << ' ' 715 << chrono::hh_mm_ss(__t - __days); 720 if constexpr (chrono::__is_duration_v<_Tp>) 721 if (__is_neg) [[unlikely]] 722 __os << _S_plus_minus[1]; 726 auto __str = std::move(__os).str(); 727 return __format::__write_padded_as_spec(__str, __str.size(), 732 static constexpr const _CharT* _S_chars 733 = _GLIBCXX_WIDEN("0123456789+-:/ {}
"); 734 static constexpr const _CharT* _S_plus_minus = _S_chars + 10; 735 static constexpr _CharT _S_colon = _S_chars[12]; 736 static constexpr _CharT _S_slash = _S_chars[13]; 737 static constexpr _CharT _S_space = _S_chars[14]; 738 static constexpr const _CharT* _S_empty_spec = _S_chars + 15; 740 template<typename _Tp, typename _FormatContext> 741 typename _FormatContext::iterator 742 _M_a_A(const _Tp& __t, typename _FormatContext::iterator __out, 743 _FormatContext& __ctx, bool __full) const 745 // %a Locale's abbreviated weekday name. 746 // %A Locale's full weekday name. 747 chrono::weekday __wd = _S_weekday(__t); 749 __throw_format_error("format error: invalid weekday
"); 751 locale __loc = _M_locale(__ctx); 752 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); 753 const _CharT* __days[7]; 755 __tp._M_days(__days); 757 __tp._M_days_abbreviated(__days); 758 __string_view __str(__days[__wd.c_encoding()]); 759 return __format::__write(std::move(__out), __str); 762 template<typename _Tp, typename _FormatContext> 763 typename _FormatContext::iterator 764 _M_b_B(const _Tp& __t, typename _FormatContext::iterator __out, 765 _FormatContext& __ctx, bool __full) const 767 // %b Locale's abbreviated month name. 768 // %B Locale's full month name. 769 chrono::month __m = _S_month(__t); 771 __throw_format_error("format error: invalid month
"); 772 locale __loc = _M_locale(__ctx); 773 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); 774 const _CharT* __months[12]; 776 __tp._M_months(__months); 778 __tp._M_months_abbreviated(__months); 779 __string_view __str(__months[(unsigned)__m - 1]); 780 return __format::__write(std::move(__out), __str); 783 template<typename _Tp, typename _FormatContext> 784 typename _FormatContext::iterator 785 _M_c(const _Tp& __tt, typename _FormatContext::iterator __out, 786 _FormatContext& __ctx, bool __mod = false) const 788 // %c Locale's date and time representation. 789 // %Ec Locale's alternate date and time representation. 791 auto __t = _S_floor_seconds(__tt); 792 locale __loc = _M_locale(__ctx); 793 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); 794 const _CharT* __formats[2]; 795 __tp._M_date_time_formats(__formats); 796 const _CharT* __rep = __formats[__mod]; 798 __rep = _GLIBCXX_WIDEN("%a %b %e %H:%M:%S %Y
"); 799 basic_string<_CharT> __fmt(_S_empty_spec); 800 __fmt.insert(1u, 1u, _S_colon); 801 __fmt.insert(2u, __rep); 802 return std::vformat_to(std::move(__out), __loc, __fmt, 803 std::make_format_args<_FormatContext>(__t)); 806 template<typename _Tp, typename _FormatContext> 807 typename _FormatContext::iterator 808 _M_C_y_Y(const _Tp& __t, typename _FormatContext::iterator __out, 809 _FormatContext& __ctx, _CharT __conv, _CharT __mod = 0) const 811 // %C Year divided by 100 using floored division. 812 // %EC Locale's alternative preresentation of the century (era name). 813 // %y Last two decimal digits of the year. 814 // %Oy Locale's alternative representation. 815 // %Ey Locale's alternative representation of offset from %EC. 816 // %Y Year as a decimal number. 817 // %EY Locale's alternative full year representation. 819 chrono::year __y = _S_year(__t); 821 if (__mod) [[unlikely]] 824 __tm.tm_year = (int)__y - 1900; 825 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm, 829 basic_string<_CharT> __s; 831 const bool __is_neg = __yi < 0; 832 __yi = __builtin_abs(__yi); 834 if (__conv == 'Y' || __conv == 'C') 836 int __ci = __yi / 100; 837 if (__is_neg) [[unlikely]] 839 __s.assign(1, _S_plus_minus[1]); 840 // For floored division -123//100 is -2 and -100//100 is -1 841 if (__conv == 'C' && (__ci * 100) != __yi) 844 if (__ci >= 100) [[unlikely]] 846 __s += std::format(_S_empty_spec, __ci / 100); 849 __s += _S_two_digits(__ci); 852 if (__conv == 'Y' || __conv == 'y') 853 __s += _S_two_digits(__yi % 100); 855 return __format::__write(std::move(__out), __string_view(__s)); 858 template<typename _Tp, typename _FormatContext> 859 typename _FormatContext::iterator 860 _M_D(const _Tp& __t, typename _FormatContext::iterator __out, 861 _FormatContext&) const 863 auto __ymd = _S_date(__t); 864 basic_string<_CharT> __s; 865 #if ! _GLIBCXX_USE_CXX11_ABI 868 __s = _S_two_digits((unsigned)__ymd.month()); 870 __s += _S_two_digits((unsigned)__ymd.day()); 872 __s += _S_two_digits(__builtin_abs((int)__ymd.year()) % 100); 873 return __format::__write(std::move(__out), __string_view(__s)); 876 template<typename _Tp, typename _FormatContext> 877 typename _FormatContext::iterator 878 _M_d_e(const _Tp& __t, typename _FormatContext::iterator __out, 879 _FormatContext& __ctx, _CharT __conv, bool __mod = false) const 881 // %d The day of month as a decimal number. 882 // %Od Locale's alternative representation. 883 // %e Day of month as decimal number, padded with space. 884 // %Oe Locale's alternative digits. 886 chrono::day __d = _S_day(__t); 887 unsigned __i = (unsigned)__d; 889 if (__mod) [[unlikely]] 893 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm, 897 auto __sv = _S_two_digits(__i); 899 if (__conv == _CharT('e') && __i < 10) 905 return __format::__write(std::move(__out), __sv); 908 template<typename _Tp, typename _FormatContext> 909 typename _FormatContext::iterator 910 _M_F(const _Tp& __t, typename _FormatContext::iterator __out, 911 _FormatContext&) const 913 auto __ymd = _S_date(__t); 914 basic_string<_CharT> __s; 915 #if ! _GLIBCXX_USE_CXX11_ABI 918 __s += std::format(_GLIBCXX_WIDEN("{:04d}- -
"), (int)__ymd.year()); 919 auto __sv = _S_two_digits((unsigned)__ymd.month()); 920 __s[__s.size() - 5] = __sv[0]; 921 __s[__s.size() - 4] = __sv[1]; 922 __sv = _S_two_digits((unsigned)__ymd.day()); 923 __s[__s.size() - 2] = __sv[0]; 924 __s[__s.size() - 1] = __sv[1]; 926 return __format::__write(std::move(__out), __sv); 929 template<typename _Tp, typename _FormatContext> 930 typename _FormatContext::iterator 931 _M_g_G(const _Tp& __t, typename _FormatContext::iterator __out, 932 _FormatContext& __ctx, bool __full) const 934 // %g last two decimal digits of the ISO week-based year. 935 // %G ISO week-based year. 936 using namespace chrono; 937 auto __d = _S_days(__t); 938 // Move to nearest Thursday: 939 __d -= (weekday(__d) - Monday) - days(3); 940 // ISO week-based year is the year that contains that Thursday: 941 year __y = year_month_day(__d).year(); 942 return _M_C_y_Y(__y, std::move(__out), __ctx, "yY
"[__full]); 945 template<typename _Tp, typename _FormatContext> 946 typename _FormatContext::iterator 947 _M_H_I(const _Tp& __t, typename _FormatContext::iterator __out, 948 _FormatContext& __ctx, _CharT __conv, bool __mod = false) const 950 // %H The hour (24-hour clock) as a decimal number. 951 // %OH Locale's alternative representation. 952 // %I The hour (12-hour clock) as a decimal number. 953 // %OI Locale's alternative representation. 955 const auto __hms = _S_hms(__t); 956 int __i = __hms.hours().count(); 958 if (__mod) [[unlikely]] 962 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm, 966 if (__conv == _CharT('I')) 973 return __format::__write(std::move(__out), _S_two_digits(__i)); 976 template<typename _Tp, typename _FormatContext> 977 typename _FormatContext::iterator 978 _M_j(const _Tp& __t, typename _FormatContext::iterator __out, 979 _FormatContext&) const 981 if constexpr (chrono::__is_duration_v<_Tp>) 983 // Decimal number of days, without padding. 984 unsigned __d = chrono::duration_cast<chrono::days>(__t).count(); 985 return std::format_to(std::move(__out), _S_empty_spec, __d); 989 // Day of the year as a decimal number, padding with zero. 990 using namespace chrono; 991 auto __day = _S_days(__t); 992 auto __ymd = _S_date(__t); 994 // See "Calculating Ordinal Dates
" at 995 // https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes 996 if constexpr (is_same_v<typename decltype(__day)::clock, local_t>) 997 __d = __day - local_days(__ymd.year()/January/0); 999 __d = __day - sys_days(__ymd.year()/January/0); 1000 return std::format_to(std::move(__out), _GLIBCXX_WIDEN("{:03d}
"), 1005 template<typename _Tp, typename _FormatContext> 1006 typename _FormatContext::iterator 1007 _M_m(const _Tp& __t, typename _FormatContext::iterator __out, 1008 _FormatContext& __ctx, bool __mod) const 1010 // %m month as a decimal number. 1011 // %Om Locale's alternative representation. 1013 auto __m = _S_month(__t); 1014 auto __i = (unsigned)__m; 1016 if (__mod) [[unlikely]] // %Om 1019 __tm.tm_mon = __i - 1; 1020 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm, 1024 return __format::__write(std::move(__out), _S_two_digits(__i)); 1027 template<typename _Tp, typename _FormatContext> 1028 typename _FormatContext::iterator 1029 _M_M(const _Tp& __t, typename _FormatContext::iterator __out, 1030 _FormatContext& __ctx, bool __mod) const 1032 // %M The minute as a decimal number. 1033 // %OM Locale's alternative representation. 1035 auto __m = _S_hms(__t).minutes(); 1036 auto __i = __m.count(); 1038 if (__mod) [[unlikely]] // %OM 1042 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm, 1046 return __format::__write(std::move(__out), _S_two_digits(__i)); 1049 template<typename _Tp, typename _FormatContext> 1050 typename _FormatContext::iterator 1051 _M_p(const _Tp& __t, typename _FormatContext::iterator __out, 1052 _FormatContext& __ctx) const 1054 // %p The locale's equivalent of the AM/PM designations. 1055 auto __hms = _S_hms(__t); 1056 locale __loc = _M_locale(__ctx); 1057 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); 1058 const _CharT* __ampm[2]; 1059 __tp._M_am_pm(__ampm); 1060 return std::format_to(std::move(__out), _S_empty_spec, 1061 __ampm[__hms.hours().count() >= 12]); 1064 template<typename _Tp, typename _FormatContext> 1065 typename _FormatContext::iterator 1066 _M_q(const _Tp&, typename _FormatContext::iterator __out, 1067 _FormatContext&) const 1069 // %q The duration's unit suffix 1070 if constexpr (!chrono::__is_duration_v<_Tp>) 1071 __throw_format_error("format error: argument is not a duration
"); 1074 namespace __d = chrono::__detail; 1075 using period = typename _Tp::period; 1076 return __d::__fmt_units_suffix<period, _CharT>(std::move(__out)); 1080 // %Q handled in _M_format 1082 template<typename _Tp, typename _FormatContext> 1083 typename _FormatContext::iterator 1084 _M_r(const _Tp& __tt, typename _FormatContext::iterator __out, 1085 _FormatContext& __ctx) const 1087 // %r locale's 12-hour clock time. 1088 auto __t = _S_floor_seconds(__tt); 1089 locale __loc = _M_locale(__ctx); 1090 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); 1091 const _CharT* __ampm_fmt; 1092 __tp._M_am_pm_format(&__ampm_fmt); 1093 basic_string<_CharT> __fmt(_S_empty_spec); 1094 __fmt.insert(1u, 1u, _S_colon); 1095 __fmt.insert(2u, __ampm_fmt); 1096 return std::vformat_to(std::move(__out), __fmt, 1097 std::make_format_args<_FormatContext>(__t)); 1100 template<typename _Tp, typename _FormatContext> 1101 typename _FormatContext::iterator 1102 _M_R_T(const _Tp& __t, typename _FormatContext::iterator __out, 1103 _FormatContext& __ctx, bool __secs) const 1105 // %R Equivalent to %H:%M 1106 // %T Equivalent to %H:%M:%S 1107 auto __hms = _S_hms(__t); 1109 basic_string<_CharT> __s; 1110 #if ! _GLIBCXX_USE_CXX11_ABI 1113 __s = std::format(_GLIBCXX_WIDEN("{:02d}:00
"), __hms.hours().count()); 1114 auto __sv = _S_two_digits(__hms.minutes().count()); 1115 __s[__s.size() - 2] = __sv[0]; 1116 __s[__s.size() - 1] = __sv[1]; 1118 __out = __format::__write(std::move(__out), __sv); 1121 *__out++ = _S_colon; 1122 __out = _M_S(__hms, std::move(__out), __ctx); 1127 template<typename _Tp, typename _FormatContext> 1128 typename _FormatContext::iterator 1129 _M_S(const _Tp& __t, typename _FormatContext::iterator __out, 1130 _FormatContext& __ctx, bool __mod = false) const 1132 // %S Seconds as a decimal number. 1133 // %OS The locale's alternative representation. 1134 auto __hms = _S_hms(__t); 1136 if (__mod) [[unlikely]] // %OS 1139 __tm.tm_sec = (int)__hms.seconds().count(); 1140 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm, 1144 if constexpr (__hms.fractional_width == 0) 1145 __out = __format::__write(std::move(__out), 1146 _S_two_digits(__hms.seconds().count())); 1149 locale __loc = _M_locale(__ctx); 1150 auto __s = __hms.seconds(); 1151 auto __ss = __hms.subseconds(); 1152 using rep = typename decltype(__ss)::rep; 1153 if constexpr (is_floating_point_v<rep>) 1155 chrono::duration<rep> __fs = __s + __ss; 1156 __out = std::format_to(std::move(__out), __loc, 1157 _GLIBCXX_WIDEN("{:#0{}.{}Lf}
"), 1159 3 + __hms.fractional_width, 1160 __hms.fractional_width); 1165 = use_facet<numpunct<_CharT>>(__loc); 1166 __out = __format::__write(std::move(__out), 1167 _S_two_digits(__s.count())); 1168 *__out++ = __np.decimal_point(); 1169 if constexpr (is_integral_v<rep>) 1170 __out = std::format_to(std::move(__out), 1171 _GLIBCXX_WIDEN("{:0{}}
"), 1173 __hms.fractional_width); 1176 auto __str = std::format(_S_empty_spec, __ss.count()); 1177 __out = std::format_to(_GLIBCXX_WIDEN("{:0>{}s}
"), 1179 __hms.fractional_width); 1186 // %t handled in _M_format 1188 template<typename _Tp, typename _FormatContext> 1189 typename _FormatContext::iterator 1190 _M_u_w(const _Tp& __t, typename _FormatContext::iterator __out, 1191 _FormatContext& __ctx, _CharT __conv, bool __mod = false) const 1193 // %u ISO weekday as a decimal number (1-7), where Monday is 1. 1194 // %Ou Locale's alternative numeric rep. 1195 // %w Weekday as a decimal number (0-6), where Sunday is 0. 1196 // %Ow Locale's alternative numeric rep. 1198 chrono::weekday __wd = _S_weekday(__t); 1200 if (__mod) [[unlikely]] 1203 __tm.tm_wday = __wd.c_encoding(); 1204 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm, 1208 unsigned __wdi = __conv == 'u' ? __wd.iso_encoding() 1209 : __wd.c_encoding(); 1210 const _CharT __d = _S_digit(__wdi); 1211 return __format::__write(std::move(__out), __string_view(&__d, 1)); 1214 template<typename _Tp, typename _FormatContext> 1215 typename _FormatContext::iterator 1216 _M_U_V_W(const _Tp& __t, typename _FormatContext::iterator __out, 1217 _FormatContext& __ctx, _CharT __conv, bool __mod = false) const 1219 // %U Week number of the year as a decimal number, from first Sunday. 1220 // %OU Locale's alternative numeric rep. 1221 // %V ISO week-based week number as a decimal number. 1222 // %OV Locale's alternative numeric rep. 1223 // %W Week number of the year as a decimal number, from first Monday. 1224 // %OW Locale's alternative numeric rep. 1225 using namespace chrono; 1226 auto __d = _S_days(__t); 1227 using _TDays = decltype(__d); // Either sys_days or local_days. 1229 if (__mod) [[unlikely]] 1231 const year_month_day __ymd(__d); 1232 const year __y = __ymd.year(); 1234 __tm.tm_year = (int)__y - 1900; 1235 __tm.tm_yday = (__d - _TDays(__y/January/1)).count(); 1236 __tm.tm_wday = weekday(__d).c_encoding(); 1237 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm, 1241 _TDays __first; // First day of week 1. 1242 if (__conv == 'V') // W01 begins on Monday before first Thursday. 1244 // Move to nearest Thursday: 1245 __d -= (weekday(__d) - Monday) - days(3); 1246 // ISO week of __t is number of weeks since January 1 of the 1247 // same year as that nearest Thursday. 1248 __first = _TDays(year_month_day(__d).year()/January/1); 1253 if constexpr (requires { __t.year(); }) 1256 __y = year_month_day(__d).year(); 1257 const weekday __weekstart = __conv == 'U' ? Sunday : Monday; 1258 __first = _TDays(__y/January/__weekstart[1]); 1260 auto __weeks = chrono::floor<weeks>(__d - __first); 1261 __string_view __sv = _S_two_digits(__weeks.count() + 1); 1262 return __format::__write(std::move(__out), __sv); 1265 template<typename _Tp, typename _FormatContext> 1266 typename _FormatContext::iterator 1267 _M_x(const _Tp& __t, typename _FormatContext::iterator __out, 1268 _FormatContext& __ctx, bool __mod = false) const 1270 // %x Locale's date rep 1271 // %Ex Locale's alternative date representation. 1272 locale __loc = _M_locale(__ctx); 1273 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); 1274 const _CharT* __date_reps[2]; 1275 __tp._M_date_formats(__date_reps); 1276 const _CharT* __rep = __date_reps[__mod]; 1278 return _M_D(__t, std::move(__out), __ctx); 1280 basic_string<_CharT> __fmt(_S_empty_spec); 1281 __fmt.insert(1u, 1u, _S_colon); 1282 __fmt.insert(2u, __rep); 1283 return std::vformat_to(std::move(__out), __fmt, 1284 std::make_format_args<_FormatContext>(__t)); 1287 template<typename _Tp, typename _FormatContext> 1288 typename _FormatContext::iterator 1289 _M_X(const _Tp& __tt, typename _FormatContext::iterator __out, 1290 _FormatContext& __ctx, bool __mod = false) const 1292 // %X Locale's time rep 1293 // %EX Locale's alternative time representation. 1294 auto __t = _S_floor_seconds(__tt); 1295 locale __loc = _M_locale(__ctx); 1296 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); 1297 const _CharT* __time_reps[2]; 1298 __tp._M_time_formats(__time_reps); 1299 const _CharT* __rep = __time_reps[__mod]; 1301 return _M_R_T(__t, std::move(__out), __ctx, true); 1303 basic_string<_CharT> __fmt(_S_empty_spec); 1304 __fmt.insert(1u, 1u, _S_colon); 1305 __fmt.insert(2u, __rep); 1306 return std::vformat_to(std::move(__out), __fmt, 1307 std::make_format_args<_FormatContext>(__t)); 1310 template<typename _Tp, typename _FormatContext> 1311 typename _FormatContext::iterator 1312 _M_z(const _Tp& __t, typename _FormatContext::iterator __out, 1313 _FormatContext&, bool __mod = false) const 1315 using ::std::chrono::__detail::__utc_leap_second; 1316 using ::std::chrono::__detail::__local_time_fmt; 1318 auto __utc = __mod ? __string_view(_GLIBCXX_WIDEN("+00:00
"), 6) 1319 : __string_view(_GLIBCXX_WIDEN("+0000
"), 5); 1321 if constexpr (chrono::__is_time_point_v<_Tp>) 1323 if constexpr (is_same_v<typename _Tp::clock, 1324 chrono::system_clock>) 1325 return __format::__write(std::move(__out), __utc); 1327 else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) 1329 if (__t._M_offset_sec) 1332 basic_string<_CharT> __s; 1333 if (*__t._M_offset_sec != 0s) 1335 chrono:: hh_mm_ss __hms(*__t._M_offset_sec); 1336 __s = _S_plus_minus[__hms.is_negative()]; 1337 __s += _S_two_digits(__hms.hours().count()); 1340 __s += _S_two_digits(__hms.minutes().count()); 1343 return __format::__write(std::move(__out), __sv); 1346 else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>) 1347 return __format::__write(std::move(__out), __utc); 1349 __no_timezone_available(); 1352 template<typename _Tp, typename _FormatContext> 1353 typename _FormatContext::iterator 1354 _M_Z(const _Tp& __t, typename _FormatContext::iterator __out, 1355 _FormatContext& __ctx) const 1357 using ::std::chrono::__detail::__utc_leap_second; 1358 using ::std::chrono::__detail::__local_time_fmt; 1360 __string_view __utc(_GLIBCXX_WIDEN("UTC
"), 3); 1361 if constexpr (chrono::__is_time_point_v<_Tp>) 1363 if constexpr (is_same_v<typename _Tp::clock, 1364 chrono::system_clock>) 1365 return __format::__write(std::move(__out), __utc); 1367 else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) 1371 string_view __sv = *__t._M_abbrev; 1372 if constexpr (is_same_v<_CharT, char>) 1373 return __format::__write(std::move(__out), __sv); 1376 // TODO use resize_and_overwrite 1377 basic_string<_CharT> __ws(__sv.size(), _CharT()); 1378 auto& __ct = use_facet<ctype<_CharT>>(_M_locale(__ctx)); 1379 __ct.widen(__sv.begin(), __sv.end(), __ws.data()); 1380 __string_view __wsv = __ws; 1381 return __format::__write(std::move(__out), __wsv); 1385 else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>) 1386 return __format::__write(std::move(__out), __utc); 1388 __no_timezone_available(); 1391 // %% handled in _M_format 1393 // A single digit character in the range '0'..'9'. 1395 _S_digit(int __n) noexcept 1397 // Extra 9s avoid past-the-end read on bad input. 1398 return _GLIBCXX_WIDEN("0123456789999999
")[__n & 0xf]; 1401 // A string view of two digit characters, "00
".."99
". 1402 static basic_string_view<_CharT> 1403 _S_two_digits(int __n) noexcept 1406 _GLIBCXX_WIDEN("0001020304050607080910111213141516171819
" 1407 "2021222324252627282930313233343536373839
" 1408 "4041424344454647484950515253545556575859
" 1409 "6061626364656667686970717273747576777879
" 1410 "8081828384858687888990919293949596979899
" 1411 "9999999999999999999999999999999999999999
" 1412 "9999999999999999
") + 2 * (__n & 0x7f), 1417 // Accessors for the components of chrono types: 1419 // Returns a hh_mm_ss. 1420 template<typename _Tp> 1421 static decltype(auto) 1422 _S_hms(const _Tp& __t) 1424 using ::std::chrono::__detail::__utc_leap_second; 1425 using ::std::chrono::__detail::__local_time_fmt; 1427 if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>) 1429 else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>) 1431 else if constexpr (chrono::__is_duration_v<_Tp>) 1432 return chrono::hh_mm_ss<_Tp>(__t); 1433 else if constexpr (chrono::__is_time_point_v<_Tp>) 1434 return chrono::hh_mm_ss(__t - chrono::floor<chrono::days>(__t)); 1435 else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) 1436 return _S_hms(__t._M_time); 1439 __invalid_chrono_spec(); 1440 return chrono::hh_mm_ss<chrono::seconds>(); 1444 // Returns a sys_days or local_days. 1445 template<typename _Tp> 1447 _S_days(const _Tp& __t) 1449 using namespace chrono; 1450 using ::std::chrono::__detail::__utc_leap_second; 1451 using ::std::chrono::__detail::__local_time_fmt; 1453 if constexpr (__is_time_point_v<_Tp>) 1454 return chrono::floor<days>(__t); 1455 else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>) 1457 else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) 1458 return chrono::floor<days>(__t._M_time); 1459 else if constexpr (is_same_v<_Tp, year_month_day> 1460 || is_same_v<_Tp, year_month_day_last> 1461 || is_same_v<_Tp, year_month_weekday> 1462 || is_same_v<_Tp, year_month_weekday_last>) 1463 return sys_days(__t); 1466 if constexpr (__is_duration_v<_Tp>) 1467 __not_valid_for_duration(); 1469 __invalid_chrono_spec(); 1470 return chrono::sys_days(); 1474 // Returns a year_month_day. 1475 template<typename _Tp> 1476 static chrono::year_month_day 1477 _S_date(const _Tp& __t) 1479 if constexpr (is_same_v<_Tp, chrono::year_month_day>) 1482 return chrono::year_month_day(_S_days(__t)); 1485 template<typename _Tp> 1487 _S_day(const _Tp& __t) 1489 using namespace chrono; 1491 if constexpr (is_same_v<_Tp, day>) 1493 else if constexpr (requires { __t.day(); }) 1496 return _S_date(__t).day(); 1499 template<typename _Tp> 1500 static chrono::month 1501 _S_month(const _Tp& __t) 1503 using namespace chrono; 1505 if constexpr (is_same_v<_Tp, month>) 1507 else if constexpr (requires { __t.month(); }) 1510 return _S_date(__t).month(); 1513 template<typename _Tp> 1515 _S_year(const _Tp& __t) 1517 using namespace chrono; 1519 if constexpr (is_same_v<_Tp, year>) 1521 else if constexpr (requires { __t.year(); }) 1524 return _S_date(__t).year(); 1527 template<typename _Tp> 1528 static chrono::weekday 1529 _S_weekday(const _Tp& __t) 1531 using namespace ::std::chrono; 1532 using ::std::chrono::__detail::__local_time_fmt; 1534 if constexpr (is_same_v<_Tp, weekday>) 1536 else if constexpr (requires { __t.weekday(); }) 1537 return __t.weekday(); 1538 else if constexpr (is_same_v<_Tp, month_weekday>) 1539 return __t.weekday_indexed().weekday(); 1540 else if constexpr (is_same_v<_Tp, month_weekday_last>) 1541 return __t.weekday_last().weekday(); 1543 return weekday(_S_days(__t)); 1546 // Remove subsecond precision from a time_point. 1547 template<typename _Tp> 1549 _S_floor_seconds(const _Tp& __t) 1551 using chrono::__detail::__local_time_fmt; 1552 if constexpr (chrono::__is_time_point_v<_Tp> 1553 || chrono::__is_duration_v<_Tp>) 1555 if constexpr (_Tp::period::den != 1) 1556 return chrono::floor<chrono::seconds>(__t); 1560 else if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>) 1562 if constexpr (_Tp::fractional_width != 0) 1563 return chrono::floor<chrono::seconds>(__t.to_duration()); 1567 else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) 1568 return _S_floor_seconds(__t._M_time); 1573 // Use the formatting locale's std::time_put facet to produce 1574 // a locale-specific representation. 1575 template<typename _Iter> 1577 _M_locale_fmt(_Iter __out, const locale& __loc, const struct tm& __tm, 1578 char __fmt, char __mod) const 1580 basic_ostringstream<_CharT> __os; 1581 const auto& __tp = use_facet<time_put<_CharT>>(__loc); 1582 __tp.put(__os, __os, _S_space, &__tm, __fmt, __mod); 1584 __out = __format::__write(std::move(__out), __os.view()); 1589 } // namespace __format 1592 template<typename _Rep, typename _Period, typename _CharT>
1593 struct formatter<chrono::duration<_Rep, _Period>, _CharT>
1595 constexpr typename basic_format_parse_context<_CharT>::iterator
1596 parse(basic_format_parse_context<_CharT>& __pc)
1598 using namespace __format;
1599 auto __it = _M_f._M_parse(__pc, _Duration|_TimeOfDay);
1600 if constexpr (!is_floating_point_v<_Rep>)
1601 if (_M_f._M_spec._M_prec_kind != __format::_WP_none)
1602 __throw_format_error("format error: invalid precision
for duration
"); 1606 template<typename _Out> 1607 typename basic_format_context<_Out, _CharT>::iterator 1608 format(const chrono::duration<_Rep, _Period>& __d, 1609 basic_format_context<_Out, _CharT>& __fc) const 1611 return _M_f._M_format(chrono::abs(__d), __fc, __d < __d.zero()); 1615 __format::__formatter_chrono<_CharT> _M_f; 1618 template<typename _CharT> 1619 struct formatter<chrono::day, _CharT> 1621 template<typename _ParseContext> 1622 constexpr typename _ParseContext::iterator 1623 parse(_ParseContext& __pc) 1624 { return _M_f._M_parse(__pc, __format::_Day); } 1626 template<typename _FormatContext> 1627 typename _FormatContext::iterator 1628 format(const chrono::day& __t, _FormatContext& __fc) const 1629 { return _M_f._M_format(__t, __fc); } 1632 __format::__formatter_chrono<_CharT> _M_f; 1635 template<typename _CharT> 1636 struct formatter<chrono::month, _CharT> 1638 template<typename _ParseContext> 1639 constexpr typename _ParseContext::iterator 1640 parse(_ParseContext& __pc) 1641 { return _M_f._M_parse(__pc, __format::_Month); } 1643 template<typename _FormatContext> 1644 typename _FormatContext::iterator 1645 format(const chrono::month& __t, _FormatContext& __fc) const 1646 { return _M_f._M_format(__t, __fc); } 1649 __format::__formatter_chrono<_CharT> _M_f; 1652 template<typename _CharT> 1653 struct formatter<chrono::year, _CharT> 1655 template<typename _ParseContext> 1656 constexpr typename _ParseContext::iterator 1657 parse(_ParseContext& __pc) 1658 { return _M_f._M_parse(__pc, __format::_Year); } 1660 template<typename _FormatContext> 1661 typename _FormatContext::iterator 1662 format(const chrono::year& __t, _FormatContext& __fc) const 1663 { return _M_f._M_format(__t, __fc); } 1666 __format::__formatter_chrono<_CharT> _M_f; 1669 template<typename _CharT> 1670 struct formatter<chrono::weekday, _CharT> 1672 template<typename _ParseContext> 1673 constexpr typename _ParseContext::iterator 1674 parse(_ParseContext& __pc) 1675 { return _M_f._M_parse(__pc, __format::_Weekday); } 1677 template<typename _FormatContext> 1678 typename _FormatContext::iterator 1679 format(const chrono::weekday& __t, _FormatContext& __fc) const 1680 { return _M_f._M_format(__t, __fc); } 1683 __format::__formatter_chrono<_CharT> _M_f; 1686 template<typename _CharT> 1687 struct formatter<chrono::weekday_indexed, _CharT> 1689 template<typename _ParseContext> 1690 constexpr typename _ParseContext::iterator 1691 parse(_ParseContext& __pc) 1692 { return _M_f._M_parse(__pc, __format::_Weekday); } 1694 template<typename _FormatContext> 1695 typename _FormatContext::iterator 1696 format(const chrono::weekday_indexed& __t, _FormatContext& __fc) const 1697 { return _M_f._M_format(__t, __fc); } 1700 __format::__formatter_chrono<_CharT> _M_f; 1703 template<typename _CharT> 1704 struct formatter<chrono::weekday_last, _CharT> 1706 template<typename _ParseContext> 1707 constexpr typename _ParseContext::iterator 1708 parse(_ParseContext& __pc) 1709 { return _M_f._M_parse(__pc, __format::_Weekday); } 1711 template<typename _FormatContext> 1712 typename _FormatContext::iterator 1713 format(const chrono::weekday_last& __t, _FormatContext& __fc) const 1714 { return _M_f._M_format(__t, __fc); } 1717 __format::__formatter_chrono<_CharT> _M_f; 1720 template<typename _CharT> 1721 struct formatter<chrono::month_day, _CharT> 1723 template<typename _ParseContext> 1724 constexpr typename _ParseContext::iterator 1725 parse(_ParseContext& __pc) 1726 { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); } 1728 template<typename _FormatContext> 1729 typename _FormatContext::iterator 1730 format(const chrono::month_day& __t, _FormatContext& __fc) const 1731 { return _M_f._M_format(__t, __fc); } 1734 __format::__formatter_chrono<_CharT> _M_f; 1737 template<typename _CharT> 1738 struct formatter<chrono::month_day_last, _CharT> 1740 template<typename _ParseContext> 1741 constexpr typename _ParseContext::iterator 1742 parse(_ParseContext& __pc) 1743 { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); } 1745 template<typename _FormatContext> 1746 typename _FormatContext::iterator 1747 format(const chrono::month_day_last& __t, _FormatContext& __fc) const 1748 { return _M_f._M_format(__t, __fc); } 1751 __format::__formatter_chrono<_CharT> _M_f; 1754 template<typename _CharT> 1755 struct formatter<chrono::month_weekday, _CharT> 1757 template<typename _ParseContext> 1758 constexpr typename _ParseContext::iterator 1759 parse(_ParseContext& __pc) 1760 { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); } 1762 template<typename _FormatContext> 1763 typename _FormatContext::iterator 1764 format(const chrono::month_weekday& __t, _FormatContext& __fc) const 1765 { return _M_f._M_format(__t, __fc); } 1768 __format::__formatter_chrono<_CharT> _M_f; 1771 template<typename _CharT> 1772 struct formatter<chrono::month_weekday_last, _CharT> 1774 template<typename _ParseContext> 1775 constexpr typename _ParseContext::iterator 1776 parse(_ParseContext& __pc) 1777 { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); } 1779 template<typename _FormatContext> 1780 typename _FormatContext::iterator 1781 format(const chrono::month_weekday_last& __t, 1782 _FormatContext& __fc) const 1783 { return _M_f._M_format(__t, __fc); } 1786 __format::__formatter_chrono<_CharT> _M_f; 1789 template<typename _CharT> 1790 struct formatter<chrono::year_month, _CharT> 1792 template<typename _ParseContext> 1793 constexpr typename _ParseContext::iterator 1794 parse(_ParseContext& __pc) 1795 { return _M_f._M_parse(__pc, __format::_Year|__format::_Month); } 1797 template<typename _FormatContext> 1798 typename _FormatContext::iterator 1799 format(const chrono::year_month& __t, _FormatContext& __fc) const 1800 { return _M_f._M_format(__t, __fc); } 1803 __format::__formatter_chrono<_CharT> _M_f; 1806 template<typename _CharT> 1807 struct formatter<chrono::year_month_day, _CharT> 1809 template<typename _ParseContext> 1810 constexpr typename _ParseContext::iterator 1811 parse(_ParseContext& __pc) 1812 { return _M_f._M_parse(__pc, __format::_Date); } 1814 template<typename _FormatContext> 1815 typename _FormatContext::iterator 1816 format(const chrono::year_month_day& __t, _FormatContext& __fc) const 1817 { return _M_f._M_format(__t, __fc); } 1820 __format::__formatter_chrono<_CharT> _M_f; 1823 template<typename _CharT> 1824 struct formatter<chrono::year_month_day_last, _CharT> 1826 template<typename _ParseContext> 1827 constexpr typename _ParseContext::iterator 1828 parse(_ParseContext& __pc) 1829 { return _M_f._M_parse(__pc, __format::_Date); } 1831 template<typename _FormatContext> 1832 typename _FormatContext::iterator 1833 format(const chrono::year_month_day_last& __t, 1834 _FormatContext& __fc) const 1835 { return _M_f._M_format(__t, __fc); } 1838 __format::__formatter_chrono<_CharT> _M_f; 1841 template<typename _CharT> 1842 struct formatter<chrono::year_month_weekday, _CharT> 1844 template<typename _ParseContext> 1845 constexpr typename _ParseContext::iterator 1846 parse(_ParseContext& __pc) 1847 { return _M_f._M_parse(__pc, __format::_Date); } 1849 template<typename _FormatContext> 1850 typename _FormatContext::iterator 1851 format(const chrono::year_month_weekday& __t, 1852 _FormatContext& __fc) const 1853 { return _M_f._M_format(__t, __fc); } 1856 __format::__formatter_chrono<_CharT> _M_f; 1859 template<typename _CharT> 1860 struct formatter<chrono::year_month_weekday_last, _CharT> 1862 template<typename _ParseContext> 1863 constexpr typename _ParseContext::iterator 1864 parse(_ParseContext& __pc) 1865 { return _M_f._M_parse(__pc, __format::_Date); } 1867 template<typename _FormatContext> 1868 typename _FormatContext::iterator 1869 format(const chrono::year_month_weekday_last& __t, 1870 _FormatContext& __fc) const 1871 { return _M_f._M_format(__t, __fc); } 1874 __format::__formatter_chrono<_CharT> _M_f; 1877 template<typename _Rep, typename _Period, typename _CharT> 1878 struct formatter<chrono::hh_mm_ss<chrono::duration<_Rep, _Period>>, _CharT> 1880 template<typename _ParseContext> 1881 constexpr typename _ParseContext::iterator 1882 parse(_ParseContext& __pc) 1883 { return _M_f._M_parse(__pc, __format::_TimeOfDay); } 1885 template<typename _FormatContext> 1886 typename _FormatContext::iterator 1887 format(const chrono::hh_mm_ss<chrono::duration<_Rep, _Period>>& __t, 1888 _FormatContext& __fc) const 1889 { return _M_f._M_format(__t, __fc); } 1892 __format::__formatter_chrono<_CharT> _M_f; 1895 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI 1896 template<typename _CharT> 1897 struct formatter<chrono::sys_info, _CharT> 1899 template<typename _ParseContext> 1900 constexpr typename _ParseContext::iterator 1901 parse(_ParseContext& __pc) 1902 { return _M_f._M_parse(__pc, __format::_ChronoParts{}); } 1904 template<typename _FormatContext> 1905 typename _FormatContext::iterator 1906 format(const chrono::sys_info& __i, _FormatContext& __fc) const 1907 { return _M_f._M_format(__i, __fc); } 1910 __format::__formatter_chrono<_CharT> _M_f; 1913 template<typename _CharT> 1914 struct formatter<chrono::local_info, _CharT> 1916 template<typename _ParseContext> 1917 constexpr typename _ParseContext::iterator 1918 parse(_ParseContext& __pc) 1919 { return _M_f._M_parse(__pc, __format::_ChronoParts{}); } 1921 template<typename _FormatContext> 1922 typename _FormatContext::iterator 1923 format(const chrono::local_info& __i, _FormatContext& __fc) const 1924 { return _M_f._M_format(__i, __fc); } 1927 __format::__formatter_chrono<_CharT> _M_f; 1931 template<typename _Duration, typename _CharT> 1932 struct formatter<chrono::sys_time<_Duration>, _CharT> 1934 template<typename _ParseContext> 1935 constexpr typename _ParseContext::iterator 1936 parse(_ParseContext& __pc) 1938 auto __next = _M_f._M_parse(__pc, __format::_ZonedDateTime); 1939 if constexpr (!__stream_insertable) 1940 if (_M_f._M_spec._M_chrono_specs.empty()) 1941 __format::__invalid_chrono_spec(); // chrono-specs can't be empty 1945 template<typename _FormatContext> 1946 typename _FormatContext::iterator 1947 format(const chrono::sys_time<_Duration>& __t, 1948 _FormatContext& __fc) const 1949 { return _M_f._M_format(__t, __fc); } 1952 static constexpr bool __stream_insertable 1953 = requires (basic_ostream<_CharT>& __os, 1954 chrono::sys_time<_Duration> __t) { __os << __t; }; 1956 __format::__formatter_chrono<_CharT> _M_f; 1959 template<typename _Duration, typename _CharT> 1960 struct formatter<chrono::utc_time<_Duration>, _CharT> 1961 : __format::__formatter_chrono<_CharT> 1963 template<typename _ParseContext> 1964 constexpr typename _ParseContext::iterator 1965 parse(_ParseContext& __pc) 1966 { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } 1968 template<typename _FormatContext> 1969 typename _FormatContext::iterator 1970 format(const chrono::utc_time<_Duration>& __t, 1971 _FormatContext& __fc) const 1973 // Adjust by removing leap seconds to get equivalent sys_time. 1974 // We can't just use clock_cast because we want to know if the time 1975 // falls within a leap second insertion, and format seconds as "60
". 1976 using chrono::__detail::__utc_leap_second; 1977 using chrono::seconds; 1978 using chrono::sys_time; 1979 using _CDur = common_type_t<_Duration, seconds>; 1980 const auto __li = chrono::get_leap_second_info(__t); 1981 sys_time<_CDur> __s{__t.time_since_epoch() - __li.elapsed}; 1982 if (!__li.is_leap_second) [[likely]] 1983 return _M_f._M_format(__s, __fc); 1985 return _M_f._M_format(__utc_leap_second(__s), __fc); 1989 friend formatter<chrono::__detail::__utc_leap_second<_Duration>, _CharT>; 1991 __format::__formatter_chrono<_CharT> _M_f; 1994 template<typename _Duration, typename _CharT> 1995 struct formatter<chrono::tai_time<_Duration>, _CharT> 1996 : __format::__formatter_chrono<_CharT> 1998 template<typename _ParseContext> 1999 constexpr typename _ParseContext::iterator 2000 parse(_ParseContext& __pc) 2001 { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } 2003 template<typename _FormatContext> 2004 typename _FormatContext::iterator 2005 format(const chrono::tai_time<_Duration>& __t, 2006 _FormatContext& __fc) const 2008 // Convert to __local_time_fmt with abbrev "TAI
" and offset 0s. 2010 // Offset is 1970y/January/1 - 1958y/January/1 2011 constexpr chrono::days __tai_offset = chrono::days(4383); 2012 using _CDur = common_type_t<_Duration, chrono::days>; 2013 chrono::local_time<_CDur> __lt(__t.time_since_epoch() - __tai_offset); 2014 const string __abbrev("TAI
", 3); 2015 const chrono::seconds __off = 0s; 2016 const auto __lf = chrono::local_time_format(__lt, &__abbrev, &__off); 2017 return _M_f._M_format(__lf, __fc); 2021 __format::__formatter_chrono<_CharT> _M_f; 2024 template<typename _Duration, typename _CharT> 2025 struct formatter<chrono::gps_time<_Duration>, _CharT> 2026 : __format::__formatter_chrono<_CharT> 2028 template<typename _ParseContext> 2029 constexpr typename _ParseContext::iterator 2030 parse(_ParseContext& __pc) 2031 { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } 2033 template<typename _FormatContext> 2034 typename _FormatContext::iterator 2035 format(const chrono::gps_time<_Duration>& __t, 2036 _FormatContext& __fc) const 2038 // Convert to __local_time_fmt with abbrev "GPS
" and offset 0s. 2040 // Offset is 1980y/January/Sunday[1] - 1970y/January/1 2041 constexpr chrono::days __gps_offset = chrono::days(3657); 2042 using _CDur = common_type_t<_Duration, chrono::days>; 2043 chrono::local_time<_CDur> __lt(__t.time_since_epoch() + __gps_offset); 2044 const string __abbrev("GPS
", 3); 2045 const chrono::seconds __off = 0s; 2046 const auto __lf = chrono::local_time_format(__lt, &__abbrev, &__off); 2047 return _M_f._M_format(__lf, __fc); 2051 __format::__formatter_chrono<_CharT> _M_f; 2054 template<typename _Duration, typename _CharT> 2055 struct formatter<chrono::file_time<_Duration>, _CharT> 2057 template<typename _ParseContext> 2058 constexpr typename _ParseContext::iterator 2059 parse(_ParseContext& __pc) 2060 { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } 2062 template<typename _FormatContext> 2063 typename _FormatContext::iterator 2064 format(const chrono::file_time<_Duration>& __t, 2065 _FormatContext& __ctx) const 2067 using namespace chrono; 2068 return _M_f._M_format(chrono::clock_cast<system_clock>(__t), __ctx); 2072 __format::__formatter_chrono<_CharT> _M_f; 2075 template<typename _Duration, typename _CharT> 2076 struct formatter<chrono::local_time<_Duration>, _CharT> 2078 template<typename _ParseContext> 2079 constexpr typename _ParseContext::iterator 2080 parse(_ParseContext& __pc) 2081 { return _M_f._M_parse(__pc, __format::_DateTime); } 2083 template<typename _FormatContext> 2084 typename _FormatContext::iterator 2085 format(const chrono::local_time<_Duration>& __t, 2086 _FormatContext& __ctx) const 2087 { return _M_f._M_format(__t, __ctx); } 2090 __format::__formatter_chrono<_CharT> _M_f; 2093 template<typename _Duration, typename _CharT> 2094 struct formatter<chrono::__detail::__local_time_fmt<_Duration>, _CharT> 2096 template<typename _ParseContext> 2097 constexpr typename _ParseContext::iterator 2098 parse(_ParseContext& __pc) 2099 { return _M_f._M_parse(__pc, __format::_ZonedDateTime); } 2101 template<typename _FormatContext> 2102 typename _FormatContext::iterator 2103 format(const chrono::__detail::__local_time_fmt<_Duration>& __t, 2104 _FormatContext& __ctx) const 2105 { return _M_f._M_format(__t, __ctx); } 2108 __format::__formatter_chrono<_CharT> _M_f; 2111 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI 2112 template<typename _Duration, typename _TimeZonePtr, typename _CharT> 2113 struct formatter<chrono::zoned_time<_Duration, _TimeZonePtr>, _CharT> 2114 : formatter<chrono::__detail::__local_time_fmt<_Duration>, _CharT> 2116 template<typename _FormatContext> 2117 typename _FormatContext::iterator 2118 format(const chrono::zoned_time<_Duration, _TimeZonePtr>& __tp, 2119 _FormatContext& __ctx) const 2121 using chrono::__detail::__local_time_fmt; 2122 using _Base = formatter<__local_time_fmt<_Duration>, _CharT>; 2123 const chrono::sys_info __info = __tp.get_info(); 2124 const auto __lf = chrono::local_time_format(__tp.get_local_time(), 2127 return _Base::format(__lf, __ctx); 2132 // Partial specialization needed for %c formatting of __utc_leap_second. 2133 template<typename _Duration, typename _CharT> 2134 struct formatter<chrono::__detail::__utc_leap_second<_Duration>, _CharT> 2135 : formatter<chrono::utc_time<_Duration>, _CharT> 2137 template<typename _FormatContext> 2138 typename _FormatContext::iterator 2139 format(const chrono::__detail::__utc_leap_second<_Duration>& __t, 2140 _FormatContext& __fc) const 2141 { return this->_M_f._M_format(__t, __fc); } 2149 // TODO: from_stream for duration
2151 template<typename _CharT, typename _Traits, typename _Rep, typename _Period,
2152 typename _Alloc = allocator<_CharT>>
2153 basic_istream<_CharT, _Traits>&
2154 from_stream(basic_istream<_CharT, _Traits>& __is, const _CharT* __fmt,
2155 duration<_Rep, _Period>& __d,
2156 basic_string<_CharT, _Traits, _Alloc>* __abbrev = nullptr,
2157 minutes* __offset = nullptr)
2162 template<typename _CharT, typename _Traits>
2163 inline basic_ostream<_CharT, _Traits>&
2164 operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d)
2166 using _Ctx = __conditional_t<is_same_v<_CharT, char>,
2167 format_context, wformat_context>;
2168 using _Str = basic_string_view<_CharT>;
2169 _Str __s = _GLIBCXX_WIDEN("{:02d} is not a valid day
"); 2171 __s = __s.substr(0, 6); 2172 auto __u = (unsigned)__d; 2173 __os << std::vformat(__s, make_format_args<_Ctx>(__u)); 2177 // TODO from_stream for day 2179 template<typename _CharT, typename _Traits> 2180 inline basic_ostream<_CharT, _Traits>& 2181 operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) 2183 using _Ctx = __conditional_t<is_same_v<_CharT, char>, 2184 format_context, wformat_context>; 2185 using _Str = basic_string_view<_CharT>; 2186 _Str __s = _GLIBCXX_WIDEN("{:L%b}{} is not a valid month
"); 2188 __os << std::vformat(__os.getloc(), __s.substr(0, 6), 2189 make_format_args<_Ctx>(__m)); 2192 auto __u = (unsigned)__m; 2193 __os << std::vformat(__s.substr(6), make_format_args<_Ctx>(__u)); 2198 // TODO from_stream for month 2200 template<typename _CharT, typename _Traits> 2201 inline basic_ostream<_CharT, _Traits>& 2202 operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y) 2204 using _Ctx = __conditional_t<is_same_v<_CharT, char>, 2205 format_context, wformat_context>; 2206 using _Str = basic_string_view<_CharT>; 2207 _Str __s = _GLIBCXX_WIDEN("-{:04d} is not a valid year
"); 2209 __s = __s.substr(0, 7); 2211 if (__i >= 0) [[likely]] 2212 __s.remove_prefix(1); 2215 __os << std::vformat(__s, make_format_args<_Ctx>(__i)); 2219 // TODO from_stream for year 2221 template<typename _CharT, typename _Traits> 2222 inline basic_ostream<_CharT, _Traits>& 2223 operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) 2225 using _Ctx = __conditional_t<is_same_v<_CharT, char>, 2226 format_context, wformat_context>; 2227 using _Str = basic_string_view<_CharT>; 2228 _Str __s = _GLIBCXX_WIDEN("{:L%a}{} is not a valid weekday
"); 2230 __os << std::vformat(__os.getloc(), __s.substr(0, 6), 2231 make_format_args<_Ctx>(__wd)); 2234 auto __c = __wd.c_encoding(); 2235 __os << std::vformat(__s.substr(6), make_format_args<_Ctx>(__c)); 2240 // TODO from_stream for weekday 2242 template<typename _CharT, typename _Traits> 2243 inline basic_ostream<_CharT, _Traits>& 2244 operator<<(basic_ostream<_CharT, _Traits>& __os, 2245 const weekday_indexed& __wdi) 2247 // The standard says to format wdi.weekday() and wdi.index() using 2248 // either "{:L}[{}]
" or "{:L}[{} is not a valid index]
". The {:L} spec 2249 // means to format the weekday using ostringstream, so just do that. 2250 basic_stringstream<_CharT> __os2; 2251 __os2.imbue(__os.getloc()); 2252 __os2 << __wdi.weekday(); 2253 const auto __i = __wdi.index(); 2254 if constexpr (is_same_v<_CharT, char>) 2255 __os2 << std::format("[{}
", __i); 2257 __os2 << std::format(L"[{}
", __i); 2258 basic_string_view<_CharT> __s = _GLIBCXX_WIDEN(" is not a valid index]
"); 2259 if (__i >= 1 && __i <= 5) 2260 __os2 << __s.back(); 2263 __os << __os2.view(); 2267 template<typename _CharT, typename _Traits> 2268 inline basic_ostream<_CharT, _Traits>& 2269 operator<<(basic_ostream<_CharT, _Traits>& __os, 2270 const weekday_last& __wdl) 2272 // As above, just write straight to a stringstream, as if by "{:L}[last]
" 2273 basic_stringstream<_CharT> __os2; 2274 __os2.imbue(__os.getloc()); 2275 __os2 << __wdl.weekday() << _GLIBCXX_WIDEN("[last]
"); 2276 __os << __os2.view(); 2280 template<typename _CharT, typename _Traits> 2281 inline basic_ostream<_CharT, _Traits>& 2282 operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) 2284 // As above, just write straight to a stringstream, as if by "{:L}/{}
" 2285 basic_stringstream<_CharT> __os2; 2286 __os2.imbue(__os.getloc()); 2287 __os2 << __md.month(); 2288 if constexpr (is_same_v<_CharT, char>) 2292 __os2 << __md.day(); 2293 __os << __os2.view(); 2297 // TODO from_stream for month_day 2299 template<typename _CharT, typename _Traits> 2300 inline basic_ostream<_CharT, _Traits>& 2301 operator<<(basic_ostream<_CharT, _Traits>& __os, 2302 const month_day_last& __mdl) 2304 // As above, just write straight to a stringstream, as if by "{:L}/last
" 2305 basic_stringstream<_CharT> __os2; 2306 __os2.imbue(__os.getloc()); 2307 __os2 << __mdl.month(); 2308 if constexpr (is_same_v<_CharT, char>) 2312 __os << __os2.view(); 2316 template<typename _CharT, typename _Traits> 2317 inline basic_ostream<_CharT, _Traits>& 2318 operator<<(basic_ostream<_CharT, _Traits>& __os, 2319 const month_weekday& __mwd) 2321 // As above, just write straight to a stringstream, as if by "{:L}/{:L}
" 2322 basic_stringstream<_CharT> __os2; 2323 __os2.imbue(__os.getloc()); 2324 __os2 << __mwd.month(); 2325 if constexpr (is_same_v<_CharT, char>) 2329 __os2 << __mwd.weekday_indexed(); 2330 __os << __os2.view(); 2334 template<typename _CharT, typename _Traits> 2335 inline basic_ostream<_CharT, _Traits>& 2336 operator<<(basic_ostream<_CharT, _Traits>& __os, 2337 const month_weekday_last& __mwdl) 2339 // As above, just write straight to a stringstream, as if by "{:L}/{:L}
" 2340 basic_stringstream<_CharT> __os2; 2341 __os2.imbue(__os.getloc()); 2342 __os2 << __mwdl.month(); 2343 if constexpr (is_same_v<_CharT, char>) 2347 __os2 << __mwdl.weekday_last(); 2348 __os << __os2.view(); 2352 template<typename _CharT, typename _Traits> 2353 inline basic_ostream<_CharT, _Traits>& 2354 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) 2356 // As above, just write straight to a stringstream, as if by "{}/{:L}
" 2357 basic_stringstream<_CharT> __os2; 2358 __os2.imbue(__os.getloc()); 2359 __os2 << __ym.year(); 2360 if constexpr (is_same_v<_CharT, char>) 2364 __os2 << __ym.month(); 2365 __os << __os2.view(); 2369 // TODO from_stream for year_month 2371 template<typename _CharT, typename _Traits> 2372 inline basic_ostream<_CharT, _Traits>& 2373 operator<<(basic_ostream<_CharT, _Traits>& __os, 2374 const year_month_day& __ymd) 2376 using _Ctx = __conditional_t<is_same_v<_CharT, char>, 2377 format_context, wformat_context>; 2378 using _Str = basic_string_view<_CharT>; 2379 _Str __s = _GLIBCXX_WIDEN("{:%F} is not a valid date
"); 2380 __os << std::vformat(__ymd.ok() ? __s.substr(0, 5) : __s, 2381 make_format_args<_Ctx>(__ymd)); 2385 // TODO from_stream for year_month_day 2387 template<typename _CharT, typename _Traits> 2388 inline basic_ostream<_CharT, _Traits>& 2389 operator<<(basic_ostream<_CharT, _Traits>& __os, 2390 const year_month_day_last& __ymdl) 2392 // As above, just write straight to a stringstream, as if by "{}/{:L}
" 2393 basic_stringstream<_CharT> __os2; 2394 __os2.imbue(__os.getloc()); 2395 __os2 << __ymdl.year(); 2396 if constexpr (is_same_v<_CharT, char>) 2400 __os2 << __ymdl.month_day_last(); 2401 __os << __os2.view(); 2405 template<typename _CharT, typename _Traits> 2406 inline basic_ostream<_CharT, _Traits>& 2407 operator<<(basic_ostream<_CharT, _Traits>& __os, 2408 const year_month_weekday& __ymwd) 2410 // As above, just write straight to a stringstream, as if by 2412 basic_stringstream<_CharT> __os2; 2413 __os2.imbue(__os.getloc()); 2415 if constexpr (is_same_v<_CharT, char>) 2419 __os2 << __ymwd.year() << __slash << __ymwd.month() << __slash 2420 << __ymwd.weekday_indexed(); 2421 __os << __os2.view(); 2425 template<typename _CharT, typename _Traits> 2426 inline basic_ostream<_CharT, _Traits>& 2427 operator<<(basic_ostream<_CharT, _Traits>& __os, 2428 const year_month_weekday_last& __ymwdl) 2430 // As above, just write straight to a stringstream, as if by 2432 basic_stringstream<_CharT> __os2; 2433 __os2.imbue(__os.getloc()); 2435 if constexpr (is_same_v<_CharT, char>) 2439 __os2 << __ymwdl.year() << __slash << __ymwdl.month() << __slash 2440 << __ymwdl.weekday_last(); 2441 __os << __os2.view(); 2445 template<typename _CharT, typename _Traits, typename _Duration> 2446 inline basic_ostream<_CharT, _Traits>& 2447 operator<<(basic_ostream<_CharT, _Traits>& __os, 2448 const hh_mm_ss<_Duration>& __hms) 2450 return __os << format(__os.getloc(), _GLIBCXX_WIDEN("{:L%T}
"), __hms); 2453 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI 2455 template<typename _CharT, typename _Traits>
2456 basic_ostream<_CharT, _Traits>&
2457 operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __i)
2459 __os << '[' << __i.begin << ',' << __i.end
2460 << ',' << hh_mm_ss(__i.offset) << ',' << __i.save
2461 << ',' << __i.abbrev << ']';
2466 template<typename _CharT, typename _Traits>
2467 basic_ostream<_CharT, _Traits>&
2468 operator<<(basic_ostream<_CharT, _Traits>& __os, const local_info& __li)
2471 if (__li.result == local_info::unique)
2475 if (__li.result == local_info::nonexistent)
2476 __os << "nonexistent
"; 2478 __os << "ambiguous
"; 2479 __os << " local time between
" << __li.first; 2480 __os << " and
" << __li.second; 2486 template<typename _CharT, typename _Traits, typename _Duration, 2487 typename _TimeZonePtr> 2488 inline basic_ostream<_CharT, _Traits>& 2489 operator<<(basic_ostream<_CharT, _Traits>& __os, 2490 const zoned_time<_Duration, _TimeZonePtr>& __t) 2492 __os << format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T %Z}
"), __t); 2497 template<typename _CharT, typename _Traits, typename _Duration> 2498 requires (!treat_as_floating_point_v<typename _Duration::rep>) 2499 && ratio_less_v<typename _Duration::period, days::period> 2500 inline basic_ostream<_CharT, _Traits>& 2501 operator<<(basic_ostream<_CharT, _Traits>& __os, 2502 const sys_time<_Duration>& __tp) 2504 __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T}
"), __tp); 2508 template<typename _CharT, typename _Traits> 2509 inline basic_ostream<_CharT, _Traits>& 2510 operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_days& __dp) 2512 __os << year_month_day{__dp}; 2516 // TODO: from_stream for sys_time 2518 template<typename _CharT, typename _Traits, typename _Duration> 2519 inline basic_ostream<_CharT, _Traits>& 2520 operator<<(basic_ostream<_CharT, _Traits>& __os, 2521 const utc_time<_Duration>& __t) 2523 __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T}
"), __t); 2527 // TODO: from_stream for utc_time 2529 template<typename _CharT, typename _Traits, typename _Duration> 2530 inline basic_ostream<_CharT, _Traits>& 2531 operator<<(basic_ostream<_CharT, _Traits>& __os, 2532 const tai_time<_Duration>& __t) 2534 __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T}
"), __t); 2538 // TODO: from_stream for tai_time 2540 template<typename _CharT, typename _Traits, typename _Duration> 2541 inline basic_ostream<_CharT, _Traits>& 2542 operator<<(basic_ostream<_CharT, _Traits>& __os, 2543 const gps_time<_Duration>& __t) 2545 __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T}
"), __t); 2549 // TODO: from_stream for gps_time 2552 template<typename _CharT, typename _Traits, typename _Duration> 2553 inline basic_ostream<_CharT, _Traits>& 2554 operator<<(basic_ostream<_CharT, _Traits>& __os, 2555 const file_time<_Duration>& __t) 2557 __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T}
"), __t); 2561 // TODO: from_stream for file_time 2563 template<typename _CharT, typename _Traits, typename _Duration> 2564 inline basic_ostream<_CharT, _Traits>& 2565 operator<<(basic_ostream<_CharT, _Traits>& __os, 2566 const local_time<_Duration>& __lt) 2568 __os << sys_time<_Duration>{__lt.time_since_epoch()}; 2572 // TODO: from_stream for local_time 2573 #undef _GLIBCXX_WIDEN 2576 } // namespace chrono
2578 _GLIBCXX_END_NAMESPACE_VERSION
2583 #endif //_GLIBCXX_CHRONO_IO_H
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
ISO C++ entities toplevel namespace is std.
chrono::duration represents a distance between two points in time
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.