File indexing completed on 2026-05-03 08:13:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___CHRONO_PARSER_STD_FORMAT_SPEC_H
0011 #define _LIBCPP___CXX03___CHRONO_PARSER_STD_FORMAT_SPEC_H
0012
0013 #include <__cxx03/__config>
0014 #include <__cxx03/__format/concepts.h>
0015 #include <__cxx03/__format/format_error.h>
0016 #include <__cxx03/__format/format_parse_context.h>
0017 #include <__cxx03/__format/formatter_string.h>
0018 #include <__cxx03/__format/parser_std_format_spec.h>
0019 #include <__cxx03/string_view>
0020
0021 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0022 # pragma GCC system_header
0023 #endif
0024
0025 _LIBCPP_BEGIN_NAMESPACE_STD
0026
0027 #if _LIBCPP_STD_VER >= 20
0028
0029 namespace __format_spec {
0030
0031
0032 inline constexpr __fields __fields_chrono_fractional{
0033 .__precision_ = true, .__locale_specific_form_ = true, .__type_ = false};
0034 inline constexpr __fields __fields_chrono{.__locale_specific_form_ = true, .__type_ = false};
0035
0036
0037
0038
0039
0040
0041
0042
0043 enum class __flags {
0044 __second = 0x1,
0045 __minute = 0x2,
0046 __hour = 0x4,
0047 __time = __hour | __minute | __second,
0048
0049 __day = 0x8,
0050 __month = 0x10,
0051 __year = 0x20,
0052
0053 __weekday = 0x40,
0054
0055 __month_day = __day | __month,
0056 __month_weekday = __weekday | __month,
0057 __year_month = __month | __year,
0058 __date = __day | __month | __year | __weekday,
0059
0060 __date_time = __date | __time,
0061
0062 __duration = 0x80 | __time,
0063
0064 __time_zone = 0x100,
0065
0066 __clock = __date_time | __time_zone
0067 };
0068
0069 _LIBCPP_HIDE_FROM_ABI constexpr __flags operator&(__flags __lhs, __flags __rhs) {
0070 return static_cast<__flags>(static_cast<unsigned>(__lhs) & static_cast<unsigned>(__rhs));
0071 }
0072
0073 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_second(__flags __flags) {
0074 if ((__flags & __flags::__second) != __flags::__second)
0075 std::__throw_format_error("The supplied date time doesn't contain a second");
0076 }
0077
0078 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_minute(__flags __flags) {
0079 if ((__flags & __flags::__minute) != __flags::__minute)
0080 std::__throw_format_error("The supplied date time doesn't contain a minute");
0081 }
0082
0083 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_hour(__flags __flags) {
0084 if ((__flags & __flags::__hour) != __flags::__hour)
0085 std::__throw_format_error("The supplied date time doesn't contain an hour");
0086 }
0087
0088 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_time(__flags __flags) {
0089 if ((__flags & __flags::__time) != __flags::__time)
0090 std::__throw_format_error("The supplied date time doesn't contain a time");
0091 }
0092
0093 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_day(__flags __flags) {
0094 if ((__flags & __flags::__day) != __flags::__day)
0095 std::__throw_format_error("The supplied date time doesn't contain a day");
0096 }
0097
0098 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_month(__flags __flags) {
0099 if ((__flags & __flags::__month) != __flags::__month)
0100 std::__throw_format_error("The supplied date time doesn't contain a month");
0101 }
0102
0103 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_year(__flags __flags) {
0104 if ((__flags & __flags::__year) != __flags::__year)
0105 std::__throw_format_error("The supplied date time doesn't contain a year");
0106 }
0107
0108 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_date(__flags __flags) {
0109 if ((__flags & __flags::__date) != __flags::__date)
0110 std::__throw_format_error("The supplied date time doesn't contain a date");
0111 }
0112
0113 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_date_or_duration(__flags __flags) {
0114 if (((__flags & __flags::__date) != __flags::__date) && ((__flags & __flags::__duration) != __flags::__duration))
0115 std::__throw_format_error("The supplied date time doesn't contain a date or duration");
0116 }
0117
0118 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_date_time(__flags __flags) {
0119 if ((__flags & __flags::__date_time) != __flags::__date_time)
0120 std::__throw_format_error("The supplied date time doesn't contain a date and time");
0121 }
0122
0123 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_weekday(__flags __flags) {
0124 if ((__flags & __flags::__weekday) != __flags::__weekday)
0125 std::__throw_format_error("The supplied date time doesn't contain a weekday");
0126 }
0127
0128 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_duration(__flags __flags) {
0129 if ((__flags & __flags::__duration) != __flags::__duration)
0130 std::__throw_format_error("The supplied date time doesn't contain a duration");
0131 }
0132
0133 _LIBCPP_HIDE_FROM_ABI constexpr void __validate_time_zone(__flags __flags) {
0134 if ((__flags & __flags::__time_zone) != __flags::__time_zone)
0135 std::__throw_format_error("The supplied date time doesn't contain a time zone");
0136 }
0137
0138 template <class _CharT>
0139 class _LIBCPP_TEMPLATE_VIS __parser_chrono {
0140 using _ConstIterator = typename basic_format_parse_context<_CharT>::const_iterator;
0141
0142 public:
0143 template <class _ParseContext>
0144 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator
0145 __parse(_ParseContext& __ctx, __fields __fields, __flags __flags) {
0146 _ConstIterator __begin = __parser_.__parse(__ctx, __fields);
0147 _ConstIterator __end = __ctx.end();
0148 if (__begin == __end)
0149 return __begin;
0150
0151 _ConstIterator __last = __parse_chrono_specs(__begin, __end, __flags);
0152 __chrono_specs_ = basic_string_view<_CharT>{__begin, __last};
0153
0154 return __last;
0155 }
0156
0157 __parser<_CharT> __parser_;
0158 basic_string_view<_CharT> __chrono_specs_;
0159
0160 private:
0161 _LIBCPP_HIDE_FROM_ABI constexpr _ConstIterator
0162 __parse_chrono_specs(_ConstIterator __begin, _ConstIterator __end, __flags __flags) {
0163 _LIBCPP_ASSERT_INTERNAL(__begin != __end,
0164 "When called with an empty input the function will cause "
0165 "undefined behavior by evaluating data not in the input");
0166
0167 if (*__begin != _CharT('%') && *__begin != _CharT('}'))
0168 std::__throw_format_error("The format specifier expects a '%' or a '}'");
0169
0170 do {
0171 switch (*__begin) {
0172 case _CharT('{'):
0173 std::__throw_format_error("The chrono specifiers contain a '{'");
0174
0175 case _CharT('}'):
0176 return __begin;
0177
0178 case _CharT('%'):
0179 __parse_conversion_spec(__begin, __end, __flags);
0180 [[fallthrough]];
0181
0182 default:
0183
0184 ++__begin;
0185 }
0186
0187 } while (__begin != __end && *__begin != _CharT('}'));
0188
0189 return __begin;
0190 }
0191
0192
0193
0194 _LIBCPP_HIDE_FROM_ABI constexpr void
0195 __parse_conversion_spec(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) {
0196 ++__begin;
0197 if (__begin == __end)
0198 std::__throw_format_error("End of input while parsing a conversion specifier");
0199
0200 switch (*__begin) {
0201 case _CharT('n'):
0202 case _CharT('t'):
0203 case _CharT('%'):
0204 break;
0205
0206 case _CharT('S'):
0207 __format_spec::__validate_second(__flags);
0208 break;
0209
0210 case _CharT('M'):
0211 __format_spec::__validate_minute(__flags);
0212 break;
0213
0214 case _CharT('p'):
0215 case _CharT('H'):
0216 case _CharT('I'):
0217 __parser_.__hour_ = true;
0218 __validate_hour(__flags);
0219 break;
0220
0221 case _CharT('r'):
0222 case _CharT('R'):
0223 case _CharT('T'):
0224 case _CharT('X'):
0225 __parser_.__hour_ = true;
0226 __format_spec::__validate_time(__flags);
0227 break;
0228
0229 case _CharT('d'):
0230 case _CharT('e'):
0231 __format_spec::__validate_day(__flags);
0232 break;
0233
0234 case _CharT('b'):
0235 case _CharT('h'):
0236 case _CharT('B'):
0237 __parser_.__month_name_ = true;
0238 [[fallthrough]];
0239 case _CharT('m'):
0240 __format_spec::__validate_month(__flags);
0241 break;
0242
0243 case _CharT('y'):
0244 case _CharT('C'):
0245 case _CharT('Y'):
0246 __format_spec::__validate_year(__flags);
0247 break;
0248
0249 case _CharT('j'):
0250 __parser_.__day_of_year_ = true;
0251 __format_spec::__validate_date_or_duration(__flags);
0252 break;
0253
0254 case _CharT('g'):
0255 case _CharT('G'):
0256 case _CharT('U'):
0257 case _CharT('V'):
0258 case _CharT('W'):
0259 __parser_.__week_of_year_ = true;
0260 [[fallthrough]];
0261 case _CharT('x'):
0262 case _CharT('D'):
0263 case _CharT('F'):
0264 __format_spec::__validate_date(__flags);
0265 break;
0266
0267 case _CharT('c'):
0268 __format_spec::__validate_date_time(__flags);
0269 break;
0270
0271 case _CharT('a'):
0272 case _CharT('A'):
0273 __parser_.__weekday_name_ = true;
0274 [[fallthrough]];
0275 case _CharT('u'):
0276 case _CharT('w'):
0277 __parser_.__weekday_ = true;
0278 __validate_weekday(__flags);
0279 __format_spec::__validate_weekday(__flags);
0280 break;
0281
0282 case _CharT('q'):
0283 case _CharT('Q'):
0284 __format_spec::__validate_duration(__flags);
0285 break;
0286
0287 case _CharT('E'):
0288 __parse_modifier_E(__begin, __end, __flags);
0289 break;
0290
0291 case _CharT('O'):
0292 __parse_modifier_O(__begin, __end, __flags);
0293 break;
0294
0295 case _CharT('z'):
0296 case _CharT('Z'):
0297
0298
0299
0300 __format_spec::__validate_time_zone(__flags);
0301 break;
0302
0303 default:
0304 std::__throw_format_error("The date time type specifier is invalid");
0305 }
0306 }
0307
0308
0309
0310 _LIBCPP_HIDE_FROM_ABI constexpr void
0311 __parse_modifier_E(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) {
0312 ++__begin;
0313 if (__begin == __end)
0314 std::__throw_format_error("End of input while parsing the modifier E");
0315
0316 switch (*__begin) {
0317 case _CharT('X'):
0318 __parser_.__hour_ = true;
0319 __format_spec::__validate_time(__flags);
0320 break;
0321
0322 case _CharT('y'):
0323 case _CharT('C'):
0324 case _CharT('Y'):
0325 __format_spec::__validate_year(__flags);
0326 break;
0327
0328 case _CharT('x'):
0329 __format_spec::__validate_date(__flags);
0330 break;
0331
0332 case _CharT('c'):
0333 __format_spec::__validate_date_time(__flags);
0334 break;
0335
0336 case _CharT('z'):
0337
0338
0339
0340 __format_spec::__validate_time_zone(__flags);
0341 break;
0342
0343 default:
0344 std::__throw_format_error("The date time type specifier for modifier E is invalid");
0345 }
0346 }
0347
0348
0349
0350 _LIBCPP_HIDE_FROM_ABI constexpr void
0351 __parse_modifier_O(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) {
0352 ++__begin;
0353 if (__begin == __end)
0354 std::__throw_format_error("End of input while parsing the modifier O");
0355
0356 switch (*__begin) {
0357 case _CharT('S'):
0358 __format_spec::__validate_second(__flags);
0359 break;
0360
0361 case _CharT('M'):
0362 __format_spec::__validate_minute(__flags);
0363 break;
0364
0365 case _CharT('I'):
0366 case _CharT('H'):
0367 __parser_.__hour_ = true;
0368 __format_spec::__validate_hour(__flags);
0369 break;
0370
0371 case _CharT('d'):
0372 case _CharT('e'):
0373 __format_spec::__validate_day(__flags);
0374 break;
0375
0376 case _CharT('m'):
0377 __format_spec::__validate_month(__flags);
0378 break;
0379
0380 case _CharT('y'):
0381 __format_spec::__validate_year(__flags);
0382 break;
0383
0384 case _CharT('U'):
0385 case _CharT('V'):
0386 case _CharT('W'):
0387 __parser_.__week_of_year_ = true;
0388 __format_spec::__validate_date(__flags);
0389 break;
0390
0391 case _CharT('u'):
0392 case _CharT('w'):
0393 __parser_.__weekday_ = true;
0394 __format_spec::__validate_weekday(__flags);
0395 break;
0396
0397 case _CharT('z'):
0398
0399
0400
0401 __format_spec::__validate_time_zone(__flags);
0402 break;
0403
0404 default:
0405 std::__throw_format_error("The date time type specifier for modifier O is invalid");
0406 }
0407 }
0408 };
0409
0410 }
0411
0412 #endif
0413
0414 _LIBCPP_END_NAMESPACE_STD
0415
0416 #endif