Remove m_nloops field from loop_versioning
[official-gcc.git] / libstdc++-v3 / include / std / chrono
blobb0aadf83b03f019af3b6db7fb2ce2a06e2baec27
1 // <chrono> -*- C++ -*-
3 // Copyright (C) 2008-2024 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.
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.
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.
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/>.
25 /** @file include/chrono
26  *  This is a Standard C++ Library header.
27  *  @ingroup chrono
28  */
30 #ifndef _GLIBCXX_CHRONO
31 #define _GLIBCXX_CHRONO 1
33 #pragma GCC system_header
35 #include <bits/requires_hosted.h> // for <ctime> and clocks
37 #if __cplusplus < 201103L
38 # include <bits/c++0x_warning.h>
39 #else
41 #include <bits/chrono.h>
43 #if __cplusplus >= 202002L
44 # include <bit>
45 # include <sstream>
46 # include <string>
47 # include <vector>
48 # include <bits/stl_algo.h> // upper_bound
49 # include <bits/shared_ptr.h>
50 # include <bits/unique_ptr.h>
51 #endif
53 #define __glibcxx_want_chrono
54 #define __glibcxx_want_chrono_udls
55 #include <bits/version.h>
57 namespace std _GLIBCXX_VISIBILITY(default)
59 _GLIBCXX_BEGIN_NAMESPACE_VERSION
61   /**
62    * @defgroup chrono Time
63    * @ingroup utilities
64    *
65    * Classes and functions for time.
66    *
67    * @since C++11
68    */
70   /** @namespace std::chrono
71    *  @brief ISO C++ 2011 namespace for date and time utilities
72    *  @ingroup chrono
73    */
74   namespace chrono
75   {
76 #if __cplusplus >= 202002L
77     /// @addtogroup chrono
78     /// @{
79     struct local_t { };
80     template<typename _Duration>
81       using local_time = time_point<local_t, _Duration>;
82     using local_seconds = local_time<seconds>;
83     using local_days = local_time<days>;
85     class utc_clock;
86     class tai_clock;
87     class gps_clock;
89     template<typename _Duration>
90       using utc_time = time_point<utc_clock, _Duration>;
91     using utc_seconds = utc_time<seconds>;
93     template<typename _Duration>
94       using tai_time = time_point<tai_clock, _Duration>;
95     using tai_seconds = tai_time<seconds>;
97     template<typename _Duration>
98       using gps_time = time_point<gps_clock, _Duration>;
99     using gps_seconds = gps_time<seconds>;
101     template<> struct is_clock<utc_clock> : true_type { };
102     template<> struct is_clock<tai_clock> : true_type { };
103     template<> struct is_clock<gps_clock> : true_type { };
105     template<> inline constexpr bool is_clock_v<utc_clock> = true;
106     template<> inline constexpr bool is_clock_v<tai_clock> = true;
107     template<> inline constexpr bool is_clock_v<gps_clock> = true;
109     struct leap_second_info
110     {
111       bool is_leap_second;
112       seconds elapsed;
113     };
115     template<typename _Duration>
116       leap_second_info
117       get_leap_second_info(const utc_time<_Duration>& __ut);
119     /** A clock that measures Universal Coordinated Time (UTC).
120      *
121      * The epoch is 1970-01-01 00:00:00.
122      *
123      * @since C++20
124      */
125     class utc_clock
126     {
127     public:
128       using rep                       = system_clock::rep;
129       using period                    = system_clock::period;
130       using duration                  = chrono::duration<rep, period>;
131       using time_point                = chrono::time_point<utc_clock>;
132       static constexpr bool is_steady = false;
134       [[nodiscard]]
135       static time_point
136       now()
137       { return from_sys(system_clock::now()); }
139       template<typename _Duration>
140         [[nodiscard]]
141         static sys_time<common_type_t<_Duration, seconds>>
142         to_sys(const utc_time<_Duration>& __t)
143         {
144           using _CDur = common_type_t<_Duration, seconds>;
145           const auto __li = chrono::get_leap_second_info(__t);
146           sys_time<_CDur> __s{__t.time_since_epoch() - __li.elapsed};
147           if (__li.is_leap_second)
148             __s = chrono::floor<seconds>(__s) + seconds{1} - _CDur{1};
149           return __s;
150         }
152       template<typename _Duration>
153         [[nodiscard]]
154         static utc_time<common_type_t<_Duration, seconds>>
155         from_sys(const sys_time<_Duration>& __t);
156     };
158     /** A clock that measures International Atomic Time.
159      *
160      * The epoch is 1958-01-01 00:00:00.
161      *
162      * @since C++20
163      */
164     class tai_clock
165     {
166     public:
167       using rep                       = system_clock::rep;
168       using period                    = system_clock::period;
169       using duration                  = chrono::duration<rep, period>;
170       using time_point                = chrono::time_point<tai_clock>;
171       static constexpr bool is_steady = false; // XXX true for CLOCK_TAI?
173       // TODO move into lib, use CLOCK_TAI on linux, add extension point.
174       [[nodiscard]]
175       static time_point
176       now()
177       { return from_utc(utc_clock::now()); }
179       template<typename _Duration>
180         [[nodiscard]]
181         static utc_time<common_type_t<_Duration, seconds>>
182         to_utc(const tai_time<_Duration>& __t)
183         {
184           using _CDur = common_type_t<_Duration, seconds>;
185           return utc_time<_CDur>{__t.time_since_epoch()} - 378691210s;
186         }
188       template<typename _Duration>
189         [[nodiscard]]
190         static tai_time<common_type_t<_Duration, seconds>>
191         from_utc(const utc_time<_Duration>& __t)
192         {
193           using _CDur = common_type_t<_Duration, seconds>;
194           return tai_time<_CDur>{__t.time_since_epoch()} + 378691210s;
195         }
196     };
198     /** A clock that measures GPS time.
199      *
200      * The epoch is 1980-01-06 00:00:00.
201      *
202      * @since C++20
203      */
204     class gps_clock
205     {
206     public:
207       using rep                       = system_clock::rep;
208       using period                    = system_clock::period;
209       using duration                  = chrono::duration<rep, period>;
210       using time_point                = chrono::time_point<gps_clock>;
211       static constexpr bool is_steady = false; // XXX
213       // TODO move into lib, add extension point.
214       [[nodiscard]]
215       static time_point
216       now()
217       { return from_utc(utc_clock::now()); }
219       template<typename _Duration>
220         [[nodiscard]]
221         static utc_time<common_type_t<_Duration, seconds>>
222         to_utc(const gps_time<_Duration>& __t)
223         {
224           using _CDur = common_type_t<_Duration, seconds>;
225           return utc_time<_CDur>{__t.time_since_epoch()} + 315964809s;
226         }
228       template<typename _Duration>
229         [[nodiscard]]
230         static gps_time<common_type_t<_Duration, seconds>>
231         from_utc(const utc_time<_Duration>& __t)
232         {
233           using _CDur = common_type_t<_Duration, seconds>;
234           return gps_time<_CDur>{__t.time_since_epoch()} - 315964809s;
235         }
236     };
239     template<typename _DestClock, typename _SourceClock>
240       struct clock_time_conversion
241       { };
243     // Identity conversions
245     template<typename _Clock>
246       struct clock_time_conversion<_Clock, _Clock>
247       {
248         template<typename _Duration>
249           time_point<_Clock, _Duration>
250           operator()(const time_point<_Clock, _Duration>& __t) const
251           { return __t; }
252       };
254     template<>
255       struct clock_time_conversion<system_clock, system_clock>
256       {
257         template<typename _Duration>
258           sys_time<_Duration>
259           operator()(const sys_time<_Duration>& __t) const
260           { return __t; }
261       };
263     template<>
264       struct clock_time_conversion<utc_clock, utc_clock>
265       {
266         template<typename _Duration>
267           utc_time<_Duration>
268           operator()(const utc_time<_Duration>& __t) const
269           { return __t; }
270       };
272     // Conversions between system_clock and utc_clock
274     template<>
275       struct clock_time_conversion<utc_clock, system_clock>
276       {
277         template<typename _Duration>
278           utc_time<common_type_t<_Duration, seconds>>
279           operator()(const sys_time<_Duration>& __t) const
280           { return utc_clock::from_sys(__t); }
281       };
283     template<>
284       struct clock_time_conversion<system_clock, utc_clock>
285       {
286         template<typename _Duration>
287           sys_time<common_type_t<_Duration, seconds>>
288           operator()(const utc_time<_Duration>& __t) const
289           { return utc_clock::to_sys(__t); }
290       };
292     template<typename _Tp, typename _Clock>
293       inline constexpr bool __is_time_point_for_v = false;
295     template<typename _Clock, typename _Duration>
296       inline constexpr bool
297        __is_time_point_for_v<time_point<_Clock, _Duration>, _Clock> = true;
299     // Conversions between system_clock and other clocks
301     template<typename _SourceClock>
302       struct clock_time_conversion<system_clock, _SourceClock>
303       {
304         template<typename _Duration, typename _Src = _SourceClock>
305           auto
306           operator()(const time_point<_SourceClock, _Duration>& __t) const
307           -> decltype(_Src::to_sys(__t))
308           {
309             using _Ret = decltype(_SourceClock::to_sys(__t));
310             static_assert(__is_time_point_for_v<_Ret, system_clock>);
311             return _SourceClock::to_sys(__t);
312           }
313       };
315     template<typename _DestClock>
316       struct clock_time_conversion<_DestClock, system_clock>
317       {
318         template<typename _Duration, typename _Dest = _DestClock>
319           auto
320           operator()(const sys_time<_Duration>& __t) const
321           -> decltype(_Dest::from_sys(__t))
322           {
323             using _Ret = decltype(_DestClock::from_sys(__t));
324             static_assert(__is_time_point_for_v<_Ret, _DestClock>);
325             return _DestClock::from_sys(__t);
326           }
327       };
329     // Conversions between utc_clock and other clocks
331     template<typename _SourceClock>
332       struct clock_time_conversion<utc_clock, _SourceClock>
333       {
334         template<typename _Duration, typename _Src = _SourceClock>
335           auto
336           operator()(const time_point<_SourceClock, _Duration>& __t) const
337           -> decltype(_Src::to_utc(__t))
338           {
339             using _Ret = decltype(_SourceClock::to_utc(__t));
340             static_assert(__is_time_point_for_v<_Ret, utc_clock>);
341             return _SourceClock::to_utc(__t);
342           }
343       };
345     template<typename _DestClock>
346       struct clock_time_conversion<_DestClock, utc_clock>
347       {
348         template<typename _Duration, typename _Dest = _DestClock>
349           auto
350           operator()(const utc_time<_Duration>& __t) const
351           -> decltype(_Dest::from_utc(__t))
352           {
353             using _Ret = decltype(_DestClock::from_utc(__t));
354             static_assert(__is_time_point_for_v<_Ret, _DestClock>);
355             return _DestClock::from_utc(__t);
356           }
357       };
359     /// @cond undocumented
360     namespace __detail
361     {
362       template<typename _DestClock, typename _SourceClock, typename _Duration>
363        concept __clock_convs
364           = requires (const time_point<_SourceClock, _Duration>& __t) {
365             clock_time_conversion<_DestClock, _SourceClock>{}(__t);
366           };
368       template<typename _DestClock, typename _SourceClock, typename _Duration>
369        concept __clock_convs_sys
370           = requires (const time_point<_SourceClock, _Duration>& __t) {
371             clock_time_conversion<_DestClock, system_clock>{}(
372               clock_time_conversion<system_clock, _SourceClock>{}(__t));
373           };
375       template<typename _DestClock, typename _SourceClock, typename _Duration>
376        concept __clock_convs_utc
377           = requires (const time_point<_SourceClock, _Duration>& __t) {
378             clock_time_conversion<_DestClock, utc_clock>{}(
379               clock_time_conversion<utc_clock, _SourceClock>{}(__t));
380           };
382       template<typename _DestClock, typename _SourceClock, typename _Duration>
383         concept __clock_convs_sys_utc
384           = requires (const time_point<_SourceClock, _Duration>& __t) {
385             clock_time_conversion<_DestClock, utc_clock>{}(
386               clock_time_conversion<utc_clock, system_clock>{}(
387                 clock_time_conversion<system_clock, _SourceClock>{}(__t)));
388           };
390       template<typename _DestClock, typename _SourceClock, typename _Duration>
391        concept __clock_convs_utc_sys
392           = requires (const time_point<_SourceClock, _Duration>& __t) {
393             clock_time_conversion<_DestClock, system_clock>{}(
394               clock_time_conversion<system_clock, utc_clock>{}(
395                 clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
396           };
398     } // namespace __detail
399     /// @endcond
401     /// Convert a time point to a different clock.
402     template<typename _DestClock, typename _SourceClock, typename _Duration>
403       [[nodiscard]]
404       inline auto
405       clock_cast(const time_point<_SourceClock, _Duration>& __t)
406       requires __detail::__clock_convs<_DestClock, _SourceClock, _Duration>
407         || __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>
408         || __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>
409         || __detail::__clock_convs_sys_utc<_DestClock, _SourceClock, _Duration>
410         || __detail::__clock_convs_utc_sys<_DestClock, _SourceClock, _Duration>
411       {
412        constexpr bool __direct
413          = __detail::__clock_convs<_DestClock, _SourceClock, _Duration>;
414        if constexpr (__direct)
415          {
416            return clock_time_conversion<_DestClock, _SourceClock>{}(__t);
417          }
418        else
419          {
420            constexpr bool __convert_via_sys_clock
421              = __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>;
422            constexpr bool __convert_via_utc_clock
423              = __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>;
424            if constexpr (__convert_via_sys_clock)
425              {
426                static_assert(!__convert_via_utc_clock,
427                  "clock_cast requires a unique best conversion, but "
428                  "conversion is possible via system_clock and also via"
429                  "utc_clock");
430                return clock_time_conversion<_DestClock, system_clock>{}(
431                         clock_time_conversion<system_clock, _SourceClock>{}(__t));
432              }
433            else if constexpr (__convert_via_utc_clock)
434              {
435                return clock_time_conversion<_DestClock, utc_clock>{}(
436                         clock_time_conversion<utc_clock, _SourceClock>{}(__t));
437              }
438            else
439              {
440                constexpr bool __convert_via_sys_and_utc_clocks
441                  = __detail::__clock_convs_sys_utc<_DestClock,
442                                                    _SourceClock,
443                                                    _Duration>;
445                if constexpr (__convert_via_sys_and_utc_clocks)
446                  {
447                    constexpr bool __convert_via_utc_and_sys_clocks
448                      = __detail::__clock_convs_utc_sys<_DestClock,
449                                                        _SourceClock,
450                                                        _Duration>;
451                    static_assert(!__convert_via_utc_and_sys_clocks,
452                      "clock_cast requires a unique best conversion, but "
453                      "conversion is possible via system_clock followed by "
454                      "utc_clock, and also via utc_clock followed by "
455                      "system_clock");
456                    return clock_time_conversion<_DestClock, utc_clock>{}(
457                             clock_time_conversion<utc_clock, system_clock>{}(
458                               clock_time_conversion<system_clock, _SourceClock>{}(__t)));
459                  }
460                else
461                  {
462                    return clock_time_conversion<_DestClock, system_clock>{}(
463                             clock_time_conversion<system_clock, utc_clock>{}(
464                               clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
465                  }
466              }
467          }
468       }
470     // CALENDRICAL TYPES
472     // CLASS DECLARATIONS
473     class day;
474     class month;
475     class year;
476     class weekday;
477     class weekday_indexed;
478     class weekday_last;
479     class month_day;
480     class month_day_last;
481     class month_weekday;
482     class month_weekday_last;
483     class year_month;
484     class year_month_day;
485     class year_month_day_last;
486     class year_month_weekday;
487     class year_month_weekday_last;
489     struct last_spec
490     {
491       explicit last_spec() = default;
493       friend constexpr month_day_last
494       operator/(int __m, last_spec) noexcept;
496       friend constexpr month_day_last
497       operator/(last_spec, int __m) noexcept;
498     };
500     inline constexpr last_spec last{};
502     namespace __detail
503     {
504       // Helper to __add_modulo and __sub_modulo.
505       template <unsigned __d, typename _Tp>
506       consteval auto
507       __modulo_offset()
508       {
509         using _Up = make_unsigned_t<_Tp>;
510         auto constexpr __a = _Up(-1) - _Up(255 + __d - 2);
511         auto constexpr __b = _Up(__d * (__a / __d) - 1);
512         // Notice: b <= a - 1 <= _Up(-1) - (255 + d - 1) and b % d = d - 1.
513         return _Up(-1) - __b; // >= 255 + d - 1
514       }
516       // Compute the remainder of the Euclidean division of __x + __y divided by
517       // __d without overflowing.  Typically, __x <= 255 + d - 1 is sum of
518       // weekday/month with a shift in [0, d - 1] and __y is a duration count.
519       template <unsigned __d, typename _Tp>
520       constexpr unsigned
521       __add_modulo(unsigned __x, _Tp __y)
522       {
523         using _Up = make_unsigned_t<_Tp>;
524         // For __y >= 0, _Up(__y) has the same mathematical value as __y and
525         // this function simply returns (__x + _Up(__y)) % d.  Typically, this
526         // doesn't overflow since the range of _Up contains many more positive
527         // values than _Tp's.  For __y < 0, _Up(__y) has a mathematical value in
528         // the upper-half range of _Up so that adding a positive value to it
529         // might overflow.  Moreover, most likely, _Up(__y) != __y mod d.  To
530         // fix both issues we subtract from _Up(__y) an __offset >=
531         // 255 + d - 1 to make room for the addition to __x and shift the modulo
532         // to the correct value.
533         auto const __offset = __y >= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
534         return (__x + _Up(__y) - __offset) % __d;
535       }
537       // Similar to __add_modulo but for __x - __y.
538       template <unsigned __d, typename _Tp>
539       constexpr unsigned
540       __sub_modulo(unsigned __x, _Tp __y)
541       {
542         using _Up = make_unsigned_t<_Tp>;
543         auto const __offset = __y <= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
544         return (__x - _Up(__y) - __offset) % __d;
545       }
547       inline constexpr unsigned __days_per_month[12]
548         = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
549     }
551     // DAY
553     class day
554     {
555     private:
556       unsigned char _M_d;
558     public:
559       day() = default;
561       explicit constexpr
562       day(unsigned __d) noexcept
563       : _M_d(__d)
564       { }
566       constexpr day&
567       operator++() noexcept
568       {
569         ++_M_d;
570         return *this;
571       }
573       constexpr day
574       operator++(int) noexcept
575       {
576         auto __ret = *this;
577         ++(*this);
578         return __ret;
579       }
581       constexpr day&
582       operator--() noexcept
583       {
584         --_M_d;
585         return *this;
586       }
588       constexpr day
589       operator--(int) noexcept
590       {
591         auto __ret = *this;
592         --(*this);
593         return __ret;
594       }
596       constexpr day&
597       operator+=(const days& __d) noexcept
598       {
599         *this = *this + __d;
600         return *this;
601       }
603       constexpr day&
604       operator-=(const days& __d) noexcept
605       {
606         *this = *this - __d;
607         return *this;
608       }
610       constexpr explicit
611       operator unsigned() const noexcept
612       { return _M_d; }
614       constexpr bool
615       ok() const noexcept
616       { return 1 <= _M_d && _M_d <= 31; }
618       friend constexpr bool
619       operator==(const day& __x, const day& __y) noexcept
620       { return unsigned{__x} == unsigned{__y}; }
622       friend constexpr strong_ordering
623       operator<=>(const day& __x, const day& __y) noexcept
624       { return unsigned{__x} <=> unsigned{__y}; }
626       friend constexpr day
627       operator+(const day& __x, const days& __y) noexcept
628       { return day(unsigned{__x} + __y.count()); }
630       friend constexpr day
631       operator+(const days& __x, const day& __y) noexcept
632       { return __y + __x; }
634       friend constexpr day
635       operator-(const day& __x, const days& __y) noexcept
636       { return __x + -__y; }
638       friend constexpr days
639       operator-(const day& __x, const day& __y) noexcept
640       { return days{int(unsigned{__x}) - int(unsigned{__y})}; }
642       friend constexpr month_day
643       operator/(const month& __m, const day& __d) noexcept;
645       friend constexpr month_day
646       operator/(int __m, const day& __d) noexcept;
648       friend constexpr month_day
649       operator/(const day& __d, const month& __m) noexcept;
651       friend constexpr month_day
652       operator/(const day& __d, int __m) noexcept;
654       friend constexpr year_month_day
655       operator/(const year_month& __ym, const day& __d) noexcept;
656     };
658     // MONTH
660     class month
661     {
662     private:
663       unsigned char _M_m;
665     public:
666       month() = default;
668       explicit constexpr
669       month(unsigned __m) noexcept
670       : _M_m(__m)
671       { }
673       constexpr month&
674       operator++() noexcept
675       {
676         *this += months{1};
677         return *this;
678       }
680       constexpr month
681       operator++(int) noexcept
682       {
683         auto __ret = *this;
684         ++(*this);
685         return __ret;
686       }
688       constexpr month&
689       operator--() noexcept
690       {
691         *this -= months{1};
692         return *this;
693       }
695       constexpr month
696       operator--(int) noexcept
697       {
698         auto __ret = *this;
699         --(*this);
700         return __ret;
701       }
703       constexpr month&
704       operator+=(const months& __m) noexcept
705       {
706         *this = *this + __m;
707         return *this;
708       }
710       constexpr month&
711       operator-=(const months& __m) noexcept
712       {
713         *this = *this - __m;
714         return *this;
715       }
717       explicit constexpr
718       operator unsigned() const noexcept
719       { return _M_m; }
721       constexpr bool
722       ok() const noexcept
723       { return 1 <= _M_m && _M_m <= 12; }
725       friend constexpr bool
726       operator==(const month& __x, const month& __y) noexcept
727       { return unsigned{__x} == unsigned{__y}; }
729       friend constexpr strong_ordering
730       operator<=>(const month& __x, const month& __y) noexcept
731       { return unsigned{__x} <=> unsigned{__y}; }
733       friend constexpr month
734       operator+(const month& __x, const months& __y) noexcept
735       {
736         // modulo(x + (y - 1), 12) = modulo(x + (y - 1) + 12, 12)
737         //                         = modulo((x + 11) + y    , 12)
738         return month{1 + __detail::__add_modulo<12>(
739           unsigned{__x} + 11, __y.count())};
740       }
742       friend constexpr month
743       operator+(const months& __x,  const month& __y) noexcept
744       { return __y + __x; }
746       friend constexpr month
747       operator-(const month& __x, const months& __y) noexcept
748       {
749         // modulo(x + (-y - 1), 12) = modulo(x + (-y - 1) + 12, 12)
750         //                          = modulo((x + 11) - y     , 12)
751         return month{1 + __detail::__sub_modulo<12>(
752           unsigned{__x} + 11, __y.count())};
753       }
755       friend constexpr months
756       operator-(const month& __x,  const month& __y) noexcept
757       {
758         const auto __dm = int(unsigned(__x)) - int(unsigned(__y));
759         return months{__dm < 0 ? 12 + __dm : __dm};
760       }
762       friend constexpr year_month
763       operator/(const year& __y, const month& __m) noexcept;
765       friend constexpr month_day
766       operator/(const month& __m, int __d) noexcept;
768       friend constexpr month_day_last
769       operator/(const month& __m, last_spec) noexcept;
771       friend constexpr month_day_last
772       operator/(last_spec, const month& __m) noexcept;
774       friend constexpr month_weekday
775       operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
777       friend constexpr month_weekday
778       operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
780       friend constexpr month_weekday_last
781       operator/(const month& __m, const weekday_last& __wdl) noexcept;
783       friend constexpr month_weekday_last
784       operator/(const weekday_last& __wdl, const month& __m) noexcept;
785     };
787     inline constexpr month January{1};
788     inline constexpr month February{2};
789     inline constexpr month March{3};
790     inline constexpr month April{4};
791     inline constexpr month May{5};
792     inline constexpr month June{6};
793     inline constexpr month July{7};
794     inline constexpr month August{8};
795     inline constexpr month September{9};
796     inline constexpr month October{10};
797     inline constexpr month November{11};
798     inline constexpr month December{12};
800     // YEAR
802     class year
803     {
804     private:
805       short _M_y;
807     public:
808       year() = default;
810       explicit constexpr
811       year(int __y) noexcept
812       : _M_y{static_cast<short>(__y)}
813       { }
815       static constexpr year
816       min() noexcept
817       { return year{-32767}; }
819       static constexpr year
820       max() noexcept
821       { return year{32767}; }
823       constexpr year&
824       operator++() noexcept
825       {
826         ++_M_y;
827         return *this;
828       }
830       constexpr year
831       operator++(int) noexcept
832       {
833         auto __ret = *this;
834         ++(*this);
835         return __ret;
836       }
838       constexpr year&
839       operator--() noexcept
840       {
841         --_M_y;
842         return *this;
843       }
845       constexpr year
846       operator--(int) noexcept
847       {
848         auto __ret = *this;
849         --(*this);
850         return __ret;
851       }
853       constexpr year&
854       operator+=(const years& __y) noexcept
855       {
856         *this = *this + __y;
857         return *this;
858       }
860       constexpr year&
861       operator-=(const years& __y) noexcept
862       {
863         *this = *this - __y;
864         return *this;
865       }
867       constexpr year
868       operator+() const noexcept
869       { return *this; }
871       constexpr year
872       operator-() const noexcept
873       { return year{-_M_y}; }
875       constexpr bool
876       is_leap() const noexcept
877       {
878         // Testing divisibility by 100 first gives better performance [1], i.e.,
879         //     return _M_y % 100 == 0 ? _M_y % 400 == 0 : _M_y % 16 == 0;
880         // Furthermore, if _M_y % 100 == 0, then _M_y % 400 == 0 is equivalent
881         // to _M_y % 16 == 0, so we can simplify it to
882         //     return _M_y % 100 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0.  // #1
883         // Similarly, we can replace 100 with 25 (which is good since
884         // _M_y % 25 == 0 requires one fewer instruction than _M_y % 100 == 0
885         // [2]):
886         //     return _M_y % 25 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0.  // #2
887         // Indeed, first assume _M_y % 4 != 0.  Then _M_y % 16 != 0 and hence,
888         // _M_y % 4 == 0 and _M_y % 16 == 0 are both false.  Therefore, #2
889         // returns false as it should (regardless of _M_y % 25.) Now assume
890         // _M_y % 4 == 0.  In this case, _M_y % 25 == 0 if, and only if,
891         // _M_y % 100 == 0, that is, #1 and #2 are equivalent.  Finally, #2 is
892         // equivalent to
893         //     return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0.
895         // References:
896         // [1] https://github.com/cassioneri/calendar
897         // [2] https://godbolt.org/z/55G8rn77e
898         // [3] https://gcc.gnu.org/pipermail/libstdc++/2021-June/052815.html
900         return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0;
901       }
903       explicit constexpr
904       operator int() const noexcept
905       { return _M_y; }
907       constexpr bool
908       ok() const noexcept
909       { return min()._M_y <= _M_y && _M_y <= max()._M_y; }
911       friend constexpr bool
912       operator==(const year& __x, const year& __y) noexcept
913       { return int{__x} == int{__y}; }
915       friend constexpr strong_ordering
916       operator<=>(const year& __x, const year& __y) noexcept
917       { return int{__x} <=> int{__y}; }
919       friend constexpr year
920       operator+(const year& __x, const years& __y) noexcept
921       { return year{int{__x} + static_cast<int>(__y.count())}; }
923       friend constexpr year
924       operator+(const years& __x, const year& __y) noexcept
925       { return __y + __x; }
927       friend constexpr year
928       operator-(const year& __x, const years& __y) noexcept
929       { return __x + -__y; }
931       friend constexpr years
932       operator-(const year& __x, const year& __y) noexcept
933       { return years{int{__x} - int{__y}}; }
935       friend constexpr year_month
936       operator/(const year& __y, int __m) noexcept;
938       friend constexpr year_month_day
939       operator/(const year& __y, const month_day& __md) noexcept;
941       friend constexpr year_month_day
942       operator/(const month_day& __md, const year& __y) noexcept;
944       friend constexpr year_month_day_last
945       operator/(const year& __y, const month_day_last& __mdl) noexcept;
947       friend constexpr year_month_day_last
948       operator/(const month_day_last& __mdl, const year& __y) noexcept;
950       friend constexpr year_month_weekday
951       operator/(const year& __y, const month_weekday& __mwd) noexcept;
953       friend constexpr year_month_weekday
954       operator/(const month_weekday& __mwd, const year& __y) noexcept;
956       friend constexpr year_month_weekday_last
957       operator/(const year& __y, const month_weekday_last& __mwdl) noexcept;
959       friend constexpr year_month_weekday_last
960       operator/(const month_weekday_last& __mwdl, const year& __y) noexcept;
961     };
963     // WEEKDAY
965     class weekday
966     {
967     private:
968       unsigned char _M_wd;
970       static constexpr weekday
971       _S_from_days(const days& __d)
972       {
973         return weekday{__detail::__add_modulo<7>(4, __d.count())};
974       }
976     public:
977       weekday() = default;
979       explicit constexpr
980       weekday(unsigned __wd) noexcept
981       : _M_wd(__wd == 7 ? 0 : __wd) // __wd % 7 ?
982       { }
984       constexpr
985       weekday(const sys_days& __dp) noexcept
986       : weekday{_S_from_days(__dp.time_since_epoch())}
987       { }
989       explicit constexpr
990       weekday(const local_days& __dp) noexcept
991       : weekday{sys_days{__dp.time_since_epoch()}}
992       { }
994       constexpr weekday&
995       operator++() noexcept
996       {
997         *this += days{1};
998         return *this;
999       }
1001       constexpr weekday
1002       operator++(int) noexcept
1003       {
1004         auto __ret = *this;
1005         ++(*this);
1006         return __ret;
1007       }
1009       constexpr weekday&
1010       operator--() noexcept
1011       {
1012         *this -= days{1};
1013         return *this;
1014       }
1016       constexpr weekday
1017       operator--(int) noexcept
1018       {
1019         auto __ret = *this;
1020         --(*this);
1021         return __ret;
1022       }
1024       constexpr weekday&
1025       operator+=(const days& __d) noexcept
1026       {
1027         *this = *this + __d;
1028         return *this;
1029       }
1031       constexpr weekday&
1032       operator-=(const days& __d) noexcept
1033       {
1034         *this = *this - __d;
1035         return *this;
1036       }
1038       constexpr unsigned
1039       c_encoding() const noexcept
1040       { return _M_wd; }
1042       constexpr unsigned
1043       iso_encoding() const noexcept
1044       { return _M_wd == 0u ? 7u : _M_wd; }
1046       constexpr bool
1047       ok() const noexcept
1048       { return _M_wd <= 6; }
1050       constexpr weekday_indexed
1051       operator[](unsigned __index) const noexcept;
1053       constexpr weekday_last
1054       operator[](last_spec) const noexcept;
1056       friend constexpr bool
1057       operator==(const weekday& __x, const weekday& __y) noexcept
1058       { return __x._M_wd == __y._M_wd; }
1060       friend constexpr weekday
1061       operator+(const weekday& __x, const days& __y) noexcept
1062       {
1063         return weekday{__detail::__add_modulo<7>(__x._M_wd, __y.count())};
1064       }
1066       friend constexpr weekday
1067       operator+(const days& __x, const weekday& __y) noexcept
1068       { return __y + __x; }
1070       friend constexpr weekday
1071       operator-(const weekday& __x, const days& __y) noexcept
1072       {
1073         return weekday{__detail::__sub_modulo<7>(__x._M_wd, __y.count())};
1074       }
1076       friend constexpr days
1077       operator-(const weekday& __x, const weekday& __y) noexcept
1078       {
1079         const auto __n = __x.c_encoding() - __y.c_encoding();
1080         return static_cast<int>(__n) >= 0 ? days{__n} : days{__n + 7};
1081       }
1082     };
1084     inline constexpr weekday Sunday{0};
1085     inline constexpr weekday Monday{1};
1086     inline constexpr weekday Tuesday{2};
1087     inline constexpr weekday Wednesday{3};
1088     inline constexpr weekday Thursday{4};
1089     inline constexpr weekday Friday{5};
1090     inline constexpr weekday Saturday{6};
1092     // WEEKDAY_INDEXED
1094     class weekday_indexed
1095     {
1096     private:
1097       chrono::weekday _M_wd;
1098       unsigned char _M_index;
1100     public:
1101       weekday_indexed() = default;
1103       constexpr
1104       weekday_indexed(const chrono::weekday& __wd, unsigned __index) noexcept
1105       : _M_wd(__wd), _M_index(__index)
1106       { }
1108       constexpr chrono::weekday
1109       weekday() const noexcept
1110       { return _M_wd; }
1112       constexpr unsigned
1113       index() const noexcept
1114       { return _M_index; };
1116       constexpr bool
1117       ok() const noexcept
1118       { return _M_wd.ok() && 1 <= _M_index && _M_index <= 5; }
1120       friend constexpr bool
1121       operator==(const weekday_indexed& __x, const weekday_indexed& __y) noexcept
1122       { return __x.weekday() == __y.weekday() && __x.index() == __y.index(); }
1124       friend constexpr month_weekday
1125       operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
1127       friend constexpr month_weekday
1128       operator/(int __m, const weekday_indexed& __wdi) noexcept;
1130       friend constexpr month_weekday
1131       operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
1133       friend constexpr month_weekday
1134       operator/(const weekday_indexed& __wdi, int __m) noexcept;
1136       friend constexpr year_month_weekday
1137       operator/(const year_month& __ym, const weekday_indexed& __wdi) noexcept;
1138     };
1140     constexpr weekday_indexed
1141     weekday::operator[](unsigned __index) const noexcept
1142     { return {*this, __index}; }
1144     // WEEKDAY_LAST
1146     class weekday_last
1147     {
1148     private:
1149       chrono::weekday _M_wd;
1151     public:
1152       explicit constexpr
1153       weekday_last(const chrono::weekday& __wd) noexcept
1154       : _M_wd{__wd}
1155       { }
1157       constexpr chrono::weekday
1158       weekday() const noexcept
1159       { return _M_wd; }
1161       constexpr bool
1162       ok() const noexcept
1163       { return _M_wd.ok(); }
1165       friend constexpr bool
1166       operator==(const weekday_last& __x, const weekday_last& __y) noexcept
1167       { return __x.weekday() == __y.weekday(); }
1169       friend constexpr month_weekday_last
1170       operator/(int __m, const weekday_last& __wdl) noexcept;
1172       friend constexpr month_weekday_last
1173       operator/(const weekday_last& __wdl, int __m) noexcept;
1175       friend constexpr year_month_weekday_last
1176       operator/(const year_month& __ym, const weekday_last& __wdl) noexcept;
1177     };
1179     constexpr weekday_last
1180     weekday::operator[](last_spec) const noexcept
1181     { return weekday_last{*this}; }
1183     // MONTH_DAY
1185     class month_day
1186     {
1187     private:
1188       chrono::month _M_m;
1189       chrono::day _M_d;
1191     public:
1192       month_day() = default;
1194       constexpr
1195       month_day(const chrono::month& __m, const chrono::day& __d) noexcept
1196       : _M_m{__m}, _M_d{__d}
1197       { }
1199       constexpr chrono::month
1200       month() const noexcept
1201       { return _M_m; }
1203       constexpr chrono::day
1204       day() const noexcept
1205       { return _M_d; }
1207       constexpr bool
1208       ok() const noexcept
1209       {
1210         return _M_m.ok()
1211           && 1u <= unsigned(_M_d)
1212           && unsigned(_M_d) <= __detail::__days_per_month[unsigned(_M_m) - 1];
1213       }
1215       friend constexpr bool
1216       operator==(const month_day& __x, const month_day& __y) noexcept
1217       { return __x.month() == __y.month() && __x.day() == __y.day(); }
1219       friend constexpr strong_ordering
1220       operator<=>(const month_day& __x, const month_day& __y) noexcept
1221         = default;
1223       friend constexpr month_day
1224       operator/(const chrono::month& __m, const chrono::day& __d) noexcept
1225       { return {__m, __d}; }
1227       friend constexpr month_day
1228       operator/(const chrono::month& __m, int __d) noexcept
1229       { return {__m, chrono::day(unsigned(__d))}; }
1231       friend constexpr month_day
1232       operator/(int __m, const chrono::day& __d) noexcept
1233       { return {chrono::month(unsigned(__m)), __d}; }
1235       friend constexpr month_day
1236       operator/(const chrono::day& __d, const chrono::month& __m) noexcept
1237       { return {__m, __d}; }
1239       friend constexpr month_day
1240       operator/(const chrono::day& __d, int __m) noexcept
1241       { return {chrono::month(unsigned(__m)), __d}; }
1243       friend constexpr year_month_day
1244       operator/(int __y, const month_day& __md) noexcept;
1246       friend constexpr year_month_day
1247       operator/(const month_day& __md, int __y) noexcept;
1248     };
1250     // MONTH_DAY_LAST
1252     class month_day_last
1253     {
1254     private:
1255       chrono::month _M_m;
1257     public:
1258       explicit constexpr
1259       month_day_last(const chrono::month& __m) noexcept
1260       : _M_m{__m}
1261       { }
1263       constexpr chrono::month
1264       month() const noexcept
1265       { return _M_m; }
1267       constexpr bool
1268       ok() const noexcept
1269       { return _M_m.ok(); }
1271       friend constexpr bool
1272       operator==(const month_day_last& __x, const month_day_last& __y) noexcept
1273       { return __x.month() == __y.month(); }
1275       friend constexpr strong_ordering
1276       operator<=>(const month_day_last& __x, const month_day_last& __y) noexcept
1277         = default;
1279       friend constexpr month_day_last
1280       operator/(const chrono::month& __m, last_spec) noexcept
1281       { return month_day_last{__m}; }
1283       friend constexpr month_day_last
1284       operator/(int __m, last_spec) noexcept
1285       { return chrono::month(unsigned(__m)) / last; }
1287       friend constexpr month_day_last
1288       operator/(last_spec, const chrono::month& __m) noexcept
1289       { return __m / last; }
1291       friend constexpr month_day_last
1292       operator/(last_spec, int __m) noexcept
1293       { return __m / last; }
1295       friend constexpr year_month_day_last
1296       operator/(int __y, const month_day_last& __mdl) noexcept;
1298       friend constexpr year_month_day_last
1299       operator/(const month_day_last& __mdl, int __y) noexcept;
1300     };
1302     // MONTH_WEEKDAY
1304     class month_weekday
1305     {
1306     private:
1307       chrono::month _M_m;
1308       chrono::weekday_indexed _M_wdi;
1310     public:
1311       constexpr
1312       month_weekday(const chrono::month& __m,
1313                     const chrono::weekday_indexed& __wdi) noexcept
1314       : _M_m{__m}, _M_wdi{__wdi}
1315       { }
1317       constexpr chrono::month
1318       month() const noexcept
1319       { return _M_m; }
1321       constexpr chrono::weekday_indexed
1322       weekday_indexed() const noexcept
1323       { return _M_wdi; }
1325       constexpr bool
1326       ok() const noexcept
1327       { return _M_m.ok() && _M_wdi.ok(); }
1329       friend constexpr bool
1330       operator==(const month_weekday& __x, const month_weekday& __y) noexcept
1331       {
1332         return __x.month() == __y.month()
1333           && __x.weekday_indexed() == __y.weekday_indexed();
1334       }
1336       friend constexpr month_weekday
1337       operator/(const chrono::month& __m,
1338                 const chrono::weekday_indexed& __wdi) noexcept
1339       { return {__m, __wdi}; }
1341       friend constexpr month_weekday
1342       operator/(int __m, const chrono::weekday_indexed& __wdi) noexcept
1343       { return chrono::month(unsigned(__m)) / __wdi; }
1345       friend constexpr month_weekday
1346       operator/(const chrono::weekday_indexed& __wdi,
1347                 const chrono::month& __m) noexcept
1348       { return __m / __wdi; }
1350       friend constexpr month_weekday
1351       operator/(const chrono::weekday_indexed& __wdi, int __m) noexcept
1352       { return __m / __wdi; }
1354       friend constexpr year_month_weekday
1355       operator/(int __y, const month_weekday& __mwd) noexcept;
1357       friend constexpr year_month_weekday
1358       operator/(const month_weekday& __mwd, int __y) noexcept;
1359     };
1361     // MONTH_WEEKDAY_LAST
1363     class month_weekday_last
1364     {
1365     private:
1366       chrono::month _M_m;
1367       chrono::weekday_last _M_wdl;
1369     public:
1370       constexpr
1371       month_weekday_last(const chrono::month& __m,
1372                          const chrono::weekday_last& __wdl) noexcept
1373       :_M_m{__m}, _M_wdl{__wdl}
1374       { }
1376       constexpr chrono::month
1377       month() const noexcept
1378       { return _M_m; }
1380       constexpr chrono::weekday_last
1381       weekday_last() const noexcept
1382       { return _M_wdl; }
1384       constexpr bool
1385       ok() const noexcept
1386       { return _M_m.ok() && _M_wdl.ok(); }
1388       friend constexpr bool
1389       operator==(const month_weekday_last& __x,
1390                  const month_weekday_last& __y) noexcept
1391       {
1392         return __x.month() == __y.month()
1393           && __x.weekday_last() == __y.weekday_last();
1394       }
1396       friend constexpr month_weekday_last
1397       operator/(const chrono::month& __m,
1398                 const chrono::weekday_last& __wdl) noexcept
1399       { return {__m, __wdl}; }
1401       friend constexpr month_weekday_last
1402       operator/(int __m, const chrono::weekday_last& __wdl) noexcept
1403       { return chrono::month(unsigned(__m)) / __wdl; }
1405       friend constexpr month_weekday_last
1406       operator/(const chrono::weekday_last& __wdl,
1407                 const chrono::month& __m) noexcept
1408       { return __m / __wdl; }
1410       friend constexpr month_weekday_last
1411       operator/(const chrono::weekday_last& __wdl, int __m) noexcept
1412       { return chrono::month(unsigned(__m)) / __wdl; }
1414       friend constexpr year_month_weekday_last
1415       operator/(int __y, const month_weekday_last& __mwdl) noexcept;
1417       friend constexpr year_month_weekday_last
1418       operator/(const month_weekday_last& __mwdl, int __y) noexcept;
1419     };
1421     // YEAR_MONTH
1423     namespace __detail
1424     {
1425       // [time.cal.ym], [time.cal.ymd], etc constrain the 'months'-based
1426       // addition/subtraction operator overloads like so:
1427       //
1428       //   Constraints: if the argument supplied by the caller for the months
1429       //   parameter is convertible to years, its implicit conversion sequence
1430       //   to years is worse than its implicit conversion sequence to months.
1431       //
1432       // We realize this constraint by templatizing the 'months'-based
1433       // overloads (using a dummy defaulted template parameter), so that
1434       // overload resolution doesn't select the 'months'-based overload unless
1435       // the implicit conversion sequence to 'months' is better than that to
1436       // 'years'.
1437       using __months_years_conversion_disambiguator = void;
1438     }
1440     class year_month
1441     {
1442     private:
1443       chrono::year _M_y;
1444       chrono::month _M_m;
1446     public:
1447       year_month() = default;
1449       constexpr
1450       year_month(const chrono::year& __y, const chrono::month& __m) noexcept
1451       : _M_y{__y}, _M_m{__m}
1452       { }
1454       constexpr chrono::year
1455       year() const noexcept
1456       { return _M_y; }
1458       constexpr chrono::month
1459       month() const noexcept
1460       { return _M_m; }
1462       template<typename = __detail::__months_years_conversion_disambiguator>
1463         constexpr year_month&
1464         operator+=(const months& __dm) noexcept
1465         {
1466           *this = *this + __dm;
1467           return *this;
1468         }
1470       template<typename = __detail::__months_years_conversion_disambiguator>
1471         constexpr year_month&
1472         operator-=(const months& __dm) noexcept
1473         {
1474           *this = *this - __dm;
1475           return *this;
1476         }
1478       constexpr year_month&
1479       operator+=(const years& __dy)  noexcept
1480       {
1481         *this = *this + __dy;
1482         return *this;
1483       }
1485       constexpr year_month&
1486       operator-=(const years& __dy)  noexcept
1487       {
1488         *this = *this - __dy;
1489         return *this;
1490       }
1492       constexpr bool
1493       ok() const noexcept
1494       { return _M_y.ok() && _M_m.ok(); }
1496       friend constexpr bool
1497       operator==(const year_month& __x, const year_month& __y) noexcept
1498       { return __x.year() == __y.year() && __x.month() == __y.month(); }
1500       friend constexpr strong_ordering
1501       operator<=>(const year_month& __x, const year_month& __y) noexcept
1502         = default;
1504       template<typename = __detail::__months_years_conversion_disambiguator>
1505         friend constexpr year_month
1506         operator+(const year_month& __ym, const months& __dm) noexcept
1507         {
1508           // TODO: Optimize?
1509           auto __m = __ym.month() + __dm;
1510           auto __i = int(unsigned(__ym.month())) - 1 + __dm.count();
1511           auto __y = (__i < 0
1512                       ? __ym.year() + years{(__i - 11) / 12}
1513                       : __ym.year() + years{__i / 12});
1514           return __y / __m;
1515         }
1517       template<typename = __detail::__months_years_conversion_disambiguator>
1518         friend constexpr year_month
1519         operator+(const months& __dm, const year_month& __ym) noexcept
1520         { return __ym + __dm; }
1522       template<typename = __detail::__months_years_conversion_disambiguator>
1523         friend constexpr year_month
1524         operator-(const year_month& __ym, const months& __dm) noexcept
1525         { return __ym + -__dm; }
1527       friend constexpr months
1528       operator-(const year_month& __x, const year_month& __y) noexcept
1529       {
1530         return (__x.year() - __y.year()
1531                 + months{static_cast<int>(unsigned{__x.month()})
1532                          - static_cast<int>(unsigned{__y.month()})});
1533       }
1535       friend constexpr year_month
1536       operator+(const year_month& __ym, const years& __dy) noexcept
1537       { return (__ym.year() + __dy) / __ym.month(); }
1539       friend constexpr year_month
1540       operator+(const years& __dy, const year_month& __ym) noexcept
1541       { return __ym + __dy; }
1543       friend constexpr year_month
1544       operator-(const year_month& __ym, const years& __dy) noexcept
1545       { return __ym + -__dy; }
1547       friend constexpr year_month
1548       operator/(const chrono::year& __y, const chrono::month& __m) noexcept
1549       { return {__y, __m}; }
1551       friend constexpr year_month
1552       operator/(const chrono::year& __y, int __m) noexcept
1553       { return {__y, chrono::month(unsigned(__m))}; }
1555       friend constexpr year_month_day
1556       operator/(const year_month& __ym, int __d) noexcept;
1558       friend constexpr year_month_day_last
1559       operator/(const year_month& __ym, last_spec) noexcept;
1560     };
1562     // YEAR_MONTH_DAY
1564     class year_month_day
1565     {
1566     private:
1567       chrono::year _M_y;
1568       chrono::month _M_m;
1569       chrono::day _M_d;
1571       static constexpr year_month_day _S_from_days(const days& __dp) noexcept;
1573       constexpr days _M_days_since_epoch() const noexcept;
1575     public:
1576       year_month_day() = default;
1578       constexpr
1579       year_month_day(const chrono::year& __y, const chrono::month& __m,
1580                      const chrono::day& __d) noexcept
1581       : _M_y{__y}, _M_m{__m}, _M_d{__d}
1582       { }
1584       constexpr
1585       year_month_day(const year_month_day_last& __ymdl) noexcept;
1587       constexpr
1588       year_month_day(const sys_days& __dp) noexcept
1589       : year_month_day(_S_from_days(__dp.time_since_epoch()))
1590       { }
1592       explicit constexpr
1593       year_month_day(const local_days& __dp) noexcept
1594       : year_month_day(sys_days{__dp.time_since_epoch()})
1595       { }
1597       template<typename = __detail::__months_years_conversion_disambiguator>
1598         constexpr year_month_day&
1599         operator+=(const months& __m) noexcept
1600         {
1601           *this = *this + __m;
1602           return *this;
1603         }
1605       template<typename = __detail::__months_years_conversion_disambiguator>
1606         constexpr year_month_day&
1607         operator-=(const months& __m) noexcept
1608         {
1609           *this = *this - __m;
1610           return *this;
1611         }
1613       constexpr year_month_day&
1614       operator+=(const years& __y) noexcept
1615       {
1616         *this = *this + __y;
1617         return *this;
1618       }
1620       constexpr year_month_day&
1621       operator-=(const years& __y) noexcept
1622       {
1623         *this = *this - __y;
1624         return *this;
1625       }
1627       constexpr chrono::year
1628       year() const noexcept
1629       { return _M_y; }
1631       constexpr chrono::month
1632       month() const noexcept
1633       { return _M_m; }
1635       constexpr chrono::day
1636       day() const noexcept
1637       { return _M_d; }
1639       constexpr
1640       operator sys_days() const noexcept
1641       { return sys_days{_M_days_since_epoch()}; }
1643       explicit constexpr
1644       operator local_days() const noexcept
1645       { return local_days{sys_days{*this}.time_since_epoch()}; }
1647       constexpr bool ok() const noexcept;
1649       friend constexpr bool
1650       operator==(const year_month_day& __x, const year_month_day& __y) noexcept
1651       {
1652         return __x.year() == __y.year()
1653           && __x.month() == __y.month()
1654           && __x.day() == __y.day();
1655       }
1657       friend constexpr strong_ordering
1658       operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept
1659         = default;
1661       template<typename = __detail::__months_years_conversion_disambiguator>
1662         friend constexpr year_month_day
1663         operator+(const year_month_day& __ymd, const months& __dm) noexcept
1664         { return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); }
1666       template<typename = __detail::__months_years_conversion_disambiguator>
1667         friend constexpr year_month_day
1668         operator+(const months& __dm, const year_month_day& __ymd) noexcept
1669         { return __ymd + __dm; }
1671       friend constexpr year_month_day
1672       operator+(const year_month_day& __ymd, const years& __dy) noexcept
1673       { return (__ymd.year() + __dy) / __ymd.month() / __ymd.day(); }
1675       friend constexpr year_month_day
1676       operator+(const years& __dy, const year_month_day& __ymd) noexcept
1677       { return __ymd + __dy; }
1679       template<typename = __detail::__months_years_conversion_disambiguator>
1680         friend constexpr year_month_day
1681         operator-(const year_month_day& __ymd, const months& __dm) noexcept
1682         { return __ymd + -__dm; }
1684       friend constexpr year_month_day
1685       operator-(const year_month_day& __ymd, const years& __dy) noexcept
1686       { return __ymd + -__dy; }
1688       friend constexpr year_month_day
1689       operator/(const year_month& __ym, const chrono::day& __d) noexcept
1690       { return {__ym.year(), __ym.month(), __d}; }
1692       friend constexpr year_month_day
1693       operator/(const year_month& __ym, int __d) noexcept
1694       { return __ym / chrono::day{unsigned(__d)}; }
1696       friend constexpr year_month_day
1697       operator/(const chrono::year& __y, const month_day& __md) noexcept
1698       { return __y / __md.month() / __md.day(); }
1700       friend constexpr year_month_day
1701       operator/(int __y, const month_day& __md) noexcept
1702       { return chrono::year{__y} / __md; }
1704       friend constexpr year_month_day
1705       operator/(const month_day& __md, const chrono::year& __y) noexcept
1706       { return __y / __md; }
1708       friend constexpr year_month_day
1709       operator/(const month_day& __md, int __y) noexcept
1710       { return chrono::year(__y) / __md; }
1711     };
1713     // Construct from days since 1970/01/01.
1714     // Proposition 6.3 of Neri and Schneider,
1715     // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1716     // https://arxiv.org/abs/2102.06959
1717     constexpr year_month_day
1718     year_month_day::_S_from_days(const days& __dp) noexcept
1719     {
1720       constexpr auto __z2    = static_cast<uint32_t>(-1468000);
1721       constexpr auto __r2_e3 = static_cast<uint32_t>(536895458);
1723       const auto __r0 = static_cast<uint32_t>(__dp.count()) + __r2_e3;
1725       const auto __n1 = 4 * __r0 + 3;
1726       const auto __q1 = __n1 / 146097;
1727       const auto __r1 = __n1 % 146097 / 4;
1729       constexpr auto __p32 = static_cast<uint64_t>(1) << 32;
1730       const auto __n2 = 4 * __r1 + 3;
1731       const auto __u2 = static_cast<uint64_t>(2939745) * __n2;
1732       const auto __q2 = static_cast<uint32_t>(__u2 / __p32);
1733       const auto __r2 = static_cast<uint32_t>(__u2 % __p32) / 2939745 / 4;
1735       constexpr auto __p16 = static_cast<uint32_t>(1) << 16;
1736       const auto __n3 = 2141 * __r2 + 197913;
1737       const auto __q3 = __n3 / __p16;
1738       const auto __r3 = __n3 % __p16 / 2141;
1740       const auto __y0 = 100 * __q1 + __q2;
1741       const auto __m0 = __q3;
1742       const auto __d0 = __r3;
1744       const auto __j  = __r2 >= 306;
1745       const auto __y1 = __y0 + __j;
1746       const auto __m1 = __j ? __m0 - 12 : __m0;
1747       const auto __d1 = __d0 + 1;
1749       return year_month_day{chrono::year{static_cast<int>(__y1 + __z2)},
1750                             chrono::month{__m1}, chrono::day{__d1}};
1751     }
1753     // Days since 1970/01/01.
1754     // Proposition 6.2 of Neri and Schneider,
1755     // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1756     // https://arxiv.org/abs/2102.06959
1757     constexpr days
1758     year_month_day::_M_days_since_epoch() const noexcept
1759     {
1760       auto constexpr __z2    = static_cast<uint32_t>(-1468000);
1761       auto constexpr __r2_e3 = static_cast<uint32_t>(536895458);
1763       const auto __y1 = static_cast<uint32_t>(static_cast<int>(_M_y)) - __z2;
1764       const auto __m1 = static_cast<uint32_t>(static_cast<unsigned>(_M_m));
1765       const auto __d1 = static_cast<uint32_t>(static_cast<unsigned>(_M_d));
1767       const auto __j  = static_cast<uint32_t>(__m1 < 3);
1768       const auto __y0 = __y1 - __j;
1769       const auto __m0 = __j ? __m1 + 12 : __m1;
1770       const auto __d0 = __d1 - 1;
1772       const auto __q1 = __y0 / 100;
1773       const auto __yc = 1461 * __y0 / 4 - __q1 + __q1 / 4;
1774       const auto __mc = (979 *__m0 - 2919) / 32;
1775       const auto __dc = __d0;
1777       return days{static_cast<int32_t>(__yc + __mc + __dc - __r2_e3)};
1778     }
1780     // YEAR_MONTH_DAY_LAST
1782     class year_month_day_last
1783     {
1784     private:
1785       chrono::year _M_y;
1786       chrono::month_day_last _M_mdl;
1788     public:
1789       constexpr
1790       year_month_day_last(const chrono::year& __y,
1791                           const chrono::month_day_last& __mdl) noexcept
1792       : _M_y{__y}, _M_mdl{__mdl}
1793       { }
1795       template<typename = __detail::__months_years_conversion_disambiguator>
1796         constexpr year_month_day_last&
1797         operator+=(const months& __m) noexcept
1798         {
1799           *this = *this + __m;
1800           return *this;
1801         }
1803       template<typename = __detail::__months_years_conversion_disambiguator>
1804         constexpr year_month_day_last&
1805         operator-=(const months& __m) noexcept
1806         {
1807           *this = *this - __m;
1808           return *this;
1809         }
1811       constexpr year_month_day_last&
1812       operator+=(const years& __y)  noexcept
1813       {
1814         *this = *this + __y;
1815         return *this;
1816       }
1818       constexpr year_month_day_last&
1819       operator-=(const years& __y)  noexcept
1820       {
1821         *this = *this - __y;
1822         return *this;
1823       }
1825       constexpr chrono::year
1826       year() const noexcept
1827       { return _M_y; }
1829       constexpr chrono::month
1830       month() const noexcept
1831       { return _M_mdl.month(); }
1833       constexpr chrono::month_day_last
1834       month_day_last() const noexcept
1835       { return _M_mdl; }
1837       // Return A day representing the last day of this year, month pair.
1838       constexpr chrono::day
1839       day() const noexcept
1840       {
1841         const auto __m = static_cast<unsigned>(month());
1843         // The result is unspecified if __m < 1 or __m > 12.  Hence, assume
1844         // 1 <= __m <= 12.  For __m != 2, day() == 30 or day() == 31 or, in
1845         // other words, day () == 30 | b, where b is in {0, 1}.
1847         // If __m in {1, 3, 4, 5, 6, 7}, then b is 1 if, and only if, __m is
1848         // odd.  Hence, b = __m & 1 = (__m ^ 0) & 1.
1850         // If __m in {8, 9, 10, 11, 12}, then b is 1 if, and only if, __m is
1851         // even.  Hence, b = (__m ^ 1) & 1.
1853         // Therefore, b = (__m ^ c) & 1, where c = 0, if __m < 8, or c = 1 if
1854         // __m >= 8, that is, c = __m >> 3.
1856         // Since 30 = (11110)_2 and __m <= 31 = (11111)_2, the "& 1" in b's
1857         // calculation is unnecessary.
1859         // The performance of this implementation does not depend on look-up
1860         // tables being on the L1 cache.
1861         return chrono::day{__m != 2 ? (__m ^ (__m >> 3)) | 30
1862           : _M_y.is_leap() ? 29 : 28};
1863       }
1865       constexpr
1866       operator sys_days() const noexcept
1867       { return sys_days{year() / month() / day()}; }
1869       explicit constexpr
1870       operator local_days() const noexcept
1871       { return local_days{sys_days{*this}.time_since_epoch()}; }
1873       constexpr bool
1874       ok() const noexcept
1875       { return _M_y.ok() && _M_mdl.ok(); }
1877       friend constexpr bool
1878       operator==(const year_month_day_last& __x,
1879                  const year_month_day_last& __y) noexcept
1880       {
1881         return __x.year() == __y.year()
1882           && __x.month_day_last() == __y.month_day_last();
1883       }
1885       friend constexpr strong_ordering
1886       operator<=>(const year_month_day_last& __x,
1887                   const year_month_day_last& __y) noexcept
1888         = default;
1890       template<typename = __detail::__months_years_conversion_disambiguator>
1891         friend constexpr year_month_day_last
1892         operator+(const year_month_day_last& __ymdl,
1893                   const months& __dm) noexcept
1894         { return (__ymdl.year() / __ymdl.month() + __dm) / last; }
1896       template<typename = __detail::__months_years_conversion_disambiguator>
1897         friend constexpr year_month_day_last
1898         operator+(const months& __dm,
1899                   const year_month_day_last& __ymdl) noexcept
1900         { return __ymdl + __dm; }
1902       template<typename = __detail::__months_years_conversion_disambiguator>
1903         friend constexpr year_month_day_last
1904         operator-(const year_month_day_last& __ymdl,
1905                   const months& __dm) noexcept
1906         { return __ymdl + -__dm; }
1908       friend constexpr year_month_day_last
1909       operator+(const year_month_day_last& __ymdl,
1910                 const years& __dy) noexcept
1911       { return {__ymdl.year() + __dy, __ymdl.month_day_last()}; }
1913       friend constexpr year_month_day_last
1914       operator+(const years& __dy,
1915                 const year_month_day_last& __ymdl) noexcept
1916       { return __ymdl + __dy; }
1918       friend constexpr year_month_day_last
1919       operator-(const year_month_day_last& __ymdl,
1920                 const years& __dy) noexcept
1921       { return __ymdl + -__dy; }
1923       friend constexpr year_month_day_last
1924       operator/(const year_month& __ym, last_spec) noexcept
1925       { return {__ym.year(), chrono::month_day_last{__ym.month()}}; }
1927       friend constexpr year_month_day_last
1928       operator/(const chrono::year& __y,
1929                 const chrono::month_day_last& __mdl) noexcept
1930       { return {__y, __mdl}; }
1932       friend constexpr year_month_day_last
1933       operator/(int __y, const chrono::month_day_last& __mdl) noexcept
1934       { return chrono::year(__y) / __mdl; }
1936       friend constexpr year_month_day_last
1937       operator/(const chrono::month_day_last& __mdl,
1938                 const chrono::year& __y) noexcept
1939       { return __y / __mdl; }
1941       friend constexpr year_month_day_last
1942       operator/(const chrono::month_day_last& __mdl, int __y) noexcept
1943       { return chrono::year(__y) / __mdl; }
1944     };
1946     // year_month_day ctor from year_month_day_last
1947     constexpr
1948     year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
1949     : _M_y{__ymdl.year()}, _M_m{__ymdl.month()}, _M_d{__ymdl.day()}
1950     { }
1952     constexpr bool
1953     year_month_day::ok() const noexcept
1954     {
1955       if (!_M_y.ok() || !_M_m.ok())
1956         return false;
1957       return chrono::day{1} <= _M_d && _M_d <= (_M_y / _M_m / last).day();
1958     }
1960     // YEAR_MONTH_WEEKDAY
1962     class year_month_weekday
1963     {
1964     private:
1965       chrono::year _M_y;
1966       chrono::month _M_m;
1967       chrono::weekday_indexed _M_wdi;
1969       static constexpr year_month_weekday
1970       _S_from_sys_days(const sys_days& __dp)
1971       {
1972         year_month_day __ymd{__dp};
1973         chrono::weekday __wd{__dp};
1974         auto __index = __wd[(unsigned{__ymd.day()} - 1) / 7 + 1];
1975         return {__ymd.year(), __ymd.month(), __index};
1976       }
1978     public:
1979       year_month_weekday() = default;
1981       constexpr
1982       year_month_weekday(const chrono::year& __y, const chrono::month& __m,
1983                          const chrono::weekday_indexed& __wdi) noexcept
1984       : _M_y{__y}, _M_m{__m}, _M_wdi{__wdi}
1985       { }
1987       constexpr
1988       year_month_weekday(const sys_days& __dp) noexcept
1989       : year_month_weekday{_S_from_sys_days(__dp)}
1990       { }
1992       explicit constexpr
1993       year_month_weekday(const local_days& __dp) noexcept
1994       : year_month_weekday{sys_days{__dp.time_since_epoch()}}
1995       { }
1997       template<typename = __detail::__months_years_conversion_disambiguator>
1998         constexpr year_month_weekday&
1999         operator+=(const months& __m) noexcept
2000         {
2001           *this = *this + __m;
2002           return *this;
2003         }
2005       template<typename = __detail::__months_years_conversion_disambiguator>
2006         constexpr year_month_weekday&
2007         operator-=(const months& __m) noexcept
2008         {
2009           *this = *this - __m;
2010           return *this;
2011         }
2013       constexpr year_month_weekday&
2014       operator+=(const years& __y) noexcept
2015       {
2016         *this = *this + __y;
2017         return *this;
2018       }
2020       constexpr year_month_weekday&
2021       operator-=(const years& __y) noexcept
2022       {
2023         *this = *this - __y;
2024         return *this;
2025       }
2027       constexpr chrono::year
2028       year() const noexcept
2029       { return _M_y; }
2031       constexpr chrono::month
2032       month() const noexcept
2033       { return _M_m; }
2035       constexpr chrono::weekday
2036       weekday() const noexcept
2037       { return _M_wdi.weekday(); }
2039       constexpr unsigned
2040       index() const noexcept
2041       { return _M_wdi.index(); }
2043       constexpr chrono::weekday_indexed
2044       weekday_indexed() const noexcept
2045       { return _M_wdi; }
2047       constexpr
2048       operator sys_days() const noexcept
2049       {
2050         auto __d = sys_days{year() / month() / 1};
2051         return __d + (weekday() - chrono::weekday(__d)
2052                       + days{(static_cast<int>(index())-1)*7});
2053       }
2055       explicit constexpr
2056       operator local_days() const noexcept
2057       { return local_days{sys_days{*this}.time_since_epoch()}; }
2059       constexpr bool
2060       ok() const noexcept
2061       {
2062         if (!_M_y.ok() || !_M_m.ok() || !_M_wdi.ok())
2063           return false;
2064         if (_M_wdi.index() <= 4)
2065           return true;
2066         days __d = (_M_wdi.weekday()
2067                     - chrono::weekday{sys_days{_M_y / _M_m / 1}}
2068                     + days((_M_wdi.index()-1)*7 + 1));
2069         __glibcxx_assert(__d.count() >= 1);
2070         return (unsigned)__d.count() <= (unsigned)(_M_y / _M_m / last).day();
2071       }
2073       friend constexpr bool
2074       operator==(const year_month_weekday& __x,
2075                  const year_month_weekday& __y) noexcept
2076       {
2077         return __x.year() == __y.year()
2078           && __x.month() == __y.month()
2079           && __x.weekday_indexed() == __y.weekday_indexed();
2080       }
2082       template<typename = __detail::__months_years_conversion_disambiguator>
2083         friend constexpr year_month_weekday
2084         operator+(const year_month_weekday& __ymwd, const months& __dm) noexcept
2085         {
2086           return ((__ymwd.year() / __ymwd.month() + __dm)
2087                   / __ymwd.weekday_indexed());
2088         }
2090       template<typename = __detail::__months_years_conversion_disambiguator>
2091         friend constexpr year_month_weekday
2092         operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept
2093         { return __ymwd + __dm; }
2095       friend constexpr year_month_weekday
2096       operator+(const year_month_weekday& __ymwd, const years& __dy) noexcept
2097       { return {__ymwd.year() + __dy, __ymwd.month(), __ymwd.weekday_indexed()}; }
2099       friend constexpr year_month_weekday
2100       operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept
2101       { return __ymwd + __dy; }
2103       template<typename = __detail::__months_years_conversion_disambiguator>
2104         friend constexpr year_month_weekday
2105         operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept
2106         { return __ymwd + -__dm; }
2108       friend constexpr year_month_weekday
2109       operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept
2110       { return __ymwd + -__dy; }
2112       friend constexpr year_month_weekday
2113       operator/(const year_month& __ym,
2114                 const chrono::weekday_indexed& __wdi) noexcept
2115       { return {__ym.year(), __ym.month(), __wdi}; }
2117       friend constexpr year_month_weekday
2118       operator/(const chrono::year& __y, const month_weekday& __mwd) noexcept
2119       { return {__y, __mwd.month(), __mwd.weekday_indexed()}; }
2121       friend constexpr year_month_weekday
2122       operator/(int __y, const month_weekday& __mwd) noexcept
2123       { return chrono::year(__y) / __mwd; }
2125       friend constexpr year_month_weekday
2126       operator/(const month_weekday& __mwd, const chrono::year& __y) noexcept
2127       { return __y / __mwd; }
2129       friend constexpr year_month_weekday
2130       operator/(const month_weekday& __mwd, int __y) noexcept
2131       { return chrono::year(__y) / __mwd; }
2132     };
2134     // YEAR_MONTH_WEEKDAY_LAST
2136     class year_month_weekday_last
2137     {
2138     private:
2139       chrono::year _M_y;
2140       chrono::month _M_m;
2141       chrono::weekday_last _M_wdl;
2143     public:
2144       constexpr
2145       year_month_weekday_last(const chrono::year& __y, const chrono::month& __m,
2146                               const chrono::weekday_last& __wdl) noexcept
2147       : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl}
2148       { }
2150       template<typename = __detail::__months_years_conversion_disambiguator>
2151         constexpr year_month_weekday_last&
2152         operator+=(const months& __m) noexcept
2153         {
2154           *this = *this + __m;
2155           return *this;
2156         }
2158       template<typename = __detail::__months_years_conversion_disambiguator>
2159         constexpr year_month_weekday_last&
2160         operator-=(const months& __m) noexcept
2161         {
2162           *this = *this - __m;
2163           return *this;
2164         }
2166       constexpr year_month_weekday_last&
2167       operator+=(const years& __y)  noexcept
2168       {
2169         *this = *this + __y;
2170         return *this;
2171       }
2173       constexpr year_month_weekday_last&
2174       operator-=(const years& __y)  noexcept
2175       {
2176         *this = *this - __y;
2177         return *this;
2178       }
2180       constexpr chrono::year
2181       year() const noexcept
2182       { return _M_y; }
2184       constexpr chrono::month
2185       month() const noexcept
2186       { return _M_m; }
2188       constexpr chrono::weekday
2189       weekday() const noexcept
2190       { return _M_wdl.weekday(); }
2192       constexpr chrono::weekday_last
2193       weekday_last() const noexcept
2194       { return _M_wdl; }
2196       constexpr
2197       operator sys_days() const noexcept
2198       {
2199         const auto __d = sys_days{_M_y / _M_m / last};
2200         return sys_days{(__d - (chrono::weekday{__d}
2201                                 - _M_wdl.weekday())).time_since_epoch()};
2202       }
2204       explicit constexpr
2205       operator local_days() const noexcept
2206       { return local_days{sys_days{*this}.time_since_epoch()}; }
2208       constexpr bool
2209       ok() const noexcept
2210       { return _M_y.ok() && _M_m.ok() && _M_wdl.ok(); }
2212       friend constexpr bool
2213       operator==(const year_month_weekday_last& __x,
2214                  const year_month_weekday_last& __y) noexcept
2215       {
2216         return __x.year() == __y.year()
2217           && __x.month() == __y.month()
2218           && __x.weekday_last() == __y.weekday_last();
2219       }
2221       template<typename = __detail::__months_years_conversion_disambiguator>
2222         friend constexpr year_month_weekday_last
2223         operator+(const year_month_weekday_last& __ymwdl,
2224                   const months& __dm) noexcept
2225         {
2226           return ((__ymwdl.year() / __ymwdl.month() + __dm)
2227                   / __ymwdl.weekday_last());
2228         }
2230       template<typename = __detail::__months_years_conversion_disambiguator>
2231         friend constexpr year_month_weekday_last
2232         operator+(const months& __dm,
2233                   const year_month_weekday_last& __ymwdl) noexcept
2234         { return __ymwdl + __dm; }
2236       friend constexpr year_month_weekday_last
2237       operator+(const year_month_weekday_last& __ymwdl,
2238                 const years& __dy) noexcept
2239       { return {__ymwdl.year() + __dy, __ymwdl.month(), __ymwdl.weekday_last()}; }
2241       friend constexpr year_month_weekday_last
2242       operator+(const years& __dy,
2243                 const year_month_weekday_last& __ymwdl) noexcept
2244       { return __ymwdl + __dy; }
2246       template<typename = __detail::__months_years_conversion_disambiguator>
2247         friend constexpr year_month_weekday_last
2248         operator-(const year_month_weekday_last& __ymwdl,
2249                   const months& __dm) noexcept
2250         { return __ymwdl + -__dm; }
2252       friend constexpr year_month_weekday_last
2253       operator-(const year_month_weekday_last& __ymwdl,
2254                 const years& __dy) noexcept
2255       { return __ymwdl + -__dy; }
2257       friend constexpr year_month_weekday_last
2258       operator/(const year_month& __ym,
2259                 const chrono::weekday_last& __wdl) noexcept
2260       { return {__ym.year(), __ym.month(), __wdl}; }
2262       friend constexpr year_month_weekday_last
2263       operator/(const chrono::year& __y,
2264                 const chrono::month_weekday_last& __mwdl) noexcept
2265       { return {__y, __mwdl.month(), __mwdl.weekday_last()}; }
2267       friend constexpr year_month_weekday_last
2268       operator/(int __y, const chrono::month_weekday_last& __mwdl) noexcept
2269       { return chrono::year(__y) / __mwdl; }
2271       friend constexpr year_month_weekday_last
2272       operator/(const chrono::month_weekday_last& __mwdl,
2273                 const chrono::year& __y) noexcept
2274       { return __y / __mwdl; }
2276       friend constexpr year_month_weekday_last
2277       operator/(const chrono::month_weekday_last& __mwdl, int __y) noexcept
2278       { return chrono::year(__y) / __mwdl; }
2279     };
2281     // HH_MM_SS
2283     /// @cond undocumented
2284     namespace __detail
2285     {
2286       consteval long long
2287       __pow10(unsigned __n)
2288       {
2289         long long __r = 1;
2290         while (__n-- > 0)
2291           __r *= 10;
2292         return __r;
2293       }
2295       template<typename _Duration> struct __utc_leap_second;
2296     }
2297     /// @endcond
2299     /** Utility for splitting a duration into hours, minutes, and seconds
2300      *
2301      * This is a convenience type that provides accessors for the constituent
2302      * parts (hours, minutes, seconds and subseconds) of a duration.
2303      *
2304      * @since C++20
2305      */
2306     template<typename _Duration>
2307       class hh_mm_ss
2308       {
2309         static_assert( __is_duration<_Duration>::value );
2311       private:
2312         static consteval int
2313         _S_fractional_width()
2314         {
2315           auto __den = _Duration::period::den;
2316           const int __multiplicity_2 = std::__countr_zero((uintmax_t)__den);
2317           __den >>= __multiplicity_2;
2318           int __multiplicity_5 = 0;
2319           while ((__den % 5) == 0)
2320             {
2321               ++__multiplicity_5;
2322               __den /= 5;
2323             }
2324           if (__den != 1)
2325             return 6;
2327           int __width = (__multiplicity_2 > __multiplicity_5
2328                          ? __multiplicity_2 : __multiplicity_5);
2329           if (__width > 18)
2330             __width = 18;
2331           return __width;
2332         }
2334         constexpr
2335         hh_mm_ss(_Duration __d, bool __is_neg)
2336         : _M_h (duration_cast<chrono::hours>(__d)),
2337           _M_m (duration_cast<chrono::minutes>(__d - hours())),
2338           _M_s (duration_cast<chrono::seconds>(__d - hours() - minutes())),
2339           _M_is_neg(__is_neg)
2340         {
2341           auto __ss = __d - hours() - minutes() - seconds();
2342           if constexpr (treat_as_floating_point_v<typename precision::rep>)
2343             _M_ss._M_r = __ss.count();
2344           else if constexpr (precision::period::den != 1)
2345             _M_ss._M_r = duration_cast<precision>(__ss).count();
2346         }
2348         static constexpr _Duration
2349         _S_abs(_Duration __d)
2350         {
2351           if constexpr (numeric_limits<typename _Duration::rep>::is_signed)
2352             return chrono::abs(__d);
2353           else
2354             return __d;
2355         }
2357       public:
2358         static constexpr unsigned fractional_width = {_S_fractional_width()};
2360         using precision
2361           = duration<common_type_t<typename _Duration::rep,
2362                                    chrono::seconds::rep>,
2363                      ratio<1, __detail::__pow10(fractional_width)>>;
2365         constexpr hh_mm_ss() noexcept = default;
2367         constexpr explicit
2368         hh_mm_ss(_Duration __d)
2369         : hh_mm_ss(_S_abs(__d), __d < _Duration::zero())
2370         { }
2372         constexpr bool
2373         is_negative() const noexcept
2374         {
2375           if constexpr (!_S_is_unsigned)
2376             return _M_is_neg;
2377           else
2378             return false;
2379         }
2381         constexpr chrono::hours
2382         hours() const noexcept
2383         { return _M_h; }
2385         constexpr chrono::minutes
2386         minutes() const noexcept
2387         { return _M_m; }
2389         constexpr chrono::seconds
2390         seconds() const noexcept
2391         { return _M_s; }
2393         constexpr precision
2394         subseconds() const noexcept
2395         { return static_cast<precision>(_M_ss); }
2397         constexpr explicit
2398         operator precision() const noexcept
2399         { return to_duration(); }
2401         constexpr precision
2402         to_duration() const noexcept
2403         {
2404           if constexpr (!_S_is_unsigned)
2405             if (_M_is_neg)
2406               return -(_M_h + _M_m + _M_s + subseconds());
2407           return _M_h + _M_m + _M_s + subseconds();
2408         }
2410       private:
2411         static constexpr bool _S_is_unsigned
2412           = __and_v<is_integral<typename _Duration::rep>,
2413                     is_unsigned<typename _Duration::rep>>;
2415         template<typename _Ratio>
2416           using __byte_duration = duration<unsigned char, _Ratio>;
2418         // The type of the _M_ss member that holds the subsecond precision.
2419         template<typename _Dur>
2420           struct __subseconds
2421           {
2422             typename _Dur::rep _M_r{};
2424             constexpr explicit
2425             operator _Dur() const noexcept
2426             { return _Dur(_M_r); }
2427           };
2429         // An empty class if this precision doesn't need subseconds.
2430         template<typename _Rep>
2431           requires (!treat_as_floating_point_v<_Rep>)
2432           struct __subseconds<duration<_Rep, ratio<1>>>
2433           {
2434             constexpr explicit
2435             operator duration<_Rep, ratio<1>>() const noexcept
2436             { return {}; }
2437           };
2439         template<typename _Rep, typename _Period>
2440           requires (!treat_as_floating_point_v<_Rep>)
2441             && ratio_less_v<_Period, ratio<1, 1>>
2442             && ratio_greater_equal_v<_Period, ratio<1, 250>>
2443           struct __subseconds<duration<_Rep, _Period>>
2444           {
2445             unsigned char _M_r{};
2447             constexpr explicit
2448             operator duration<_Rep, _Period>() const noexcept
2449             { return duration<_Rep, _Period>(_M_r); }
2450           };
2452         template<typename _Rep, typename _Period>
2453           requires (!treat_as_floating_point_v<_Rep>)
2454             && ratio_less_v<_Period, ratio<1, 250>>
2455             && ratio_greater_equal_v<_Period, ratio<1, 4000000000>>
2456           struct __subseconds<duration<_Rep, _Period>>
2457           {
2458             uint_least32_t _M_r{};
2460             constexpr explicit
2461             operator duration<_Rep, _Period>() const noexcept
2462             { return duration<_Rep, _Period>(_M_r); }
2463           };
2465         chrono::hours               _M_h{};
2466         __byte_duration<ratio<60>>  _M_m{};
2467         __byte_duration<ratio<1>>   _M_s{};
2468         bool                        _M_is_neg{};
2469         __subseconds<precision>     _M_ss{};
2471         template<typename> friend struct __detail::__utc_leap_second;
2472       };
2474     /// @cond undocumented
2475     namespace __detail
2476     {
2477       // Represents a time that is within a leap second insertion.
2478       template<typename _Duration>
2479         struct __utc_leap_second
2480         {
2481           explicit
2482           __utc_leap_second(const sys_time<_Duration>& __s)
2483           : _M_date(chrono::floor<days>(__s)), _M_time(__s - _M_date)
2484           {
2485             ++_M_time._M_s;
2486           }
2488           sys_days _M_date;
2489           hh_mm_ss<common_type_t<_Duration, days>> _M_time;
2490         };
2491     }
2492     /// @endcond
2494     // 12/24 HOURS FUNCTIONS
2496     constexpr bool
2497     is_am(const hours& __h) noexcept
2498     { return 0h <= __h && __h <= 11h; }
2500     constexpr bool
2501     is_pm(const hours& __h) noexcept
2502     { return 12h <= __h && __h <= 23h; }
2504     constexpr hours
2505     make12(const hours& __h) noexcept
2506     {
2507       if (__h == 0h)
2508         return 12h;
2509       else if (__h > 12h)
2510         return __h - 12h;
2511       return __h;
2512     }
2514     constexpr hours
2515     make24(const hours& __h, bool __is_pm) noexcept
2516     {
2517       if (!__is_pm)
2518         {
2519           if (__h == 12h)
2520             return 0h;
2521           else
2522             return __h;
2523         }
2524       else
2525         {
2526           if (__h == 12h)
2527             return __h;
2528           else
2529             return __h + 12h;
2530         }
2531     }
2533 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
2534     // C++20 [time.zones] Time zones
2536     struct tzdb;
2538     struct sys_info
2539     {
2540       sys_seconds begin;
2541       sys_seconds end;
2542       seconds offset;
2543       minutes save;
2544       string abbrev;
2545     };
2547     struct local_info
2548     {
2549       static constexpr int unique      = 0;
2550       static constexpr int nonexistent = 1;
2551       static constexpr int ambiguous   = 2;
2553       int result;
2554       sys_info first;
2555       sys_info second;
2556     };
2558     class nonexistent_local_time : public runtime_error
2559     {
2560     public:
2561       template<typename _Duration>
2562         nonexistent_local_time(const local_time<_Duration>& __tp,
2563                                const local_info& __i)
2564         : runtime_error(_S_make_what_str(__tp, __i))
2565         { __glibcxx_assert(__i.result == local_info::nonexistent); }
2567     private:
2568       template<typename _Duration>
2569         static string
2570         _S_make_what_str(const local_time<_Duration>& __tp,
2571                          const local_info& __i)
2572         {
2573           std::ostringstream __os;
2574           __os << __tp << " is in a gap between\n"
2575                << local_seconds(__i.first.end.time_since_epoch())
2576                + __i.first.offset << ' ' << __i.first.abbrev << " and\n"
2577                << local_seconds(__i.second.begin.time_since_epoch())
2578                + __i.second.offset << ' ' << __i.second.abbrev
2579                << " which are both equivalent to\n"
2580                << __i.first.end << " UTC";
2581           return std::move(__os).str();
2582         }
2583     };
2585     class ambiguous_local_time : public runtime_error
2586     {
2587     public:
2588       template<typename _Duration>
2589         ambiguous_local_time(const local_time<_Duration>& __tp,
2590                              const local_info& __i)
2591         : runtime_error(_S_make_what_str(__tp, __i))
2592         { __glibcxx_assert(__i.result == local_info::ambiguous); }
2594     private:
2595       template<typename _Duration>
2596         static string
2597         _S_make_what_str(const local_time<_Duration>& __tp,
2598                          const local_info& __i)
2599         {
2600           std::ostringstream __os;
2601           __os << __tp << " is ambiguous.  It could be\n"
2602                << __tp << ' ' << __i.first.abbrev << " == "
2603                << __tp - __i.first.offset << " UTC or\n"
2604                << __tp << ' ' << __i.second.abbrev << " == "
2605                << __tp - __i.second.offset << " UTC";
2606           return std::move(__os).str();
2607         }
2608     };
2610     template<typename _Duration>
2611       [[noreturn]] void
2612       __throw_bad_local_time(const local_time<_Duration>& __tp,
2613                              const local_info& __i)
2614       {
2615 #if __cpp_exceptions
2616         if (__i.result == local_info::nonexistent)
2617           throw nonexistent_local_time(__tp, __i);
2618         throw ambiguous_local_time(__tp, __i);
2619 #else
2620         __builtin_abort();
2621 #endif
2622       }
2624     enum class choose { earliest, latest };
2626     class time_zone
2627     {
2628     public:
2629       time_zone(time_zone&&) = default;
2630       time_zone& operator=(time_zone&&) = default;
2632       ~time_zone();
2634       [[nodiscard]]
2635       string_view name() const noexcept { return _M_name; }
2637       template<typename _Duration>
2638         sys_info
2639         get_info(const sys_time<_Duration>& __st) const
2640         { return _M_get_sys_info(chrono::floor<seconds>(__st)); }
2642       template<typename _Duration>
2643         local_info
2644         get_info(const local_time<_Duration>& __tp) const
2645         { return _M_get_local_info(chrono::floor<seconds>(__tp)); }
2647       template<typename _Duration>
2648         sys_time<common_type_t<_Duration, seconds>>
2649         to_sys(const local_time<_Duration>& __tp) const
2650         {
2651           local_info __info = get_info(__tp);
2653           if (__info.result != local_info::unique)
2654             __throw_bad_local_time(__tp, __info);
2656           return sys_time<_Duration>(__tp.time_since_epoch())
2657                    - __info.first.offset;
2658         }
2660       template<typename _Duration>
2661         sys_time<common_type_t<_Duration, seconds>>
2662         to_sys(const local_time<_Duration>& __tp, choose __z) const
2663         {
2664           local_info __info = get_info(__tp);
2666           if (__info.result == local_info::nonexistent)
2667             return __info.first.end; // Last second of the previous sys_info.
2669           sys_time<_Duration> __st(__tp.time_since_epoch());
2671           if (__info.result == local_info::ambiguous && __z == choose::latest)
2672             return __st - __info.second.offset; // Time in the later sys_info.
2673           // else if __z == earliest, use __info.first.offset as below:
2675           return __st - __info.first.offset;
2676         }
2678       template<typename _Duration>
2679         local_time<common_type_t<_Duration, seconds>>
2680         to_local(const sys_time<_Duration>& __tp) const
2681         {
2682           auto __d = (__tp + get_info(__tp).offset).time_since_epoch();
2683           return local_time<common_type_t<_Duration, seconds>>(__d);
2684         }
2686       [[nodiscard]] friend bool
2687       operator==(const time_zone& __x, const time_zone& __y) noexcept
2688       { return __x._M_name == __y._M_name; }
2690       [[nodiscard]] friend strong_ordering
2691       operator<=>(const time_zone& __x, const time_zone& __y) noexcept
2692       { return __x._M_name <=> __y._M_name; }
2694     private:
2695       sys_info _M_get_sys_info(sys_seconds) const;
2696       local_info _M_get_local_info(local_seconds) const;
2698       friend const tzdb& reload_tzdb();
2699       friend struct tzdb;
2700       friend class tzdb_list;
2702       struct _Impl;
2704       explicit time_zone(unique_ptr<_Impl> __p);
2705       string _M_name;
2706       unique_ptr<_Impl> _M_impl;
2707     };
2709     const time_zone* locate_zone(string_view __tz_name);
2710     const time_zone* current_zone();
2712     /** The list of `chrono::tzdb` objects
2713      *
2714      * A single object of this type is constructed by the C++ runtime,
2715      * and can be accessed by calling `chrono::get_tzdb_list()`.
2716      *
2717      * The front of the list is the current `tzdb` object and can be accessed
2718      * via `chrono::get_tzdb_list().front()` or `chrono::get_tzdb()` or
2719      * `*chrono::get_tzdb_list().begin()`.
2720      *
2721      * The `chrono::reload_tzdb()` function will check for a newer version
2722      * and if found, insert it at the front of the list.
2723      *
2724      * @since C++20
2725      */
2726     class tzdb_list
2727     {
2728       struct _Node;
2730     public:
2731       tzdb_list(const tzdb_list&) = delete;
2732       tzdb_list& operator=(const tzdb_list&) = delete;
2734       /** An iterator into the `tzdb_list`
2735        *
2736        * As a extension, in libstdc++ each `tzdb` is reference-counted
2737        * and the `const_iterator` type shares ownership of the object it
2738        * refers to. This ensures that a `tzdb` erased from the list will
2739        * not be destroyed while there is an iterator that refers to it.
2740        */
2741       class const_iterator
2742       {
2743       public:
2744         using value_type        = tzdb;
2745         using reference         = const tzdb&;
2746         using pointer           = const tzdb*;
2747         using difference_type   = ptrdiff_t;
2748         using iterator_category = forward_iterator_tag;
2750         constexpr const_iterator() = default;
2751         const_iterator(const const_iterator&) = default;
2752         const_iterator(const_iterator&&) = default;
2753         const_iterator& operator=(const const_iterator&) = default;
2754         const_iterator& operator=(const_iterator&&) = default;
2756         reference operator*() const noexcept;
2757         pointer operator->() const noexcept { return &**this; }
2758         const_iterator& operator++();
2759         const_iterator operator++(int);
2761         bool operator==(const const_iterator&) const noexcept = default;
2763       private:
2764         explicit const_iterator(const shared_ptr<_Node>&) noexcept;
2766         friend class tzdb_list;
2768         shared_ptr<_Node> _M_node;
2769         void* _M_reserved = nullptr;
2770       };
2772       /** Access the current `tzdb` at the front of the list.
2773        *
2774        * This returns a reference to the same object as `chrono::get_tzdb()`.
2775        *
2776        * @returns A reference to the current tzdb object.
2777        * @since C++20
2778        */
2779       const tzdb& front() const noexcept;
2781       /** Remove the tzdb object _after_ the one the iterator refers to.
2782        *
2783        * Calling this function concurrently with any of `front()`, `begin()`,
2784        * or `end()` does not cause a data race, but in general this function
2785        * is not thread-safe. The behaviour may be undefined if erasing an
2786        * element from the list while another thread is calling the same
2787        * function, or incrementing an iterator into the list, or accessing
2788        * the element being erased (unless it is accessed through an iterator).
2789        *
2790        * @param __p A dereferenceable iterator.
2791        * @returns An iterator the element after the one that was erased
2792        *          (or `end()` if there is no such element).
2793        * @since C++20
2794        */
2795       const_iterator erase_after(const_iterator __p);
2797       const_iterator begin() const noexcept;
2798       const_iterator end() const noexcept { return {}; }
2799       const_iterator cbegin() const noexcept { return begin(); }
2800       const_iterator cend() const noexcept { return end(); }
2802     private:
2803       constexpr explicit tzdb_list(nullptr_t);
2805       friend tzdb_list& get_tzdb_list();
2806       friend const tzdb& get_tzdb();
2807       friend const tzdb& reload_tzdb();
2808       friend struct tzdb;
2809       friend class leap_second;
2810       friend struct time_zone::_Impl;
2811       friend class time_zone_link;
2812     };
2814     class time_zone_link
2815     {
2816     public:
2817       time_zone_link(time_zone_link&&) = default;
2818       time_zone_link& operator=(time_zone_link&&) = default;
2820       string_view name() const noexcept { return _M_name; }
2821       string_view target() const noexcept { return _M_target; }
2823       friend bool
2824       operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept
2825       { return __x.name() == __y.name(); }
2827       friend strong_ordering
2828       operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept
2829       { return __x.name() <=> __y.name(); }
2831     private:
2832       friend const tzdb& reload_tzdb();
2833       friend struct tzdb_list::_Node;
2835       explicit time_zone_link(nullptr_t) { }
2837       string _M_name;
2838       string _M_target;
2839     };
2841     class leap_second
2842     {
2843     public:
2844       leap_second(const leap_second&) = default;
2845       leap_second& operator=(const leap_second&) = default;
2847       [[nodiscard]]
2848       constexpr sys_seconds
2849       date() const noexcept
2850       {
2851         if (_M_s >= _M_s.zero()) [[likely]]
2852           return sys_seconds(_M_s);
2853         return sys_seconds(-_M_s);
2854       }
2856       [[nodiscard]]
2857       constexpr seconds
2858       value() const noexcept
2859       {
2860         if (_M_s >= _M_s.zero()) [[likely]]
2861           return seconds(1);
2862         return seconds(-1);
2863       }
2865       // This can be defaulted because the database will never contain two
2866       // leap_second objects with the same date but different signs.
2867       [[nodiscard]] friend constexpr bool
2868       operator==(const leap_second&, const leap_second&) noexcept = default;
2870       [[nodiscard]] friend constexpr strong_ordering
2871       operator<=>(const leap_second& __x, const leap_second& __y) noexcept
2872       { return __x.date() <=> __y.date(); }
2874       template<typename _Duration>
2875         [[nodiscard]] friend constexpr bool
2876         operator==(const leap_second& __x,
2877                    const sys_time<_Duration>& __y) noexcept
2878         { return __x.date() == __y; }
2880       template<typename _Duration>
2881         [[nodiscard]] friend constexpr bool
2882         operator<(const leap_second& __x,
2883                   const sys_time<_Duration>& __y) noexcept
2884         { return __x.date() < __y; }
2886       template<typename _Duration>
2887         [[nodiscard]] friend constexpr bool
2888         operator<(const sys_time<_Duration>& __x,
2889                   const leap_second& __y) noexcept
2890         { return __x < __y.date(); }
2892       template<typename _Duration>
2893         [[nodiscard]] friend constexpr bool
2894         operator>(const leap_second& __x,
2895                   const sys_time<_Duration>& __y) noexcept
2896         { return __y < __x.date(); }
2898       template<typename _Duration>
2899         [[nodiscard]] friend constexpr bool
2900         operator>(const sys_time<_Duration>& __x,
2901                   const leap_second& __y) noexcept
2902         { return __y.date() < __x; }
2904       template<typename _Duration>
2905         [[nodiscard]] friend constexpr bool
2906         operator<=(const leap_second& __x,
2907                    const sys_time<_Duration>& __y) noexcept
2908         { return !(__y < __x.date()); }
2910       template<typename _Duration>
2911         [[nodiscard]] friend constexpr bool
2912         operator<=(const sys_time<_Duration>& __x,
2913                    const leap_second& __y) noexcept
2914         { return !(__y.date() < __x); }
2916       template<typename _Duration>
2917         [[nodiscard]] friend constexpr bool
2918         operator>=(const leap_second& __x,
2919                    const sys_time<_Duration>& __y) noexcept
2920         { return !(__x.date() < __y); }
2922       template<typename _Duration>
2923         [[nodiscard]] friend constexpr bool
2924         operator>=(const sys_time<_Duration>& __x,
2925                    const leap_second& __y) noexcept
2926         { return !(__x < __y.date()); }
2928       template<three_way_comparable_with<seconds> _Duration>
2929         [[nodiscard]] friend constexpr auto
2930         operator<=>(const leap_second& __x,
2931                     const sys_time<_Duration>& __y) noexcept
2932         { return __x.date() <=> __y; }
2934     private:
2935       explicit leap_second(seconds::rep __s) : _M_s(__s) { }
2937       friend struct tzdb_list::_Node;
2939       friend const tzdb& reload_tzdb();
2941       template<typename _Duration>
2942         friend leap_second_info
2943         get_leap_second_info(const utc_time<_Duration>&);
2945       seconds _M_s; // == date().time_since_epoch() * value().count()
2946     };
2948     template<class _Tp> struct zoned_traits { };
2950     template<>
2951       struct zoned_traits<const time_zone*>
2952       {
2953         static const time_zone*
2954         default_zone()
2955         { return std::chrono::locate_zone("UTC"); }
2957         static const time_zone*
2958         locate_zone(string_view __name)
2959         { return std::chrono::locate_zone(__name); }
2960       };
2962     struct tzdb
2963     {
2964       string version;
2965       _GLIBCXX_STD_C::vector<time_zone> zones;
2966       _GLIBCXX_STD_C::vector<time_zone_link> links;
2967       _GLIBCXX_STD_C::vector<leap_second> leap_seconds;
2969       const time_zone*
2970       locate_zone(string_view __tz_name) const;
2972       const time_zone*
2973       current_zone() const;
2975     private:
2976       friend const tzdb& reload_tzdb();
2977       friend class time_zone;
2978       friend struct tzdb_list::_Node;
2979     };
2981     tzdb_list& get_tzdb_list();
2982     const tzdb& get_tzdb();
2984     const tzdb& reload_tzdb();
2985     string remote_version();
2987     template<typename _Duration, typename _TimeZonePtr = const time_zone*>
2988       class zoned_time
2989       {
2990         static_assert(__is_duration_v<_Duration>);
2992         using _Traits = zoned_traits<_TimeZonePtr>;
2994         // Every constructor that accepts a string_view as its first parameter
2995         // does not participate in class template argument deduction.
2996         using string_view = type_identity_t<std::string_view>;
2998       public:
2999         using duration = common_type_t<_Duration, seconds>;
3001         zoned_time() requires requires { _Traits::default_zone(); }
3002         { }
3004         zoned_time(const zoned_time&) = default;
3005         zoned_time& operator=(const zoned_time&) = default;
3007         zoned_time(const sys_time<_Duration>& __st)
3008           requires requires { _Traits::default_zone(); }
3009         : _M_tp(__st)
3010         { }
3012         explicit
3013         zoned_time(_TimeZonePtr __z) : _M_zone(std::move(__z)) { }
3015         explicit
3016         zoned_time(string_view __name)
3017           requires requires {
3018             _TimeZonePtr{_Traits::locate_zone(std::string_view{})};
3019           }
3020         : _M_zone(_Traits::locate_zone(__name))
3021         { }
3023         template<typename _Duration2>
3024           zoned_time(const zoned_time<_Duration2, _TimeZonePtr>& __zt)
3025           requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3026           : _M_zone(__zt._M_zone), _M_tp(__zt._M_tp)
3027           { }
3029         zoned_time(_TimeZonePtr __z, const sys_time<_Duration>& __st)
3030         : _M_zone(std::move(__z)), _M_tp(__st)
3031         { }
3033         zoned_time(string_view __name, const sys_time<_Duration>& __st)
3034         : zoned_time(_Traits::locate_zone(__name), __st)
3035         { }
3037         zoned_time(_TimeZonePtr __z, const local_time<_Duration>& __tp)
3038         requires requires {
3039           { __z->to_sys(__tp) } -> convertible_to<sys_time<_Duration>>;
3040         }
3041         : _M_zone(std::move(__z)), _M_tp(_M_zone->to_sys(__tp))
3042         { }
3044         zoned_time(string_view __name, const local_time<_Duration>& __tp)
3045         requires requires (_TimeZonePtr __z) {
3046           { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3047           { __z->to_sys(__tp) } -> convertible_to<sys_time<_Duration>>;
3048         }
3049         : zoned_time(_Traits::locate_zone(__name), __tp)
3050         { }
3052         zoned_time(_TimeZonePtr __z, const local_time<_Duration>& __tp,
3053                    choose __c)
3054         requires requires {
3055           { __z->to_sys(__tp, __c) } -> convertible_to<sys_time<_Duration>>;
3056         }
3057         : _M_zone(std::move(__z)), _M_tp(_M_zone->to_sys(__tp, __c))
3058         { }
3060         zoned_time(string_view __name, const local_time<_Duration>& __tp,
3061                    choose __c)
3062         requires requires (_TimeZonePtr __z) {
3063           { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3064           { __z->to_sys(__tp, __c) } -> convertible_to<sys_time<_Duration>>;
3065         }
3066         : _M_zone(_Traits::locate_zone(__name)),
3067           _M_tp(_M_zone->to_sys(__tp, __c))
3068         { }
3070         template<typename _Duration2, typename _TimeZonePtr2>
3071           zoned_time(_TimeZonePtr __z,
3072                      const zoned_time<_Duration2, _TimeZonePtr2>& __zt)
3073           requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3074           : _M_zone(__z), _M_tp(__zt._M_tp)
3075           { }
3077         template<typename _Duration2, typename _TimeZonePtr2>
3078           zoned_time(_TimeZonePtr __z,
3079                      const zoned_time<_Duration2, _TimeZonePtr2>& __zt,
3080                      choose)
3081           requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3082           : _M_zone(__z), _M_tp(__zt._M_tp)
3083           { }
3085         template<typename _Duration2, typename _TimeZonePtr2>
3086           zoned_time(string_view __name,
3087                      const zoned_time<_Duration2, _TimeZonePtr2>& __zt)
3088           requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3089           && requires {
3090             { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3091           }
3092           : _M_zone(_Traits::locate_zone(__name)), _M_tp(__zt._M_tp)
3093           { }
3095         template<typename _Duration2, typename _TimeZonePtr2>
3096           zoned_time(string_view __name,
3097                      const zoned_time<_Duration2, _TimeZonePtr2>& __zt,
3098                      choose)
3099           requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3100           && requires {
3101             { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3102           }
3103           : _M_zone(_Traits::locate_zone(__name)), _M_tp(__zt._M_tp)
3104           { }
3106         zoned_time&
3107         operator=(const sys_time<_Duration>& __st)
3108         {
3109           _M_tp = __st;
3110           return *this;
3111         }
3113         zoned_time&
3114         operator=(const local_time<_Duration>& __lt)
3115         {
3116           _M_tp = _M_zone->to_sys(__lt);
3117           return *this;
3118         }
3120         [[nodiscard]]
3121         operator sys_time<duration>() const { return _M_tp; }
3123         [[nodiscard]]
3124         explicit operator local_time<duration>() const
3125         { return get_local_time(); }
3127         [[nodiscard]]
3128         _TimeZonePtr
3129         get_time_zone() const
3130         { return _M_zone; }
3132         [[nodiscard]]
3133         local_time<duration>
3134         get_local_time() const
3135         { return _M_zone->to_local(_M_tp); }
3137         [[nodiscard]]
3138         sys_time<duration>
3139         get_sys_time() const
3140         { return _M_tp; }
3142         [[nodiscard]]
3143         sys_info
3144         get_info() const
3145         { return _M_zone->get_info(_M_tp); }
3147         [[nodiscard]] friend bool
3148         operator==(const zoned_time&, const zoned_time&) = default;
3150       private:
3151         _TimeZonePtr       _M_zone{ _Traits::default_zone() };
3152         sys_time<duration> _M_tp{};
3154         template<typename _Duration2, typename _TimeZonePtr2>
3155           friend class zoned_time;
3156       };
3158     zoned_time() -> zoned_time<seconds>;
3160     template<typename _Duration>
3161     zoned_time(sys_time<_Duration>)
3162       -> zoned_time<common_type_t<_Duration, seconds>>;
3164   /// @cond undocumented
3165   template<typename _TimeZonePtrOrName>
3166     using __time_zone_representation
3167       = __conditional_t<is_convertible_v<_TimeZonePtrOrName, string_view>,
3168                         const time_zone*,
3169                         remove_cvref_t<_TimeZonePtrOrName>>;
3170   /// @endcond
3172   template<typename _TimeZonePtrOrName>
3173     zoned_time(_TimeZonePtrOrName&&)
3174       -> zoned_time<seconds, __time_zone_representation<_TimeZonePtrOrName>>;
3176   template<typename _TimeZonePtrOrName, typename _Duration>
3177     zoned_time(_TimeZonePtrOrName&&, sys_time<_Duration>)
3178       -> zoned_time<common_type_t<_Duration, seconds>,
3179                     __time_zone_representation<_TimeZonePtrOrName>>;
3181   template<typename _TimeZonePtrOrName, typename _Duration>
3182     zoned_time(_TimeZonePtrOrName&&, local_time<_Duration>,
3183                choose = choose::earliest)
3184       -> zoned_time<common_type_t<_Duration, seconds>,
3185                     __time_zone_representation<_TimeZonePtrOrName>>;
3187   template<typename _Duration, typename _TimeZonePtrOrName,
3188            typename _TimeZonePtr2>
3189     zoned_time(_TimeZonePtrOrName&&, zoned_time<_Duration, _TimeZonePtr2>,
3190                choose = choose::earliest)
3191       -> zoned_time<common_type_t<_Duration, seconds>,
3192                     __time_zone_representation<_TimeZonePtrOrName>>;
3194   template<typename _Dur1, typename _TZPtr1, typename _Dur2, typename _TZPtr2>
3195     [[nodiscard]]
3196     inline bool
3197     operator==(const zoned_time<_Dur1, _TZPtr1>& __x,
3198                const zoned_time<_Dur2, _TZPtr2>& __y)
3199     {
3200       return __x.get_time_zone() == __y.get_time_zone()
3201                && __x.get_sys_time() == __y.get_sys_time();
3202     }
3204     using zoned_seconds = zoned_time<seconds>;
3205 #endif // _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3207 namespace __detail
3209     inline leap_second_info
3210     __get_leap_second_info(sys_seconds __ss, bool __is_utc)
3211     {
3212       if (__ss < sys_seconds{}) [[unlikely]]
3213         return {};
3215       const seconds::rep __leaps[] {
3216           78796800, // 1 Jul 1972
3217           94694400, // 1 Jan 1973
3218          126230400, // 1 Jan 1974
3219          157766400, // 1 Jan 1975
3220          189302400, // 1 Jan 1976
3221          220924800, // 1 Jan 1977
3222          252460800, // 1 Jan 1978
3223          283996800, // 1 Jan 1979
3224          315532800, // 1 Jan 1980
3225          362793600, // 1 Jul 1981
3226          394329600, // 1 Jul 1982
3227          425865600, // 1 Jul 1983
3228          489024000, // 1 Jul 1985
3229          567993600, // 1 Jan 1988
3230          631152000, // 1 Jan 1990
3231          662688000, // 1 Jan 1991
3232          709948800, // 1 Jul 1992
3233          741484800, // 1 Jul 1993
3234          773020800, // 1 Jul 1994
3235          820454400, // 1 Jan 1996
3236          867715200, // 1 Jul 1997
3237          915148800, // 1 Jan 1999
3238         1136073600, // 1 Jan 2006
3239         1230768000, // 1 Jan 2009
3240         1341100800, // 1 Jul 2012
3241         1435708800, // 1 Jul 2015
3242         1483228800, // 1 Jan 2017
3243       };
3244       // The list above is known to be valid until (at least) this date
3245       // and only contains positive leap seconds.
3246       const sys_seconds __expires(1735344000s); // 2024-12-28 00:00:00 UTC
3248 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3249       if (__ss > __expires)
3250         {
3251           // Use updated leap_seconds from tzdb.
3252           size_t __n = std::size(__leaps);
3254           auto __db = get_tzdb_list().begin();
3255           auto __first = __db->leap_seconds.begin() + __n;
3256           auto __last = __db->leap_seconds.end();
3257           auto __pos = std::upper_bound(__first, __last, __ss);
3258           seconds __elapsed(__n);
3259           for (auto __i = __first; __i != __pos; ++__i)
3260             __elapsed += __i->value();
3262           if (__is_utc)
3263             {
3264               // Convert utc_time to sys_time:
3265               __ss -= __elapsed;
3266               // See if that sys_time is before (or during) previous leap sec:
3267               if (__pos != __first && __ss < __pos[-1])
3268                 {
3269                   if ((__ss + 1s) >= __pos[-1])
3270                     return {true, __elapsed};
3271                   __elapsed -= __pos[-1].value();
3272                 }
3273             }
3274           return {false, __elapsed};
3275         }
3276       else
3277 #endif
3278         {
3279           seconds::rep __s = __ss.time_since_epoch().count();
3280           const seconds::rep* __first = std::begin(__leaps);
3281           const seconds::rep* __last = std::end(__leaps);
3283           // Don't bother searching the list if we're after the last one.
3284           if (__s > (__last[-1] + (__last - __first) + 1))
3285             return { false, seconds(__last - __first) };
3287           auto __pos = std::upper_bound(__first, __last, __s);
3288           seconds __elapsed{__pos - __first};
3289           if (__is_utc)
3290             {
3291               // Convert utc_time to sys_time:
3292               __s -= __elapsed.count();
3293               // See if that sys_time is before (or during) previous leap sec:
3294               if (__pos != __first && __s < __pos[-1])
3295                 {
3296                   if ((__s + 1) >= __pos[-1])
3297                     return {true, __elapsed};
3298                   --__elapsed;
3299                 }
3300             }
3301           return {false, __elapsed};
3302         }
3303     }
3304 } // namespace __detail
3306     template<typename _Duration>
3307       [[nodiscard]]
3308       inline leap_second_info
3309       get_leap_second_info(const utc_time<_Duration>& __ut)
3310       {
3311         auto __s = chrono::duration_cast<seconds>(__ut.time_since_epoch());
3312         return __detail::__get_leap_second_info(sys_seconds(__s), true);
3313       }
3315     template<typename _Duration>
3316       [[nodiscard]]
3317       inline utc_time<common_type_t<_Duration, seconds>>
3318       utc_clock::from_sys(const sys_time<_Duration>& __t)
3319       {
3320         using _CDur = common_type_t<_Duration, seconds>;
3321         auto __s = chrono::time_point_cast<seconds>(__t);
3322         const auto __li = __detail::__get_leap_second_info(__s, false);
3323         return utc_time<_CDur>{__t.time_since_epoch()} + __li.elapsed;
3324       }
3326     /// @} group chrono
3327 #endif // C++20
3328   } // namespace chrono
3330 #if __cplusplus >= 202002L
3331   inline namespace literals
3332   {
3333   inline namespace chrono_literals
3334   {
3335     /// @addtogroup chrono
3336     /// @{
3337 #pragma GCC diagnostic push
3338 #pragma GCC diagnostic ignored "-Wliteral-suffix"
3339     /// Literal suffix for creating chrono::day objects.
3340     /// @since C++20
3341     constexpr chrono::day
3342     operator""d(unsigned long long __d) noexcept
3343     { return chrono::day{static_cast<unsigned>(__d)}; }
3345     /// Literal suffix for creating chrono::year objects.
3346     /// @since C++20
3347     constexpr chrono::year
3348     operator""y(unsigned long long __y) noexcept
3349     { return chrono::year{static_cast<int>(__y)}; }
3350 #pragma GCC diagnostic pop
3351     /// @}
3352   } // inline namespace chrono_literals
3353   } // inline namespace literals
3354 #endif // C++20
3356 _GLIBCXX_END_NAMESPACE_VERSION
3357 } // namespace std
3359 #if __cplusplus >= 202002L
3360 # include <bits/chrono_io.h>
3361 #endif
3363 #endif // C++11
3365 #endif //_GLIBCXX_CHRONO