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