File indexing completed on 2026-05-03 08:13:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CHRONO_FORMATTER_H
0011 #define _LIBCPP___CHRONO_FORMATTER_H
0012
0013 #include <__config>
0014
0015 #if _LIBCPP_HAS_LOCALIZATION
0016
0017 # include <__algorithm/ranges_copy.h>
0018 # include <__chrono/calendar.h>
0019 # include <__chrono/concepts.h>
0020 # include <__chrono/convert_to_tm.h>
0021 # include <__chrono/day.h>
0022 # include <__chrono/duration.h>
0023 # include <__chrono/file_clock.h>
0024 # include <__chrono/hh_mm_ss.h>
0025 # include <__chrono/local_info.h>
0026 # include <__chrono/month.h>
0027 # include <__chrono/month_weekday.h>
0028 # include <__chrono/monthday.h>
0029 # include <__chrono/ostream.h>
0030 # include <__chrono/parser_std_format_spec.h>
0031 # include <__chrono/statically_widen.h>
0032 # include <__chrono/sys_info.h>
0033 # include <__chrono/system_clock.h>
0034 # include <__chrono/time_point.h>
0035 # include <__chrono/utc_clock.h>
0036 # include <__chrono/weekday.h>
0037 # include <__chrono/year.h>
0038 # include <__chrono/year_month.h>
0039 # include <__chrono/year_month_day.h>
0040 # include <__chrono/year_month_weekday.h>
0041 # include <__chrono/zoned_time.h>
0042 # include <__concepts/arithmetic.h>
0043 # include <__concepts/same_as.h>
0044 # include <__format/concepts.h>
0045 # include <__format/format_error.h>
0046 # include <__format/format_functions.h>
0047 # include <__format/format_parse_context.h>
0048 # include <__format/formatter.h>
0049 # include <__format/parser_std_format_spec.h>
0050 # include <__format/write_escaped.h>
0051 # include <__memory/addressof.h>
0052 # include <__type_traits/is_specialization.h>
0053 # include <cmath>
0054 # include <ctime>
0055 # include <limits>
0056 # include <locale>
0057 # include <sstream>
0058 # include <string_view>
0059
0060 # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0061 # pragma GCC system_header
0062 # endif
0063
0064 _LIBCPP_BEGIN_NAMESPACE_STD
0065
0066 # if _LIBCPP_STD_VER >= 20
0067
0068 namespace __formatter {
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 template <class _CharT, class _Rep, class _Period>
0092 _LIBCPP_HIDE_FROM_ABI void
0093 __format_sub_seconds(basic_stringstream<_CharT>& __sstr, const chrono::duration<_Rep, _Period>& __value) {
0094 __sstr << std::use_facet<numpunct<_CharT>>(__sstr.getloc()).decimal_point();
0095
0096 using __duration = chrono::duration<_Rep, _Period>;
0097
0098 auto __fraction = __value - chrono::duration_cast<chrono::seconds>(__value);
0099
0100 if (__value < chrono::seconds{0} && __fraction != __duration{0})
0101 __fraction += chrono::seconds{1};
0102 if constexpr (chrono::treat_as_floating_point_v<_Rep>)
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115 std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
0116 _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"),
0117 chrono::duration_cast<typename chrono::hh_mm_ss<__duration>::precision>(__fraction).count(),
0118 chrono::hh_mm_ss<__duration>::fractional_width);
0119 else
0120 std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
0121 _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"),
0122 chrono::duration_cast<typename chrono::hh_mm_ss<__duration>::precision>(__fraction).count(),
0123 chrono::hh_mm_ss<__duration>::fractional_width);
0124 }
0125
0126 template <class _CharT, __is_time_point _Tp>
0127 _LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(basic_stringstream<_CharT>& __sstr, const _Tp& __value) {
0128 __formatter::__format_sub_seconds(__sstr, __value.time_since_epoch());
0129 }
0130
0131 template <class _CharT, class _Duration>
0132 _LIBCPP_HIDE_FROM_ABI void
0133 __format_sub_seconds(basic_stringstream<_CharT>& __sstr, const chrono::hh_mm_ss<_Duration>& __value) {
0134 __sstr << std::use_facet<numpunct<_CharT>>(__sstr.getloc()).decimal_point();
0135 if constexpr (chrono::treat_as_floating_point_v<typename _Duration::rep>)
0136 std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
0137 _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"),
0138 __value.subseconds().count(),
0139 __value.fractional_width);
0140 else
0141 std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
0142 _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"),
0143 __value.subseconds().count(),
0144 __value.fractional_width);
0145 }
0146
0147 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0148 template <class _CharT, class _Duration, class _TimeZonePtr>
0149 _LIBCPP_HIDE_FROM_ABI void
0150 __format_sub_seconds(basic_stringstream<_CharT>& __sstr, const chrono::zoned_time<_Duration, _TimeZonePtr>& __value) {
0151 __formatter::__format_sub_seconds(__sstr, __value.get_local_time().time_since_epoch());
0152 }
0153 # endif
0154
0155 template <class _Tp>
0156 consteval bool __use_fraction() {
0157 if constexpr (__is_time_point<_Tp>)
0158 return chrono::hh_mm_ss<typename _Tp::duration>::fractional_width;
0159 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0160 else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>)
0161 return chrono::hh_mm_ss<typename _Tp::duration>::fractional_width;
0162 # endif
0163 else if constexpr (chrono::__is_duration_v<_Tp>)
0164 return chrono::hh_mm_ss<_Tp>::fractional_width;
0165 else if constexpr (__is_hh_mm_ss<_Tp>)
0166 return _Tp::fractional_width;
0167 else
0168 return false;
0169 }
0170
0171 template <class _CharT>
0172 _LIBCPP_HIDE_FROM_ABI void __format_year(basic_stringstream<_CharT>& __sstr, int __year) {
0173 if (__year < 0) {
0174 __sstr << _CharT('-');
0175 __year = -__year;
0176 }
0177
0178
0179
0180
0181
0182
0183
0184 __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:04}"), __year);
0185 }
0186
0187 template <class _CharT>
0188 _LIBCPP_HIDE_FROM_ABI void __format_century(basic_stringstream<_CharT>& __sstr, int __year) {
0189
0190
0191
0192
0193
0194 bool __negative = __year < 0;
0195 int __century = (__year - (99 * __negative)) / 100;
0196 __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), __century);
0197 }
0198
0199
0200
0201
0202 template <class _CharT>
0203 _LIBCPP_HIDE_FROM_ABI void
0204 __format_zone_offset(basic_stringstream<_CharT>& __sstr, chrono::seconds __offset, bool __modifier) {
0205 if (__offset < 0s) {
0206 __sstr << _CharT('-');
0207 __offset = -__offset;
0208 } else {
0209 __sstr << _CharT('+');
0210 }
0211
0212 chrono::hh_mm_ss __hms{__offset};
0213 std::ostreambuf_iterator<_CharT> __out_it{__sstr};
0214
0215 std::format_to(__out_it, _LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), __hms.hours().count());
0216 if (__modifier)
0217 __sstr << _CharT(':');
0218 std::format_to(__out_it, _LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), __hms.minutes().count());
0219 }
0220
0221
0222 struct _LIBCPP_HIDE_FROM_ABI __time_zone {
0223
0224
0225 string __abbrev;
0226 chrono::seconds __offset;
0227 };
0228
0229 template <class _Tp>
0230 _LIBCPP_HIDE_FROM_ABI __time_zone __convert_to_time_zone([[maybe_unused]] const _Tp& __value) {
0231 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0232 if constexpr (same_as<_Tp, chrono::sys_info>)
0233 return {__value.abbrev, __value.offset};
0234 # if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0235 else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>)
0236 return __formatter::__convert_to_time_zone(__value.get_info());
0237 # endif
0238 else
0239 # endif
0240 return {"UTC", chrono::seconds{0}};
0241 }
0242
0243 template <class _CharT, class _Tp>
0244 _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
0245 basic_stringstream<_CharT>& __sstr, const _Tp& __value, basic_string_view<_CharT> __chrono_specs) {
0246 tm __t = std::__convert_to_tm<tm>(__value);
0247 __time_zone __z = __formatter::__convert_to_time_zone(__value);
0248 const auto& __facet = std::use_facet<time_put<_CharT>>(__sstr.getloc());
0249 for (auto __it = __chrono_specs.begin(); __it != __chrono_specs.end(); ++__it) {
0250 if (*__it == _CharT('%')) {
0251 auto __s = __it;
0252 ++__it;
0253
0254
0255 switch (*__it) {
0256 case _CharT('n'):
0257 __sstr << _CharT('\n');
0258 break;
0259 case _CharT('t'):
0260 __sstr << _CharT('\t');
0261 break;
0262 case _CharT('%'):
0263 __sstr << *__it;
0264 break;
0265
0266 case _CharT('C'): {
0267
0268 int __year = __t.tm_year + 1900;
0269 if (__year < 1000 || __year > 9999)
0270 __formatter::__format_century(__sstr, __year);
0271 else
0272 __facet.put(
0273 {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
0274 } break;
0275
0276 case _CharT('j'):
0277 if constexpr (chrono::__is_duration_v<_Tp>)
0278
0279
0280
0281
0282 __sstr << chrono::duration_cast<chrono::days>(chrono::duration_cast<chrono::seconds>(__value)).count();
0283 else
0284 __facet.put(
0285 {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
0286 break;
0287
0288 case _CharT('q'):
0289 if constexpr (chrono::__is_duration_v<_Tp>) {
0290 __sstr << chrono::__units_suffix<_CharT, typename _Tp::period>();
0291 break;
0292 }
0293 __builtin_unreachable();
0294
0295 case _CharT('Q'):
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 if constexpr (chrono::__is_duration_v<_Tp>) {
0306 __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{}"), __value.count());
0307 break;
0308 }
0309 __builtin_unreachable();
0310
0311 case _CharT('S'):
0312 case _CharT('T'):
0313 __facet.put(
0314 {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
0315 if constexpr (__use_fraction<_Tp>())
0316 __formatter::__format_sub_seconds(__sstr, __value);
0317 break;
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346 # if defined(__GLIBC__) || defined(_AIX) || defined(_WIN32)
0347 case _CharT('y'):
0348
0349 __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), (std::abs(__t.tm_year + 1900)) % 100);
0350 break;
0351 # endif
0352
0353 case _CharT('Y'):
0354
0355
0356
0357 __formatter::__format_year(__sstr, __t.tm_year + 1900);
0358 break;
0359
0360 case _CharT('F'):
0361
0362
0363
0364 __formatter::__format_year(__sstr, __t.tm_year + 1900);
0365 __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday);
0366 break;
0367
0368 case _CharT('z'):
0369 __formatter::__format_zone_offset(__sstr, __z.__offset, false);
0370 break;
0371
0372 case _CharT('Z'):
0373
0374 ranges::copy(__z.__abbrev, std::ostreambuf_iterator<_CharT>{__sstr});
0375 break;
0376
0377 case _CharT('O'):
0378 if constexpr (__use_fraction<_Tp>()) {
0379
0380
0381
0382 if (*(__it + 1) == 'S') {
0383 ++__it;
0384 __facet.put(
0385 {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
0386 __formatter::__format_sub_seconds(__sstr, __value);
0387 break;
0388 }
0389 }
0390
0391
0392 [[fallthrough]];
0393 case _CharT('E'):
0394 ++__it;
0395 if (*__it == 'z') {
0396 __formatter::__format_zone_offset(__sstr, __z.__offset, true);
0397 break;
0398 }
0399 [[fallthrough]];
0400 default:
0401 __facet.put(
0402 {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
0403 break;
0404 }
0405 } else {
0406 __sstr << *__it;
0407 }
0408 }
0409 }
0410
0411 template <class _Tp>
0412 _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) {
0413 if constexpr (__is_time_point<_Tp>)
0414 return true;
0415 else if constexpr (same_as<_Tp, chrono::day>)
0416 return true;
0417 else if constexpr (same_as<_Tp, chrono::month>)
0418 return __value.ok();
0419 else if constexpr (same_as<_Tp, chrono::year>)
0420 return true;
0421 else if constexpr (same_as<_Tp, chrono::weekday>)
0422 return true;
0423 else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
0424 return true;
0425 else if constexpr (same_as<_Tp, chrono::weekday_last>)
0426 return true;
0427 else if constexpr (same_as<_Tp, chrono::month_day>)
0428 return true;
0429 else if constexpr (same_as<_Tp, chrono::month_day_last>)
0430 return true;
0431 else if constexpr (same_as<_Tp, chrono::month_weekday>)
0432 return true;
0433 else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
0434 return true;
0435 else if constexpr (same_as<_Tp, chrono::year_month>)
0436 return true;
0437 else if constexpr (same_as<_Tp, chrono::year_month_day>)
0438 return __value.ok();
0439 else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
0440 return __value.ok();
0441 else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
0442 return __value.weekday().ok();
0443 else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
0444 return __value.weekday().ok();
0445 else if constexpr (__is_hh_mm_ss<_Tp>)
0446 return true;
0447 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0448 else if constexpr (same_as<_Tp, chrono::sys_info>)
0449 return true;
0450 else if constexpr (same_as<_Tp, chrono::local_info>)
0451 return true;
0452 # if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0453 else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>)
0454 return true;
0455 # endif
0456 # endif
0457 else
0458 static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
0459 }
0460
0461 template <class _Tp>
0462 _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) {
0463 if constexpr (__is_time_point<_Tp>)
0464 return true;
0465 else if constexpr (same_as<_Tp, chrono::day>)
0466 return true;
0467 else if constexpr (same_as<_Tp, chrono::month>)
0468 return __value.ok();
0469 else if constexpr (same_as<_Tp, chrono::year>)
0470 return true;
0471 else if constexpr (same_as<_Tp, chrono::weekday>)
0472 return __value.ok();
0473 else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
0474 return __value.weekday().ok();
0475 else if constexpr (same_as<_Tp, chrono::weekday_last>)
0476 return __value.weekday().ok();
0477 else if constexpr (same_as<_Tp, chrono::month_day>)
0478 return true;
0479 else if constexpr (same_as<_Tp, chrono::month_day_last>)
0480 return true;
0481 else if constexpr (same_as<_Tp, chrono::month_weekday>)
0482 return __value.weekday_indexed().ok();
0483 else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
0484 return __value.weekday_indexed().ok();
0485 else if constexpr (same_as<_Tp, chrono::year_month>)
0486 return true;
0487 else if constexpr (same_as<_Tp, chrono::year_month_day>)
0488 return __value.ok();
0489 else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
0490 return __value.ok();
0491 else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
0492 return __value.weekday().ok();
0493 else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
0494 return __value.weekday().ok();
0495 else if constexpr (__is_hh_mm_ss<_Tp>)
0496 return true;
0497 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0498 else if constexpr (same_as<_Tp, chrono::sys_info>)
0499 return true;
0500 else if constexpr (same_as<_Tp, chrono::local_info>)
0501 return true;
0502 # if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0503 else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>)
0504 return true;
0505 # endif
0506 # endif
0507 else
0508 static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
0509 }
0510
0511 template <class _Tp>
0512 _LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) {
0513 if constexpr (__is_time_point<_Tp>)
0514 return true;
0515 else if constexpr (same_as<_Tp, chrono::day>)
0516 return true;
0517 else if constexpr (same_as<_Tp, chrono::month>)
0518 return __value.ok();
0519 else if constexpr (same_as<_Tp, chrono::year>)
0520 return true;
0521 else if constexpr (same_as<_Tp, chrono::weekday>)
0522 return true;
0523 else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
0524 return true;
0525 else if constexpr (same_as<_Tp, chrono::weekday_last>)
0526 return true;
0527 else if constexpr (same_as<_Tp, chrono::month_day>)
0528 return true;
0529 else if constexpr (same_as<_Tp, chrono::month_day_last>)
0530 return true;
0531 else if constexpr (same_as<_Tp, chrono::month_weekday>)
0532 return true;
0533 else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
0534 return true;
0535 else if constexpr (same_as<_Tp, chrono::year_month>)
0536 return true;
0537 else if constexpr (same_as<_Tp, chrono::year_month_day>)
0538 return __value.ok();
0539 else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
0540 return __value.ok();
0541 else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
0542 return __value.ok();
0543 else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
0544 return __value.ok();
0545 else if constexpr (__is_hh_mm_ss<_Tp>)
0546 return true;
0547 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0548 else if constexpr (same_as<_Tp, chrono::sys_info>)
0549 return true;
0550 else if constexpr (same_as<_Tp, chrono::local_info>)
0551 return true;
0552 # if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0553 else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>)
0554 return true;
0555 # endif
0556 # endif
0557 else
0558 static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
0559 }
0560
0561 template <class _Tp>
0562 _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
0563 if constexpr (__is_time_point<_Tp>)
0564 return true;
0565 else if constexpr (same_as<_Tp, chrono::day>)
0566 return true;
0567 else if constexpr (same_as<_Tp, chrono::month>)
0568 return __value.ok();
0569 else if constexpr (same_as<_Tp, chrono::year>)
0570 return true;
0571 else if constexpr (same_as<_Tp, chrono::weekday>)
0572 return true;
0573 else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
0574 return true;
0575 else if constexpr (same_as<_Tp, chrono::weekday_last>)
0576 return true;
0577 else if constexpr (same_as<_Tp, chrono::month_day>)
0578 return __value.month().ok();
0579 else if constexpr (same_as<_Tp, chrono::month_day_last>)
0580 return __value.month().ok();
0581 else if constexpr (same_as<_Tp, chrono::month_weekday>)
0582 return __value.month().ok();
0583 else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
0584 return __value.month().ok();
0585 else if constexpr (same_as<_Tp, chrono::year_month>)
0586 return __value.month().ok();
0587 else if constexpr (same_as<_Tp, chrono::year_month_day>)
0588 return __value.month().ok();
0589 else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
0590 return __value.month().ok();
0591 else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
0592 return __value.month().ok();
0593 else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
0594 return __value.month().ok();
0595 else if constexpr (__is_hh_mm_ss<_Tp>)
0596 return true;
0597 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0598 else if constexpr (same_as<_Tp, chrono::sys_info>)
0599 return true;
0600 else if constexpr (same_as<_Tp, chrono::local_info>)
0601 return true;
0602 # if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0603 else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>)
0604 return true;
0605 # endif
0606 # endif
0607 else
0608 static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
0609 }
0610
0611 template <class _CharT, class _Tp, class _FormatContext>
0612 _LIBCPP_HIDE_FROM_ABI auto
0613 __format_chrono(const _Tp& __value,
0614 _FormatContext& __ctx,
0615 __format_spec::__parsed_specifications<_CharT> __specs,
0616 basic_string_view<_CharT> __chrono_specs) {
0617 basic_stringstream<_CharT> __sstr;
0618
0619
0620
0621
0622
0623 if (__specs.__chrono_.__locale_specific_form_)
0624 __sstr.imbue(__ctx.locale());
0625 else
0626 __sstr.imbue(locale::classic());
0627
0628 if (__chrono_specs.empty())
0629 __sstr << __value;
0630 else {
0631 if constexpr (chrono::__is_duration_v<_Tp>) {
0632
0633
0634 if constexpr (numeric_limits<typename _Tp::rep>::is_signed) {
0635 if (__value < __value.zero()) {
0636 __sstr << _CharT('-');
0637 __formatter::__format_chrono_using_chrono_specs(__sstr, -__value, __chrono_specs);
0638 } else
0639 __formatter::__format_chrono_using_chrono_specs(__sstr, __value, __chrono_specs);
0640 } else
0641 __formatter::__format_chrono_using_chrono_specs(__sstr, __value, __chrono_specs);
0642
0643
0644 __specs.__precision_ = -1;
0645 } else {
0646
0647 if (__specs.__chrono_.__weekday_name_ && !__formatter::__weekday_name_ok(__value))
0648 std::__throw_format_error("Formatting a weekday name needs a valid weekday");
0649
0650 if (__specs.__chrono_.__weekday_ && !__formatter::__weekday_ok(__value))
0651 std::__throw_format_error("Formatting a weekday needs a valid weekday");
0652
0653 if (__specs.__chrono_.__day_of_year_ && !__formatter::__date_ok(__value))
0654 std::__throw_format_error("Formatting a day of year needs a valid date");
0655
0656 if (__specs.__chrono_.__week_of_year_ && !__formatter::__date_ok(__value))
0657 std::__throw_format_error("Formatting a week of year needs a valid date");
0658
0659 if (__specs.__chrono_.__month_name_ && !__formatter::__month_name_ok(__value))
0660 std::__throw_format_error("Formatting a month name from an invalid month number");
0661
0662 if constexpr (__is_hh_mm_ss<_Tp>) {
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678 if (__specs.__chrono_.__hour_ && __value.hours().count() > 23)
0679 std::__throw_format_error("Formatting a hour needs a valid value");
0680
0681 if (__value.is_negative())
0682 __sstr << _CharT('-');
0683 }
0684
0685 __formatter::__format_chrono_using_chrono_specs(__sstr, __value, __chrono_specs);
0686 }
0687 }
0688
0689 return __formatter::__write_string(__sstr.view(), __ctx.out(), __specs);
0690 }
0691
0692 }
0693
0694 template <__fmt_char_type _CharT>
0695 struct _LIBCPP_TEMPLATE_VIS __formatter_chrono {
0696 public:
0697 template <class _ParseContext>
0698 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator
0699 __parse(_ParseContext& __ctx, __format_spec::__fields __fields, __format_spec::__flags __flags) {
0700 return __parser_.__parse(__ctx, __fields, __flags);
0701 }
0702
0703 template <class _Tp, class _FormatContext>
0704 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _Tp& __value, _FormatContext& __ctx) const {
0705 return __formatter::__format_chrono(
0706 __value, __ctx, __parser_.__parser_.__get_parsed_chrono_specifications(__ctx), __parser_.__chrono_specs_);
0707 }
0708
0709 __format_spec::__parser_chrono<_CharT> __parser_;
0710 };
0711
0712 template <class _Duration, __fmt_char_type _CharT>
0713 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::sys_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
0714 public:
0715 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0716
0717 template <class _ParseContext>
0718 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0719 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock);
0720 }
0721 };
0722
0723 # if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0724 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0725
0726 template <class _Duration, __fmt_char_type _CharT>
0727 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::utc_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
0728 public:
0729 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0730
0731 template <class _ParseContext>
0732 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0733 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock);
0734 }
0735 };
0736
0737 # endif
0738 # endif
0739
0740 template <class _Duration, __fmt_char_type _CharT>
0741 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::file_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
0742 public:
0743 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0744
0745 template <class _ParseContext>
0746 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0747 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock);
0748 }
0749 };
0750
0751 template <class _Duration, __fmt_char_type _CharT>
0752 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::local_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
0753 public:
0754 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0755
0756 template <class _ParseContext>
0757 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0758
0759 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date_time);
0760 }
0761 };
0762
0763 template <class _Rep, class _Period, __fmt_char_type _CharT>
0764 struct formatter<chrono::duration<_Rep, _Period>, _CharT> : public __formatter_chrono<_CharT> {
0765 public:
0766 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0767
0768 template <class _ParseContext>
0769 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0770
0771
0772
0773
0774
0775
0776
0777
0778 if constexpr (std::floating_point<_Rep>)
0779 return _Base::__parse(__ctx, __format_spec::__fields_chrono_fractional, __format_spec::__flags::__duration);
0780 else
0781 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__duration);
0782 }
0783 };
0784
0785 template <__fmt_char_type _CharT>
0786 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::day, _CharT> : public __formatter_chrono<_CharT> {
0787 public:
0788 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0789
0790 template <class _ParseContext>
0791 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0792 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__day);
0793 }
0794 };
0795
0796 template <__fmt_char_type _CharT>
0797 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month, _CharT> : public __formatter_chrono<_CharT> {
0798 public:
0799 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0800
0801 template <class _ParseContext>
0802 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0803 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
0804 }
0805 };
0806
0807 template <__fmt_char_type _CharT>
0808 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year, _CharT> : public __formatter_chrono<_CharT> {
0809 public:
0810 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0811
0812 template <class _ParseContext>
0813 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0814 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year);
0815 }
0816 };
0817
0818 template <__fmt_char_type _CharT>
0819 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday, _CharT> : public __formatter_chrono<_CharT> {
0820 public:
0821 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0822
0823 template <class _ParseContext>
0824 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0825 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
0826 }
0827 };
0828
0829 template <__fmt_char_type _CharT>
0830 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday_indexed, _CharT> : public __formatter_chrono<_CharT> {
0831 public:
0832 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0833
0834 template <class _ParseContext>
0835 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0836 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
0837 }
0838 };
0839
0840 template <__fmt_char_type _CharT>
0841 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday_last, _CharT> : public __formatter_chrono<_CharT> {
0842 public:
0843 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0844
0845 template <class _ParseContext>
0846 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0847 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
0848 }
0849 };
0850
0851 template <__fmt_char_type _CharT>
0852 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_day, _CharT> : public __formatter_chrono<_CharT> {
0853 public:
0854 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0855
0856 template <class _ParseContext>
0857 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0858 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day);
0859 }
0860 };
0861
0862 template <__fmt_char_type _CharT>
0863 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_day_last, _CharT> : public __formatter_chrono<_CharT> {
0864 public:
0865 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0866
0867 template <class _ParseContext>
0868 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0869 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
0870 }
0871 };
0872
0873 template <__fmt_char_type _CharT>
0874 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_weekday, _CharT> : public __formatter_chrono<_CharT> {
0875 public:
0876 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0877
0878 template <class _ParseContext>
0879 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0880 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
0881 }
0882 };
0883
0884 template <__fmt_char_type _CharT>
0885 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_weekday_last, _CharT> : public __formatter_chrono<_CharT> {
0886 public:
0887 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0888
0889 template <class _ParseContext>
0890 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0891 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
0892 }
0893 };
0894
0895 template <__fmt_char_type _CharT>
0896 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month, _CharT> : public __formatter_chrono<_CharT> {
0897 public:
0898 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0899
0900 template <class _ParseContext>
0901 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0902 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month);
0903 }
0904 };
0905
0906 template <__fmt_char_type _CharT>
0907 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_day, _CharT> : public __formatter_chrono<_CharT> {
0908 public:
0909 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0910
0911 template <class _ParseContext>
0912 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0913 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
0914 }
0915 };
0916
0917 template <__fmt_char_type _CharT>
0918 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_day_last, _CharT> : public __formatter_chrono<_CharT> {
0919 public:
0920 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0921
0922 template <class _ParseContext>
0923 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0924 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
0925 }
0926 };
0927
0928 template <__fmt_char_type _CharT>
0929 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_weekday, _CharT> : public __formatter_chrono<_CharT> {
0930 public:
0931 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0932
0933 template <class _ParseContext>
0934 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0935 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
0936 }
0937 };
0938
0939 template <__fmt_char_type _CharT>
0940 struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_weekday_last, _CharT> : public __formatter_chrono<_CharT> {
0941 public:
0942 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0943
0944 template <class _ParseContext>
0945 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0946 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
0947 }
0948 };
0949
0950 template <class _Duration, __fmt_char_type _CharT>
0951 struct formatter<chrono::hh_mm_ss<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
0952 public:
0953 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0954
0955 template <class _ParseContext>
0956 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0957 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__time);
0958 }
0959 };
0960
0961 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0962 template <__fmt_char_type _CharT>
0963 struct formatter<chrono::sys_info, _CharT> : public __formatter_chrono<_CharT> {
0964 public:
0965 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0966
0967 template <class _ParseContext>
0968 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0969 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__time_zone);
0970 }
0971 };
0972
0973 template <__fmt_char_type _CharT>
0974 struct formatter<chrono::local_info, _CharT> : public __formatter_chrono<_CharT> {
0975 public:
0976 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0977
0978 template <class _ParseContext>
0979 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0980 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags{});
0981 }
0982 };
0983 # if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0984
0985
0986 template <class _Duration, class _TimeZonePtr, __fmt_char_type _CharT>
0987 struct formatter<chrono::zoned_time<_Duration, _TimeZonePtr>, _CharT> : public __formatter_chrono<_CharT> {
0988 public:
0989 using _Base _LIBCPP_NODEBUG = __formatter_chrono<_CharT>;
0990
0991 template <class _ParseContext>
0992 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0993 return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock);
0994 }
0995 };
0996 # endif
0997 # endif
0998
0999 # endif
1000
1001 _LIBCPP_END_NAMESPACE_STD
1002
1003 #endif
1004
1005 #endif