libstdc++
chrono
Go to the documentation of this file.
1// <chrono> -*- C++ -*-
2
3// Copyright (C) 2008-2022 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/chrono
26 * This is a Standard C++ Library header.
27 * @ingroup chrono
28 */
29
30#ifndef _GLIBCXX_CHRONO
31#define _GLIBCXX_CHRONO 1
32
33#pragma GCC system_header
34
35#if __cplusplus < 201103L
36# include <bits/c++0x_warning.h>
37#else
38
39#include <bits/chrono.h>
40#if __cplusplus > 201703L
41# include <sstream> // ostringstream
42# include <bits/charconv.h>
43#endif
44
45namespace std _GLIBCXX_VISIBILITY(default)
46{
47_GLIBCXX_BEGIN_NAMESPACE_VERSION
48
49 /**
50 * @defgroup chrono Time
51 * @ingroup utilities
52 *
53 * Classes and functions for time.
54 *
55 * @since C++11
56 */
57
58 /** @namespace std::chrono
59 * @brief ISO C++ 2011 namespace for date and time utilities
60 * @ingroup chrono
61 */
62 namespace chrono
63 {
64#if __cplusplus >= 202002L
65 /// @addtogroup chrono
66 /// @{
67 struct local_t { };
68 template<typename _Duration>
69 using local_time = time_point<local_t, _Duration>;
70 using local_seconds = local_time<seconds>;
71 using local_days = local_time<days>;
72
73 class utc_clock;
74 class tai_clock;
75 class gps_clock;
76
77 template<typename _Duration>
78 using utc_time = time_point<utc_clock, _Duration>;
79 using utc_seconds = utc_time<seconds>;
80
81 template<typename _Duration>
82 using tai_time = time_point<tai_clock, _Duration>;
83 using tai_seconds = tai_time<seconds>;
84
85 template<typename _Duration>
86 using gps_time = time_point<gps_clock, _Duration>;
87 using gps_seconds = gps_time<seconds>;
88
89 template<> struct is_clock<utc_clock> : true_type { };
90 template<> struct is_clock<tai_clock> : true_type { };
91 template<> struct is_clock<gps_clock> : true_type { };
92
93 template<> inline constexpr bool is_clock_v<utc_clock> = true;
94 template<> inline constexpr bool is_clock_v<tai_clock> = true;
95 template<> inline constexpr bool is_clock_v<gps_clock> = true;
96
97 struct leap_second_info
98 {
99 bool is_leap_second;
100 seconds elapsed;
101 };
102
103 // CALENDRICAL TYPES
104
105 // CLASS DECLARATIONS
106 class day;
107 class month;
108 class year;
109 class weekday;
110 class weekday_indexed;
111 class weekday_last;
112 class month_day;
113 class month_day_last;
114 class month_weekday;
115 class month_weekday_last;
116 class year_month;
117 class year_month_day;
118 class year_month_day_last;
119 class year_month_weekday;
120 class year_month_weekday_last;
121
122 struct last_spec
123 {
124 explicit last_spec() = default;
125
126 friend constexpr month_day_last
127 operator/(int __m, last_spec) noexcept;
128
129 friend constexpr month_day_last
130 operator/(last_spec, int __m) noexcept;
131 };
132
133 inline constexpr last_spec last{};
134
135 namespace __detail
136 {
137 // Compute the remainder of the Euclidean division of __n divided by __d.
138 // Euclidean division truncates toward negative infinity and always
139 // produces a remainder in the range of [0,__d-1] (whereas standard
140 // division truncates toward zero and yields a nonpositive remainder
141 // for negative __n).
142 constexpr unsigned
143 __modulo(long long __n, unsigned __d)
144 {
145 if (__n >= 0)
146 return __n % __d;
147 else
148 return (__d + (__n % __d)) % __d;
149 }
150
151 inline constexpr unsigned __days_per_month[12]
152 = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
153 }
154
155 // DAY
156
157 class day
158 {
159 private:
160 unsigned char _M_d;
161
162 public:
163 day() = default;
164
165 explicit constexpr
166 day(unsigned __d) noexcept
167 : _M_d(__d)
168 { }
169
170 constexpr day&
171 operator++() noexcept
172 {
173 ++_M_d;
174 return *this;
175 }
176
177 constexpr day
178 operator++(int) noexcept
179 {
180 auto __ret = *this;
181 ++(*this);
182 return __ret;
183 }
184
185 constexpr day&
186 operator--() noexcept
187 {
188 --_M_d;
189 return *this;
190 }
191
192 constexpr day
193 operator--(int) noexcept
194 {
195 auto __ret = *this;
196 --(*this);
197 return __ret;
198 }
199
200 constexpr day&
201 operator+=(const days& __d) noexcept
202 {
203 *this = *this + __d;
204 return *this;
205 }
206
207 constexpr day&
208 operator-=(const days& __d) noexcept
209 {
210 *this = *this - __d;
211 return *this;
212 }
213
214 constexpr explicit
215 operator unsigned() const noexcept
216 { return _M_d; }
217
218 constexpr bool
219 ok() const noexcept
220 { return 1 <= _M_d && _M_d <= 31; }
221
222 friend constexpr bool
223 operator==(const day& __x, const day& __y) noexcept
224 { return unsigned{__x} == unsigned{__y}; }
225
226 friend constexpr strong_ordering
227 operator<=>(const day& __x, const day& __y) noexcept
228 { return unsigned{__x} <=> unsigned{__y}; }
229
230 friend constexpr day
231 operator+(const day& __x, const days& __y) noexcept
232 { return day(unsigned{__x} + __y.count()); }
233
234 friend constexpr day
235 operator+(const days& __x, const day& __y) noexcept
236 { return __y + __x; }
237
238 friend constexpr day
239 operator-(const day& __x, const days& __y) noexcept
240 { return __x + -__y; }
241
242 friend constexpr days
243 operator-(const day& __x, const day& __y) noexcept
244 { return days{int(unsigned{__x}) - int(unsigned{__y})}; }
245
246 friend constexpr month_day
247 operator/(const month& __m, const day& __d) noexcept;
248
249 friend constexpr month_day
250 operator/(int __m, const day& __d) noexcept;
251
252 friend constexpr month_day
253 operator/(const day& __d, const month& __m) noexcept;
254
255 friend constexpr month_day
256 operator/(const day& __d, int __m) noexcept;
257
258 friend constexpr year_month_day
259 operator/(const year_month& __ym, const day& __d) noexcept;
260
261 // TODO: Implement operator<<, to_stream, from_stream.
262 };
263
264 // MONTH
265
266 class month
267 {
268 private:
269 unsigned char _M_m;
270
271 public:
272 month() = default;
273
274 explicit constexpr
275 month(unsigned __m) noexcept
276 : _M_m(__m)
277 { }
278
279 constexpr month&
280 operator++() noexcept
281 {
282 *this += months{1};
283 return *this;
284 }
285
286 constexpr month
287 operator++(int) noexcept
288 {
289 auto __ret = *this;
290 ++(*this);
291 return __ret;
292 }
293
294 constexpr month&
295 operator--() noexcept
296 {
297 *this -= months{1};
298 return *this;
299 }
300
301 constexpr month
302 operator--(int) noexcept
303 {
304 auto __ret = *this;
305 --(*this);
306 return __ret;
307 }
308
309 constexpr month&
310 operator+=(const months& __m) noexcept
311 {
312 *this = *this + __m;
313 return *this;
314 }
315
316 constexpr month&
317 operator-=(const months& __m) noexcept
318 {
319 *this = *this - __m;
320 return *this;
321 }
322
323 explicit constexpr
324 operator unsigned() const noexcept
325 { return _M_m; }
326
327 constexpr bool
328 ok() const noexcept
329 { return 1 <= _M_m && _M_m <= 12; }
330
331 friend constexpr bool
332 operator==(const month& __x, const month& __y) noexcept
333 { return unsigned{__x} == unsigned{__y}; }
334
335 friend constexpr strong_ordering
336 operator<=>(const month& __x, const month& __y) noexcept
337 { return unsigned{__x} <=> unsigned{__y}; }
338
339 friend constexpr month
340 operator+(const month& __x, const months& __y) noexcept
341 {
342 auto __n = static_cast<long long>(unsigned{__x}) + (__y.count() - 1);
343 return month{__detail::__modulo(__n, 12) + 1};
344 }
345
346 friend constexpr month
347 operator+(const months& __x, const month& __y) noexcept
348 { return __y + __x; }
349
350 friend constexpr month
351 operator-(const month& __x, const months& __y) noexcept
352 { return __x + -__y; }
353
354 friend constexpr months
355 operator-(const month& __x, const month& __y) noexcept
356 {
357 const auto __dm = int(unsigned(__x)) - int(unsigned(__y));
358 return months{__dm < 0 ? 12 + __dm : __dm};
359 }
360
361 friend constexpr year_month
362 operator/(const year& __y, const month& __m) noexcept;
363
364 friend constexpr month_day
365 operator/(const month& __m, int __d) noexcept;
366
367 friend constexpr month_day_last
368 operator/(const month& __m, last_spec) noexcept;
369
370 friend constexpr month_day_last
371 operator/(last_spec, const month& __m) noexcept;
372
373 friend constexpr month_weekday
374 operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
375
376 friend constexpr month_weekday
377 operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
378
379 friend constexpr month_weekday_last
380 operator/(const month& __m, const weekday_last& __wdl) noexcept;
381
382 friend constexpr month_weekday_last
383 operator/(const weekday_last& __wdl, const month& __m) noexcept;
384
385 // TODO: Implement operator<<, to_stream, from_stream.
386 };
387
388 inline constexpr month January{1};
389 inline constexpr month February{2};
390 inline constexpr month March{3};
391 inline constexpr month April{4};
392 inline constexpr month May{5};
393 inline constexpr month June{6};
394 inline constexpr month July{7};
395 inline constexpr month August{8};
396 inline constexpr month September{9};
397 inline constexpr month October{10};
398 inline constexpr month November{11};
399 inline constexpr month December{12};
400
401 // YEAR
402
403 class year
404 {
405 private:
406 short _M_y;
407
408 public:
409 year() = default;
410
411 explicit constexpr
412 year(int __y) noexcept
413 : _M_y{static_cast<short>(__y)}
414 { }
415
416 static constexpr year
417 min() noexcept
418 { return year{-32767}; }
419
420 static constexpr year
421 max() noexcept
422 { return year{32767}; }
423
424 constexpr year&
425 operator++() noexcept
426 {
427 ++_M_y;
428 return *this;
429 }
430
431 constexpr year
432 operator++(int) noexcept
433 {
434 auto __ret = *this;
435 ++(*this);
436 return __ret;
437 }
438
439 constexpr year&
440 operator--() noexcept
441 {
442 --_M_y;
443 return *this;
444 }
445
446 constexpr year
447 operator--(int) noexcept
448 {
449 auto __ret = *this;
450 --(*this);
451 return __ret;
452 }
453
454 constexpr year&
455 operator+=(const years& __y) noexcept
456 {
457 *this = *this + __y;
458 return *this;
459 }
460
461 constexpr year&
462 operator-=(const years& __y) noexcept
463 {
464 *this = *this - __y;
465 return *this;
466 }
467
468 constexpr year
469 operator+() const noexcept
470 { return *this; }
471
472 constexpr year
473 operator-() const noexcept
474 { return year{-_M_y}; }
475
476 constexpr bool
477 is_leap() const noexcept
478 {
479 // Testing divisibility by 100 first gives better performance, that is,
480 // return (_M_y % 100 != 0 || _M_y % 400 == 0) && _M_y % 4 == 0;
481
482 // It gets even faster if _M_y is in [-536870800, 536870999]
483 // (which is the case here) and _M_y % 100 is replaced by
484 // __is_multiple_of_100 below.
485
486 // References:
487 // [1] https://github.com/cassioneri/calendar
488 // [2] https://accu.org/journals/overload/28/155/overload155.pdf#page=16
489
490 // Furthermore, if y%100 == 0, then y%400==0 is equivalent to y%16==0,
491 // so we can simplify it to (!mult_100 && y % 4 == 0) || y % 16 == 0,
492 // which is equivalent to (y & (mult_100 ? 15 : 3)) == 0.
493 // See https://gcc.gnu.org/pipermail/libstdc++/2021-June/052815.html
494
495 constexpr uint32_t __multiplier = 42949673;
496 constexpr uint32_t __bound = 42949669;
497 constexpr uint32_t __max_dividend = 1073741799;
498 constexpr uint32_t __offset = __max_dividend / 2 / 100 * 100;
499 const bool __is_multiple_of_100
500 = __multiplier * (_M_y + __offset) < __bound;
501 return (_M_y & (__is_multiple_of_100 ? 15 : 3)) == 0;
502 }
503
504 explicit constexpr
505 operator int() const noexcept
506 { return _M_y; }
507
508 constexpr bool
509 ok() const noexcept
510 { return min()._M_y <= _M_y && _M_y <= max()._M_y; }
511
512 friend constexpr bool
513 operator==(const year& __x, const year& __y) noexcept
514 { return int{__x} == int{__y}; }
515
516 friend constexpr strong_ordering
517 operator<=>(const year& __x, const year& __y) noexcept
518 { return int{__x} <=> int{__y}; }
519
520 friend constexpr year
521 operator+(const year& __x, const years& __y) noexcept
522 { return year{int{__x} + static_cast<int>(__y.count())}; }
523
524 friend constexpr year
525 operator+(const years& __x, const year& __y) noexcept
526 { return __y + __x; }
527
528 friend constexpr year
529 operator-(const year& __x, const years& __y) noexcept
530 { return __x + -__y; }
531
532 friend constexpr years
533 operator-(const year& __x, const year& __y) noexcept
534 { return years{int{__x} - int{__y}}; }
535
536 friend constexpr year_month
537 operator/(const year& __y, int __m) noexcept;
538
539 friend constexpr year_month_day
540 operator/(const year& __y, const month_day& __md) noexcept;
541
542 friend constexpr year_month_day
543 operator/(const month_day& __md, const year& __y) noexcept;
544
545 friend constexpr year_month_day_last
546 operator/(const year& __y, const month_day_last& __mdl) noexcept;
547
548 friend constexpr year_month_day_last
549 operator/(const month_day_last& __mdl, const year& __y) noexcept;
550
551 friend constexpr year_month_weekday
552 operator/(const year& __y, const month_weekday& __mwd) noexcept;
553
554 friend constexpr year_month_weekday
555 operator/(const month_weekday& __mwd, const year& __y) noexcept;
556
557 friend constexpr year_month_weekday_last
558 operator/(const year& __y, const month_weekday_last& __mwdl) noexcept;
559
560 friend constexpr year_month_weekday_last
561 operator/(const month_weekday_last& __mwdl, const year& __y) noexcept;
562
563 // TODO: Implement operator<<, to_stream, from_stream.
564 };
565
566 // WEEKDAY
567
568 class weekday
569 {
570 private:
571 unsigned char _M_wd;
572
573 static constexpr weekday
574 _S_from_days(const days& __d)
575 {
576 auto __n = __d.count();
577 return weekday(__n >= -4 ? (__n + 4) % 7 : (__n + 5) % 7 + 6);
578 }
579
580 public:
581 weekday() = default;
582
583 explicit constexpr
584 weekday(unsigned __wd) noexcept
585 : _M_wd(__wd == 7 ? 0 : __wd) // __wd % 7 ?
586 { }
587
588 constexpr
589 weekday(const sys_days& __dp) noexcept
590 : weekday{_S_from_days(__dp.time_since_epoch())}
591 { }
592
593 explicit constexpr
594 weekday(const local_days& __dp) noexcept
595 : weekday{sys_days{__dp.time_since_epoch()}}
596 { }
597
598 constexpr weekday&
599 operator++() noexcept
600 {
601 *this += days{1};
602 return *this;
603 }
604
605 constexpr weekday
606 operator++(int) noexcept
607 {
608 auto __ret = *this;
609 ++(*this);
610 return __ret;
611 }
612
613 constexpr weekday&
614 operator--() noexcept
615 {
616 *this -= days{1};
617 return *this;
618 }
619
620 constexpr weekday
621 operator--(int) noexcept
622 {
623 auto __ret = *this;
624 --(*this);
625 return __ret;
626 }
627
628 constexpr weekday&
629 operator+=(const days& __d) noexcept
630 {
631 *this = *this + __d;
632 return *this;
633 }
634
635 constexpr weekday&
636 operator-=(const days& __d) noexcept
637 {
638 *this = *this - __d;
639 return *this;
640 }
641
642 constexpr unsigned
643 c_encoding() const noexcept
644 { return _M_wd; }
645
646 constexpr unsigned
647 iso_encoding() const noexcept
648 { return _M_wd == 0u ? 7u : _M_wd; }
649
650 constexpr bool
651 ok() const noexcept
652 { return _M_wd <= 6; }
653
654 constexpr weekday_indexed
655 operator[](unsigned __index) const noexcept;
656
657 constexpr weekday_last
658 operator[](last_spec) const noexcept;
659
660 friend constexpr bool
661 operator==(const weekday& __x, const weekday& __y) noexcept
662 { return __x._M_wd == __y._M_wd; }
663
664 friend constexpr weekday
665 operator+(const weekday& __x, const days& __y) noexcept
666 {
667 auto __n = static_cast<long long>(__x._M_wd) + __y.count();
668 return weekday{__detail::__modulo(__n, 7)};
669 }
670
671 friend constexpr weekday
672 operator+(const days& __x, const weekday& __y) noexcept
673 { return __y + __x; }
674
675 friend constexpr weekday
676 operator-(const weekday& __x, const days& __y) noexcept
677 { return __x + -__y; }
678
679 friend constexpr days
680 operator-(const weekday& __x, const weekday& __y) noexcept
681 {
682 auto __n = static_cast<long long>(__x._M_wd) - __y._M_wd;
683 return days{__detail::__modulo(__n, 7)};
684 }
685
686 // TODO: operator<<, from_stream.
687 };
688
689 inline constexpr weekday Sunday{0};
690 inline constexpr weekday Monday{1};
691 inline constexpr weekday Tuesday{2};
692 inline constexpr weekday Wednesday{3};
693 inline constexpr weekday Thursday{4};
694 inline constexpr weekday Friday{5};
695 inline constexpr weekday Saturday{6};
696
697 // WEEKDAY_INDEXED
698
699 class weekday_indexed
700 {
701 private:
702 chrono::weekday _M_wd;
703 unsigned char _M_index;
704
705 public:
706 weekday_indexed() = default;
707
708 constexpr
709 weekday_indexed(const chrono::weekday& __wd, unsigned __index) noexcept
710 : _M_wd(__wd), _M_index(__index)
711 { }
712
713 constexpr chrono::weekday
714 weekday() const noexcept
715 { return _M_wd; }
716
717 constexpr unsigned
718 index() const noexcept
719 { return _M_index; };
720
721 constexpr bool
722 ok() const noexcept
723 { return _M_wd.ok() && 1 <= _M_index && _M_index <= 5; }
724
725 friend constexpr bool
726 operator==(const weekday_indexed& __x, const weekday_indexed& __y) noexcept
727 { return __x.weekday() == __y.weekday() && __x.index() == __y.index(); }
728
729 friend constexpr month_weekday
730 operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
731
732 friend constexpr month_weekday
733 operator/(int __m, const weekday_indexed& __wdi) noexcept;
734
735 friend constexpr month_weekday
736 operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
737
738 friend constexpr month_weekday
739 operator/(const weekday_indexed& __wdi, int __m) noexcept;
740
741 friend constexpr year_month_weekday
742 operator/(const year_month& __ym, const weekday_indexed& __wdi) noexcept;
743
744 // TODO: Implement operator<<.
745 };
746
747 constexpr weekday_indexed
748 weekday::operator[](unsigned __index) const noexcept
749 { return {*this, __index}; }
750
751 // WEEKDAY_LAST
752
753 class weekday_last
754 {
755 private:
756 chrono::weekday _M_wd;
757
758 public:
759 explicit constexpr
760 weekday_last(const chrono::weekday& __wd) noexcept
761 : _M_wd{__wd}
762 { }
763
764 constexpr chrono::weekday
765 weekday() const noexcept
766 { return _M_wd; }
767
768 constexpr bool
769 ok() const noexcept
770 { return _M_wd.ok(); }
771
772 friend constexpr bool
773 operator==(const weekday_last& __x, const weekday_last& __y) noexcept
774 { return __x.weekday() == __y.weekday(); }
775
776 friend constexpr month_weekday_last
777 operator/(int __m, const weekday_last& __wdl) noexcept;
778
779 friend constexpr month_weekday_last
780 operator/(const weekday_last& __wdl, int __m) noexcept;
781
782 friend constexpr year_month_weekday_last
783 operator/(const year_month& __ym, const weekday_last& __wdl) noexcept;
784
785 // TODO: Implement operator<<.
786 };
787
788 constexpr weekday_last
789 weekday::operator[](last_spec) const noexcept
790 { return weekday_last{*this}; }
791
792 // MONTH_DAY
793
794 class month_day
795 {
796 private:
797 chrono::month _M_m;
798 chrono::day _M_d;
799
800 public:
801 month_day() = default;
802
803 constexpr
804 month_day(const chrono::month& __m, const chrono::day& __d) noexcept
805 : _M_m{__m}, _M_d{__d}
806 { }
807
808 constexpr chrono::month
809 month() const noexcept
810 { return _M_m; }
811
812 constexpr chrono::day
813 day() const noexcept
814 { return _M_d; }
815
816 constexpr bool
817 ok() const noexcept
818 {
819 return _M_m.ok()
820 && 1u <= unsigned(_M_d)
821 && unsigned(_M_d) <= __detail::__days_per_month[unsigned(_M_m) - 1];
822 }
823
824 friend constexpr bool
825 operator==(const month_day& __x, const month_day& __y) noexcept
826 { return __x.month() == __y.month() && __x.day() == __y.day(); }
827
828 friend constexpr strong_ordering
829 operator<=>(const month_day& __x, const month_day& __y) noexcept
830 = default;
831
832 friend constexpr month_day
833 operator/(const chrono::month& __m, const chrono::day& __d) noexcept
834 { return {__m, __d}; }
835
836 friend constexpr month_day
837 operator/(const chrono::month& __m, int __d) noexcept
838 { return {__m, chrono::day(unsigned(__d))}; }
839
840 friend constexpr month_day
841 operator/(int __m, const chrono::day& __d) noexcept
842 { return {chrono::month(unsigned(__m)), __d}; }
843
844 friend constexpr month_day
845 operator/(const chrono::day& __d, const chrono::month& __m) noexcept
846 { return {__m, __d}; }
847
848 friend constexpr month_day
849 operator/(const chrono::day& __d, int __m) noexcept
850 { return {chrono::month(unsigned(__m)), __d}; }
851
852 friend constexpr year_month_day
853 operator/(int __y, const month_day& __md) noexcept;
854
855 friend constexpr year_month_day
856 operator/(const month_day& __md, int __y) noexcept;
857
858 // TODO: Implement operator<<, from_stream.
859 };
860
861 // MONTH_DAY_LAST
862
863 class month_day_last
864 {
865 private:
866 chrono::month _M_m;
867
868 public:
869 explicit constexpr
870 month_day_last(const chrono::month& __m) noexcept
871 : _M_m{__m}
872 { }
873
874 constexpr chrono::month
875 month() const noexcept
876 { return _M_m; }
877
878 constexpr bool
879 ok() const noexcept
880 { return _M_m.ok(); }
881
882 friend constexpr bool
883 operator==(const month_day_last& __x, const month_day_last& __y) noexcept
884 { return __x.month() == __y.month(); }
885
886 friend constexpr strong_ordering
887 operator<=>(const month_day_last& __x, const month_day_last& __y) noexcept
888 = default;
889
890 friend constexpr month_day_last
891 operator/(const chrono::month& __m, last_spec) noexcept
892 { return month_day_last{__m}; }
893
894 friend constexpr month_day_last
895 operator/(int __m, last_spec) noexcept
896 { return chrono::month(unsigned(__m)) / last; }
897
898 friend constexpr month_day_last
899 operator/(last_spec, const chrono::month& __m) noexcept
900 { return __m / last; }
901
902 friend constexpr month_day_last
903 operator/(last_spec, int __m) noexcept
904 { return __m / last; }
905
906 friend constexpr year_month_day_last
907 operator/(int __y, const month_day_last& __mdl) noexcept;
908
909 friend constexpr year_month_day_last
910 operator/(const month_day_last& __mdl, int __y) noexcept;
911
912 // TODO: Implement operator<<.
913 };
914
915 // MONTH_WEEKDAY
916
917 class month_weekday
918 {
919 private:
920 chrono::month _M_m;
921 chrono::weekday_indexed _M_wdi;
922
923 public:
924 constexpr
925 month_weekday(const chrono::month& __m,
926 const chrono::weekday_indexed& __wdi) noexcept
927 : _M_m{__m}, _M_wdi{__wdi}
928 { }
929
930 constexpr chrono::month
931 month() const noexcept
932 { return _M_m; }
933
934 constexpr chrono::weekday_indexed
935 weekday_indexed() const noexcept
936 { return _M_wdi; }
937
938 constexpr bool
939 ok() const noexcept
940 { return _M_m.ok() && _M_wdi.ok(); }
941
942 friend constexpr bool
943 operator==(const month_weekday& __x, const month_weekday& __y) noexcept
944 {
945 return __x.month() == __y.month()
946 && __x.weekday_indexed() == __y.weekday_indexed();
947 }
948
949 friend constexpr month_weekday
950 operator/(const chrono::month& __m,
951 const chrono::weekday_indexed& __wdi) noexcept
952 { return {__m, __wdi}; }
953
954 friend constexpr month_weekday
955 operator/(int __m, const chrono::weekday_indexed& __wdi) noexcept
956 { return chrono::month(unsigned(__m)) / __wdi; }
957
958 friend constexpr month_weekday
959 operator/(const chrono::weekday_indexed& __wdi,
960 const chrono::month& __m) noexcept
961 { return __m / __wdi; }
962
963 friend constexpr month_weekday
964 operator/(const chrono::weekday_indexed& __wdi, int __m) noexcept
965 { return __m / __wdi; }
966
967 friend constexpr year_month_weekday
968 operator/(int __y, const month_weekday& __mwd) noexcept;
969
970 friend constexpr year_month_weekday
971 operator/(const month_weekday& __mwd, int __y) noexcept;
972
973 // TODO: Implement operator<<.
974 };
975
976 // MONTH_WEEKDAY_LAST
977
978 class month_weekday_last
979 {
980 private:
981 chrono::month _M_m;
982 chrono::weekday_last _M_wdl;
983
984 public:
985 constexpr
986 month_weekday_last(const chrono::month& __m,
987 const chrono::weekday_last& __wdl) noexcept
988 :_M_m{__m}, _M_wdl{__wdl}
989 { }
990
991 constexpr chrono::month
992 month() const noexcept
993 { return _M_m; }
994
995 constexpr chrono::weekday_last
996 weekday_last() const noexcept
997 { return _M_wdl; }
998
999 constexpr bool
1000 ok() const noexcept
1001 { return _M_m.ok() && _M_wdl.ok(); }
1002
1003 friend constexpr bool
1004 operator==(const month_weekday_last& __x,
1005 const month_weekday_last& __y) noexcept
1006 {
1007 return __x.month() == __y.month()
1008 && __x.weekday_last() == __y.weekday_last();
1009 }
1010
1011 friend constexpr month_weekday_last
1012 operator/(const chrono::month& __m,
1013 const chrono::weekday_last& __wdl) noexcept
1014 { return {__m, __wdl}; }
1015
1016 friend constexpr month_weekday_last
1017 operator/(int __m, const chrono::weekday_last& __wdl) noexcept
1018 { return chrono::month(unsigned(__m)) / __wdl; }
1019
1020 friend constexpr month_weekday_last
1021 operator/(const chrono::weekday_last& __wdl,
1022 const chrono::month& __m) noexcept
1023 { return __m / __wdl; }
1024
1025 friend constexpr month_weekday_last
1026 operator/(const chrono::weekday_last& __wdl, int __m) noexcept
1027 { return chrono::month(unsigned(__m)) / __wdl; }
1028
1029 friend constexpr year_month_weekday_last
1030 operator/(int __y, const month_weekday_last& __mwdl) noexcept;
1031
1032 friend constexpr year_month_weekday_last
1033 operator/(const month_weekday_last& __mwdl, int __y) noexcept;
1034
1035 // TODO: Implement operator<<.
1036 };
1037
1038 // YEAR_MONTH
1039
1040 namespace __detail
1041 {
1042 // [time.cal.ym], [time.cal.ymd], etc constrain the 'months'-based
1043 // addition/subtraction operator overloads like so:
1044 //
1045 // Constraints: if the argument supplied by the caller for the months
1046 // parameter is convertible to years, its implicit conversion sequence
1047 // to years is worse than its implicit conversion sequence to months.
1048 //
1049 // We realize this constraint by templatizing the 'months'-based
1050 // overloads (using a dummy defaulted template parameter), so that
1051 // overload resolution doesn't select the 'months'-based overload unless
1052 // the implicit conversion sequence to 'months' is better than that to
1053 // 'years'.
1054 using __months_years_conversion_disambiguator = void;
1055 }
1056
1057 class year_month
1058 {
1059 private:
1060 chrono::year _M_y;
1061 chrono::month _M_m;
1062
1063 public:
1064 year_month() = default;
1065
1066 constexpr
1067 year_month(const chrono::year& __y, const chrono::month& __m) noexcept
1068 : _M_y{__y}, _M_m{__m}
1069 { }
1070
1071 constexpr chrono::year
1072 year() const noexcept
1073 { return _M_y; }
1074
1075 constexpr chrono::month
1076 month() const noexcept
1077 { return _M_m; }
1078
1079 template<typename = __detail::__months_years_conversion_disambiguator>
1080 constexpr year_month&
1081 operator+=(const months& __dm) noexcept
1082 {
1083 *this = *this + __dm;
1084 return *this;
1085 }
1086
1087 template<typename = __detail::__months_years_conversion_disambiguator>
1088 constexpr year_month&
1089 operator-=(const months& __dm) noexcept
1090 {
1091 *this = *this - __dm;
1092 return *this;
1093 }
1094
1095 constexpr year_month&
1096 operator+=(const years& __dy) noexcept
1097 {
1098 *this = *this + __dy;
1099 return *this;
1100 }
1101
1102 constexpr year_month&
1103 operator-=(const years& __dy) noexcept
1104 {
1105 *this = *this - __dy;
1106 return *this;
1107 }
1108
1109 constexpr bool
1110 ok() const noexcept
1111 { return _M_y.ok() && _M_m.ok(); }
1112
1113 friend constexpr bool
1114 operator==(const year_month& __x, const year_month& __y) noexcept
1115 { return __x.year() == __y.year() && __x.month() == __y.month(); }
1116
1117 friend constexpr strong_ordering
1118 operator<=>(const year_month& __x, const year_month& __y) noexcept
1119 = default;
1120
1121 template<typename = __detail::__months_years_conversion_disambiguator>
1122 friend constexpr year_month
1123 operator+(const year_month& __ym, const months& __dm) noexcept
1124 {
1125 // TODO: Optimize?
1126 auto __m = __ym.month() + __dm;
1127 auto __i = int(unsigned(__ym.month())) - 1 + __dm.count();
1128 auto __y = (__i < 0
1129 ? __ym.year() + years{(__i - 11) / 12}
1130 : __ym.year() + years{__i / 12});
1131 return __y / __m;
1132 }
1133
1134 template<typename = __detail::__months_years_conversion_disambiguator>
1135 friend constexpr year_month
1136 operator+(const months& __dm, const year_month& __ym) noexcept
1137 { return __ym + __dm; }
1138
1139 template<typename = __detail::__months_years_conversion_disambiguator>
1140 friend constexpr year_month
1141 operator-(const year_month& __ym, const months& __dm) noexcept
1142 { return __ym + -__dm; }
1143
1144 friend constexpr months
1145 operator-(const year_month& __x, const year_month& __y) noexcept
1146 {
1147 return (__x.year() - __y.year()
1148 + months{static_cast<int>(unsigned{__x.month()})
1149 - static_cast<int>(unsigned{__y.month()})});
1150 }
1151
1152 friend constexpr year_month
1153 operator+(const year_month& __ym, const years& __dy) noexcept
1154 { return (__ym.year() + __dy) / __ym.month(); }
1155
1156 friend constexpr year_month
1157 operator+(const years& __dy, const year_month& __ym) noexcept
1158 { return __ym + __dy; }
1159
1160 friend constexpr year_month
1161 operator-(const year_month& __ym, const years& __dy) noexcept
1162 { return __ym + -__dy; }
1163
1164 friend constexpr year_month
1165 operator/(const chrono::year& __y, const chrono::month& __m) noexcept
1166 { return {__y, __m}; }
1167
1168 friend constexpr year_month
1169 operator/(const chrono::year& __y, int __m) noexcept
1170 { return {__y, chrono::month(unsigned(__m))}; }
1171
1172 friend constexpr year_month_day
1173 operator/(const year_month& __ym, int __d) noexcept;
1174
1175 friend constexpr year_month_day_last
1176 operator/(const year_month& __ym, last_spec) noexcept;
1177
1178 // TODO: Implement operator<<, from_stream.
1179 };
1180
1181 // YEAR_MONTH_DAY
1182
1183 class year_month_day
1184 {
1185 private:
1186 chrono::year _M_y;
1187 chrono::month _M_m;
1188 chrono::day _M_d;
1189
1190 static constexpr year_month_day _S_from_days(const days& __dp) noexcept;
1191
1192 constexpr days _M_days_since_epoch() const noexcept;
1193
1194 public:
1195 year_month_day() = default;
1196
1197 constexpr
1198 year_month_day(const chrono::year& __y, const chrono::month& __m,
1199 const chrono::day& __d) noexcept
1200 : _M_y{__y}, _M_m{__m}, _M_d{__d}
1201 { }
1202
1203 constexpr
1204 year_month_day(const year_month_day_last& __ymdl) noexcept;
1205
1206 constexpr
1207 year_month_day(const sys_days& __dp) noexcept
1208 : year_month_day(_S_from_days(__dp.time_since_epoch()))
1209 { }
1210
1211 explicit constexpr
1212 year_month_day(const local_days& __dp) noexcept
1213 : year_month_day(sys_days{__dp.time_since_epoch()})
1214 { }
1215
1216 template<typename = __detail::__months_years_conversion_disambiguator>
1217 constexpr year_month_day&
1218 operator+=(const months& __m) noexcept
1219 {
1220 *this = *this + __m;
1221 return *this;
1222 }
1223
1224 template<typename = __detail::__months_years_conversion_disambiguator>
1225 constexpr year_month_day&
1226 operator-=(const months& __m) noexcept
1227 {
1228 *this = *this - __m;
1229 return *this;
1230 }
1231
1232 constexpr year_month_day&
1233 operator+=(const years& __y) noexcept
1234 {
1235 *this = *this + __y;
1236 return *this;
1237 }
1238
1239 constexpr year_month_day&
1240 operator-=(const years& __y) noexcept
1241 {
1242 *this = *this - __y;
1243 return *this;
1244 }
1245
1246 constexpr chrono::year
1247 year() const noexcept
1248 { return _M_y; }
1249
1250 constexpr chrono::month
1251 month() const noexcept
1252 { return _M_m; }
1253
1254 constexpr chrono::day
1255 day() const noexcept
1256 { return _M_d; }
1257
1258 constexpr
1259 operator sys_days() const noexcept
1260 { return sys_days{_M_days_since_epoch()}; }
1261
1262 explicit constexpr
1263 operator local_days() const noexcept
1264 { return local_days{sys_days{*this}.time_since_epoch()}; }
1265
1266 constexpr bool ok() const noexcept;
1267
1268 friend constexpr bool
1269 operator==(const year_month_day& __x, const year_month_day& __y) noexcept
1270 {
1271 return __x.year() == __y.year()
1272 && __x.month() == __y.month()
1273 && __x.day() == __y.day();
1274 }
1275
1276 friend constexpr strong_ordering
1277 operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept
1278 = default;
1279
1280 template<typename = __detail::__months_years_conversion_disambiguator>
1281 friend constexpr year_month_day
1282 operator+(const year_month_day& __ymd, const months& __dm) noexcept
1283 { return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); }
1284
1285 template<typename = __detail::__months_years_conversion_disambiguator>
1286 friend constexpr year_month_day
1287 operator+(const months& __dm, const year_month_day& __ymd) noexcept
1288 { return __ymd + __dm; }
1289
1290 friend constexpr year_month_day
1291 operator+(const year_month_day& __ymd, const years& __dy) noexcept
1292 { return (__ymd.year() + __dy) / __ymd.month() / __ymd.day(); }
1293
1294 friend constexpr year_month_day
1295 operator+(const years& __dy, const year_month_day& __ymd) noexcept
1296 { return __ymd + __dy; }
1297
1298 template<typename = __detail::__months_years_conversion_disambiguator>
1299 friend constexpr year_month_day
1300 operator-(const year_month_day& __ymd, const months& __dm) noexcept
1301 { return __ymd + -__dm; }
1302
1303 friend constexpr year_month_day
1304 operator-(const year_month_day& __ymd, const years& __dy) noexcept
1305 { return __ymd + -__dy; }
1306
1307 friend constexpr year_month_day
1308 operator/(const year_month& __ym, const chrono::day& __d) noexcept
1309 { return {__ym.year(), __ym.month(), __d}; }
1310
1311 friend constexpr year_month_day
1312 operator/(const year_month& __ym, int __d) noexcept
1313 { return __ym / chrono::day{unsigned(__d)}; }
1314
1315 friend constexpr year_month_day
1316 operator/(const chrono::year& __y, const month_day& __md) noexcept
1317 { return __y / __md.month() / __md.day(); }
1318
1319 friend constexpr year_month_day
1320 operator/(int __y, const month_day& __md) noexcept
1321 { return chrono::year{__y} / __md; }
1322
1323 friend constexpr year_month_day
1324 operator/(const month_day& __md, const chrono::year& __y) noexcept
1325 { return __y / __md; }
1326
1327 friend constexpr year_month_day
1328 operator/(const month_day& __md, int __y) noexcept
1329 { return chrono::year(__y) / __md; }
1330
1331 // TODO: Implement operator<<, from_stream.
1332 };
1333
1334 // Construct from days since 1970/01/01.
1335 // Proposition 6.3 of Neri and Schneider,
1336 // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1337 // https://arxiv.org/abs/2102.06959
1338 constexpr year_month_day
1339 year_month_day::_S_from_days(const days& __dp) noexcept
1340 {
1341 constexpr auto __z2 = static_cast<uint32_t>(-1468000);
1342 constexpr auto __r2_e3 = static_cast<uint32_t>(536895458);
1343
1344 const auto __r0 = static_cast<uint32_t>(__dp.count()) + __r2_e3;
1345
1346 const auto __n1 = 4 * __r0 + 3;
1347 const auto __q1 = __n1 / 146097;
1348 const auto __r1 = __n1 % 146097 / 4;
1349
1350 constexpr auto __p32 = static_cast<uint64_t>(1) << 32;
1351 const auto __n2 = 4 * __r1 + 3;
1352 const auto __u2 = static_cast<uint64_t>(2939745) * __n2;
1353 const auto __q2 = static_cast<uint32_t>(__u2 / __p32);
1354 const auto __r2 = static_cast<uint32_t>(__u2 % __p32) / 2939745 / 4;
1355
1356 constexpr auto __p16 = static_cast<uint32_t>(1) << 16;
1357 const auto __n3 = 2141 * __r2 + 197913;
1358 const auto __q3 = __n3 / __p16;
1359 const auto __r3 = __n3 % __p16 / 2141;
1360
1361 const auto __y0 = 100 * __q1 + __q2;
1362 const auto __m0 = __q3;
1363 const auto __d0 = __r3;
1364
1365 const auto __j = __r2 >= 306;
1366 const auto __y1 = __y0 + __j;
1367 const auto __m1 = __j ? __m0 - 12 : __m0;
1368 const auto __d1 = __d0 + 1;
1369
1370 return year_month_day{chrono::year{static_cast<int>(__y1 + __z2)},
1371 chrono::month{__m1}, chrono::day{__d1}};
1372 }
1373
1374 // Days since 1970/01/01.
1375 // Proposition 6.2 of Neri and Schneider,
1376 // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1377 // https://arxiv.org/abs/2102.06959
1378 constexpr days
1379 year_month_day::_M_days_since_epoch() const noexcept
1380 {
1381 auto constexpr __z2 = static_cast<uint32_t>(-1468000);
1382 auto constexpr __r2_e3 = static_cast<uint32_t>(536895458);
1383
1384 const auto __y1 = static_cast<uint32_t>(static_cast<int>(_M_y)) - __z2;
1385 const auto __m1 = static_cast<uint32_t>(static_cast<unsigned>(_M_m));
1386 const auto __d1 = static_cast<uint32_t>(static_cast<unsigned>(_M_d));
1387
1388 const auto __j = static_cast<uint32_t>(__m1 < 3);
1389 const auto __y0 = __y1 - __j;
1390 const auto __m0 = __j ? __m1 + 12 : __m1;
1391 const auto __d0 = __d1 - 1;
1392
1393 const auto __q1 = __y0 / 100;
1394 const auto __yc = 1461 * __y0 / 4 - __q1 + __q1 / 4;
1395 const auto __mc = (979 *__m0 - 2919) / 32;
1396 const auto __dc = __d0;
1397
1398 return days{static_cast<int32_t>(__yc + __mc + __dc - __r2_e3)};
1399 }
1400
1401 // YEAR_MONTH_DAY_LAST
1402
1403 class year_month_day_last
1404 {
1405 private:
1406 chrono::year _M_y;
1407 chrono::month_day_last _M_mdl;
1408
1409 public:
1410 constexpr
1411 year_month_day_last(const chrono::year& __y,
1412 const chrono::month_day_last& __mdl) noexcept
1413 : _M_y{__y}, _M_mdl{__mdl}
1414 { }
1415
1416 template<typename = __detail::__months_years_conversion_disambiguator>
1417 constexpr year_month_day_last&
1418 operator+=(const months& __m) noexcept
1419 {
1420 *this = *this + __m;
1421 return *this;
1422 }
1423
1424 template<typename = __detail::__months_years_conversion_disambiguator>
1425 constexpr year_month_day_last&
1426 operator-=(const months& __m) noexcept
1427 {
1428 *this = *this - __m;
1429 return *this;
1430 }
1431
1432 constexpr year_month_day_last&
1433 operator+=(const years& __y) noexcept
1434 {
1435 *this = *this + __y;
1436 return *this;
1437 }
1438
1439 constexpr year_month_day_last&
1440 operator-=(const years& __y) noexcept
1441 {
1442 *this = *this - __y;
1443 return *this;
1444 }
1445
1446 constexpr chrono::year
1447 year() const noexcept
1448 { return _M_y; }
1449
1450 constexpr chrono::month
1451 month() const noexcept
1452 { return _M_mdl.month(); }
1453
1454 constexpr chrono::month_day_last
1455 month_day_last() const noexcept
1456 { return _M_mdl; }
1457
1458 // Return A day representing the last day of this year, month pair.
1459 constexpr chrono::day
1460 day() const noexcept
1461 {
1462 const auto __m = static_cast<unsigned>(month());
1463
1464 // Excluding February, the last day of month __m is either 30 or 31 or,
1465 // in another words, it is 30 + b = 30 | b, where b is in {0, 1}.
1466
1467 // If __m in {1, 3, 4, 5, 6, 7}, then b is 1 if, and only if __m is odd.
1468 // Hence, b = __m & 1 = (__m ^ 0) & 1.
1469
1470 // If __m in {8, 9, 10, 11, 12}, then b is 1 if, and only if __m is even.
1471 // Hence, b = (__m ^ 1) & 1.
1472
1473 // Therefore, b = (__m ^ c) & 1, where c = 0, if __m < 8, or c = 1 if
1474 // __m >= 8, that is, c = __m >> 3.
1475
1476 // The above mathematically justifies this implementation whose
1477 // performance does not depend on look-up tables being on the L1 cache.
1478 return chrono::day{__m != 2 ? ((__m ^ (__m >> 3)) & 1) | 30
1479 : _M_y.is_leap() ? 29 : 28};
1480 }
1481
1482 constexpr
1483 operator sys_days() const noexcept
1484 { return sys_days{year() / month() / day()}; }
1485
1486 explicit constexpr
1487 operator local_days() const noexcept
1488 { return local_days{sys_days{*this}.time_since_epoch()}; }
1489
1490 constexpr bool
1491 ok() const noexcept
1492 { return _M_y.ok() && _M_mdl.ok(); }
1493
1494 friend constexpr bool
1495 operator==(const year_month_day_last& __x,
1496 const year_month_day_last& __y) noexcept
1497 {
1498 return __x.year() == __y.year()
1499 && __x.month_day_last() == __y.month_day_last();
1500 }
1501
1502 friend constexpr strong_ordering
1503 operator<=>(const year_month_day_last& __x,
1504 const year_month_day_last& __y) noexcept
1505 = default;
1506
1507 template<typename = __detail::__months_years_conversion_disambiguator>
1508 friend constexpr year_month_day_last
1509 operator+(const year_month_day_last& __ymdl,
1510 const months& __dm) noexcept
1511 { return (__ymdl.year() / __ymdl.month() + __dm) / last; }
1512
1513 template<typename = __detail::__months_years_conversion_disambiguator>
1514 friend constexpr year_month_day_last
1515 operator+(const months& __dm,
1516 const year_month_day_last& __ymdl) noexcept
1517 { return __ymdl + __dm; }
1518
1519 template<typename = __detail::__months_years_conversion_disambiguator>
1520 friend constexpr year_month_day_last
1521 operator-(const year_month_day_last& __ymdl,
1522 const months& __dm) noexcept
1523 { return __ymdl + -__dm; }
1524
1525 friend constexpr year_month_day_last
1526 operator+(const year_month_day_last& __ymdl,
1527 const years& __dy) noexcept
1528 { return {__ymdl.year() + __dy, __ymdl.month_day_last()}; }
1529
1530 friend constexpr year_month_day_last
1531 operator+(const years& __dy,
1532 const year_month_day_last& __ymdl) noexcept
1533 { return __ymdl + __dy; }
1534
1535 friend constexpr year_month_day_last
1536 operator-(const year_month_day_last& __ymdl,
1537 const years& __dy) noexcept
1538 { return __ymdl + -__dy; }
1539
1540 friend constexpr year_month_day_last
1541 operator/(const year_month& __ym, last_spec) noexcept
1542 { return {__ym.year(), chrono::month_day_last{__ym.month()}}; }
1543
1544 friend constexpr year_month_day_last
1545 operator/(const chrono::year& __y,
1546 const chrono::month_day_last& __mdl) noexcept
1547 { return {__y, __mdl}; }
1548
1549 friend constexpr year_month_day_last
1550 operator/(int __y, const chrono::month_day_last& __mdl) noexcept
1551 { return chrono::year(__y) / __mdl; }
1552
1553 friend constexpr year_month_day_last
1554 operator/(const chrono::month_day_last& __mdl,
1555 const chrono::year& __y) noexcept
1556 { return __y / __mdl; }
1557
1558 friend constexpr year_month_day_last
1559 operator/(const chrono::month_day_last& __mdl, int __y) noexcept
1560 { return chrono::year(__y) / __mdl; }
1561
1562 // TODO: Implement operator<<.
1563 };
1564
1565 // year_month_day ctor from year_month_day_last
1566 constexpr
1567 year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
1568 : _M_y{__ymdl.year()}, _M_m{__ymdl.month()}, _M_d{__ymdl.day()}
1569 { }
1570
1571 constexpr bool
1572 year_month_day::ok() const noexcept
1573 {
1574 if (!_M_y.ok() || !_M_m.ok())
1575 return false;
1576 return chrono::day{1} <= _M_d && _M_d <= (_M_y / _M_m / last).day();
1577 }
1578
1579 // YEAR_MONTH_WEEKDAY
1580
1581 class year_month_weekday
1582 {
1583 private:
1584 chrono::year _M_y;
1585 chrono::month _M_m;
1586 chrono::weekday_indexed _M_wdi;
1587
1588 static constexpr year_month_weekday
1589 _S_from_sys_days(const sys_days& __dp)
1590 {
1591 year_month_day __ymd{__dp};
1592 chrono::weekday __wd{__dp};
1593 auto __index = __wd[(unsigned{__ymd.day()} - 1) / 7 + 1];
1594 return {__ymd.year(), __ymd.month(), __index};
1595 }
1596
1597 public:
1598 year_month_weekday() = default;
1599
1600 constexpr
1601 year_month_weekday(const chrono::year& __y, const chrono::month& __m,
1602 const chrono::weekday_indexed& __wdi) noexcept
1603 : _M_y{__y}, _M_m{__m}, _M_wdi{__wdi}
1604 { }
1605
1606 constexpr
1607 year_month_weekday(const sys_days& __dp) noexcept
1608 : year_month_weekday{_S_from_sys_days(__dp)}
1609 { }
1610
1611 explicit constexpr
1612 year_month_weekday(const local_days& __dp) noexcept
1613 : year_month_weekday{sys_days{__dp.time_since_epoch()}}
1614 { }
1615
1616 template<typename = __detail::__months_years_conversion_disambiguator>
1617 constexpr year_month_weekday&
1618 operator+=(const months& __m) noexcept
1619 {
1620 *this = *this + __m;
1621 return *this;
1622 }
1623
1624 template<typename = __detail::__months_years_conversion_disambiguator>
1625 constexpr year_month_weekday&
1626 operator-=(const months& __m) noexcept
1627 {
1628 *this = *this - __m;
1629 return *this;
1630 }
1631
1632 constexpr year_month_weekday&
1633 operator+=(const years& __y) noexcept
1634 {
1635 *this = *this + __y;
1636 return *this;
1637 }
1638
1639 constexpr year_month_weekday&
1640 operator-=(const years& __y) noexcept
1641 {
1642 *this = *this - __y;
1643 return *this;
1644 }
1645
1646 constexpr chrono::year
1647 year() const noexcept
1648 { return _M_y; }
1649
1650 constexpr chrono::month
1651 month() const noexcept
1652 { return _M_m; }
1653
1654 constexpr chrono::weekday
1655 weekday() const noexcept
1656 { return _M_wdi.weekday(); }
1657
1658 constexpr unsigned
1659 index() const noexcept
1660 { return _M_wdi.index(); }
1661
1662 constexpr chrono::weekday_indexed
1663 weekday_indexed() const noexcept
1664 { return _M_wdi; }
1665
1666 constexpr
1667 operator sys_days() const noexcept
1668 {
1669 auto __d = sys_days{year() / month() / 1};
1670 return __d + (weekday() - chrono::weekday(__d)
1671 + days{(static_cast<int>(index())-1)*7});
1672 }
1673
1674 explicit constexpr
1675 operator local_days() const noexcept
1676 { return local_days{sys_days{*this}.time_since_epoch()}; }
1677
1678 constexpr bool
1679 ok() const noexcept
1680 {
1681 if (!_M_y.ok() || !_M_m.ok() || !_M_wdi.ok())
1682 return false;
1683 if (_M_wdi.index() <= 4)
1684 return true;
1685 days __d = (_M_wdi.weekday()
1686 - chrono::weekday{sys_days{_M_y / _M_m / 1}}
1687 + days((_M_wdi.index()-1)*7 + 1));
1688 __glibcxx_assert(__d.count() >= 1);
1689 return __d.count() <= unsigned{(_M_y / _M_m / last).day()};
1690 }
1691
1692 friend constexpr bool
1693 operator==(const year_month_weekday& __x,
1694 const year_month_weekday& __y) noexcept
1695 {
1696 return __x.year() == __y.year()
1697 && __x.month() == __y.month()
1698 && __x.weekday_indexed() == __y.weekday_indexed();
1699 }
1700
1701 template<typename = __detail::__months_years_conversion_disambiguator>
1702 friend constexpr year_month_weekday
1703 operator+(const year_month_weekday& __ymwd, const months& __dm) noexcept
1704 {
1705 return ((__ymwd.year() / __ymwd.month() + __dm)
1706 / __ymwd.weekday_indexed());
1707 }
1708
1709 template<typename = __detail::__months_years_conversion_disambiguator>
1710 friend constexpr year_month_weekday
1711 operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept
1712 { return __ymwd + __dm; }
1713
1714 friend constexpr year_month_weekday
1715 operator+(const year_month_weekday& __ymwd, const years& __dy) noexcept
1716 { return {__ymwd.year() + __dy, __ymwd.month(), __ymwd.weekday_indexed()}; }
1717
1718 friend constexpr year_month_weekday
1719 operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept
1720 { return __ymwd + __dy; }
1721
1722 template<typename = __detail::__months_years_conversion_disambiguator>
1723 friend constexpr year_month_weekday
1724 operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept
1725 { return __ymwd + -__dm; }
1726
1727 friend constexpr year_month_weekday
1728 operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept
1729 { return __ymwd + -__dy; }
1730
1731 friend constexpr year_month_weekday
1732 operator/(const year_month& __ym,
1733 const chrono::weekday_indexed& __wdi) noexcept
1734 { return {__ym.year(), __ym.month(), __wdi}; }
1735
1736 friend constexpr year_month_weekday
1737 operator/(const chrono::year& __y, const month_weekday& __mwd) noexcept
1738 { return {__y, __mwd.month(), __mwd.weekday_indexed()}; }
1739
1740 friend constexpr year_month_weekday
1741 operator/(int __y, const month_weekday& __mwd) noexcept
1742 { return chrono::year(__y) / __mwd; }
1743
1744 friend constexpr year_month_weekday
1745 operator/(const month_weekday& __mwd, const chrono::year& __y) noexcept
1746 { return __y / __mwd; }
1747
1748 friend constexpr year_month_weekday
1749 operator/(const month_weekday& __mwd, int __y) noexcept
1750 { return chrono::year(__y) / __mwd; }
1751
1752 // TODO: Implement operator<<.
1753 };
1754
1755 // YEAR_MONTH_WEEKDAY_LAST
1756
1757 class year_month_weekday_last
1758 {
1759 private:
1760 chrono::year _M_y;
1761 chrono::month _M_m;
1762 chrono::weekday_last _M_wdl;
1763
1764 public:
1765 constexpr
1766 year_month_weekday_last(const chrono::year& __y, const chrono::month& __m,
1767 const chrono::weekday_last& __wdl) noexcept
1768 : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl}
1769 { }
1770
1771 template<typename = __detail::__months_years_conversion_disambiguator>
1772 constexpr year_month_weekday_last&
1773 operator+=(const months& __m) noexcept
1774 {
1775 *this = *this + __m;
1776 return *this;
1777 }
1778
1779 template<typename = __detail::__months_years_conversion_disambiguator>
1780 constexpr year_month_weekday_last&
1781 operator-=(const months& __m) noexcept
1782 {
1783 *this = *this - __m;
1784 return *this;
1785 }
1786
1787 constexpr year_month_weekday_last&
1788 operator+=(const years& __y) noexcept
1789 {
1790 *this = *this + __y;
1791 return *this;
1792 }
1793
1794 constexpr year_month_weekday_last&
1795 operator-=(const years& __y) noexcept
1796 {
1797 *this = *this - __y;
1798 return *this;
1799 }
1800
1801 constexpr chrono::year
1802 year() const noexcept
1803 { return _M_y; }
1804
1805 constexpr chrono::month
1806 month() const noexcept
1807 { return _M_m; }
1808
1809 constexpr chrono::weekday
1810 weekday() const noexcept
1811 { return _M_wdl.weekday(); }
1812
1813 constexpr chrono::weekday_last
1814 weekday_last() const noexcept
1815 { return _M_wdl; }
1816
1817 constexpr
1818 operator sys_days() const noexcept
1819 {
1820 const auto __d = sys_days{_M_y / _M_m / last};
1821 return sys_days{(__d - (chrono::weekday{__d}
1822 - _M_wdl.weekday())).time_since_epoch()};
1823 }
1824
1825 explicit constexpr
1826 operator local_days() const noexcept
1827 { return local_days{sys_days{*this}.time_since_epoch()}; }
1828
1829 constexpr bool
1830 ok() const noexcept
1831 { return _M_y.ok() && _M_m.ok() && _M_wdl.ok(); }
1832
1833 friend constexpr bool
1834 operator==(const year_month_weekday_last& __x,
1835 const year_month_weekday_last& __y) noexcept
1836 {
1837 return __x.year() == __y.year()
1838 && __x.month() == __y.month()
1839 && __x.weekday_last() == __y.weekday_last();
1840 }
1841
1842 template<typename = __detail::__months_years_conversion_disambiguator>
1843 friend constexpr year_month_weekday_last
1844 operator+(const year_month_weekday_last& __ymwdl,
1845 const months& __dm) noexcept
1846 {
1847 return ((__ymwdl.year() / __ymwdl.month() + __dm)
1848 / __ymwdl.weekday_last());
1849 }
1850
1851 template<typename = __detail::__months_years_conversion_disambiguator>
1852 friend constexpr year_month_weekday_last
1853 operator+(const months& __dm,
1854 const year_month_weekday_last& __ymwdl) noexcept
1855 { return __ymwdl + __dm; }
1856
1857 friend constexpr year_month_weekday_last
1858 operator+(const year_month_weekday_last& __ymwdl,
1859 const years& __dy) noexcept
1860 { return {__ymwdl.year() + __dy, __ymwdl.month(), __ymwdl.weekday_last()}; }
1861
1862 friend constexpr year_month_weekday_last
1863 operator+(const years& __dy,
1864 const year_month_weekday_last& __ymwdl) noexcept
1865 { return __ymwdl + __dy; }
1866
1867 template<typename = __detail::__months_years_conversion_disambiguator>
1868 friend constexpr year_month_weekday_last
1869 operator-(const year_month_weekday_last& __ymwdl,
1870 const months& __dm) noexcept
1871 { return __ymwdl + -__dm; }
1872
1873 friend constexpr year_month_weekday_last
1874 operator-(const year_month_weekday_last& __ymwdl,
1875 const years& __dy) noexcept
1876 { return __ymwdl + -__dy; }
1877
1878 friend constexpr year_month_weekday_last
1879 operator/(const year_month& __ym,
1880 const chrono::weekday_last& __wdl) noexcept
1881 { return {__ym.year(), __ym.month(), __wdl}; }
1882
1883 friend constexpr year_month_weekday_last
1884 operator/(const chrono::year& __y,
1885 const chrono::month_weekday_last& __mwdl) noexcept
1886 { return {__y, __mwdl.month(), __mwdl.weekday_last()}; }
1887
1888 friend constexpr year_month_weekday_last
1889 operator/(int __y, const chrono::month_weekday_last& __mwdl) noexcept
1890 { return chrono::year(__y) / __mwdl; }
1891
1892 friend constexpr year_month_weekday_last
1893 operator/(const chrono::month_weekday_last& __mwdl,
1894 const chrono::year& __y) noexcept
1895 { return __y / __mwdl; }
1896
1897 friend constexpr year_month_weekday_last
1898 operator/(const chrono::month_weekday_last& __mwdl, int __y) noexcept
1899 { return chrono::year(__y) / __mwdl; }
1900
1901 // TODO: Implement operator<<.
1902 };
1903
1904 // HH_MM_SS
1905
1906 namespace __detail
1907 {
1908 consteval long long
1909 __pow10(unsigned __n)
1910 {
1911 long long __r = 1;
1912 while (__n-- > 0)
1913 __r *= 10;
1914 return __r;
1915 }
1916 }
1917
1918 template<typename _Duration>
1919 class hh_mm_ss
1920 {
1921 private:
1922 static constexpr int
1923 _S_fractional_width()
1924 {
1925 int __multiplicity_2 = 0;
1926 int __multiplicity_5 = 0;
1927 auto __den = _Duration::period::den;
1928 while ((__den % 2) == 0)
1929 {
1930 ++__multiplicity_2;
1931 __den /= 2;
1932 }
1933 while ((__den % 5) == 0)
1934 {
1935 ++__multiplicity_5;
1936 __den /= 5;
1937 }
1938 if (__den != 1)
1939 return 6;
1940
1941 int __width = (__multiplicity_2 > __multiplicity_5
1942 ? __multiplicity_2 : __multiplicity_5);
1943 if (__width > 18)
1944 __width = 18;
1945 return __width;
1946 }
1947
1948 constexpr
1949 hh_mm_ss(_Duration __d, bool __is_neg)
1950 : _M_is_neg(__is_neg),
1951 _M_h (duration_cast<chrono::hours>(__d)),
1952 _M_m (duration_cast<chrono::minutes>(__d - hours())),
1953 _M_s (duration_cast<chrono::seconds>(__d - hours() - minutes()))
1954 {
1955 auto __ss = __d - hours() - minutes() - seconds();
1956 if constexpr (treat_as_floating_point_v<typename precision::rep>)
1957 _M_ss = __ss;
1958 else
1959 _M_ss = duration_cast<precision>(__ss);
1960 }
1961
1962 static constexpr _Duration
1963 _S_abs(_Duration __d)
1964 {
1965 if constexpr (numeric_limits<typename _Duration::rep>::is_signed)
1966 return chrono::abs(__d);
1967 else
1968 return __d;
1969 }
1970
1971 public:
1972 static constexpr unsigned fractional_width = {_S_fractional_width()};
1973
1974 using precision
1975 = duration<common_type_t<typename _Duration::rep,
1976 chrono::seconds::rep>,
1977 ratio<1, __detail::__pow10(fractional_width)>>;
1978
1979 constexpr
1980 hh_mm_ss() noexcept
1981 : hh_mm_ss{_Duration::zero()}
1982 { }
1983
1984 constexpr explicit
1985 hh_mm_ss(_Duration __d)
1986 : hh_mm_ss(_S_abs(__d), __d < _Duration::zero())
1987 { }
1988
1989 constexpr bool
1990 is_negative() const noexcept
1991 { return _M_is_neg; }
1992
1993 constexpr chrono::hours
1994 hours() const noexcept
1995 { return _M_h; }
1996
1997 constexpr chrono::minutes
1998 minutes() const noexcept
1999 { return _M_m; }
2000
2001 constexpr chrono::seconds
2002 seconds() const noexcept
2003 { return _M_s; }
2004
2005 constexpr precision
2006 subseconds() const noexcept
2007 { return _M_ss; }
2008
2009 constexpr explicit
2010 operator precision() const noexcept
2011 { return to_duration(); }
2012
2013 constexpr precision
2014 to_duration() const noexcept
2015 {
2016 if (_M_is_neg)
2017 return -(_M_h + _M_m + _M_s + _M_ss);
2018 else
2019 return _M_h + _M_m + _M_s + _M_ss;
2020 }
2021
2022 // TODO: Implement operator<<.
2023
2024 private:
2025 bool _M_is_neg;
2026 chrono::hours _M_h;
2027 chrono::minutes _M_m;
2028 chrono::seconds _M_s;
2029 precision _M_ss;
2030 };
2031
2032 // 12/24 HOURS FUNCTIONS
2033
2034 constexpr bool
2035 is_am(const hours& __h) noexcept
2036 { return 0h <= __h && __h <= 11h; }
2037
2038 constexpr bool
2039 is_pm(const hours& __h) noexcept
2040 { return 12h <= __h && __h <= 23h; }
2041
2042 constexpr hours
2043 make12(const hours& __h) noexcept
2044 {
2045 if (__h == 0h)
2046 return 12h;
2047 else if (__h > 12h)
2048 return __h - 12h;
2049 return __h;
2050 }
2051
2052 constexpr hours
2053 make24(const hours& __h, bool __is_pm) noexcept
2054 {
2055 if (!__is_pm)
2056 {
2057 if (__h == 12h)
2058 return 0h;
2059 else
2060 return __h;
2061 }
2062 else
2063 {
2064 if (__h == 12h)
2065 return __h;
2066 else
2067 return __h + 12h;
2068 }
2069 }
2070 /// @} group chrono
2071#endif // C++20
2072 } // namespace chrono
2073
2074#if __cplusplus >= 202002L
2075 inline namespace literals
2076 {
2077 inline namespace chrono_literals
2078 {
2079 /// @addtogroup chrono
2080 /// @{
2081#pragma GCC diagnostic push
2082#pragma GCC diagnostic ignored "-Wliteral-suffix"
2083 /// Literal suffix for creating chrono::day objects.
2084 /// @since C++20
2085 constexpr chrono::day
2086 operator""d(unsigned long long __d) noexcept
2087 { return chrono::day{static_cast<unsigned>(__d)}; }
2088
2089 /// Literal suffix for creating chrono::year objects.
2090 /// @since C++20
2091 constexpr chrono::year
2092 operator""y(unsigned long long __y) noexcept
2093 { return chrono::year{static_cast<int>(__y)}; }
2094#pragma GCC diagnostic pop
2095 /// @}
2096 } // inline namespace chrono_literals
2097 } // inline namespace literals
2098
2099 namespace chrono
2100 {
2101 /// @addtogroup chrono
2102 /// @{
2103
2104 /// @cond undocumented
2105 namespace __detail
2106 {
2107 template<typename _Period>
2108 const char*
2109 __units_suffix_misc(char* __buf, size_t __n) noexcept
2110 {
2111 namespace __tc = std::__detail;
2112 char* __p = __buf;
2113 __p[0] = '[';
2114 unsigned __nlen = __tc::__to_chars_len((uintmax_t)_Period::num);
2115 __tc::__to_chars_10_impl(__p + 1, __nlen, (uintmax_t)_Period::num);
2116 __p += 1 + __nlen;
2117 if constexpr (_Period::den != 1)
2118 {
2119 __p[0] = '/';
2120 unsigned __dlen = __tc::__to_chars_len((uintmax_t)_Period::den);
2121 __tc::__to_chars_10_impl(__p + 1, __dlen, (uintmax_t)_Period::den);
2122 __p += 1 + __dlen;
2123 }
2124 __p[0] = ']';
2125 __p[1] = 's';
2126 __p[2] = '\0';
2127 return __buf;
2128 }
2129
2130 template<typename _Period, typename _CharT>
2131 auto
2132 __units_suffix(char* __buf, size_t __n) noexcept
2133 {
2134#define _GLIBCXX_UNITS_SUFFIX(period, suffix) \
2135 if constexpr (is_same_v<_Period, period>) \
2136 { \
2137 if constexpr (is_same_v<_CharT, wchar_t>) \
2138 return L##suffix; \
2139 else \
2140 return suffix; \
2141 } \
2142 else
2143
2144 _GLIBCXX_UNITS_SUFFIX(atto, "as")
2145 _GLIBCXX_UNITS_SUFFIX(femto, "fs")
2146 _GLIBCXX_UNITS_SUFFIX(pico, "ps")
2147 _GLIBCXX_UNITS_SUFFIX(nano, "ns")
2148 _GLIBCXX_UNITS_SUFFIX(micro, "\u00b5s")
2149 _GLIBCXX_UNITS_SUFFIX(milli, "ms")
2150 _GLIBCXX_UNITS_SUFFIX(centi, "cs")
2151 _GLIBCXX_UNITS_SUFFIX(deci, "ds")
2152 _GLIBCXX_UNITS_SUFFIX(ratio<1>, "s")
2153 _GLIBCXX_UNITS_SUFFIX(deca, "das")
2154 _GLIBCXX_UNITS_SUFFIX(hecto, "hs")
2155 _GLIBCXX_UNITS_SUFFIX(kilo, "ks")
2156 _GLIBCXX_UNITS_SUFFIX(mega, "Ms")
2157 _GLIBCXX_UNITS_SUFFIX(giga, "Gs")
2158 _GLIBCXX_UNITS_SUFFIX(tera, "Ts")
2159 _GLIBCXX_UNITS_SUFFIX(tera, "Ts")
2160 _GLIBCXX_UNITS_SUFFIX(peta, "Ps")
2161 _GLIBCXX_UNITS_SUFFIX(exa, "Es")
2162 _GLIBCXX_UNITS_SUFFIX(ratio<60>, "min")
2163 _GLIBCXX_UNITS_SUFFIX(ratio<3600>, "h")
2164 _GLIBCXX_UNITS_SUFFIX(ratio<86400>, "d")
2165#undef _GLIBCXX_UNITS_SUFFIX
2166 return __detail::__units_suffix_misc<_Period>(__buf, __n);
2167 }
2168 } // namespace __detail
2169 /// @endcond
2170
2171 template<typename _CharT, typename _Traits,
2172 typename _Rep, typename _Period>
2173 inline basic_ostream<_CharT, _Traits>&
2174 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2175 const duration<_Rep, _Period>& __d)
2176 {
2177 using period = typename _Period::type;
2178 char __buf[sizeof("[/]s") + 2 * numeric_limits<intmax_t>::digits10];
2179 std::basic_ostringstream<_CharT, _Traits> __s;
2180 __s.flags(__os.flags());
2181 __s.imbue(__os.getloc());
2182 __s.precision(__os.precision());
2183 __s << __d.count();
2184 __s << __detail::__units_suffix<period, _CharT>(__buf, sizeof(__buf));
2185 __os << std::move(__s).str();
2186 return __os;
2187 }
2188
2189 // TODO: from_stream for duration
2190
2191 /// @} group chrono
2192 } // namespace chrono
2193#endif // C++20
2194
2195_GLIBCXX_END_NAMESPACE_VERSION
2196} // namespace std
2197
2198#endif // C++11
2199
2200#endif //_GLIBCXX_CHRONO