Home | History | Annotate | Line # | Download | only in std
      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 
     45 namespace 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