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
2241