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