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