libstdc++
chrono
Go to the documentation of this file.
1 // <chrono> -*- C++ -*-
2 
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.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file include/chrono
26  * This is a Standard C++ Library header.
27  * @ingroup chrono
28  */
29 
30 #ifndef _GLIBCXX_CHRONO
31 #define _GLIBCXX_CHRONO 1
32 
33 #pragma GCC system_header
34 
35 #include <bits/requires_hosted.h> // for <ctime> and clocks
36 
37 #if __cplusplus < 201103L
38 # include <bits/c++0x_warning.h>
39 #else
40 
41 #include <bits/chrono.h>
42 
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
52 
53 #define __glibcxx_want_chrono
54 #define __glibcxx_want_chrono_udls
55 #include <bits/version.h>
56 
57 namespace std _GLIBCXX_VISIBILITY(default)
58 {
59 _GLIBCXX_BEGIN_NAMESPACE_VERSION
60 
61  /**
62  * @defgroup chrono Time
63  * @ingroup utilities
64  *
65  * Classes and functions for time.
66  *
67  * @since C++11
68  */
69 
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>;
84 
85  class utc_clock;
86  class tai_clock;
87  class gps_clock;
88 
89  template<typename _Duration>
90  using utc_time = time_point<utc_clock, _Duration>;
91  using utc_seconds = utc_time<seconds>;
92 
93  template<typename _Duration>
94  using tai_time = time_point<tai_clock, _Duration>;
95  using tai_seconds = tai_time<seconds>;
96 
97  template<typename _Duration>
98  using gps_time = time_point<gps_clock, _Duration>;
99  using gps_seconds = gps_time<seconds>;
100 
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 { };
104 
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;
108 
109  struct leap_second_info
110  {
111  bool is_leap_second;
112  seconds elapsed;
113  };
114 
115  template<typename _Duration>
116  leap_second_info
117  get_leap_second_info(const utc_time<_Duration>& __ut);
118 
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;
133 
134  [[nodiscard]]
135  static time_point
136  now()
137  { return from_sys(system_clock::now()); }
138 
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  }
151 
152  template<typename _Duration>
153  [[nodiscard]]
154  static utc_time<common_type_t<_Duration, seconds>>
155  from_sys(const sys_time<_Duration>& __t);
156  };
157 
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?
172 
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()); }
178 
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  }
187 
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  };
197 
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
212 
213  // TODO move into lib, add extension point.
214  [[nodiscard]]
215  static time_point
216  now()
217  { return from_utc(utc_clock::now()); }
218 
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  }
227 
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  };
237 
238 
239  template<typename _DestClock, typename _SourceClock>
240  struct clock_time_conversion
241  { };
242 
243  // Identity conversions
244 
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  };
253 
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  };
262 
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  };
271 
272  // Conversions between system_clock and utc_clock
273 
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  };
282 
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  };
291 
292  template<typename _Tp, typename _Clock>
293  inline constexpr bool __is_time_point_for_v = false;
294 
295  template<typename _Clock, typename _Duration>
296  inline constexpr bool
297  __is_time_point_for_v<time_point<_Clock, _Duration>, _Clock> = true;
298 
299  // Conversions between system_clock and other clocks
300 
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  };
314 
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  };
328 
329  // Conversions between utc_clock and other clocks
330 
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  };
344 
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  };
358 
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  };
367 
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  };
374 
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  };
381 
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  };
389 
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  };
397 
398  } // namespace __detail
399  /// @endcond
400 
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>;
444 
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  }
469 
470  // CALENDRICAL TYPES
471 
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;
488 
489  struct last_spec
490  {
491  explicit last_spec() = default;
492 
493  friend constexpr month_day_last
494  operator/(int __m, last_spec) noexcept;
495 
496  friend constexpr month_day_last
497  operator/(last_spec, int __m) noexcept;
498  };
499 
500  inline constexpr last_spec last{};
501 
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  }
515 
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  }
536 
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  }
546 
547  inline constexpr unsigned __days_per_month[12]
548  = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
549  }
550 
551  // DAY
552 
553  class day
554  {
555  private:
556  unsigned char _M_d;
557 
558  public:
559  day() = default;
560 
561  explicit constexpr
562  day(unsigned __d) noexcept
563  : _M_d(__d)
564  { }
565 
566  constexpr day&
567  operator++() noexcept
568  {
569  ++_M_d;
570  return *this;
571  }
572 
573  constexpr day
574  operator++(int) noexcept
575  {
576  auto __ret = *this;
577  ++(*this);
578  return __ret;
579  }
580 
581  constexpr day&
582  operator--() noexcept
583  {
584  --_M_d;
585  return *this;
586  }
587 
588  constexpr day
589  operator--(int) noexcept
590  {
591  auto __ret = *this;
592  --(*this);
593  return __ret;
594  }
595 
596  constexpr day&
597  operator+=(const days& __d) noexcept
598  {
599  *this = *this + __d;
600  return *this;
601  }
602 
603  constexpr day&
604  operator-=(const days& __d) noexcept
605  {
606  *this = *this - __d;
607  return *this;
608  }
609 
610  constexpr explicit
611  operator unsigned() const noexcept
612  { return _M_d; }
613 
614  constexpr bool
615  ok() const noexcept
616  { return 1 <= _M_d && _M_d <= 31; }
617 
618  friend constexpr bool
619  operator==(const day& __x, const day& __y) noexcept
620  { return unsigned{__x} == unsigned{__y}; }
621 
622  friend constexpr strong_ordering
623  operator<=>(const day& __x, const day& __y) noexcept
624  { return unsigned{__x} <=> unsigned{__y}; }
625 
626  friend constexpr day
627  operator+(const day& __x, const days& __y) noexcept
628  { return day(unsigned{__x} + __y.count()); }
629 
630  friend constexpr day
631  operator+(const days& __x, const day& __y) noexcept
632  { return __y + __x; }
633 
634  friend constexpr day
635  operator-(const day& __x, const days& __y) noexcept
636  { return __x + -__y; }
637 
638  friend constexpr days
639  operator-(const day& __x, const day& __y) noexcept
640  { return days{int(unsigned{__x}) - int(unsigned{__y})}; }
641 
642  friend constexpr month_day
643  operator/(const month& __m, const day& __d) noexcept;
644 
645  friend constexpr month_day
646  operator/(int __m, const day& __d) noexcept;
647 
648  friend constexpr month_day
649  operator/(const day& __d, const month& __m) noexcept;
650 
651  friend constexpr month_day
652  operator/(const day& __d, int __m) noexcept;
653 
654  friend constexpr year_month_day
655  operator/(const year_month& __ym, const day& __d) noexcept;
656  };
657 
658  // MONTH
659 
660  class month
661  {
662  private:
663  unsigned char _M_m;
664 
665  public:
666  month() = default;
667 
668  explicit constexpr
669  month(unsigned __m) noexcept
670  : _M_m(__m)
671  { }
672 
673  constexpr month&
674  operator++() noexcept
675  {
676  *this += months{1};
677  return *this;
678  }
679 
680  constexpr month
681  operator++(int) noexcept
682  {
683  auto __ret = *this;
684  ++(*this);
685  return __ret;
686  }
687 
688  constexpr month&
689  operator--() noexcept
690  {
691  *this -= months{1};
692  return *this;
693  }
694 
695  constexpr month
696  operator--(int) noexcept
697  {
698  auto __ret = *this;
699  --(*this);
700  return __ret;
701  }
702 
703  constexpr month&
704  operator+=(const months& __m) noexcept
705  {
706  *this = *this + __m;
707  return *this;
708  }
709 
710  constexpr month&
711  operator-=(const months& __m) noexcept
712  {
713  *this = *this - __m;
714  return *this;
715  }
716 
717  explicit constexpr
718  operator unsigned() const noexcept
719  { return _M_m; }
720 
721  constexpr bool
722  ok() const noexcept
723  { return 1 <= _M_m && _M_m <= 12; }
724 
725  friend constexpr bool
726  operator==(const month& __x, const month& __y) noexcept
727  { return unsigned{__x} == unsigned{__y}; }
728 
729  friend constexpr strong_ordering
730  operator<=>(const month& __x, const month& __y) noexcept
731  { return unsigned{__x} <=> unsigned{__y}; }
732 
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  }
741 
742  friend constexpr month
743  operator+(const months& __x, const month& __y) noexcept
744  { return __y + __x; }
745 
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  }
754 
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  }
761 
762  friend constexpr year_month
763  operator/(const year& __y, const month& __m) noexcept;
764 
765  friend constexpr month_day
766  operator/(const month& __m, int __d) noexcept;
767 
768  friend constexpr month_day_last
769  operator/(const month& __m, last_spec) noexcept;
770 
771  friend constexpr month_day_last
772  operator/(last_spec, const month& __m) noexcept;
773 
774  friend constexpr month_weekday
775  operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
776 
777  friend constexpr month_weekday
778  operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
779 
780  friend constexpr month_weekday_last
781  operator/(const month& __m, const weekday_last& __wdl) noexcept;
782 
783  friend constexpr month_weekday_last
784  operator/(const weekday_last& __wdl, const month& __m) noexcept;
785  };
786 
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};
799 
800  // YEAR
801 
802  class year
803  {
804  private:
805  short _M_y;
806 
807  public:
808  year() = default;
809 
810  explicit constexpr
811  year(int __y) noexcept
812  : _M_y{static_cast<short>(__y)}
813  { }
814 
815  static constexpr year
816  min() noexcept
817  { return year{-32767}; }
818 
819  static constexpr year
820  max() noexcept
821  { return year{32767}; }
822 
823  constexpr year&
824  operator++() noexcept
825  {
826  ++_M_y;
827  return *this;
828  }
829 
830  constexpr year
831  operator++(int) noexcept
832  {
833  auto __ret = *this;
834  ++(*this);
835  return __ret;
836  }
837 
838  constexpr year&
839  operator--() noexcept
840  {
841  --_M_y;
842  return *this;
843  }
844 
845  constexpr year
846  operator--(int) noexcept
847  {
848  auto __ret = *this;
849  --(*this);
850  return __ret;
851  }
852 
853  constexpr year&
854  operator+=(const years& __y) noexcept
855  {
856  *this = *this + __y;
857  return *this;
858  }
859 
860  constexpr year&
861  operator-=(const years& __y) noexcept
862  {
863  *this = *this - __y;
864  return *this;
865  }
866 
867  constexpr year
868  operator+() const noexcept
869  { return *this; }
870 
871  constexpr year
872  operator-() const noexcept
873  { return year{-_M_y}; }
874 
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.
894 
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
899 
900  return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0;
901  }
902 
903  explicit constexpr
904  operator int() const noexcept
905  { return _M_y; }
906 
907  constexpr bool
908  ok() const noexcept
909  { return min()._M_y <= _M_y && _M_y <= max()._M_y; }
910 
911  friend constexpr bool
912  operator==(const year& __x, const year& __y) noexcept
913  { return int{__x} == int{__y}; }
914 
915  friend constexpr strong_ordering
916  operator<=>(const year& __x, const year& __y) noexcept
917  { return int{__x} <=> int{__y}; }
918 
919  friend constexpr year
920  operator+(const year& __x, const years& __y) noexcept
921  { return year{int{__x} + static_cast<int>(__y.count())}; }
922 
923  friend constexpr year
924  operator+(const years& __x, const year& __y) noexcept
925  { return __y + __x; }
926 
927  friend constexpr year
928  operator-(const year& __x, const years& __y) noexcept
929  { return __x + -__y; }
930 
931  friend constexpr years
932  operator-(const year& __x, const year& __y) noexcept
933  { return years{int{__x} - int{__y}}; }
934 
935  friend constexpr year_month
936  operator/(const year& __y, int __m) noexcept;
937 
938  friend constexpr year_month_day
939  operator/(const year& __y, const month_day& __md) noexcept;
940 
941  friend constexpr year_month_day
942  operator/(const month_day& __md, const year& __y) noexcept;
943 
944  friend constexpr year_month_day_last
945  operator/(const year& __y, const month_day_last& __mdl) noexcept;
946 
947  friend constexpr year_month_day_last
948  operator/(const month_day_last& __mdl, const year& __y) noexcept;
949 
950  friend constexpr year_month_weekday
951  operator/(const year& __y, const month_weekday& __mwd) noexcept;
952 
953  friend constexpr year_month_weekday
954  operator/(const month_weekday& __mwd, const year& __y) noexcept;
955 
956  friend constexpr year_month_weekday_last
957  operator/(const year& __y, const month_weekday_last& __mwdl) noexcept;
958 
959  friend constexpr year_month_weekday_last
960  operator/(const month_weekday_last& __mwdl, const year& __y) noexcept;
961  };
962 
963  // WEEKDAY
964 
965  class weekday
966  {
967  private:
968  unsigned char _M_wd;
969 
970  static constexpr weekday
971  _S_from_days(const days& __d)
972  {
973  return weekday{__detail::__add_modulo<7>(4, __d.count())};
974  }
975 
976  public:
977  weekday() = default;
978 
979  explicit constexpr
980  weekday(unsigned __wd) noexcept
981  : _M_wd(__wd == 7 ? 0 : __wd) // __wd % 7 ?
982  { }
983 
984  constexpr
985  weekday(const sys_days& __dp) noexcept
986  : weekday{_S_from_days(__dp.time_since_epoch())}
987  { }
988 
989  explicit constexpr
990  weekday(const local_days& __dp) noexcept
991  : weekday{sys_days{__dp.time_since_epoch()}}
992  { }
993 
994  constexpr weekday&
995  operator++() noexcept
996  {
997  *this += days{1};
998  return *this;
999  }
1000 
1001  constexpr weekday
1002  operator++(int) noexcept
1003  {
1004  auto __ret = *this;
1005  ++(*this);
1006  return __ret;
1007  }
1008 
1009  constexpr weekday&
1010  operator--() noexcept
1011  {
1012  *this -= days{1};
1013  return *this;
1014  }
1015 
1016  constexpr weekday
1017  operator--(int) noexcept
1018  {
1019  auto __ret = *this;
1020  --(*this);
1021  return __ret;
1022  }
1023 
1024  constexpr weekday&
1025  operator+=(const days& __d) noexcept
1026  {
1027  *this = *this + __d;
1028  return *this;
1029  }
1030 
1031  constexpr weekday&
1032  operator-=(const days& __d) noexcept
1033  {
1034  *this = *this - __d;
1035  return *this;
1036  }
1037 
1038  constexpr unsigned
1039  c_encoding() const noexcept
1040  { return _M_wd; }
1041 
1042  constexpr unsigned
1043  iso_encoding() const noexcept
1044  { return _M_wd == 0u ? 7u : _M_wd; }
1045 
1046  constexpr bool
1047  ok() const noexcept
1048  { return _M_wd <= 6; }
1049 
1050  constexpr weekday_indexed
1051  operator[](unsigned __index) const noexcept;
1052 
1053  constexpr weekday_last
1054  operator[](last_spec) const noexcept;
1055 
1056  friend constexpr bool
1057  operator==(const weekday& __x, const weekday& __y) noexcept
1058  { return __x._M_wd == __y._M_wd; }
1059 
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  }
1065 
1066  friend constexpr weekday
1067  operator+(const days& __x, const weekday& __y) noexcept
1068  { return __y + __x; }
1069 
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  }
1075 
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  };
1083 
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};
1091 
1092  // WEEKDAY_INDEXED
1093 
1094  class weekday_indexed
1095  {
1096  private:
1097  chrono::weekday _M_wd;
1098  unsigned char _M_index;
1099 
1100  public:
1101  weekday_indexed() = default;
1102 
1103  constexpr
1104  weekday_indexed(const chrono::weekday& __wd, unsigned __index) noexcept
1105  : _M_wd(__wd), _M_index(__index)
1106  { }
1107 
1108  constexpr chrono::weekday
1109  weekday() const noexcept
1110  { return _M_wd; }
1111 
1112  constexpr unsigned
1113  index() const noexcept
1114  { return _M_index; };
1115 
1116  constexpr bool
1117  ok() const noexcept
1118  { return _M_wd.ok() && 1 <= _M_index && _M_index <= 5; }
1119 
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(); }
1123 
1124  friend constexpr month_weekday
1125  operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
1126 
1127  friend constexpr month_weekday
1128  operator/(int __m, const weekday_indexed& __wdi) noexcept;
1129 
1130  friend constexpr month_weekday
1131  operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
1132 
1133  friend constexpr month_weekday
1134  operator/(const weekday_indexed& __wdi, int __m) noexcept;
1135 
1136  friend constexpr year_month_weekday
1137  operator/(const year_month& __ym, const weekday_indexed& __wdi) noexcept;
1138  };
1139 
1140  constexpr weekday_indexed
1141  weekday::operator[](unsigned __index) const noexcept
1142  { return {*this, __index}; }
1143 
1144  // WEEKDAY_LAST
1145 
1146  class weekday_last
1147  {
1148  private:
1149  chrono::weekday _M_wd;
1150 
1151  public:
1152  explicit constexpr
1153  weekday_last(const chrono::weekday& __wd) noexcept
1154  : _M_wd{__wd}
1155  { }
1156 
1157  constexpr chrono::weekday
1158  weekday() const noexcept
1159  { return _M_wd; }
1160 
1161  constexpr bool
1162  ok() const noexcept
1163  { return _M_wd.ok(); }
1164 
1165  friend constexpr bool
1166  operator==(const weekday_last& __x, const weekday_last& __y) noexcept
1167  { return __x.weekday() == __y.weekday(); }
1168 
1169  friend constexpr month_weekday_last
1170  operator/(int __m, const weekday_last& __wdl) noexcept;
1171 
1172  friend constexpr month_weekday_last
1173  operator/(const weekday_last& __wdl, int __m) noexcept;
1174 
1175  friend constexpr year_month_weekday_last
1176  operator/(const year_month& __ym, const weekday_last& __wdl) noexcept;
1177  };
1178 
1179  constexpr weekday_last
1180  weekday::operator[](last_spec) const noexcept
1181  { return weekday_last{*this}; }
1182 
1183  // MONTH_DAY
1184 
1185  class month_day
1186  {
1187  private:
1188  chrono::month _M_m;
1189  chrono::day _M_d;
1190 
1191  public:
1192  month_day() = default;
1193 
1194  constexpr
1195  month_day(const chrono::month& __m, const chrono::day& __d) noexcept
1196  : _M_m{__m}, _M_d{__d}
1197  { }
1198 
1199  constexpr chrono::month
1200  month() const noexcept
1201  { return _M_m; }
1202 
1203  constexpr chrono::day
1204  day() const noexcept
1205  { return _M_d; }
1206 
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  }
1214 
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(); }
1218 
1219  friend constexpr strong_ordering
1220  operator<=>(const month_day& __x, const month_day& __y) noexcept
1221  = default;
1222 
1223  friend constexpr month_day
1224  operator/(const chrono::month& __m, const chrono::day& __d) noexcept
1225  { return {__m, __d}; }
1226 
1227  friend constexpr month_day
1228  operator/(const chrono::month& __m, int __d) noexcept
1229  { return {__m, chrono::day(unsigned(__d))}; }
1230 
1231  friend constexpr month_day
1232  operator/(int __m, const chrono::day& __d) noexcept
1233  { return {chrono::month(unsigned(__m)), __d}; }
1234 
1235  friend constexpr month_day
1236  operator/(const chrono::day& __d, const chrono::month& __m) noexcept
1237  { return {__m, __d}; }
1238 
1239  friend constexpr month_day
1240  operator/(const chrono::day& __d, int __m) noexcept
1241  { return {chrono::month(unsigned(__m)), __d}; }
1242 
1243  friend constexpr year_month_day
1244  operator/(int __y, const month_day& __md) noexcept;
1245 
1246  friend constexpr year_month_day
1247  operator/(const month_day& __md, int __y) noexcept;
1248  };
1249 
1250  // MONTH_DAY_LAST
1251 
1252  class month_day_last
1253  {
1254  private:
1255  chrono::month _M_m;
1256 
1257  public:
1258  explicit constexpr
1259  month_day_last(const chrono::month& __m) noexcept
1260  : _M_m{__m}
1261  { }
1262 
1263  constexpr chrono::month
1264  month() const noexcept
1265  { return _M_m; }
1266 
1267  constexpr bool
1268  ok() const noexcept
1269  { return _M_m.ok(); }
1270 
1271  friend constexpr bool
1272  operator==(const month_day_last& __x, const month_day_last& __y) noexcept
1273  { return __x.month() == __y.month(); }
1274 
1275  friend constexpr strong_ordering
1276  operator<=>(const month_day_last& __x, const month_day_last& __y) noexcept
1277  = default;
1278 
1279  friend constexpr month_day_last
1280  operator/(const chrono::month& __m, last_spec) noexcept
1281  { return month_day_last{__m}; }
1282 
1283  friend constexpr month_day_last
1284  operator/(int __m, last_spec) noexcept
1285  { return chrono::month(unsigned(__m)) / last; }
1286 
1287  friend constexpr month_day_last
1288  operator/(last_spec, const chrono::month& __m) noexcept
1289  { return __m / last; }
1290 
1291  friend constexpr month_day_last
1292  operator/(last_spec, int __m) noexcept
1293  { return __m / last; }
1294 
1295  friend constexpr year_month_day_last
1296  operator/(int __y, const month_day_last& __mdl) noexcept;
1297 
1298  friend constexpr year_month_day_last
1299  operator/(const month_day_last& __mdl, int __y) noexcept;
1300  };
1301 
1302  // MONTH_WEEKDAY
1303 
1304  class month_weekday
1305  {
1306  private:
1307  chrono::month _M_m;
1308  chrono::weekday_indexed _M_wdi;
1309 
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  { }
1316 
1317  constexpr chrono::month
1318  month() const noexcept
1319  { return _M_m; }
1320 
1321  constexpr chrono::weekday_indexed
1322  weekday_indexed() const noexcept
1323  { return _M_wdi; }
1324 
1325  constexpr bool
1326  ok() const noexcept
1327  { return _M_m.ok() && _M_wdi.ok(); }
1328 
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  }
1335 
1336  friend constexpr month_weekday
1337  operator/(const chrono::month& __m,
1338  const chrono::weekday_indexed& __wdi) noexcept
1339  { return {__m, __wdi}; }
1340 
1341  friend constexpr month_weekday
1342  operator/(int __m, const chrono::weekday_indexed& __wdi) noexcept
1343  { return chrono::month(unsigned(__m)) / __wdi; }
1344 
1345  friend constexpr month_weekday
1346  operator/(const chrono::weekday_indexed& __wdi,
1347  const chrono::month& __m) noexcept
1348  { return __m / __wdi; }
1349 
1350  friend constexpr month_weekday
1351  operator/(const chrono::weekday_indexed& __wdi, int __m) noexcept
1352  { return __m / __wdi; }
1353 
1354  friend constexpr year_month_weekday
1355  operator/(int __y, const month_weekday& __mwd) noexcept;
1356 
1357  friend constexpr year_month_weekday
1358  operator/(const month_weekday& __mwd, int __y) noexcept;
1359  };
1360 
1361  // MONTH_WEEKDAY_LAST
1362 
1363  class month_weekday_last
1364  {
1365  private:
1366  chrono::month _M_m;
1367  chrono::weekday_last _M_wdl;
1368 
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  { }
1375 
1376  constexpr chrono::month
1377  month() const noexcept
1378  { return _M_m; }
1379 
1380  constexpr chrono::weekday_last
1381  weekday_last() const noexcept
1382  { return _M_wdl; }
1383 
1384  constexpr bool
1385  ok() const noexcept
1386  { return _M_m.ok() && _M_wdl.ok(); }
1387 
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  }
1395 
1396  friend constexpr month_weekday_last
1397  operator/(const chrono::month& __m,
1398  const chrono::weekday_last& __wdl) noexcept
1399  { return {__m, __wdl}; }
1400 
1401  friend constexpr month_weekday_last
1402  operator/(int __m, const chrono::weekday_last& __wdl) noexcept
1403  { return chrono::month(unsigned(__m)) / __wdl; }
1404 
1405  friend constexpr month_weekday_last
1406  operator/(const chrono::weekday_last& __wdl,
1407  const chrono::month& __m) noexcept
1408  { return __m / __wdl; }
1409 
1410  friend constexpr month_weekday_last
1411  operator/(const chrono::weekday_last& __wdl, int __m) noexcept
1412  { return chrono::month(unsigned(__m)) / __wdl; }
1413 
1414  friend constexpr year_month_weekday_last
1415  operator/(int __y, const month_weekday_last& __mwdl) noexcept;
1416 
1417  friend constexpr year_month_weekday_last
1418  operator/(const month_weekday_last& __mwdl, int __y) noexcept;
1419  };
1420 
1421  // YEAR_MONTH
1422 
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  }
1439 
1440  class year_month
1441  {
1442  private:
1443  chrono::year _M_y;
1444  chrono::month _M_m;
1445 
1446  public:
1447  year_month() = default;
1448 
1449  constexpr
1450  year_month(const chrono::year& __y, const chrono::month& __m) noexcept
1451  : _M_y{__y}, _M_m{__m}
1452  { }
1453 
1454  constexpr chrono::year
1455  year() const noexcept
1456  { return _M_y; }
1457 
1458  constexpr chrono::month
1459  month() const noexcept
1460  { return _M_m; }
1461 
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  }
1469 
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  }
1477 
1478  constexpr year_month&
1479  operator+=(const years& __dy) noexcept
1480  {
1481  *this = *this + __dy;
1482  return *this;
1483  }
1484 
1485  constexpr year_month&
1486  operator-=(const years& __dy) noexcept
1487  {
1488  *this = *this - __dy;
1489  return *this;
1490  }
1491 
1492  constexpr bool
1493  ok() const noexcept
1494  { return _M_y.ok() && _M_m.ok(); }
1495 
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(); }
1499 
1500  friend constexpr strong_ordering
1501  operator<=>(const year_month& __x, const year_month& __y) noexcept
1502  = default;
1503 
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  }
1516 
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; }
1521 
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; }
1526 
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  }
1534 
1535  friend constexpr year_month
1536  operator+(const year_month& __ym, const years& __dy) noexcept
1537  { return (__ym.year() + __dy) / __ym.month(); }
1538 
1539  friend constexpr year_month
1540  operator+(const years& __dy, const year_month& __ym) noexcept
1541  { return __ym + __dy; }
1542 
1543  friend constexpr year_month
1544  operator-(const year_month& __ym, const years& __dy) noexcept
1545  { return __ym + -__dy; }
1546 
1547  friend constexpr year_month
1548  operator/(const chrono::year& __y, const chrono::month& __m) noexcept
1549  { return {__y, __m}; }
1550 
1551  friend constexpr year_month
1552  operator/(const chrono::year& __y, int __m) noexcept
1553  { return {__y, chrono::month(unsigned(__m))}; }
1554 
1555  friend constexpr year_month_day
1556  operator/(const year_month& __ym, int __d) noexcept;
1557 
1558  friend constexpr year_month_day_last
1559  operator/(const year_month& __ym, last_spec) noexcept;
1560  };
1561 
1562  // YEAR_MONTH_DAY
1563 
1564  class year_month_day
1565  {
1566  private:
1567  chrono::year _M_y;
1568  chrono::month _M_m;
1569  chrono::day _M_d;
1570 
1571  static constexpr year_month_day _S_from_days(const days& __dp) noexcept;
1572 
1573  constexpr days _M_days_since_epoch() const noexcept;
1574 
1575  public:
1576  year_month_day() = default;
1577 
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  { }
1583 
1584  constexpr
1585  year_month_day(const year_month_day_last& __ymdl) noexcept;
1586 
1587  constexpr
1588  year_month_day(const sys_days& __dp) noexcept
1589  : year_month_day(_S_from_days(__dp.time_since_epoch()))
1590  { }
1591 
1592  explicit constexpr
1593  year_month_day(const local_days& __dp) noexcept
1594  : year_month_day(sys_days{__dp.time_since_epoch()})
1595  { }
1596 
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  }
1604 
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  }
1612 
1613  constexpr year_month_day&
1614  operator+=(const years& __y) noexcept
1615  {
1616  *this = *this + __y;
1617  return *this;
1618  }
1619 
1620  constexpr year_month_day&
1621  operator-=(const years& __y) noexcept
1622  {
1623  *this = *this - __y;
1624  return *this;
1625  }
1626 
1627  constexpr chrono::year
1628  year() const noexcept
1629  { return _M_y; }
1630 
1631  constexpr chrono::month
1632  month() const noexcept
1633  { return _M_m; }
1634 
1635  constexpr chrono::day
1636  day() const noexcept
1637  { return _M_d; }
1638 
1639  constexpr
1640  operator sys_days() const noexcept
1641  { return sys_days{_M_days_since_epoch()}; }
1642 
1643  explicit constexpr
1644  operator local_days() const noexcept
1645  { return local_days{sys_days{*this}.time_since_epoch()}; }
1646 
1647  constexpr bool ok() const noexcept;
1648 
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  }
1656 
1657  friend constexpr strong_ordering
1658  operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept
1659  = default;
1660 
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(); }
1665 
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; }
1670 
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(); }
1674 
1675  friend constexpr year_month_day
1676  operator+(const years& __dy, const year_month_day& __ymd) noexcept
1677  { return __ymd + __dy; }
1678 
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; }
1683 
1684  friend constexpr year_month_day
1685  operator-(const year_month_day& __ymd, const years& __dy) noexcept
1686  { return __ymd + -__dy; }
1687 
1688  friend constexpr year_month_day
1689  operator/(const year_month& __ym, const chrono::day& __d) noexcept
1690  { return {__ym.year(), __ym.month(), __d}; }
1691 
1692  friend constexpr year_month_day
1693  operator/(const year_month& __ym, int __d) noexcept
1694  { return __ym / chrono::day{unsigned(__d)}; }
1695 
1696  friend constexpr year_month_day
1697  operator/(const chrono::year& __y, const month_day& __md) noexcept
1698  { return __y / __md.month() / __md.day(); }
1699 
1700  friend constexpr year_month_day
1701  operator/(int __y, const month_day& __md) noexcept
1702  { return chrono::year{__y} / __md; }
1703 
1704  friend constexpr year_month_day
1705  operator/(const month_day& __md, const chrono::year& __y) noexcept
1706  { return __y / __md; }
1707 
1708  friend constexpr year_month_day
1709  operator/(const month_day& __md, int __y) noexcept
1710  { return chrono::year(__y) / __md; }
1711  };
1712 
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);
1722 
1723  const auto __r0 = static_cast<uint32_t>(__dp.count()) + __r2_e3;
1724 
1725  const auto __n1 = 4 * __r0 + 3;
1726  const auto __q1 = __n1 / 146097;
1727  const auto __r1 = __n1 % 146097 / 4;
1728 
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;
1734 
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;
1739 
1740  const auto __y0 = 100 * __q1 + __q2;
1741  const auto __m0 = __q3;
1742  const auto __d0 = __r3;
1743 
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;
1748 
1749  return year_month_day{chrono::year{static_cast<int>(__y1 + __z2)},
1750  chrono::month{__m1}, chrono::day{__d1}};
1751  }
1752 
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);
1762 
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));
1766 
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;
1771 
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;
1776 
1777  return days{static_cast<int32_t>(__yc + __mc + __dc - __r2_e3)};
1778  }
1779 
1780  // YEAR_MONTH_DAY_LAST
1781 
1782  class year_month_day_last
1783  {
1784  private:
1785  chrono::year _M_y;
1786  chrono::month_day_last _M_mdl;
1787 
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  { }
1794 
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  }
1802 
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  }
1810 
1811  constexpr year_month_day_last&
1812  operator+=(const years& __y) noexcept
1813  {
1814  *this = *this + __y;
1815  return *this;
1816  }
1817 
1818  constexpr year_month_day_last&
1819  operator-=(const years& __y) noexcept
1820  {
1821  *this = *this - __y;
1822  return *this;
1823  }
1824 
1825  constexpr chrono::year
1826  year() const noexcept
1827  { return _M_y; }
1828 
1829  constexpr chrono::month
1830  month() const noexcept
1831  { return _M_mdl.month(); }
1832 
1833  constexpr chrono::month_day_last
1834  month_day_last() const noexcept
1835  { return _M_mdl; }
1836 
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());
1842 
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}.
1846 
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.
1849 
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.
1852 
1853  // Therefore, b = (__m ^ c) & 1, where c = 0, if __m < 8, or c = 1 if
1854  // __m >= 8, that is, c = __m >> 3.
1855 
1856  // Since 30 = (11110)_2 and __m <= 31 = (11111)_2, the "& 1" in b's
1857  // calculation is unnecessary.
1858 
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  }
1864 
1865  constexpr
1866  operator sys_days() const noexcept
1867  { return sys_days{year() / month() / day()}; }
1868 
1869  explicit constexpr
1870  operator local_days() const noexcept
1871  { return local_days{sys_days{*this}.time_since_epoch()}; }
1872 
1873  constexpr bool
1874  ok() const noexcept
1875  { return _M_y.ok() && _M_mdl.ok(); }
1876 
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  }
1884 
1885  friend constexpr strong_ordering
1886  operator<=>(const year_month_day_last& __x,
1887  const year_month_day_last& __y) noexcept
1888  = default;
1889 
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; }
1895 
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; }
1901 
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; }
1907 
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()}; }
1912 
1913  friend constexpr year_month_day_last
1914  operator+(const years& __dy,
1915  const year_month_day_last& __ymdl) noexcept
1916  { return __ymdl + __dy; }
1917 
1918  friend constexpr year_month_day_last
1919  operator-(const year_month_day_last& __ymdl,
1920  const years& __dy) noexcept
1921  { return __ymdl + -__dy; }
1922 
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()}}; }
1926 
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}; }
1931 
1932  friend constexpr year_month_day_last
1933  operator/(int __y, const chrono::month_day_last& __mdl) noexcept
1934  { return chrono::year(__y) / __mdl; }
1935 
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; }
1940 
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  };
1945 
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  { }
1951 
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  }
1959 
1960  // YEAR_MONTH_WEEKDAY
1961 
1962  class year_month_weekday
1963  {
1964  private:
1965  chrono::year _M_y;
1966  chrono::month _M_m;
1967  chrono::weekday_indexed _M_wdi;
1968 
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  }
1977 
1978  public:
1979  year_month_weekday() = default;
1980 
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  { }
1986 
1987  constexpr
1988  year_month_weekday(const sys_days& __dp) noexcept
1989  : year_month_weekday{_S_from_sys_days(__dp)}
1990  { }
1991 
1992  explicit constexpr
1993  year_month_weekday(const local_days& __dp) noexcept
1994  : year_month_weekday{sys_days{__dp.time_since_epoch()}}
1995  { }
1996 
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  }
2004 
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  }
2012 
2013  constexpr year_month_weekday&
2014  operator+=(const years& __y) noexcept
2015  {
2016  *this = *this + __y;
2017  return *this;
2018  }
2019 
2020  constexpr year_month_weekday&
2021  operator-=(const years& __y) noexcept
2022  {
2023  *this = *this - __y;
2024  return *this;
2025  }
2026 
2027  constexpr chrono::year
2028  year() const noexcept
2029  { return _M_y; }
2030 
2031  constexpr chrono::month
2032  month() const noexcept
2033  { return _M_m; }
2034 
2035  constexpr chrono::weekday
2036  weekday() const noexcept
2037  { return _M_wdi.weekday(); }
2038 
2039  constexpr unsigned
2040  index() const noexcept
2041  { return _M_wdi.index(); }
2042 
2043  constexpr chrono::weekday_indexed
2044  weekday_indexed() const noexcept
2045  { return _M_wdi; }
2046 
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  }
2054 
2055  explicit constexpr
2056  operator local_days() const noexcept
2057  { return local_days{sys_days{*this}.time_since_epoch()}; }
2058 
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  }
2072 
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  }
2081 
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  }
2089 
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; }
2094 
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()}; }
2098 
2099  friend constexpr year_month_weekday
2100  operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept
2101  { return __ymwd + __dy; }
2102 
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; }
2107 
2108  friend constexpr year_month_weekday
2109  operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept
2110  { return __ymwd + -__dy; }
2111 
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}; }
2116 
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()}; }
2120 
2121  friend constexpr year_month_weekday
2122  operator/(int __y, const month_weekday& __mwd) noexcept
2123  { return chrono::year(__y) / __mwd; }
2124 
2125  friend constexpr year_month_weekday
2126  operator/(const month_weekday& __mwd, const chrono::year& __y) noexcept
2127  { return __y / __mwd; }
2128 
2129  friend constexpr year_month_weekday
2130  operator/(const month_weekday& __mwd, int __y) noexcept
2131  { return chrono::year(__y) / __mwd; }
2132  };
2133 
2134  // YEAR_MONTH_WEEKDAY_LAST
2135 
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;
2142 
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  { }
2149 
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  }
2157 
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  }
2165 
2166  constexpr year_month_weekday_last&
2167  operator+=(const years& __y) noexcept
2168  {
2169  *this = *this + __y;
2170  return *this;
2171  }
2172 
2173  constexpr year_month_weekday_last&
2174  operator-=(const years& __y) noexcept
2175  {
2176  *this = *this - __y;
2177  return *this;
2178  }
2179 
2180  constexpr chrono::year
2181  year() const noexcept
2182  { return _M_y; }
2183 
2184  constexpr chrono::month
2185  month() const noexcept
2186  { return _M_m; }
2187 
2188  constexpr chrono::weekday
2189  weekday() const noexcept
2190  { return _M_wdl.weekday(); }
2191 
2192  constexpr chrono::weekday_last
2193  weekday_last() const noexcept
2194  { return _M_wdl; }
2195 
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  }
2203 
2204  explicit constexpr
2205  operator local_days() const noexcept
2206  { return local_days{sys_days{*this}.time_since_epoch()}; }
2207 
2208  constexpr bool
2209  ok() const noexcept
2210  { return _M_y.ok() && _M_m.ok() && _M_wdl.ok(); }
2211 
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  }
2220 
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  }
2229 
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; }
2235 
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()}; }
2240 
2241  friend constexpr year_month_weekday_last
2242  operator+(const years& __dy,
2243  const year_month_weekday_last& __ymwdl) noexcept
2244  { return __ymwdl + __dy; }
2245 
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; }
2251 
2252  friend constexpr year_month_weekday_last
2253  operator-(const year_month_weekday_last& __ymwdl,
2254  const years& __dy) noexcept
2255  { return __ymwdl + -__dy; }
2256 
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}; }
2261 
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()}; }
2266 
2267  friend constexpr year_month_weekday_last
2268  operator/(int __y, const chrono::month_weekday_last& __mwdl) noexcept
2269  { return chrono::year(__y) / __mwdl; }
2270 
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; }
2275 
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  };
2280 
2281  // HH_MM_SS
2282 
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  }
2294 
2295  template<typename _Duration> struct __utc_leap_second;
2296  }
2297  /// @endcond
2298 
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 );
2310 
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;
2326 
2327  int __width = (__multiplicity_2 > __multiplicity_5
2328  ? __multiplicity_2 : __multiplicity_5);
2329  if (__width > 18)
2330  __width = 18;
2331  return __width;
2332  }
2333 
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  }
2347 
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  }
2356 
2357  public:
2358  static constexpr unsigned fractional_width = {_S_fractional_width()};
2359 
2360  using precision
2361  = duration<common_type_t<typename _Duration::rep,
2362  chrono::seconds::rep>,
2363  ratio<1, __detail::__pow10(fractional_width)>>;
2364 
2365  constexpr hh_mm_ss() noexcept = default;
2366 
2367  constexpr explicit
2368  hh_mm_ss(_Duration __d)
2369  : hh_mm_ss(_S_abs(__d), __d < _Duration::zero())
2370  { }
2371 
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  }
2380 
2381  constexpr chrono::hours
2382  hours() const noexcept
2383  { return _M_h; }
2384 
2385  constexpr chrono::minutes
2386  minutes() const noexcept
2387  { return _M_m; }
2388 
2389  constexpr chrono::seconds
2390  seconds() const noexcept
2391  { return _M_s; }
2392 
2393  constexpr precision
2394  subseconds() const noexcept
2395  { return static_cast<precision>(_M_ss); }
2396 
2397  constexpr explicit
2398  operator precision() const noexcept
2399  { return to_duration(); }
2400 
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  }
2409 
2410  private:
2411  static constexpr bool _S_is_unsigned
2412  = __and_v<is_integral<typename _Duration::rep>,
2413  is_unsigned<typename _Duration::rep>>;
2414 
2415  template<typename _Ratio>
2416  using __byte_duration = duration<unsigned char, _Ratio>;
2417 
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{};
2423 
2424  constexpr explicit
2425  operator _Dur() const noexcept
2426  { return _Dur(_M_r); }
2427  };
2428 
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  };
2438 
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{};
2446 
2447  constexpr explicit
2448  operator duration<_Rep, _Period>() const noexcept
2449  { return duration<_Rep, _Period>(_M_r); }
2450  };
2451 
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{};
2459 
2460  constexpr explicit
2461  operator duration<_Rep, _Period>() const noexcept
2462  { return duration<_Rep, _Period>(_M_r); }
2463  };
2464 
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{};
2470 
2471  template<typename> friend struct __detail::__utc_leap_second;
2472  };
2473 
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  }
2487 
2488  sys_days _M_date;
2489  hh_mm_ss<common_type_t<_Duration, days>> _M_time;
2490  };
2491  }
2492  /// @endcond
2493 
2494  // 12/24 HOURS FUNCTIONS
2495 
2496  constexpr bool
2497  is_am(const hours& __h) noexcept
2498  { return 0h <= __h && __h <= 11h; }
2499 
2500  constexpr bool
2501  is_pm(const hours& __h) noexcept
2502  { return 12h <= __h && __h <= 23h; }
2503 
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  }
2513 
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  }
2532 
2533 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
2534  // C++20 [time.zones] Time zones
2535 
2536  struct tzdb;
2537 
2538  struct sys_info
2539  {
2540  sys_seconds begin;
2541  sys_seconds end;
2542  seconds offset;
2543  minutes save;
2544  string abbrev;
2545  };
2546 
2547  struct local_info
2548  {
2549  static constexpr int unique = 0;
2550  static constexpr int nonexistent = 1;
2551  static constexpr int ambiguous = 2;
2552 
2553  int result;
2554  sys_info first;
2555  sys_info second;
2556  };
2557 
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); }
2566 
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  };
2584 
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); }
2593 
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  };
2609 
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  }
2623 
2624  enum class choose { earliest, latest };
2625 
2626  class time_zone
2627  {
2628  public:
2629  time_zone(time_zone&&) = default;
2630  time_zone& operator=(time_zone&&) = default;
2631 
2632  ~time_zone();
2633 
2634  [[nodiscard]]
2635  string_view name() const noexcept { return _M_name; }
2636 
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)); }
2641 
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)); }
2646 
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);
2652 
2653  if (__info.result != local_info::unique)
2654  __throw_bad_local_time(__tp, __info);
2655 
2656  return sys_time<_Duration>(__tp.time_since_epoch())
2657  - __info.first.offset;
2658  }
2659 
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);
2665 
2666  if (__info.result == local_info::nonexistent)
2667  return __info.first.end; // Last second of the previous sys_info.
2668 
2669  sys_time<_Duration> __st(__tp.time_since_epoch());
2670 
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:
2674 
2675  return __st - __info.first.offset;
2676  }
2677 
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  }
2685 
2686  [[nodiscard]] friend bool
2687  operator==(const time_zone& __x, const time_zone& __y) noexcept
2688  { return __x._M_name == __y._M_name; }
2689 
2690  [[nodiscard]] friend strong_ordering
2691  operator<=>(const time_zone& __x, const time_zone& __y) noexcept
2692  { return __x._M_name <=> __y._M_name; }
2693 
2694  private:
2695  sys_info _M_get_sys_info(sys_seconds) const;
2696  local_info _M_get_local_info(local_seconds) const;
2697 
2698  friend const tzdb& reload_tzdb();
2699  friend struct tzdb;
2700  friend class tzdb_list;
2701 
2702  struct _Impl;
2703 
2704  explicit time_zone(unique_ptr<_Impl> __p);
2705  string _M_name;
2706  unique_ptr<_Impl> _M_impl;
2707  };
2708 
2709  const time_zone* locate_zone(string_view __tz_name);
2710  const time_zone* current_zone();
2711 
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;
2729 
2730  public:
2731  tzdb_list(const tzdb_list&) = delete;
2732  tzdb_list& operator=(const tzdb_list&) = delete;
2733 
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;
2749 
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;
2755 
2756  reference operator*() const noexcept;
2757  pointer operator->() const noexcept { return &**this; }
2758  const_iterator& operator++();
2759  const_iterator operator++(int);
2760 
2761  bool operator==(const const_iterator&) const noexcept = default;
2762 
2763  private:
2764  explicit const_iterator(const shared_ptr<_Node>&) noexcept;
2765 
2766  friend class tzdb_list;
2767 
2768  shared_ptr<_Node> _M_node;
2769  void* _M_reserved = nullptr;
2770  };
2771 
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;
2780 
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);
2796 
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(); }
2801 
2802  private:
2803  constexpr explicit tzdb_list(nullptr_t);
2804 
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  };
2813 
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;
2819 
2820  string_view name() const noexcept { return _M_name; }
2821  string_view target() const noexcept { return _M_target; }
2822 
2823  friend bool
2824  operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept
2825  { return __x.name() == __y.name(); }
2826 
2827  friend strong_ordering
2828  operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept
2829  { return __x.name() <=> __y.name(); }
2830 
2831  private:
2832  friend const tzdb& reload_tzdb();
2833  friend struct tzdb_list::_Node;
2834 
2835  explicit time_zone_link(nullptr_t) { }
2836 
2837  string _M_name;
2838  string _M_target;
2839  };
2840 
2841  class leap_second
2842  {
2843  public:
2844  leap_second(const leap_second&) = default;
2845  leap_second& operator=(const leap_second&) = default;
2846 
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  }
2855 
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  }
2864 
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;
2869 
2870  [[nodiscard]] friend constexpr strong_ordering
2871  operator<=>(const leap_second& __x, const leap_second& __y) noexcept
2872  { return __x.date() <=> __y.date(); }
2873 
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; }
2879 
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; }
2885 
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(); }
2891 
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(); }
2897 
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; }
2903 
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()); }
2909 
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); }
2915 
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); }
2921 
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()); }
2927 
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; }
2933 
2934  private:
2935  explicit leap_second(seconds::rep __s) : _M_s(__s) { }
2936 
2937  friend struct tzdb_list::_Node;
2938 
2939  friend const tzdb& reload_tzdb();
2940 
2941  template<typename _Duration>
2942  friend leap_second_info
2943  get_leap_second_info(const utc_time<_Duration>&);
2944 
2945  seconds _M_s; // == date().time_since_epoch() * value().count()
2946  };
2947 
2948  template<class _Tp> struct zoned_traits { };
2949 
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"); }
2956 
2957  static const time_zone*
2958  locate_zone(string_view __name)
2959  { return std::chrono::locate_zone(__name); }
2960  };
2961 
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;
2968 
2969  const time_zone*
2970  locate_zone(string_view __tz_name) const;
2971 
2972  const time_zone*
2973  current_zone() const;
2974 
2975  private:
2976  friend const tzdb& reload_tzdb();
2977  friend class time_zone;
2978  friend struct tzdb_list::_Node;
2979  };
2980 
2981  tzdb_list& get_tzdb_list();
2982  const tzdb& get_tzdb();
2983 
2984  const tzdb& reload_tzdb();
2985  string remote_version();
2986 
2987  template<typename _Duration, typename _TimeZonePtr = const time_zone*>
2988  class zoned_time
2989  {
2990  static_assert(__is_duration_v<_Duration>);
2991 
2992  using _Traits = zoned_traits<_TimeZonePtr>;
2993 
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>;
2997 
2998  public:
2999  using duration = common_type_t<_Duration, seconds>;
3000 
3001  zoned_time() requires requires { _Traits::default_zone(); }
3002  { }
3003 
3004  zoned_time(const zoned_time&) = default;
3005  zoned_time& operator=(const zoned_time&) = default;
3006 
3007  zoned_time(const sys_time<_Duration>& __st)
3008  requires requires { _Traits::default_zone(); }
3009  : _M_tp(__st)
3010  { }
3011 
3012  explicit
3013  zoned_time(_TimeZonePtr __z) : _M_zone(std::move(__z)) { }
3014 
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  { }
3022 
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  { }
3028 
3029  zoned_time(_TimeZonePtr __z, const sys_time<_Duration>& __st)
3030  : _M_zone(std::move(__z)), _M_tp(__st)
3031  { }
3032 
3033  zoned_time(string_view __name, const sys_time<_Duration>& __st)
3034  : zoned_time(_Traits::locate_zone(__name), __st)
3035  { }
3036 
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  { }
3043 
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  { }
3051 
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  { }
3059 
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  { }
3069 
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  { }
3076 
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  { }
3084 
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  { }
3094 
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  { }
3105 
3106  zoned_time&
3107  operator=(const sys_time<_Duration>& __st)
3108  {
3109  _M_tp = __st;
3110  return *this;
3111  }
3112 
3113  zoned_time&
3114  operator=(const local_time<_Duration>& __lt)
3115  {
3116  _M_tp = _M_zone->to_sys(__lt);
3117  return *this;
3118  }
3119 
3120  [[nodiscard]]
3121  operator sys_time<duration>() const { return _M_tp; }
3122 
3123  [[nodiscard]]
3124  explicit operator local_time<duration>() const
3125  { return get_local_time(); }
3126 
3127  [[nodiscard]]
3128  _TimeZonePtr
3129  get_time_zone() const
3130  { return _M_zone; }
3131 
3132  [[nodiscard]]
3133  local_time<duration>
3134  get_local_time() const
3135  { return _M_zone->to_local(_M_tp); }
3136 
3137  [[nodiscard]]
3138  sys_time<duration>
3139  get_sys_time() const
3140  { return _M_tp; }
3141 
3142  [[nodiscard]]
3143  sys_info
3144  get_info() const
3145  { return _M_zone->get_info(_M_tp); }
3146 
3147  [[nodiscard]] friend bool
3148  operator==(const zoned_time&, const zoned_time&) = default;
3149 
3150  private:
3151  _TimeZonePtr _M_zone{ _Traits::default_zone() };
3152  sys_time<duration> _M_tp{};
3153 
3154  template<typename _Duration2, typename _TimeZonePtr2>
3155  friend class zoned_time;
3156  };
3157 
3158  zoned_time() -> zoned_time<seconds>;
3159 
3160  template<typename _Duration>
3161  zoned_time(sys_time<_Duration>)
3162  -> zoned_time<common_type_t<_Duration, seconds>>;
3163 
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
3171 
3172  template<typename _TimeZonePtrOrName>
3173  zoned_time(_TimeZonePtrOrName&&)
3174  -> zoned_time<seconds, __time_zone_representation<_TimeZonePtrOrName>>;
3175 
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>>;
3180 
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>>;
3186 
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>>;
3193 
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  }
3203 
3204  using zoned_seconds = zoned_time<seconds>;
3205 #endif // _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3206 
3207 namespace __detail
3208 {
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 {};
3214 
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
3247 
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);
3253 
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();
3261 
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);
3282 
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) };
3286 
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
3305 
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  }
3314 
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  }
3325 
3326  /// @} group chrono
3327 #endif // C++20
3328  } // namespace chrono
3329 
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)}; }
3344 
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
3355 
3356 _GLIBCXX_END_NAMESPACE_VERSION
3357 } // namespace std
3358 
3359 #if __cplusplus >= 202002L
3360 # include <bits/chrono_io.h>
3361 #endif
3362 
3363 #endif // C++11
3364 
3365 #endif //_GLIBCXX_CHRONO