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