[lld][WebAssembly] Reinstate mistakenly disabled test. NFC
[llvm-project.git] / libcxx / include / __chrono / calendar.h
blob0854ca60d3dfbec599c3ade120ac2cd9dd79dfef
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___CHRONO_CALENDAR_H
11 #define _LIBCPP___CHRONO_CALENDAR_H
13 #include <__chrono/duration.h>
14 #include <__chrono/system_clock.h>
15 #include <__chrono/time_point.h>
16 #include <__config>
17 #include <limits>
18 #include <ratio>
19 #include <type_traits>
21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 #pragma GCC system_header
23 #endif
25 _LIBCPP_PUSH_MACROS
26 #include <__undef_macros>
28 #if _LIBCPP_STD_VER > 17
30 _LIBCPP_BEGIN_NAMESPACE_STD
32 namespace chrono
35 struct local_t {};
36 template<class Duration>
37 using local_time = time_point<local_t, Duration>;
38 using local_seconds = local_time<seconds>;
39 using local_days = local_time<days>;
41 struct last_spec { explicit last_spec() = default; };
43 class day {
44 private:
45 unsigned char __d;
46 public:
47 day() = default;
48 explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {}
49 inline constexpr day& operator++() noexcept { ++__d; return *this; }
50 inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; }
51 inline constexpr day& operator--() noexcept { --__d; return *this; }
52 inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; }
53 constexpr day& operator+=(const days& __dd) noexcept;
54 constexpr day& operator-=(const days& __dd) noexcept;
55 explicit inline constexpr operator unsigned() const noexcept { return __d; }
56 inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; }
60 inline constexpr
61 bool operator==(const day& __lhs, const day& __rhs) noexcept
62 { return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
64 inline constexpr
65 bool operator!=(const day& __lhs, const day& __rhs) noexcept
66 { return !(__lhs == __rhs); }
68 inline constexpr
69 bool operator< (const day& __lhs, const day& __rhs) noexcept
70 { return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
72 inline constexpr
73 bool operator> (const day& __lhs, const day& __rhs) noexcept
74 { return __rhs < __lhs; }
76 inline constexpr
77 bool operator<=(const day& __lhs, const day& __rhs) noexcept
78 { return !(__rhs < __lhs);}
80 inline constexpr
81 bool operator>=(const day& __lhs, const day& __rhs) noexcept
82 { return !(__lhs < __rhs); }
84 inline constexpr
85 day operator+ (const day& __lhs, const days& __rhs) noexcept
86 { return day(static_cast<unsigned>(__lhs) + __rhs.count()); }
88 inline constexpr
89 day operator+ (const days& __lhs, const day& __rhs) noexcept
90 { return __rhs + __lhs; }
92 inline constexpr
93 day operator- (const day& __lhs, const days& __rhs) noexcept
94 { return __lhs + -__rhs; }
96 inline constexpr
97 days operator-(const day& __lhs, const day& __rhs) noexcept
98 { return days(static_cast<int>(static_cast<unsigned>(__lhs)) -
99 static_cast<int>(static_cast<unsigned>(__rhs))); }
101 inline constexpr day& day::operator+=(const days& __dd) noexcept
102 { *this = *this + __dd; return *this; }
104 inline constexpr day& day::operator-=(const days& __dd) noexcept
105 { *this = *this - __dd; return *this; }
108 class month {
109 private:
110 unsigned char __m;
111 public:
112 month() = default;
113 explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {}
114 inline constexpr month& operator++() noexcept { ++__m; return *this; }
115 inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; }
116 inline constexpr month& operator--() noexcept { --__m; return *this; }
117 inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; }
118 constexpr month& operator+=(const months& __m1) noexcept;
119 constexpr month& operator-=(const months& __m1) noexcept;
120 explicit inline constexpr operator unsigned() const noexcept { return __m; }
121 inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; }
125 inline constexpr
126 bool operator==(const month& __lhs, const month& __rhs) noexcept
127 { return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
129 inline constexpr
130 bool operator!=(const month& __lhs, const month& __rhs) noexcept
131 { return !(__lhs == __rhs); }
133 inline constexpr
134 bool operator< (const month& __lhs, const month& __rhs) noexcept
135 { return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
137 inline constexpr
138 bool operator> (const month& __lhs, const month& __rhs) noexcept
139 { return __rhs < __lhs; }
141 inline constexpr
142 bool operator<=(const month& __lhs, const month& __rhs) noexcept
143 { return !(__rhs < __lhs); }
145 inline constexpr
146 bool operator>=(const month& __lhs, const month& __rhs) noexcept
147 { return !(__lhs < __rhs); }
149 inline constexpr
150 month operator+ (const month& __lhs, const months& __rhs) noexcept
152 auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1);
153 auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12;
154 return month{static_cast<unsigned>(__mu - __yr * 12 + 1)};
157 inline constexpr
158 month operator+ (const months& __lhs, const month& __rhs) noexcept
159 { return __rhs + __lhs; }
161 inline constexpr
162 month operator- (const month& __lhs, const months& __rhs) noexcept
163 { return __lhs + -__rhs; }
165 inline constexpr
166 months operator-(const month& __lhs, const month& __rhs) noexcept
168 auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs);
169 return months(__dm <= 11 ? __dm : __dm + 12);
172 inline constexpr month& month::operator+=(const months& __dm) noexcept
173 { *this = *this + __dm; return *this; }
175 inline constexpr month& month::operator-=(const months& __dm) noexcept
176 { *this = *this - __dm; return *this; }
179 class year {
180 private:
181 short __y;
182 public:
183 year() = default;
184 explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {}
186 inline constexpr year& operator++() noexcept { ++__y; return *this; }
187 inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; }
188 inline constexpr year& operator--() noexcept { --__y; return *this; }
189 inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; }
190 constexpr year& operator+=(const years& __dy) noexcept;
191 constexpr year& operator-=(const years& __dy) noexcept;
192 inline constexpr year operator+() const noexcept { return *this; }
193 inline constexpr year operator-() const noexcept { return year{-__y}; }
195 inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); }
196 explicit inline constexpr operator int() const noexcept { return __y; }
197 constexpr bool ok() const noexcept;
198 static inline constexpr year min() noexcept { return year{-32767}; }
199 static inline constexpr year max() noexcept { return year{ 32767}; }
203 inline constexpr
204 bool operator==(const year& __lhs, const year& __rhs) noexcept
205 { return static_cast<int>(__lhs) == static_cast<int>(__rhs); }
207 inline constexpr
208 bool operator!=(const year& __lhs, const year& __rhs) noexcept
209 { return !(__lhs == __rhs); }
211 inline constexpr
212 bool operator< (const year& __lhs, const year& __rhs) noexcept
213 { return static_cast<int>(__lhs) < static_cast<int>(__rhs); }
215 inline constexpr
216 bool operator> (const year& __lhs, const year& __rhs) noexcept
217 { return __rhs < __lhs; }
219 inline constexpr
220 bool operator<=(const year& __lhs, const year& __rhs) noexcept
221 { return !(__rhs < __lhs); }
223 inline constexpr
224 bool operator>=(const year& __lhs, const year& __rhs) noexcept
225 { return !(__lhs < __rhs); }
227 inline constexpr
228 year operator+ (const year& __lhs, const years& __rhs) noexcept
229 { return year(static_cast<int>(__lhs) + __rhs.count()); }
231 inline constexpr
232 year operator+ (const years& __lhs, const year& __rhs) noexcept
233 { return __rhs + __lhs; }
235 inline constexpr
236 year operator- (const year& __lhs, const years& __rhs) noexcept
237 { return __lhs + -__rhs; }
239 inline constexpr
240 years operator-(const year& __lhs, const year& __rhs) noexcept
241 { return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; }
244 inline constexpr year& year::operator+=(const years& __dy) noexcept
245 { *this = *this + __dy; return *this; }
247 inline constexpr year& year::operator-=(const years& __dy) noexcept
248 { *this = *this - __dy; return *this; }
250 inline constexpr bool year::ok() const noexcept
251 { return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); }
253 class weekday_indexed;
254 class weekday_last;
256 class weekday {
257 private:
258 unsigned char __wd;
259 static constexpr unsigned char __weekday_from_days(int __days) noexcept;
260 public:
261 weekday() = default;
262 inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {}
263 inline constexpr weekday(const sys_days& __sysd) noexcept
264 : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {}
265 inline explicit constexpr weekday(const local_days& __locd) noexcept
266 : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {}
268 inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; }
269 inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; }
270 inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; }
271 inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; }
272 constexpr weekday& operator+=(const days& __dd) noexcept;
273 constexpr weekday& operator-=(const days& __dd) noexcept;
274 inline constexpr unsigned c_encoding() const noexcept { return __wd; }
275 inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; }
276 inline constexpr bool ok() const noexcept { return __wd <= 6; }
277 constexpr weekday_indexed operator[](unsigned __index) const noexcept;
278 constexpr weekday_last operator[](last_spec) const noexcept;
282 // https://howardhinnant.github.io/date_algorithms.html#weekday_from_days
283 inline constexpr
284 unsigned char weekday::__weekday_from_days(int __days) noexcept
286 return static_cast<unsigned char>(
287 static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6)
291 inline constexpr
292 bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept
293 { return __lhs.c_encoding() == __rhs.c_encoding(); }
295 inline constexpr
296 bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept
297 { return !(__lhs == __rhs); }
299 inline constexpr
300 bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept
301 { return __lhs.c_encoding() < __rhs.c_encoding(); }
303 inline constexpr
304 bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept
305 { return __rhs < __lhs; }
307 inline constexpr
308 bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept
309 { return !(__rhs < __lhs);}
311 inline constexpr
312 bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept
313 { return !(__lhs < __rhs); }
315 constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept
317 auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count();
318 auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7;
319 return weekday{static_cast<unsigned>(__mu - __yr * 7)};
322 constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept
323 { return __rhs + __lhs; }
325 constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept
326 { return __lhs + -__rhs; }
328 constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept
330 const int __wdu = __lhs.c_encoding() - __rhs.c_encoding();
331 const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7;
332 return days{__wdu - __wk * 7};
335 inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept
336 { *this = *this + __dd; return *this; }
338 inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept
339 { *this = *this - __dd; return *this; }
342 class weekday_indexed {
343 private:
344 chrono::weekday __wd;
345 unsigned char __idx;
346 public:
347 weekday_indexed() = default;
348 inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept
349 : __wd{__wdval}, __idx(__idxval) {}
350 inline constexpr chrono::weekday weekday() const noexcept { return __wd; }
351 inline constexpr unsigned index() const noexcept { return __idx; }
352 inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; }
355 inline constexpr
356 bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
357 { return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); }
359 inline constexpr
360 bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
361 { return !(__lhs == __rhs); }
364 class weekday_last {
365 private:
366 chrono::weekday __wd;
367 public:
368 explicit constexpr weekday_last(const chrono::weekday& __val) noexcept
369 : __wd{__val} {}
370 constexpr chrono::weekday weekday() const noexcept { return __wd; }
371 constexpr bool ok() const noexcept { return __wd.ok(); }
374 inline constexpr
375 bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
376 { return __lhs.weekday() == __rhs.weekday(); }
378 inline constexpr
379 bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
380 { return !(__lhs == __rhs); }
382 inline constexpr
383 weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; }
385 inline constexpr
386 weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; }
389 inline constexpr last_spec last{};
390 inline constexpr weekday Sunday{0};
391 inline constexpr weekday Monday{1};
392 inline constexpr weekday Tuesday{2};
393 inline constexpr weekday Wednesday{3};
394 inline constexpr weekday Thursday{4};
395 inline constexpr weekday Friday{5};
396 inline constexpr weekday Saturday{6};
398 inline constexpr month January{1};
399 inline constexpr month February{2};
400 inline constexpr month March{3};
401 inline constexpr month April{4};
402 inline constexpr month May{5};
403 inline constexpr month June{6};
404 inline constexpr month July{7};
405 inline constexpr month August{8};
406 inline constexpr month September{9};
407 inline constexpr month October{10};
408 inline constexpr month November{11};
409 inline constexpr month December{12};
412 class month_day {
413 private:
414 chrono::month __m;
415 chrono::day __d;
416 public:
417 month_day() = default;
418 constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept
419 : __m{__mval}, __d{__dval} {}
420 inline constexpr chrono::month month() const noexcept { return __m; }
421 inline constexpr chrono::day day() const noexcept { return __d; }
422 constexpr bool ok() const noexcept;
425 inline constexpr
426 bool month_day::ok() const noexcept
428 if (!__m.ok()) return false;
429 const unsigned __dval = static_cast<unsigned>(__d);
430 if (__dval < 1 || __dval > 31) return false;
431 if (__dval <= 29) return true;
432 // Now we've got either 30 or 31
433 const unsigned __mval = static_cast<unsigned>(__m);
434 if (__mval == 2) return false;
435 if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11)
436 return __dval == 30;
437 return true;
440 inline constexpr
441 bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept
442 { return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
444 inline constexpr
445 bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept
446 { return !(__lhs == __rhs); }
448 inline constexpr
449 month_day operator/(const month& __lhs, const day& __rhs) noexcept
450 { return month_day{__lhs, __rhs}; }
452 constexpr
453 month_day operator/(const day& __lhs, const month& __rhs) noexcept
454 { return __rhs / __lhs; }
456 inline constexpr
457 month_day operator/(const month& __lhs, int __rhs) noexcept
458 { return __lhs / day(__rhs); }
460 constexpr
461 month_day operator/(int __lhs, const day& __rhs) noexcept
462 { return month(__lhs) / __rhs; }
464 constexpr
465 month_day operator/(const day& __lhs, int __rhs) noexcept
466 { return month(__rhs) / __lhs; }
469 inline constexpr
470 bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept
471 { return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); }
473 inline constexpr
474 bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept
475 { return __rhs < __lhs; }
477 inline constexpr
478 bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept
479 { return !(__rhs < __lhs);}
481 inline constexpr
482 bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept
483 { return !(__lhs < __rhs); }
487 class month_day_last {
488 private:
489 chrono::month __m;
490 public:
491 explicit constexpr month_day_last(const chrono::month& __val) noexcept
492 : __m{__val} {}
493 inline constexpr chrono::month month() const noexcept { return __m; }
494 inline constexpr bool ok() const noexcept { return __m.ok(); }
497 inline constexpr
498 bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
499 { return __lhs.month() == __rhs.month(); }
501 inline constexpr
502 bool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
503 { return !(__lhs == __rhs); }
505 inline constexpr
506 bool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept
507 { return __lhs.month() < __rhs.month(); }
509 inline constexpr
510 bool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept
511 { return __rhs < __lhs; }
513 inline constexpr
514 bool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
515 { return !(__rhs < __lhs);}
517 inline constexpr
518 bool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
519 { return !(__lhs < __rhs); }
521 inline constexpr
522 month_day_last operator/(const month& __lhs, last_spec) noexcept
523 { return month_day_last{__lhs}; }
525 inline constexpr
526 month_day_last operator/(last_spec, const month& __rhs) noexcept
527 { return month_day_last{__rhs}; }
529 inline constexpr
530 month_day_last operator/(int __lhs, last_spec) noexcept
531 { return month_day_last{month(__lhs)}; }
533 inline constexpr
534 month_day_last operator/(last_spec, int __rhs) noexcept
535 { return month_day_last{month(__rhs)}; }
538 class month_weekday {
539 private:
540 chrono::month __m;
541 chrono::weekday_indexed __wdi;
542 public:
543 month_weekday() = default;
544 constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept
545 : __m{__mval}, __wdi{__wdival} {}
546 inline constexpr chrono::month month() const noexcept { return __m; }
547 inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
548 inline constexpr bool ok() const noexcept { return __m.ok() && __wdi.ok(); }
551 inline constexpr
552 bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
553 { return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
555 inline constexpr
556 bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
557 { return !(__lhs == __rhs); }
559 inline constexpr
560 month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept
561 { return month_weekday{__lhs, __rhs}; }
563 inline constexpr
564 month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept
565 { return month_weekday{month(__lhs), __rhs}; }
567 inline constexpr
568 month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept
569 { return month_weekday{__rhs, __lhs}; }
571 inline constexpr
572 month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept
573 { return month_weekday{month(__rhs), __lhs}; }
576 class month_weekday_last {
577 chrono::month __m;
578 chrono::weekday_last __wdl;
579 public:
580 constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept
581 : __m{__mval}, __wdl{__wdlval} {}
582 inline constexpr chrono::month month() const noexcept { return __m; }
583 inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; }
584 inline constexpr bool ok() const noexcept { return __m.ok() && __wdl.ok(); }
587 inline constexpr
588 bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
589 { return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
591 inline constexpr
592 bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
593 { return !(__lhs == __rhs); }
596 inline constexpr
597 month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept
598 { return month_weekday_last{__lhs, __rhs}; }
600 inline constexpr
601 month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept
602 { return month_weekday_last{month(__lhs), __rhs}; }
604 inline constexpr
605 month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept
606 { return month_weekday_last{__rhs, __lhs}; }
608 inline constexpr
609 month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept
610 { return month_weekday_last{month(__rhs), __lhs}; }
613 class year_month {
614 chrono::year __y;
615 chrono::month __m;
616 public:
617 year_month() = default;
618 constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept
619 : __y{__yval}, __m{__mval} {}
620 inline constexpr chrono::year year() const noexcept { return __y; }
621 inline constexpr chrono::month month() const noexcept { return __m; }
622 inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; }
623 inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; }
624 inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; }
625 inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; }
626 inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); }
629 inline constexpr
630 year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; }
632 inline constexpr
633 year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; }
635 inline constexpr
636 bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept
637 { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); }
639 inline constexpr
640 bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept
641 { return !(__lhs == __rhs); }
643 inline constexpr
644 bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept
645 { return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); }
647 inline constexpr
648 bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept
649 { return __rhs < __lhs; }
651 inline constexpr
652 bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept
653 { return !(__rhs < __lhs);}
655 inline constexpr
656 bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept
657 { return !(__lhs < __rhs); }
659 constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept
661 int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count();
662 const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12;
663 __dmi = __dmi - __dy * 12 + 1;
664 return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi));
667 constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept
668 { return __rhs + __lhs; }
670 constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept
671 { return (__lhs.year() + __rhs) / __lhs.month(); }
673 constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept
674 { return __rhs + __lhs; }
676 constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept
677 { return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); }
679 constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept
680 { return __lhs + -__rhs; }
682 constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept
683 { return __lhs + -__rhs; }
685 class year_month_day_last;
687 class year_month_day {
688 private:
689 chrono::year __y;
690 chrono::month __m;
691 chrono::day __d;
692 public:
693 year_month_day() = default;
694 inline constexpr year_month_day(
695 const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept
696 : __y{__yval}, __m{__mval}, __d{__dval} {}
697 constexpr year_month_day(const year_month_day_last& __ymdl) noexcept;
698 inline constexpr year_month_day(const sys_days& __sysd) noexcept
699 : year_month_day(__from_days(__sysd.time_since_epoch())) {}
700 inline explicit constexpr year_month_day(const local_days& __locd) noexcept
701 : year_month_day(__from_days(__locd.time_since_epoch())) {}
703 constexpr year_month_day& operator+=(const months& __dm) noexcept;
704 constexpr year_month_day& operator-=(const months& __dm) noexcept;
705 constexpr year_month_day& operator+=(const years& __dy) noexcept;
706 constexpr year_month_day& operator-=(const years& __dy) noexcept;
708 inline constexpr chrono::year year() const noexcept { return __y; }
709 inline constexpr chrono::month month() const noexcept { return __m; }
710 inline constexpr chrono::day day() const noexcept { return __d; }
711 inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
712 inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
714 constexpr bool ok() const noexcept;
716 static constexpr year_month_day __from_days(days __d) noexcept;
717 constexpr days __to_days() const noexcept;
721 // https://howardhinnant.github.io/date_algorithms.html#civil_from_days
722 inline constexpr
723 year_month_day
724 year_month_day::__from_days(days __d) noexcept
726 static_assert(numeric_limits<unsigned>::digits >= 18, "");
727 static_assert(numeric_limits<int>::digits >= 20 , "");
728 const int __z = __d.count() + 719468;
729 const int __era = (__z >= 0 ? __z : __z - 146096) / 146097;
730 const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096]
731 const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399]
732 const int __yr = static_cast<int>(__yoe) + __era * 400;
733 const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365]
734 const unsigned __mp = (5 * __doy + 2)/153; // [0, 11]
735 const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31]
736 const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12]
737 return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}};
740 // https://howardhinnant.github.io/date_algorithms.html#days_from_civil
741 inline constexpr days year_month_day::__to_days() const noexcept
743 static_assert(numeric_limits<unsigned>::digits >= 18, "");
744 static_assert(numeric_limits<int>::digits >= 20 , "");
746 const int __yr = static_cast<int>(__y) - (__m <= February);
747 const unsigned __mth = static_cast<unsigned>(__m);
748 const unsigned __dy = static_cast<unsigned>(__d);
750 const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400;
751 const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399]
752 const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365]
753 const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096]
754 return days{__era * 146097 + static_cast<int>(__doe) - 719468};
757 inline constexpr
758 bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
759 { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
761 inline constexpr
762 bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
763 { return !(__lhs == __rhs); }
765 inline constexpr
766 bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
768 if (__lhs.year() < __rhs.year()) return true;
769 if (__lhs.year() > __rhs.year()) return false;
770 if (__lhs.month() < __rhs.month()) return true;
771 if (__lhs.month() > __rhs.month()) return false;
772 return __lhs.day() < __rhs.day();
775 inline constexpr
776 bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
777 { return __rhs < __lhs; }
779 inline constexpr
780 bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
781 { return !(__rhs < __lhs);}
783 inline constexpr
784 bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
785 { return !(__lhs < __rhs); }
787 inline constexpr
788 year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept
789 { return year_month_day{__lhs.year(), __lhs.month(), __rhs}; }
791 inline constexpr
792 year_month_day operator/(const year_month& __lhs, int __rhs) noexcept
793 { return __lhs / day(__rhs); }
795 inline constexpr
796 year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept
797 { return __lhs / __rhs.month() / __rhs.day(); }
799 inline constexpr
800 year_month_day operator/(int __lhs, const month_day& __rhs) noexcept
801 { return year(__lhs) / __rhs; }
803 inline constexpr
804 year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept
805 { return __rhs / __lhs; }
807 inline constexpr
808 year_month_day operator/(const month_day& __lhs, int __rhs) noexcept
809 { return year(__rhs) / __lhs; }
812 inline constexpr
813 year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept
814 { return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); }
816 inline constexpr
817 year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept
818 { return __rhs + __lhs; }
820 inline constexpr
821 year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept
822 { return __lhs + -__rhs; }
824 inline constexpr
825 year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept
826 { return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); }
828 inline constexpr
829 year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept
830 { return __rhs + __lhs; }
832 inline constexpr
833 year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept
834 { return __lhs + -__rhs; }
836 inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
837 inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
838 inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
839 inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
841 class year_month_day_last {
842 private:
843 chrono::year __y;
844 chrono::month_day_last __mdl;
845 public:
846 constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept
847 : __y{__yval}, __mdl{__mdlval} {}
849 constexpr year_month_day_last& operator+=(const months& __m) noexcept;
850 constexpr year_month_day_last& operator-=(const months& __m) noexcept;
851 constexpr year_month_day_last& operator+=(const years& __y) noexcept;
852 constexpr year_month_day_last& operator-=(const years& __y) noexcept;
854 inline constexpr chrono::year year() const noexcept { return __y; }
855 inline constexpr chrono::month month() const noexcept { return __mdl.month(); }
856 inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; }
857 constexpr chrono::day day() const noexcept;
858 inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; }
859 inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; }
860 inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); }
863 inline constexpr
864 chrono::day year_month_day_last::day() const noexcept
866 constexpr chrono::day __d[] =
868 chrono::day(31), chrono::day(28), chrono::day(31),
869 chrono::day(30), chrono::day(31), chrono::day(30),
870 chrono::day(31), chrono::day(31), chrono::day(30),
871 chrono::day(31), chrono::day(30), chrono::day(31)
873 return (month() != February || !__y.is_leap()) && month().ok() ?
874 __d[static_cast<unsigned>(month()) - 1] : chrono::day{29};
877 inline constexpr
878 bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
879 { return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); }
881 inline constexpr
882 bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
883 { return !(__lhs == __rhs); }
885 inline constexpr
886 bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
888 if (__lhs.year() < __rhs.year()) return true;
889 if (__lhs.year() > __rhs.year()) return false;
890 return __lhs.month_day_last() < __rhs.month_day_last();
893 inline constexpr
894 bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
895 { return __rhs < __lhs; }
897 inline constexpr
898 bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
899 { return !(__rhs < __lhs);}
901 inline constexpr
902 bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
903 { return !(__lhs < __rhs); }
905 inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept
906 { return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; }
908 inline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept
909 { return year_month_day_last{__lhs, __rhs}; }
911 inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept
912 { return year_month_day_last{year{__lhs}, __rhs}; }
914 inline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept
915 { return __rhs / __lhs; }
917 inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept
918 { return year{__rhs} / __lhs; }
921 inline constexpr
922 year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept
923 { return (__lhs.year() / __lhs.month() + __rhs) / last; }
925 inline constexpr
926 year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept
927 { return __rhs + __lhs; }
929 inline constexpr
930 year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept
931 { return __lhs + (-__rhs); }
933 inline constexpr
934 year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept
935 { return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; }
937 inline constexpr
938 year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept
939 { return __rhs + __lhs; }
941 inline constexpr
942 year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept
943 { return __lhs + (-__rhs); }
945 inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
946 inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
947 inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
948 inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
950 inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
951 : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {}
953 inline constexpr bool year_month_day::ok() const noexcept
955 if (!__y.ok() || !__m.ok()) return false;
956 return chrono::day{1} <= __d && __d <= (__y / __m / last).day();
959 class year_month_weekday {
960 chrono::year __y;
961 chrono::month __m;
962 chrono::weekday_indexed __wdi;
963 public:
964 year_month_weekday() = default;
965 constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval,
966 const chrono::weekday_indexed& __wdival) noexcept
967 : __y{__yval}, __m{__mval}, __wdi{__wdival} {}
968 constexpr year_month_weekday(const sys_days& __sysd) noexcept
969 : year_month_weekday(__from_days(__sysd.time_since_epoch())) {}
970 inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept
971 : year_month_weekday(__from_days(__locd.time_since_epoch())) {}
972 constexpr year_month_weekday& operator+=(const months& m) noexcept;
973 constexpr year_month_weekday& operator-=(const months& m) noexcept;
974 constexpr year_month_weekday& operator+=(const years& y) noexcept;
975 constexpr year_month_weekday& operator-=(const years& y) noexcept;
977 inline constexpr chrono::year year() const noexcept { return __y; }
978 inline constexpr chrono::month month() const noexcept { return __m; }
979 inline constexpr chrono::weekday weekday() const noexcept { return __wdi.weekday(); }
980 inline constexpr unsigned index() const noexcept { return __wdi.index(); }
981 inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
983 inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
984 inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
985 inline constexpr bool ok() const noexcept
987 if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false;
988 if (__wdi.index() <= 4) return true;
989 auto __nth_weekday_day =
990 __wdi.weekday() -
991 chrono::weekday{static_cast<sys_days>(__y / __m / 1)} +
992 days{(__wdi.index() - 1) * 7 + 1};
993 return static_cast<unsigned>(__nth_weekday_day.count()) <=
994 static_cast<unsigned>((__y / __m / last).day());
997 static constexpr year_month_weekday __from_days(days __d) noexcept;
998 constexpr days __to_days() const noexcept;
1001 inline constexpr
1002 year_month_weekday year_month_weekday::__from_days(days __d) noexcept
1004 const sys_days __sysd{__d};
1005 const chrono::weekday __wd = chrono::weekday(__sysd);
1006 const year_month_day __ymd = year_month_day(__sysd);
1007 return year_month_weekday{__ymd.year(), __ymd.month(),
1008 __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]};
1011 inline constexpr
1012 days year_month_weekday::__to_days() const noexcept
1014 const sys_days __sysd = sys_days(__y/__m/1);
1015 return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7}))
1016 .time_since_epoch();
1019 inline constexpr
1020 bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
1021 { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
1023 inline constexpr
1024 bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
1025 { return !(__lhs == __rhs); }
1027 inline constexpr
1028 year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept
1029 { return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; }
1031 inline constexpr
1032 year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept
1033 { return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; }
1035 inline constexpr
1036 year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept
1037 { return year(__lhs) / __rhs; }
1039 inline constexpr
1040 year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept
1041 { return __rhs / __lhs; }
1043 inline constexpr
1044 year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept
1045 { return year(__rhs) / __lhs; }
1048 inline constexpr
1049 year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept
1050 { return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); }
1052 inline constexpr
1053 year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept
1054 { return __rhs + __lhs; }
1056 inline constexpr
1057 year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept
1058 { return __lhs + (-__rhs); }
1060 inline constexpr
1061 year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept
1062 { return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; }
1064 inline constexpr
1065 year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept
1066 { return __rhs + __lhs; }
1068 inline constexpr
1069 year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept
1070 { return __lhs + (-__rhs); }
1073 inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
1074 inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
1075 inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
1076 inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
1078 class year_month_weekday_last {
1079 private:
1080 chrono::year __y;
1081 chrono::month __m;
1082 chrono::weekday_last __wdl;
1083 public:
1084 constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval,
1085 const chrono::weekday_last& __wdlval) noexcept
1086 : __y{__yval}, __m{__mval}, __wdl{__wdlval} {}
1087 constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept;
1088 constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept;
1089 constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept;
1090 constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept;
1092 inline constexpr chrono::year year() const noexcept { return __y; }
1093 inline constexpr chrono::month month() const noexcept { return __m; }
1094 inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); }
1095 inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; }
1096 inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
1097 inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
1098 inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); }
1100 constexpr days __to_days() const noexcept;
1104 inline constexpr
1105 days year_month_weekday_last::__to_days() const noexcept
1107 const sys_days __last = sys_days{__y/__m/last};
1108 return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch();
1112 inline constexpr
1113 bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
1114 { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
1116 inline constexpr
1117 bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
1118 { return !(__lhs == __rhs); }
1121 inline constexpr
1122 year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept
1123 { return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; }
1125 inline constexpr
1126 year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept
1127 { return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; }
1129 inline constexpr
1130 year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept
1131 { return year(__lhs) / __rhs; }
1133 inline constexpr
1134 year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept
1135 { return __rhs / __lhs; }
1137 inline constexpr
1138 year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept
1139 { return year(__rhs) / __lhs; }
1142 inline constexpr
1143 year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
1144 { return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); }
1146 inline constexpr
1147 year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept
1148 { return __rhs + __lhs; }
1150 inline constexpr
1151 year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
1152 { return __lhs + (-__rhs); }
1154 inline constexpr
1155 year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
1156 { return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; }
1158 inline constexpr
1159 year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept
1160 { return __rhs + __lhs; }
1162 inline constexpr
1163 year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
1164 { return __lhs + (-__rhs); }
1166 inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
1167 inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
1168 inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
1169 inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
1172 template <class _Duration>
1173 class hh_mm_ss
1175 private:
1176 static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration");
1177 using __CommonType = common_type_t<_Duration, chrono::seconds>;
1179 static constexpr uint64_t __pow10(unsigned __exp)
1181 uint64_t __ret = 1;
1182 for (unsigned __i = 0; __i < __exp; ++__i)
1183 __ret *= 10U;
1184 return __ret;
1187 static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0)
1189 if (__n >= 2 && __d != 0 && __w < 19)
1190 return 1 + __width(__n, __d % __n * 10, __w+1);
1191 return 0;
1194 public:
1195 static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ?
1196 __width(__CommonType::period::den) : 6u;
1197 using precision = duration<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>;
1199 constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {}
1201 constexpr explicit hh_mm_ss(_Duration __d) noexcept :
1202 __is_neg(__d < _Duration(0)),
1203 __h(duration_cast<chrono::hours> (abs(__d))),
1204 __m(duration_cast<chrono::minutes>(abs(__d) - hours())),
1205 __s(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())),
1206 __f(duration_cast<precision> (abs(__d) - hours() - minutes() - seconds()))
1209 constexpr bool is_negative() const noexcept { return __is_neg; }
1210 constexpr chrono::hours hours() const noexcept { return __h; }
1211 constexpr chrono::minutes minutes() const noexcept { return __m; }
1212 constexpr chrono::seconds seconds() const noexcept { return __s; }
1213 constexpr precision subseconds() const noexcept { return __f; }
1215 constexpr precision to_duration() const noexcept
1217 auto __dur = __h + __m + __s + __f;
1218 return __is_neg ? -__dur : __dur;
1221 constexpr explicit operator precision() const noexcept { return to_duration(); }
1223 private:
1224 bool __is_neg;
1225 chrono::hours __h;
1226 chrono::minutes __m;
1227 chrono::seconds __s;
1228 precision __f;
1231 constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); }
1232 constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); }
1234 constexpr hours make12(const hours& __h) noexcept
1236 if (__h == hours( 0)) return hours(12);
1237 else if (__h <= hours(12)) return __h;
1238 else return __h - hours(12);
1241 constexpr hours make24(const hours& __h, bool __is_pm) noexcept
1243 if (__is_pm)
1244 return __h == hours(12) ? __h : __h + hours(12);
1245 else
1246 return __h == hours(12) ? hours(0) : __h;
1249 } // namespace chrono
1251 inline namespace literals
1253 inline namespace chrono_literals
1255 constexpr chrono::day operator ""d(unsigned long long __d) noexcept
1257 return chrono::day(static_cast<unsigned>(__d));
1260 constexpr chrono::year operator ""y(unsigned long long __y) noexcept
1262 return chrono::year(static_cast<int>(__y));
1264 } // namespace chrono_literals
1265 } // namespace literals
1267 namespace chrono { // hoist the literals into namespace std::chrono
1268 using namespace literals::chrono_literals;
1269 } // namespace chrono
1271 _LIBCPP_END_NAMESPACE_STD
1273 #endif // _LIBCPP_STD_VER > 17
1275 _LIBCPP_POP_MACROS
1277 #endif // _LIBCPP___CHRONO_CALENDAR_H