libstdc++
chrono
Go to the documentation of this file.
1 // <chrono> -*- C++ -*-
2 
3 // Copyright (C) 2008-2026 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 // [time]
26 
27 /** @file include/chrono
28  * This is a Standard C++ Library header.
29  * @ingroup chrono
30  */
31 
32 #ifndef _GLIBCXX_CHRONO
33 #define _GLIBCXX_CHRONO 1
34 
35 #ifdef _GLIBCXX_SYSHDR
36 #pragma GCC system_header
37 #endif
38 
39 #ifdef _GLIBCXX_NO_FREESTANDING_CHRONO
40 # include <bits/requires_hosted.h> // for <ctime> and clocks
41 #endif
42 
43 #if __cplusplus < 201103L
44 # include <bits/c++0x_warning.h>
45 #else
46 
47 #define __glibcxx_want_chrono
48 #define __glibcxx_want_chrono_udls
49 #include <bits/version.h>
50 
51 #include <bits/chrono.h>
52 
53 #if __cpp_lib_bitops >= 201907L
54 # include <bit> // __countr_zero
55 #endif
56 #ifdef __glibcxx_chrono_cxx20
57 # include <bits/stl_algo.h> // upper_bound
58 # include <bits/range_access.h> // begin/end for arrays
59 #endif
60 #if __cpp_lib_chrono >= 201803L // C++20 && HOSTED && USE_CXX11_ABI
61 # include <sstream>
62 # include <string>
63 # include <vector>
64 # include <bits/shared_ptr.h>
65 # include <bits/unique_ptr.h>
66 #endif
67 #if __glibcxx_chrono_cxx20 >= 202306L // C++26
68 # include <bits/functional_hash.h>
69 #endif
70 
71 namespace std _GLIBCXX_VISIBILITY(default)
72 {
73 _GLIBCXX_BEGIN_NAMESPACE_VERSION
74 
75  /**
76  * @defgroup chrono Time
77  * @ingroup utilities
78  *
79  * Classes and functions for time.
80  *
81  * @since C++11
82  */
83 
84  /** @namespace std::chrono
85  * @brief ISO C++ 2011 namespace for date and time utilities
86  * @ingroup chrono
87  */
88  namespace chrono
89  {
90 #ifdef __glibcxx_chrono_cxx20
91  /// @addtogroup chrono
92  /// @{
93  struct local_t { };
94  template<typename _Duration>
95  using local_time = time_point<local_t, _Duration>;
96  using local_seconds = local_time<seconds>;
97  using local_days = local_time<days>;
98 
99 #if _GLIBCXX_HOSTED
100  class utc_clock;
101  class tai_clock;
102  class gps_clock;
103 
104  template<typename _Duration>
105  using utc_time = time_point<utc_clock, _Duration>;
106  using utc_seconds = utc_time<seconds>;
107 
108  template<typename _Duration>
109  using tai_time = time_point<tai_clock, _Duration>;
110  using tai_seconds = tai_time<seconds>;
111 
112  template<typename _Duration>
113  using gps_time = time_point<gps_clock, _Duration>;
114  using gps_seconds = gps_time<seconds>;
115 
116  template<> struct is_clock<utc_clock> : true_type { };
117  template<> struct is_clock<tai_clock> : true_type { };
118  template<> struct is_clock<gps_clock> : true_type { };
119 
120  template<> inline constexpr bool is_clock_v<utc_clock> = true;
121  template<> inline constexpr bool is_clock_v<tai_clock> = true;
122  template<> inline constexpr bool is_clock_v<gps_clock> = true;
123 
124  struct leap_second_info
125  {
126  bool is_leap_second;
127  seconds elapsed;
128  };
129 
130  template<typename _Duration>
131  leap_second_info
132  get_leap_second_info(const utc_time<_Duration>& __ut);
133 
134  /** A clock that measures Universal Coordinated Time (UTC).
135  *
136  * The epoch is 1970-01-01 00:00:00.
137  *
138  * @since C++20
139  */
140  class utc_clock
141  {
142  public:
143  using rep = system_clock::rep;
144  using period = system_clock::period;
145  using duration = chrono::duration<rep, period>;
146  using time_point = chrono::time_point<utc_clock>;
147  static constexpr bool is_steady = false;
148 
149  [[nodiscard]]
150  static time_point
151  now()
152  { return from_sys(system_clock::now()); }
153 
154  template<typename _Duration>
155  [[nodiscard]]
156  static sys_time<common_type_t<_Duration, seconds>>
157  to_sys(const utc_time<_Duration>& __t)
158  {
159  using _CDur = common_type_t<_Duration, seconds>;
160  const auto __li = chrono::get_leap_second_info(__t);
161  sys_time<_CDur> __s{__t.time_since_epoch() - __li.elapsed};
162  if (__li.is_leap_second)
163  __s = chrono::floor<seconds>(__s) + seconds{1} - _CDur{1};
164  return __s;
165  }
166 
167  template<typename _Duration>
168  [[nodiscard]]
169  static utc_time<common_type_t<_Duration, seconds>>
170  from_sys(const sys_time<_Duration>& __t);
171  };
172 
173  /** A clock that measures International Atomic Time.
174  *
175  * The epoch is 1958-01-01 00:00:00.
176  *
177  * @since C++20
178  */
179  class tai_clock
180  {
181  public:
182  using rep = system_clock::rep;
183  using period = system_clock::period;
184  using duration = chrono::duration<rep, period>;
185  using time_point = chrono::time_point<tai_clock>;
186  static constexpr bool is_steady = false;
187 
188  [[nodiscard]]
189  static time_point
190  now(); // in src/c++20/clock.cc
191 
192  template<typename _Duration>
193  [[nodiscard]]
194  static utc_time<common_type_t<_Duration, seconds>>
195  to_utc(const tai_time<_Duration>& __t)
196  {
197  using _CDur = common_type_t<_Duration, seconds>;
198  return utc_time<_CDur>{__t.time_since_epoch()} - 378691210s;
199  }
200 
201  template<typename _Duration>
202  [[nodiscard]]
203  static tai_time<common_type_t<_Duration, seconds>>
204  from_utc(const utc_time<_Duration>& __t)
205  {
206  using _CDur = common_type_t<_Duration, seconds>;
207  return tai_time<_CDur>{__t.time_since_epoch()} + 378691210s;
208  }
209  };
210 
211  /** A clock that measures GPS time.
212  *
213  * The epoch is 1980-01-06 00:00:00.
214  *
215  * @since C++20
216  */
217  class gps_clock
218  {
219  public:
220  using rep = system_clock::rep;
221  using period = system_clock::period;
222  using duration = chrono::duration<rep, period>;
223  using time_point = chrono::time_point<gps_clock>;
224  static constexpr bool is_steady = false;
225 
226  [[nodiscard]]
227  static time_point
228  now(); // in src/c++20/clock.cc
229 
230  template<typename _Duration>
231  [[nodiscard]]
232  static utc_time<common_type_t<_Duration, seconds>>
233  to_utc(const gps_time<_Duration>& __t)
234  {
235  using _CDur = common_type_t<_Duration, seconds>;
236  return utc_time<_CDur>{__t.time_since_epoch()} + 315964809s;
237  }
238 
239  template<typename _Duration>
240  [[nodiscard]]
241  static gps_time<common_type_t<_Duration, seconds>>
242  from_utc(const utc_time<_Duration>& __t)
243  {
244  using _CDur = common_type_t<_Duration, seconds>;
245  return gps_time<_CDur>{__t.time_since_epoch()} - 315964809s;
246  }
247  };
248 #endif // _GLIBCXX_HOSTED
249 
250  template<typename _DestClock, typename _SourceClock>
251  struct clock_time_conversion
252  { };
253 
254  // Identity conversions
255 
256  template<typename _Clock>
257  struct clock_time_conversion<_Clock, _Clock>
258  {
259  template<typename _Duration>
260  time_point<_Clock, _Duration>
261  operator()(const time_point<_Clock, _Duration>& __t) const
262  { return __t; }
263  };
264 
265 #if _GLIBCXX_HOSTED
266  template<>
267  struct clock_time_conversion<system_clock, system_clock>
268  {
269  template<typename _Duration>
270  sys_time<_Duration>
271  operator()(const sys_time<_Duration>& __t) const
272  { return __t; }
273  };
274 
275  template<>
276  struct clock_time_conversion<utc_clock, utc_clock>
277  {
278  template<typename _Duration>
279  utc_time<_Duration>
280  operator()(const utc_time<_Duration>& __t) const
281  { return __t; }
282  };
283 
284  // Conversions between system_clock and utc_clock
285 
286  template<>
287  struct clock_time_conversion<utc_clock, system_clock>
288  {
289  template<typename _Duration>
290  utc_time<common_type_t<_Duration, seconds>>
291  operator()(const sys_time<_Duration>& __t) const
292  { return utc_clock::from_sys(__t); }
293  };
294 
295  template<>
296  struct clock_time_conversion<system_clock, utc_clock>
297  {
298  template<typename _Duration>
299  sys_time<common_type_t<_Duration, seconds>>
300  operator()(const utc_time<_Duration>& __t) const
301  { return utc_clock::to_sys(__t); }
302  };
303 
304  /// @cond undocumented
305  template<typename _Tp, typename _Clock>
306  inline constexpr bool __is_time_point_for_v = false;
307 
308  template<typename _Clock, typename _Duration>
309  inline constexpr bool
310  __is_time_point_for_v<time_point<_Clock, _Duration>, _Clock> = true;
311  /// @endcond
312 
313  // Conversions between system_clock and other clocks
314 
315  template<typename _SourceClock>
316  struct clock_time_conversion<system_clock, _SourceClock>
317  {
318  template<typename _Duration, typename _Src = _SourceClock>
319  auto
320  operator()(const time_point<_SourceClock, _Duration>& __t) const
321  -> decltype(_Src::to_sys(__t))
322  {
323  using _Ret = decltype(_SourceClock::to_sys(__t));
324  static_assert(__is_time_point_for_v<_Ret, system_clock>);
325  return _SourceClock::to_sys(__t);
326  }
327  };
328 
329  template<typename _DestClock>
330  struct clock_time_conversion<_DestClock, system_clock>
331  {
332  template<typename _Duration, typename _Dest = _DestClock>
333  auto
334  operator()(const sys_time<_Duration>& __t) const
335  -> decltype(_Dest::from_sys(__t))
336  {
337  using _Ret = decltype(_DestClock::from_sys(__t));
338  static_assert(__is_time_point_for_v<_Ret, _DestClock>);
339  return _DestClock::from_sys(__t);
340  }
341  };
342 
343  // Conversions between utc_clock and other clocks
344 
345  template<typename _SourceClock>
346  struct clock_time_conversion<utc_clock, _SourceClock>
347  {
348  template<typename _Duration, typename _Src = _SourceClock>
349  auto
350  operator()(const time_point<_SourceClock, _Duration>& __t) const
351  -> decltype(_Src::to_utc(__t))
352  {
353  using _Ret = decltype(_SourceClock::to_utc(__t));
354  static_assert(__is_time_point_for_v<_Ret, utc_clock>);
355  return _SourceClock::to_utc(__t);
356  }
357  };
358 
359  template<typename _DestClock>
360  struct clock_time_conversion<_DestClock, utc_clock>
361  {
362  template<typename _Duration, typename _Dest = _DestClock>
363  auto
364  operator()(const utc_time<_Duration>& __t) const
365  -> decltype(_Dest::from_utc(__t))
366  {
367  using _Ret = decltype(_DestClock::from_utc(__t));
368  static_assert(__is_time_point_for_v<_Ret, _DestClock>);
369  return _DestClock::from_utc(__t);
370  }
371  };
372 #endif // _GLIBCXX_HOSTED
373 
374  /// @cond undocumented
375  namespace __detail
376  {
377  template<typename _DestClock, typename _SourceClock, typename _Duration>
378  concept __clock_convs
379  = requires (const time_point<_SourceClock, _Duration>& __t) {
380  clock_time_conversion<_DestClock, _SourceClock>{}(__t);
381  };
382 
383 #if _GLIBCXX_HOSTED
384  template<typename _DestClock, typename _SourceClock, typename _Duration>
385  concept __clock_convs_sys
386  = requires (const time_point<_SourceClock, _Duration>& __t) {
387  clock_time_conversion<_DestClock, system_clock>{}(
388  clock_time_conversion<system_clock, _SourceClock>{}(__t));
389  };
390 
391  template<typename _DestClock, typename _SourceClock, typename _Duration>
392  concept __clock_convs_utc
393  = requires (const time_point<_SourceClock, _Duration>& __t) {
394  clock_time_conversion<_DestClock, utc_clock>{}(
395  clock_time_conversion<utc_clock, _SourceClock>{}(__t));
396  };
397 
398  template<typename _DestClock, typename _SourceClock, typename _Duration>
399  concept __clock_convs_sys_utc
400  = requires (const time_point<_SourceClock, _Duration>& __t) {
401  clock_time_conversion<_DestClock, utc_clock>{}(
402  clock_time_conversion<utc_clock, system_clock>{}(
403  clock_time_conversion<system_clock, _SourceClock>{}(__t)));
404  };
405 
406  template<typename _DestClock, typename _SourceClock, typename _Duration>
407  concept __clock_convs_utc_sys
408  = requires (const time_point<_SourceClock, _Duration>& __t) {
409  clock_time_conversion<_DestClock, system_clock>{}(
410  clock_time_conversion<system_clock, utc_clock>{}(
411  clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
412  };
413 #endif // _GLIBCXX_HOSTED
414  } // namespace __detail
415  /// @endcond
416 
417  /// Convert a time point to a different clock.
418  template<typename _DestClock, typename _SourceClock, typename _Duration>
419  [[nodiscard]]
420  inline auto
421  clock_cast(const time_point<_SourceClock, _Duration>& __t)
422  requires __detail::__clock_convs<_DestClock, _SourceClock, _Duration>
423 #if _GLIBCXX_HOSTED
424  || __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>
425  || __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>
426  || __detail::__clock_convs_sys_utc<_DestClock, _SourceClock, _Duration>
427  || __detail::__clock_convs_utc_sys<_DestClock, _SourceClock, _Duration>
428 #endif // _GLIBCXX_HOSTED
429  {
430  constexpr bool __direct
431  = __detail::__clock_convs<_DestClock, _SourceClock, _Duration>;
432  if constexpr (__direct)
433  {
434  return clock_time_conversion<_DestClock, _SourceClock>{}(__t);
435  }
436 #if _GLIBCXX_HOSTED
437  else
438  {
439  constexpr bool __convert_via_sys_clock
440  = __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>;
441  constexpr bool __convert_via_utc_clock
442  = __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>;
443  if constexpr (__convert_via_sys_clock)
444  {
445  static_assert(!__convert_via_utc_clock,
446  "clock_cast requires a unique best conversion, but "
447  "conversion is possible via system_clock and also via"
448  "utc_clock");
449  return clock_time_conversion<_DestClock, system_clock>{}(
450  clock_time_conversion<system_clock, _SourceClock>{}(__t));
451  }
452  else if constexpr (__convert_via_utc_clock)
453  {
454  return clock_time_conversion<_DestClock, utc_clock>{}(
455  clock_time_conversion<utc_clock, _SourceClock>{}(__t));
456  }
457  else
458  {
459  constexpr bool __convert_via_sys_and_utc_clocks
460  = __detail::__clock_convs_sys_utc<_DestClock,
461  _SourceClock,
462  _Duration>;
463 
464  if constexpr (__convert_via_sys_and_utc_clocks)
465  {
466  constexpr bool __convert_via_utc_and_sys_clocks
467  = __detail::__clock_convs_utc_sys<_DestClock,
468  _SourceClock,
469  _Duration>;
470  static_assert(!__convert_via_utc_and_sys_clocks,
471  "clock_cast requires a unique best conversion, but "
472  "conversion is possible via system_clock followed by "
473  "utc_clock, and also via utc_clock followed by "
474  "system_clock");
475  return clock_time_conversion<_DestClock, utc_clock>{}(
476  clock_time_conversion<utc_clock, system_clock>{}(
477  clock_time_conversion<system_clock, _SourceClock>{}(__t)));
478  }
479  else
480  {
481  return clock_time_conversion<_DestClock, system_clock>{}(
482  clock_time_conversion<system_clock, utc_clock>{}(
483  clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
484  }
485  }
486  }
487 #endif // _GLIBCXX_HOSTED
488  }
489 
490  // CALENDRICAL TYPES
491 
492  // CLASS DECLARATIONS
493  class day;
494  class month;
495  class year;
496  class weekday;
497  class weekday_indexed;
498  class weekday_last;
499  class month_day;
500  class month_day_last;
501  class month_weekday;
502  class month_weekday_last;
503  class year_month;
504  class year_month_day;
505  class year_month_day_last;
506  class year_month_weekday;
507  class year_month_weekday_last;
508 
509  struct last_spec
510  {
511  explicit last_spec() = default;
512 
513  friend constexpr month_day_last
514  operator/(int __m, last_spec) noexcept;
515 
516  friend constexpr month_day_last
517  operator/(last_spec, int __m) noexcept;
518  };
519 
520  inline constexpr last_spec last{};
521 
522  /// @cond undocumented
523  namespace __detail
524  {
525  // Helper to __add_modulo and __sub_modulo.
526  template <unsigned __d, typename _Tp>
527  consteval auto
528  __modulo_offset()
529  {
530  using _Up = make_unsigned_t<_Tp>;
531  auto constexpr __a = _Up(-1) - _Up(255 + __d - 2);
532  auto constexpr __b = _Up(__d * (__a / __d) - 1);
533  // Notice: b <= a - 1 <= _Up(-1) - (255 + d - 1) and b % d = d - 1.
534  return _Up(-1) - __b; // >= 255 + d - 1
535  }
536 
537  // Compute the remainder of the Euclidean division of __x + __y divided by
538  // __d without overflowing. Typically, __x <= 255 + d - 1 is sum of
539  // weekday/month with a shift in [0, d - 1] and __y is a duration count.
540  template <unsigned __d, typename _Tp>
541  constexpr unsigned
542  __add_modulo(unsigned __x, _Tp __y)
543  {
544  using _Up = make_unsigned_t<_Tp>;
545  // For __y >= 0, _Up(__y) has the same mathematical value as __y and
546  // this function simply returns (__x + _Up(__y)) % d. Typically, this
547  // doesn't overflow since the range of _Up contains many more positive
548  // values than _Tp's. For __y < 0, _Up(__y) has a mathematical value in
549  // the upper-half range of _Up so that adding a positive value to it
550  // might overflow. Moreover, most likely, _Up(__y) != __y mod d. To
551  // fix both issues we subtract from _Up(__y) an __offset >=
552  // 255 + d - 1 to make room for the addition to __x and shift the modulo
553  // to the correct value.
554  auto const __offset = __y >= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
555  return (__x + _Up(__y) - __offset) % __d;
556  }
557 
558  // Similar to __add_modulo but for __x - __y.
559  template <unsigned __d, typename _Tp>
560  constexpr unsigned
561  __sub_modulo(unsigned __x, _Tp __y)
562  {
563  using _Up = make_unsigned_t<_Tp>;
564  auto const __offset = __y <= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
565  return (__x - _Up(__y) - __offset) % __d;
566  }
567 
568  inline constexpr unsigned __days_per_month[12]
569  = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
570  } // namespace __detail
571  /// @endcond
572 
573  // DAY
574 
575  class day
576  {
577  private:
578  unsigned char _M_d;
579 
580  public:
581  day() = default;
582 
583  explicit constexpr
584  day(unsigned __d) noexcept
585  : _M_d(__d)
586  { }
587 
588  constexpr day&
589  operator++() noexcept
590  {
591  ++_M_d;
592  return *this;
593  }
594 
595  constexpr day
596  operator++(int) noexcept
597  {
598  auto __ret = *this;
599  ++(*this);
600  return __ret;
601  }
602 
603  constexpr day&
604  operator--() noexcept
605  {
606  --_M_d;
607  return *this;
608  }
609 
610  constexpr day
611  operator--(int) noexcept
612  {
613  auto __ret = *this;
614  --(*this);
615  return __ret;
616  }
617 
618  constexpr day&
619  operator+=(const days& __d) noexcept
620  {
621  *this = *this + __d;
622  return *this;
623  }
624 
625  constexpr day&
626  operator-=(const days& __d) noexcept
627  {
628  *this = *this - __d;
629  return *this;
630  }
631 
632  constexpr explicit
633  operator unsigned() const noexcept
634  { return _M_d; }
635 
636  constexpr bool
637  ok() const noexcept
638  { return 1 <= _M_d && _M_d <= 31; }
639 
640  friend constexpr bool
641  operator==(const day& __x, const day& __y) noexcept
642  { return unsigned{__x} == unsigned{__y}; }
643 
644  friend constexpr strong_ordering
645  operator<=>(const day& __x, const day& __y) noexcept
646  { return unsigned{__x} <=> unsigned{__y}; }
647 
648  friend constexpr day
649  operator+(const day& __x, const days& __y) noexcept
650  { return day(unsigned{__x} + __y.count()); }
651 
652  friend constexpr day
653  operator+(const days& __x, const day& __y) noexcept
654  { return __y + __x; }
655 
656  friend constexpr day
657  operator-(const day& __x, const days& __y) noexcept
658  { return __x + -__y; }
659 
660  friend constexpr days
661  operator-(const day& __x, const day& __y) noexcept
662  { return days{int(unsigned{__x}) - int(unsigned{__y})}; }
663 
664  friend constexpr month_day
665  operator/(const month& __m, const day& __d) noexcept;
666 
667  friend constexpr month_day
668  operator/(int __m, const day& __d) noexcept;
669 
670  friend constexpr month_day
671  operator/(const day& __d, const month& __m) noexcept;
672 
673  friend constexpr month_day
674  operator/(const day& __d, int __m) noexcept;
675 
676  friend constexpr year_month_day
677  operator/(const year_month& __ym, const day& __d) noexcept;
678  };
679 
680  // MONTH
681 
682  class month
683  {
684  private:
685  unsigned char _M_m;
686 
687  public:
688  month() = default;
689 
690  explicit constexpr
691  month(unsigned __m) noexcept
692  : _M_m(__m)
693  { }
694 
695  constexpr month&
696  operator++() noexcept
697  {
698  *this += months{1};
699  return *this;
700  }
701 
702  constexpr month
703  operator++(int) noexcept
704  {
705  auto __ret = *this;
706  ++(*this);
707  return __ret;
708  }
709 
710  constexpr month&
711  operator--() noexcept
712  {
713  *this -= months{1};
714  return *this;
715  }
716 
717  constexpr month
718  operator--(int) noexcept
719  {
720  auto __ret = *this;
721  --(*this);
722  return __ret;
723  }
724 
725  constexpr month&
726  operator+=(const months& __m) noexcept
727  {
728  *this = *this + __m;
729  return *this;
730  }
731 
732  constexpr month&
733  operator-=(const months& __m) noexcept
734  {
735  *this = *this - __m;
736  return *this;
737  }
738 
739  explicit constexpr
740  operator unsigned() const noexcept
741  { return _M_m; }
742 
743  constexpr bool
744  ok() const noexcept
745  { return 1 <= _M_m && _M_m <= 12; }
746 
747  friend constexpr bool
748  operator==(const month& __x, const month& __y) noexcept
749  { return unsigned{__x} == unsigned{__y}; }
750 
751  friend constexpr strong_ordering
752  operator<=>(const month& __x, const month& __y) noexcept
753  { return unsigned{__x} <=> unsigned{__y}; }
754 
755  friend constexpr month
756  operator+(const month& __x, const months& __y) noexcept
757  {
758  // modulo(x + (y - 1), 12) = modulo(x + (y - 1) + 12, 12)
759  // = modulo((x + 11) + y , 12)
760  return month{1 + __detail::__add_modulo<12>(
761  unsigned{__x} + 11, __y.count())};
762  }
763 
764  friend constexpr month
765  operator+(const months& __x, const month& __y) noexcept
766  { return __y + __x; }
767 
768  friend constexpr month
769  operator-(const month& __x, const months& __y) noexcept
770  {
771  // modulo(x + (-y - 1), 12) = modulo(x + (-y - 1) + 12, 12)
772  // = modulo((x + 11) - y , 12)
773  return month{1 + __detail::__sub_modulo<12>(
774  unsigned{__x} + 11, __y.count())};
775  }
776 
777  friend constexpr months
778  operator-(const month& __x, const month& __y) noexcept
779  {
780  const auto __dm = int(unsigned(__x)) - int(unsigned(__y));
781  return months{__dm < 0 ? 12 + __dm : __dm};
782  }
783 
784  friend constexpr year_month
785  operator/(const year& __y, const month& __m) noexcept;
786 
787  friend constexpr month_day
788  operator/(const month& __m, int __d) noexcept;
789 
790  friend constexpr month_day_last
791  operator/(const month& __m, last_spec) noexcept;
792 
793  friend constexpr month_day_last
794  operator/(last_spec, const month& __m) noexcept;
795 
796  friend constexpr month_weekday
797  operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
798 
799  friend constexpr month_weekday
800  operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
801 
802  friend constexpr month_weekday_last
803  operator/(const month& __m, const weekday_last& __wdl) noexcept;
804 
805  friend constexpr month_weekday_last
806  operator/(const weekday_last& __wdl, const month& __m) noexcept;
807  };
808 
809  inline constexpr month January{1};
810  inline constexpr month February{2};
811  inline constexpr month March{3};
812  inline constexpr month April{4};
813  inline constexpr month May{5};
814  inline constexpr month June{6};
815  inline constexpr month July{7};
816  inline constexpr month August{8};
817  inline constexpr month September{9};
818  inline constexpr month October{10};
819  inline constexpr month November{11};
820  inline constexpr month December{12};
821 
822  // YEAR
823 
824  class year
825  {
826  private:
827  short _M_y;
828 
829  public:
830  year() = default;
831 
832  explicit constexpr
833  year(int __y) noexcept
834  : _M_y{static_cast<short>(__y)}
835  { }
836 
837  static constexpr year
838  min() noexcept
839  { return year{-32767}; }
840 
841  static constexpr year
842  max() noexcept
843  { return year{32767}; }
844 
845  constexpr year&
846  operator++() noexcept
847  {
848  ++_M_y;
849  return *this;
850  }
851 
852  constexpr year
853  operator++(int) noexcept
854  {
855  auto __ret = *this;
856  ++(*this);
857  return __ret;
858  }
859 
860  constexpr year&
861  operator--() noexcept
862  {
863  --_M_y;
864  return *this;
865  }
866 
867  constexpr year
868  operator--(int) noexcept
869  {
870  auto __ret = *this;
871  --(*this);
872  return __ret;
873  }
874 
875  constexpr year&
876  operator+=(const years& __y) noexcept
877  {
878  *this = *this + __y;
879  return *this;
880  }
881 
882  constexpr year&
883  operator-=(const years& __y) noexcept
884  {
885  *this = *this - __y;
886  return *this;
887  }
888 
889  constexpr year
890  operator+() const noexcept
891  { return *this; }
892 
893  constexpr year
894  operator-() const noexcept
895  { return year{-_M_y}; }
896 
897  constexpr bool
898  is_leap() const noexcept
899  {
900  // Testing divisibility by 100 first gives better performance [1], i.e.,
901  // return _M_y % 100 == 0 ? _M_y % 400 == 0 : _M_y % 16 == 0;
902  // Furthermore, if _M_y % 100 == 0, then _M_y % 400 == 0 is equivalent
903  // to _M_y % 16 == 0, so we can simplify it to
904  // return _M_y % 100 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0. // #1
905  // Similarly, we can replace 100 with 25 (which is good since
906  // _M_y % 25 == 0 requires one fewer instruction than _M_y % 100 == 0
907  // [2]):
908  // return _M_y % 25 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0. // #2
909  // Indeed, first assume _M_y % 4 != 0. Then _M_y % 16 != 0 and hence,
910  // _M_y % 4 == 0 and _M_y % 16 == 0 are both false. Therefore, #2
911  // returns false as it should (regardless of _M_y % 25.) Now assume
912  // _M_y % 4 == 0. In this case, _M_y % 25 == 0 if, and only if,
913  // _M_y % 100 == 0, that is, #1 and #2 are equivalent. Finally, #2 is
914  // equivalent to
915  // return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0.
916 
917  // References:
918  // [1] https://github.com/cassioneri/calendar
919  // [2] https://godbolt.org/z/55G8rn77e
920  // [3] https://gcc.gnu.org/pipermail/libstdc++/2021-June/052815.html
921 
922  return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0;
923  }
924 
925  explicit constexpr
926  operator int() const noexcept
927  { return _M_y; }
928 
929  constexpr bool
930  ok() const noexcept
931  { return min()._M_y <= _M_y && _M_y <= max()._M_y; }
932 
933  friend constexpr bool
934  operator==(const year& __x, const year& __y) noexcept
935  { return int{__x} == int{__y}; }
936 
937  friend constexpr strong_ordering
938  operator<=>(const year& __x, const year& __y) noexcept
939  { return int{__x} <=> int{__y}; }
940 
941  friend constexpr year
942  operator+(const year& __x, const years& __y) noexcept
943  { return year{int{__x} + static_cast<int>(__y.count())}; }
944 
945  friend constexpr year
946  operator+(const years& __x, const year& __y) noexcept
947  { return __y + __x; }
948 
949  friend constexpr year
950  operator-(const year& __x, const years& __y) noexcept
951  { return __x + -__y; }
952 
953  friend constexpr years
954  operator-(const year& __x, const year& __y) noexcept
955  { return years{int{__x} - int{__y}}; }
956 
957  friend constexpr year_month
958  operator/(const year& __y, int __m) noexcept;
959 
960  friend constexpr year_month_day
961  operator/(const year& __y, const month_day& __md) noexcept;
962 
963  friend constexpr year_month_day
964  operator/(const month_day& __md, const year& __y) noexcept;
965 
966  friend constexpr year_month_day_last
967  operator/(const year& __y, const month_day_last& __mdl) noexcept;
968 
969  friend constexpr year_month_day_last
970  operator/(const month_day_last& __mdl, const year& __y) noexcept;
971 
972  friend constexpr year_month_weekday
973  operator/(const year& __y, const month_weekday& __mwd) noexcept;
974 
975  friend constexpr year_month_weekday
976  operator/(const month_weekday& __mwd, const year& __y) noexcept;
977 
978  friend constexpr year_month_weekday_last
979  operator/(const year& __y, const month_weekday_last& __mwdl) noexcept;
980 
981  friend constexpr year_month_weekday_last
982  operator/(const month_weekday_last& __mwdl, const year& __y) noexcept;
983  };
984 
985  // WEEKDAY
986 
987  class weekday
988  {
989  private:
990  unsigned char _M_wd;
991 
992  static constexpr weekday
993  _S_from_days(const days& __d)
994  {
995  return weekday{__detail::__add_modulo<7>(4, __d.count())};
996  }
997 
998  public:
999  weekday() = default;
1000 
1001  explicit constexpr
1002  weekday(unsigned __wd) noexcept
1003  : _M_wd(__wd == 7 ? 0 : __wd) // __wd % 7 ?
1004  { }
1005 
1006  constexpr
1007  weekday(const sys_days& __dp) noexcept
1008  : weekday{_S_from_days(__dp.time_since_epoch())}
1009  { }
1010 
1011  explicit constexpr
1012  weekday(const local_days& __dp) noexcept
1013  : weekday{sys_days{__dp.time_since_epoch()}}
1014  { }
1015 
1016  constexpr weekday&
1017  operator++() noexcept
1018  {
1019  *this += days{1};
1020  return *this;
1021  }
1022 
1023  constexpr weekday
1024  operator++(int) noexcept
1025  {
1026  auto __ret = *this;
1027  ++(*this);
1028  return __ret;
1029  }
1030 
1031  constexpr weekday&
1032  operator--() noexcept
1033  {
1034  *this -= days{1};
1035  return *this;
1036  }
1037 
1038  constexpr weekday
1039  operator--(int) noexcept
1040  {
1041  auto __ret = *this;
1042  --(*this);
1043  return __ret;
1044  }
1045 
1046  constexpr weekday&
1047  operator+=(const days& __d) noexcept
1048  {
1049  *this = *this + __d;
1050  return *this;
1051  }
1052 
1053  constexpr weekday&
1054  operator-=(const days& __d) noexcept
1055  {
1056  *this = *this - __d;
1057  return *this;
1058  }
1059 
1060  constexpr unsigned
1061  c_encoding() const noexcept
1062  { return _M_wd; }
1063 
1064  constexpr unsigned
1065  iso_encoding() const noexcept
1066  { return _M_wd == 0u ? 7u : _M_wd; }
1067 
1068  constexpr bool
1069  ok() const noexcept
1070  { return _M_wd <= 6; }
1071 
1072  constexpr weekday_indexed
1073  operator[](unsigned __index) const noexcept;
1074 
1075  constexpr weekday_last
1076  operator[](last_spec) const noexcept;
1077 
1078  friend constexpr bool
1079  operator==(const weekday& __x, const weekday& __y) noexcept
1080  { return __x._M_wd == __y._M_wd; }
1081 
1082  friend constexpr weekday
1083  operator+(const weekday& __x, const days& __y) noexcept
1084  {
1085  return weekday{__detail::__add_modulo<7>(__x._M_wd, __y.count())};
1086  }
1087 
1088  friend constexpr weekday
1089  operator+(const days& __x, const weekday& __y) noexcept
1090  { return __y + __x; }
1091 
1092  friend constexpr weekday
1093  operator-(const weekday& __x, const days& __y) noexcept
1094  {
1095  return weekday{__detail::__sub_modulo<7>(__x._M_wd, __y.count())};
1096  }
1097 
1098  friend constexpr days
1099  operator-(const weekday& __x, const weekday& __y) noexcept
1100  {
1101  const auto __n = __x.c_encoding() - __y.c_encoding();
1102  return static_cast<int>(__n) >= 0 ? days{__n} : days{__n + 7};
1103  }
1104  };
1105 
1106  inline constexpr weekday Sunday{0};
1107  inline constexpr weekday Monday{1};
1108  inline constexpr weekday Tuesday{2};
1109  inline constexpr weekday Wednesday{3};
1110  inline constexpr weekday Thursday{4};
1111  inline constexpr weekday Friday{5};
1112  inline constexpr weekday Saturday{6};
1113 
1114  // WEEKDAY_INDEXED
1115 
1116  class weekday_indexed
1117  {
1118  private:
1119  chrono::weekday _M_wd;
1120  unsigned char _M_index;
1121 
1122  public:
1123  weekday_indexed() = default;
1124 
1125  constexpr
1126  weekday_indexed(const chrono::weekday& __wd, unsigned __index) noexcept
1127  : _M_wd(__wd), _M_index(__index)
1128  { }
1129 
1130  constexpr chrono::weekday
1131  weekday() const noexcept
1132  { return _M_wd; }
1133 
1134  constexpr unsigned
1135  index() const noexcept
1136  { return _M_index; };
1137 
1138  constexpr bool
1139  ok() const noexcept
1140  { return _M_wd.ok() && 1 <= _M_index && _M_index <= 5; }
1141 
1142  friend constexpr bool
1143  operator==(const weekday_indexed& __x, const weekday_indexed& __y) noexcept
1144  { return __x.weekday() == __y.weekday() && __x.index() == __y.index(); }
1145 
1146  friend constexpr month_weekday
1147  operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
1148 
1149  friend constexpr month_weekday
1150  operator/(int __m, const weekday_indexed& __wdi) noexcept;
1151 
1152  friend constexpr month_weekday
1153  operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
1154 
1155  friend constexpr month_weekday
1156  operator/(const weekday_indexed& __wdi, int __m) noexcept;
1157 
1158  friend constexpr year_month_weekday
1159  operator/(const year_month& __ym, const weekday_indexed& __wdi) noexcept;
1160  };
1161 
1162  constexpr weekday_indexed
1163  weekday::operator[](unsigned __index) const noexcept
1164  { return {*this, __index}; }
1165 
1166  // WEEKDAY_LAST
1167 
1168  class weekday_last
1169  {
1170  private:
1171  chrono::weekday _M_wd;
1172 
1173  public:
1174  explicit constexpr
1175  weekday_last(const chrono::weekday& __wd) noexcept
1176  : _M_wd{__wd}
1177  { }
1178 
1179  constexpr chrono::weekday
1180  weekday() const noexcept
1181  { return _M_wd; }
1182 
1183  constexpr bool
1184  ok() const noexcept
1185  { return _M_wd.ok(); }
1186 
1187  friend constexpr bool
1188  operator==(const weekday_last& __x, const weekday_last& __y) noexcept
1189  { return __x.weekday() == __y.weekday(); }
1190 
1191  friend constexpr month_weekday_last
1192  operator/(int __m, const weekday_last& __wdl) noexcept;
1193 
1194  friend constexpr month_weekday_last
1195  operator/(const weekday_last& __wdl, int __m) noexcept;
1196 
1197  friend constexpr year_month_weekday_last
1198  operator/(const year_month& __ym, const weekday_last& __wdl) noexcept;
1199  };
1200 
1201  constexpr weekday_last
1202  weekday::operator[](last_spec) const noexcept
1203  { return weekday_last{*this}; }
1204 
1205  // MONTH_DAY
1206 
1207  class month_day
1208  {
1209  private:
1210  chrono::month _M_m;
1211  chrono::day _M_d;
1212 
1213  public:
1214  month_day() = default;
1215 
1216  constexpr
1217  month_day(const chrono::month& __m, const chrono::day& __d) noexcept
1218  : _M_m{__m}, _M_d{__d}
1219  { }
1220 
1221  constexpr chrono::month
1222  month() const noexcept
1223  { return _M_m; }
1224 
1225  constexpr chrono::day
1226  day() const noexcept
1227  { return _M_d; }
1228 
1229  constexpr bool
1230  ok() const noexcept
1231  {
1232  return _M_m.ok()
1233  && 1u <= unsigned(_M_d)
1234  && unsigned(_M_d) <= __detail::__days_per_month[unsigned(_M_m) - 1];
1235  }
1236 
1237  friend constexpr bool
1238  operator==(const month_day& __x, const month_day& __y) noexcept
1239  { return __x.month() == __y.month() && __x.day() == __y.day(); }
1240 
1241  friend constexpr strong_ordering
1242  operator<=>(const month_day& __x, const month_day& __y) noexcept
1243  = default;
1244 
1245  friend constexpr month_day
1246  operator/(const chrono::month& __m, const chrono::day& __d) noexcept
1247  { return {__m, __d}; }
1248 
1249  friend constexpr month_day
1250  operator/(const chrono::month& __m, int __d) noexcept
1251  { return {__m, chrono::day(unsigned(__d))}; }
1252 
1253  friend constexpr month_day
1254  operator/(int __m, const chrono::day& __d) noexcept
1255  { return {chrono::month(unsigned(__m)), __d}; }
1256 
1257  friend constexpr month_day
1258  operator/(const chrono::day& __d, const chrono::month& __m) noexcept
1259  { return {__m, __d}; }
1260 
1261  friend constexpr month_day
1262  operator/(const chrono::day& __d, int __m) noexcept
1263  { return {chrono::month(unsigned(__m)), __d}; }
1264 
1265  friend constexpr year_month_day
1266  operator/(int __y, const month_day& __md) noexcept;
1267 
1268  friend constexpr year_month_day
1269  operator/(const month_day& __md, int __y) noexcept;
1270  };
1271 
1272  // MONTH_DAY_LAST
1273 
1274  class month_day_last
1275  {
1276  private:
1277  chrono::month _M_m;
1278 
1279  public:
1280  explicit constexpr
1281  month_day_last(const chrono::month& __m) noexcept
1282  : _M_m{__m}
1283  { }
1284 
1285  constexpr chrono::month
1286  month() const noexcept
1287  { return _M_m; }
1288 
1289  constexpr bool
1290  ok() const noexcept
1291  { return _M_m.ok(); }
1292 
1293  friend constexpr bool
1294  operator==(const month_day_last& __x, const month_day_last& __y) noexcept
1295  { return __x.month() == __y.month(); }
1296 
1297  friend constexpr strong_ordering
1298  operator<=>(const month_day_last& __x, const month_day_last& __y) noexcept
1299  = default;
1300 
1301  friend constexpr month_day_last
1302  operator/(const chrono::month& __m, last_spec) noexcept
1303  { return month_day_last{__m}; }
1304 
1305  friend constexpr month_day_last
1306  operator/(int __m, last_spec) noexcept
1307  { return chrono::month(unsigned(__m)) / last; }
1308 
1309  friend constexpr month_day_last
1310  operator/(last_spec, const chrono::month& __m) noexcept
1311  { return __m / last; }
1312 
1313  friend constexpr month_day_last
1314  operator/(last_spec, int __m) noexcept
1315  { return __m / last; }
1316 
1317  friend constexpr year_month_day_last
1318  operator/(int __y, const month_day_last& __mdl) noexcept;
1319 
1320  friend constexpr year_month_day_last
1321  operator/(const month_day_last& __mdl, int __y) noexcept;
1322  };
1323 
1324  // MONTH_WEEKDAY
1325 
1326  class month_weekday
1327  {
1328  private:
1329  chrono::month _M_m;
1330  chrono::weekday_indexed _M_wdi;
1331 
1332  public:
1333  constexpr
1334  month_weekday(const chrono::month& __m,
1335  const chrono::weekday_indexed& __wdi) noexcept
1336  : _M_m{__m}, _M_wdi{__wdi}
1337  { }
1338 
1339  constexpr chrono::month
1340  month() const noexcept
1341  { return _M_m; }
1342 
1343  constexpr chrono::weekday_indexed
1344  weekday_indexed() const noexcept
1345  { return _M_wdi; }
1346 
1347  constexpr bool
1348  ok() const noexcept
1349  { return _M_m.ok() && _M_wdi.ok(); }
1350 
1351  friend constexpr bool
1352  operator==(const month_weekday& __x, const month_weekday& __y) noexcept
1353  {
1354  return __x.month() == __y.month()
1355  && __x.weekday_indexed() == __y.weekday_indexed();
1356  }
1357 
1358  friend constexpr month_weekday
1359  operator/(const chrono::month& __m,
1360  const chrono::weekday_indexed& __wdi) noexcept
1361  { return {__m, __wdi}; }
1362 
1363  friend constexpr month_weekday
1364  operator/(int __m, const chrono::weekday_indexed& __wdi) noexcept
1365  { return chrono::month(unsigned(__m)) / __wdi; }
1366 
1367  friend constexpr month_weekday
1368  operator/(const chrono::weekday_indexed& __wdi,
1369  const chrono::month& __m) noexcept
1370  { return __m / __wdi; }
1371 
1372  friend constexpr month_weekday
1373  operator/(const chrono::weekday_indexed& __wdi, int __m) noexcept
1374  { return __m / __wdi; }
1375 
1376  friend constexpr year_month_weekday
1377  operator/(int __y, const month_weekday& __mwd) noexcept;
1378 
1379  friend constexpr year_month_weekday
1380  operator/(const month_weekday& __mwd, int __y) noexcept;
1381  };
1382 
1383  // MONTH_WEEKDAY_LAST
1384 
1385  class month_weekday_last
1386  {
1387  private:
1388  chrono::month _M_m;
1389  chrono::weekday_last _M_wdl;
1390 
1391  public:
1392  constexpr
1393  month_weekday_last(const chrono::month& __m,
1394  const chrono::weekday_last& __wdl) noexcept
1395  :_M_m{__m}, _M_wdl{__wdl}
1396  { }
1397 
1398  constexpr chrono::month
1399  month() const noexcept
1400  { return _M_m; }
1401 
1402  constexpr chrono::weekday_last
1403  weekday_last() const noexcept
1404  { return _M_wdl; }
1405 
1406  constexpr bool
1407  ok() const noexcept
1408  { return _M_m.ok() && _M_wdl.ok(); }
1409 
1410  friend constexpr bool
1411  operator==(const month_weekday_last& __x,
1412  const month_weekday_last& __y) noexcept
1413  {
1414  return __x.month() == __y.month()
1415  && __x.weekday_last() == __y.weekday_last();
1416  }
1417 
1418  friend constexpr month_weekday_last
1419  operator/(const chrono::month& __m,
1420  const chrono::weekday_last& __wdl) noexcept
1421  { return {__m, __wdl}; }
1422 
1423  friend constexpr month_weekday_last
1424  operator/(int __m, const chrono::weekday_last& __wdl) noexcept
1425  { return chrono::month(unsigned(__m)) / __wdl; }
1426 
1427  friend constexpr month_weekday_last
1428  operator/(const chrono::weekday_last& __wdl,
1429  const chrono::month& __m) noexcept
1430  { return __m / __wdl; }
1431 
1432  friend constexpr month_weekday_last
1433  operator/(const chrono::weekday_last& __wdl, int __m) noexcept
1434  { return chrono::month(unsigned(__m)) / __wdl; }
1435 
1436  friend constexpr year_month_weekday_last
1437  operator/(int __y, const month_weekday_last& __mwdl) noexcept;
1438 
1439  friend constexpr year_month_weekday_last
1440  operator/(const month_weekday_last& __mwdl, int __y) noexcept;
1441  };
1442 
1443  // YEAR_MONTH
1444 
1445  /// @cond undocumented
1446  namespace __detail
1447  {
1448  // [time.cal.ym], [time.cal.ymd], etc constrain the 'months'-based
1449  // addition/subtraction operator overloads like so:
1450  //
1451  // Constraints: if the argument supplied by the caller for the months
1452  // parameter is convertible to years, its implicit conversion sequence
1453  // to years is worse than its implicit conversion sequence to months.
1454  //
1455  // We realize this constraint by templatizing the 'months'-based
1456  // overloads (using a dummy defaulted template parameter), so that
1457  // overload resolution doesn't select the 'months'-based overload unless
1458  // the implicit conversion sequence to 'months' is better than that to
1459  // 'years'.
1460  using __months_years_conversion_disambiguator = void;
1461  }
1462  /// @endcond
1463 
1464  class year_month
1465  {
1466  private:
1467  chrono::year _M_y;
1468  chrono::month _M_m;
1469 
1470  public:
1471  year_month() = default;
1472 
1473  constexpr
1474  year_month(const chrono::year& __y, const chrono::month& __m) noexcept
1475  : _M_y{__y}, _M_m{__m}
1476  { }
1477 
1478  constexpr chrono::year
1479  year() const noexcept
1480  { return _M_y; }
1481 
1482  constexpr chrono::month
1483  month() const noexcept
1484  { return _M_m; }
1485 
1486  template<typename = __detail::__months_years_conversion_disambiguator>
1487  constexpr year_month&
1488  operator+=(const months& __dm) noexcept
1489  {
1490  *this = *this + __dm;
1491  return *this;
1492  }
1493 
1494  template<typename = __detail::__months_years_conversion_disambiguator>
1495  constexpr year_month&
1496  operator-=(const months& __dm) noexcept
1497  {
1498  *this = *this - __dm;
1499  return *this;
1500  }
1501 
1502  constexpr year_month&
1503  operator+=(const years& __dy) noexcept
1504  {
1505  *this = *this + __dy;
1506  return *this;
1507  }
1508 
1509  constexpr year_month&
1510  operator-=(const years& __dy) noexcept
1511  {
1512  *this = *this - __dy;
1513  return *this;
1514  }
1515 
1516  constexpr bool
1517  ok() const noexcept
1518  { return _M_y.ok() && _M_m.ok(); }
1519 
1520  friend constexpr bool
1521  operator==(const year_month& __x, const year_month& __y) noexcept
1522  { return __x.year() == __y.year() && __x.month() == __y.month(); }
1523 
1524  friend constexpr strong_ordering
1525  operator<=>(const year_month& __x, const year_month& __y) noexcept
1526  = default;
1527 
1528  template<typename = __detail::__months_years_conversion_disambiguator>
1529  friend constexpr year_month
1530  operator+(const year_month& __ym, const months& __dm) noexcept
1531  {
1532  // TODO: Optimize?
1533  auto __m = __ym.month() + __dm;
1534  auto __i = int(unsigned(__ym.month())) - 1 + __dm.count();
1535  auto __y = (__i < 0
1536  ? __ym.year() + years{(__i - 11) / 12}
1537  : __ym.year() + years{__i / 12});
1538  return __y / __m;
1539  }
1540 
1541  template<typename = __detail::__months_years_conversion_disambiguator>
1542  friend constexpr year_month
1543  operator+(const months& __dm, const year_month& __ym) noexcept
1544  { return __ym + __dm; }
1545 
1546  template<typename = __detail::__months_years_conversion_disambiguator>
1547  friend constexpr year_month
1548  operator-(const year_month& __ym, const months& __dm) noexcept
1549  { return __ym + -__dm; }
1550 
1551  friend constexpr months
1552  operator-(const year_month& __x, const year_month& __y) noexcept
1553  {
1554  return (__x.year() - __y.year()
1555  + months{static_cast<int>(unsigned{__x.month()})
1556  - static_cast<int>(unsigned{__y.month()})});
1557  }
1558 
1559  friend constexpr year_month
1560  operator+(const year_month& __ym, const years& __dy) noexcept
1561  { return (__ym.year() + __dy) / __ym.month(); }
1562 
1563  friend constexpr year_month
1564  operator+(const years& __dy, const year_month& __ym) noexcept
1565  { return __ym + __dy; }
1566 
1567  friend constexpr year_month
1568  operator-(const year_month& __ym, const years& __dy) noexcept
1569  { return __ym + -__dy; }
1570 
1571  friend constexpr year_month
1572  operator/(const chrono::year& __y, const chrono::month& __m) noexcept
1573  { return {__y, __m}; }
1574 
1575  friend constexpr year_month
1576  operator/(const chrono::year& __y, int __m) noexcept
1577  { return {__y, chrono::month(unsigned(__m))}; }
1578 
1579  friend constexpr year_month_day
1580  operator/(const year_month& __ym, int __d) noexcept;
1581 
1582  friend constexpr year_month_day_last
1583  operator/(const year_month& __ym, last_spec) noexcept;
1584  };
1585 
1586  // YEAR_MONTH_DAY
1587 
1588  class year_month_day
1589  {
1590  private:
1591  chrono::year _M_y;
1592  chrono::month _M_m;
1593  chrono::day _M_d;
1594 
1595  static constexpr year_month_day _S_from_days(const days& __dp) noexcept;
1596 
1597  constexpr days _M_days_since_epoch() const noexcept;
1598 
1599  public:
1600  year_month_day() = default;
1601 
1602  constexpr
1603  year_month_day(const chrono::year& __y, const chrono::month& __m,
1604  const chrono::day& __d) noexcept
1605  : _M_y{__y}, _M_m{__m}, _M_d{__d}
1606  { }
1607 
1608  constexpr
1609  year_month_day(const year_month_day_last& __ymdl) noexcept;
1610 
1611  constexpr
1612  year_month_day(const sys_days& __dp) noexcept
1613  : year_month_day(_S_from_days(__dp.time_since_epoch()))
1614  { }
1615 
1616  explicit constexpr
1617  year_month_day(const local_days& __dp) noexcept
1618  : year_month_day(sys_days{__dp.time_since_epoch()})
1619  { }
1620 
1621  template<typename = __detail::__months_years_conversion_disambiguator>
1622  constexpr year_month_day&
1623  operator+=(const months& __m) noexcept
1624  {
1625  *this = *this + __m;
1626  return *this;
1627  }
1628 
1629  template<typename = __detail::__months_years_conversion_disambiguator>
1630  constexpr year_month_day&
1631  operator-=(const months& __m) noexcept
1632  {
1633  *this = *this - __m;
1634  return *this;
1635  }
1636 
1637  constexpr year_month_day&
1638  operator+=(const years& __y) noexcept
1639  {
1640  *this = *this + __y;
1641  return *this;
1642  }
1643 
1644  constexpr year_month_day&
1645  operator-=(const years& __y) noexcept
1646  {
1647  *this = *this - __y;
1648  return *this;
1649  }
1650 
1651  constexpr chrono::year
1652  year() const noexcept
1653  { return _M_y; }
1654 
1655  constexpr chrono::month
1656  month() const noexcept
1657  { return _M_m; }
1658 
1659  constexpr chrono::day
1660  day() const noexcept
1661  { return _M_d; }
1662 
1663  constexpr
1664  operator sys_days() const noexcept
1665  { return sys_days{_M_days_since_epoch()}; }
1666 
1667  explicit constexpr
1668  operator local_days() const noexcept
1669  { return local_days{sys_days{*this}.time_since_epoch()}; }
1670 
1671  constexpr bool ok() const noexcept;
1672 
1673  friend constexpr bool
1674  operator==(const year_month_day& __x, const year_month_day& __y) noexcept
1675  {
1676  return __x.year() == __y.year()
1677  && __x.month() == __y.month()
1678  && __x.day() == __y.day();
1679  }
1680 
1681  friend constexpr strong_ordering
1682  operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept
1683  = default;
1684 
1685  template<typename = __detail::__months_years_conversion_disambiguator>
1686  friend constexpr year_month_day
1687  operator+(const year_month_day& __ymd, const months& __dm) noexcept
1688  { return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); }
1689 
1690  template<typename = __detail::__months_years_conversion_disambiguator>
1691  friend constexpr year_month_day
1692  operator+(const months& __dm, const year_month_day& __ymd) noexcept
1693  { return __ymd + __dm; }
1694 
1695  friend constexpr year_month_day
1696  operator+(const year_month_day& __ymd, const years& __dy) noexcept
1697  { return (__ymd.year() + __dy) / __ymd.month() / __ymd.day(); }
1698 
1699  friend constexpr year_month_day
1700  operator+(const years& __dy, const year_month_day& __ymd) noexcept
1701  { return __ymd + __dy; }
1702 
1703  template<typename = __detail::__months_years_conversion_disambiguator>
1704  friend constexpr year_month_day
1705  operator-(const year_month_day& __ymd, const months& __dm) noexcept
1706  { return __ymd + -__dm; }
1707 
1708  friend constexpr year_month_day
1709  operator-(const year_month_day& __ymd, const years& __dy) noexcept
1710  { return __ymd + -__dy; }
1711 
1712  friend constexpr year_month_day
1713  operator/(const year_month& __ym, const chrono::day& __d) noexcept
1714  { return {__ym.year(), __ym.month(), __d}; }
1715 
1716  friend constexpr year_month_day
1717  operator/(const year_month& __ym, int __d) noexcept
1718  { return __ym / chrono::day{unsigned(__d)}; }
1719 
1720  friend constexpr year_month_day
1721  operator/(const chrono::year& __y, const month_day& __md) noexcept
1722  { return __y / __md.month() / __md.day(); }
1723 
1724  friend constexpr year_month_day
1725  operator/(int __y, const month_day& __md) noexcept
1726  { return chrono::year{__y} / __md; }
1727 
1728  friend constexpr year_month_day
1729  operator/(const month_day& __md, const chrono::year& __y) noexcept
1730  { return __y / __md; }
1731 
1732  friend constexpr year_month_day
1733  operator/(const month_day& __md, int __y) noexcept
1734  { return chrono::year(__y) / __md; }
1735  };
1736 
1737  // Construct from days since 1970/01/01.
1738  // Proposition 6.3 of Neri and Schneider,
1739  // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1740  // https://arxiv.org/abs/2102.06959
1741  constexpr year_month_day
1742  year_month_day::_S_from_days(const days& __dp) noexcept
1743  {
1744  constexpr auto __z2 = static_cast<uint32_t>(-1468000);
1745  constexpr auto __r2_e3 = static_cast<uint32_t>(536895458);
1746 
1747  const auto __r0 = static_cast<uint32_t>(__dp.count()) + __r2_e3;
1748 
1749  const auto __n1 = 4 * __r0 + 3;
1750  const auto __q1 = __n1 / 146097;
1751  const auto __r1 = __n1 % 146097 / 4;
1752 
1753  constexpr auto __p32 = static_cast<uint64_t>(1) << 32;
1754  const auto __n2 = 4 * __r1 + 3;
1755  const auto __u2 = static_cast<uint64_t>(2939745) * __n2;
1756  const auto __q2 = static_cast<uint32_t>(__u2 / __p32);
1757  const auto __r2 = static_cast<uint32_t>(__u2 % __p32) / 2939745 / 4;
1758 
1759  constexpr auto __p16 = static_cast<uint32_t>(1) << 16;
1760  const auto __n3 = 2141 * __r2 + 197913;
1761  const auto __q3 = __n3 / __p16;
1762  const auto __r3 = __n3 % __p16 / 2141;
1763 
1764  const auto __y0 = 100 * __q1 + __q2;
1765  const auto __m0 = __q3;
1766  const auto __d0 = __r3;
1767 
1768  const auto __j = __r2 >= 306;
1769  const auto __y1 = __y0 + __j;
1770  const auto __m1 = __j ? __m0 - 12 : __m0;
1771  const auto __d1 = __d0 + 1;
1772 
1773  return year_month_day{chrono::year{static_cast<int>(__y1 + __z2)},
1774  chrono::month{__m1}, chrono::day{__d1}};
1775  }
1776 
1777  // Days since 1970/01/01.
1778  // Proposition 6.2 of Neri and Schneider,
1779  // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1780  // https://arxiv.org/abs/2102.06959
1781  constexpr days
1782  year_month_day::_M_days_since_epoch() const noexcept
1783  {
1784  auto constexpr __z2 = static_cast<uint32_t>(-1468000);
1785  auto constexpr __r2_e3 = static_cast<uint32_t>(536895458);
1786 
1787  const auto __y1 = static_cast<uint32_t>(static_cast<int>(_M_y)) - __z2;
1788  const auto __m1 = static_cast<uint32_t>(static_cast<unsigned>(_M_m));
1789  const auto __d1 = static_cast<uint32_t>(static_cast<unsigned>(_M_d));
1790 
1791  const auto __j = static_cast<uint32_t>(__m1 < 3);
1792  const auto __y0 = __y1 - __j;
1793  const auto __m0 = __j ? __m1 + 12 : __m1;
1794  const auto __d0 = __d1 - 1;
1795 
1796  const auto __q1 = __y0 / 100;
1797  const auto __yc = 1461 * __y0 / 4 - __q1 + __q1 / 4;
1798  const auto __mc = (979 *__m0 - 2919) / 32;
1799  const auto __dc = __d0;
1800 
1801  return days{static_cast<int32_t>(__yc + __mc + __dc - __r2_e3)};
1802  }
1803 
1804  // YEAR_MONTH_DAY_LAST
1805 
1806  class year_month_day_last
1807  {
1808  private:
1809  chrono::year _M_y;
1810  chrono::month_day_last _M_mdl;
1811 
1812  public:
1813  constexpr
1814  year_month_day_last(const chrono::year& __y,
1815  const chrono::month_day_last& __mdl) noexcept
1816  : _M_y{__y}, _M_mdl{__mdl}
1817  { }
1818 
1819  template<typename = __detail::__months_years_conversion_disambiguator>
1820  constexpr year_month_day_last&
1821  operator+=(const months& __m) noexcept
1822  {
1823  *this = *this + __m;
1824  return *this;
1825  }
1826 
1827  template<typename = __detail::__months_years_conversion_disambiguator>
1828  constexpr year_month_day_last&
1829  operator-=(const months& __m) noexcept
1830  {
1831  *this = *this - __m;
1832  return *this;
1833  }
1834 
1835  constexpr year_month_day_last&
1836  operator+=(const years& __y) noexcept
1837  {
1838  *this = *this + __y;
1839  return *this;
1840  }
1841 
1842  constexpr year_month_day_last&
1843  operator-=(const years& __y) noexcept
1844  {
1845  *this = *this - __y;
1846  return *this;
1847  }
1848 
1849  constexpr chrono::year
1850  year() const noexcept
1851  { return _M_y; }
1852 
1853  constexpr chrono::month
1854  month() const noexcept
1855  { return _M_mdl.month(); }
1856 
1857  constexpr chrono::month_day_last
1858  month_day_last() const noexcept
1859  { return _M_mdl; }
1860 
1861  // Return A day representing the last day of this year, month pair.
1862  constexpr chrono::day
1863  day() const noexcept
1864  {
1865  const auto __m = static_cast<unsigned>(month());
1866 
1867  // The result is unspecified if __m < 1 or __m > 12. Hence, assume
1868  // 1 <= __m <= 12. For __m != 2, day() == 30 or day() == 31 or, in
1869  // other words, day () == 30 | b, where b is in {0, 1}.
1870 
1871  // If __m in {1, 3, 4, 5, 6, 7}, then b is 1 if, and only if, __m is
1872  // odd. Hence, b = __m & 1 = (__m ^ 0) & 1.
1873 
1874  // If __m in {8, 9, 10, 11, 12}, then b is 1 if, and only if, __m is
1875  // even. Hence, b = (__m ^ 1) & 1.
1876 
1877  // Therefore, b = (__m ^ c) & 1, where c = 0, if __m < 8, or c = 1 if
1878  // __m >= 8, that is, c = __m >> 3.
1879 
1880  // Since 30 = (11110)_2 and __m <= 31 = (11111)_2, the "& 1" in b's
1881  // calculation is unnecessary.
1882 
1883  // The performance of this implementation does not depend on look-up
1884  // tables being on the L1 cache.
1885  return chrono::day{__m != 2 ? (__m ^ (__m >> 3)) | 30
1886  : _M_y.is_leap() ? 29 : 28};
1887  }
1888 
1889  constexpr
1890  operator sys_days() const noexcept
1891  { return sys_days{year() / month() / day()}; }
1892 
1893  explicit constexpr
1894  operator local_days() const noexcept
1895  { return local_days{sys_days{*this}.time_since_epoch()}; }
1896 
1897  constexpr bool
1898  ok() const noexcept
1899  { return _M_y.ok() && _M_mdl.ok(); }
1900 
1901  friend constexpr bool
1902  operator==(const year_month_day_last& __x,
1903  const year_month_day_last& __y) noexcept
1904  {
1905  return __x.year() == __y.year()
1906  && __x.month_day_last() == __y.month_day_last();
1907  }
1908 
1909  friend constexpr strong_ordering
1910  operator<=>(const year_month_day_last& __x,
1911  const year_month_day_last& __y) noexcept
1912  = default;
1913 
1914  template<typename = __detail::__months_years_conversion_disambiguator>
1915  friend constexpr year_month_day_last
1916  operator+(const year_month_day_last& __ymdl,
1917  const months& __dm) noexcept
1918  { return (__ymdl.year() / __ymdl.month() + __dm) / last; }
1919 
1920  template<typename = __detail::__months_years_conversion_disambiguator>
1921  friend constexpr year_month_day_last
1922  operator+(const months& __dm,
1923  const year_month_day_last& __ymdl) noexcept
1924  { return __ymdl + __dm; }
1925 
1926  template<typename = __detail::__months_years_conversion_disambiguator>
1927  friend constexpr year_month_day_last
1928  operator-(const year_month_day_last& __ymdl,
1929  const months& __dm) noexcept
1930  { return __ymdl + -__dm; }
1931 
1932  friend constexpr year_month_day_last
1933  operator+(const year_month_day_last& __ymdl,
1934  const years& __dy) noexcept
1935  { return {__ymdl.year() + __dy, __ymdl.month_day_last()}; }
1936 
1937  friend constexpr year_month_day_last
1938  operator+(const years& __dy,
1939  const year_month_day_last& __ymdl) noexcept
1940  { return __ymdl + __dy; }
1941 
1942  friend constexpr year_month_day_last
1943  operator-(const year_month_day_last& __ymdl,
1944  const years& __dy) noexcept
1945  { return __ymdl + -__dy; }
1946 
1947  friend constexpr year_month_day_last
1948  operator/(const year_month& __ym, last_spec) noexcept
1949  { return {__ym.year(), chrono::month_day_last{__ym.month()}}; }
1950 
1951  friend constexpr year_month_day_last
1952  operator/(const chrono::year& __y,
1953  const chrono::month_day_last& __mdl) noexcept
1954  { return {__y, __mdl}; }
1955 
1956  friend constexpr year_month_day_last
1957  operator/(int __y, const chrono::month_day_last& __mdl) noexcept
1958  { return chrono::year(__y) / __mdl; }
1959 
1960  friend constexpr year_month_day_last
1961  operator/(const chrono::month_day_last& __mdl,
1962  const chrono::year& __y) noexcept
1963  { return __y / __mdl; }
1964 
1965  friend constexpr year_month_day_last
1966  operator/(const chrono::month_day_last& __mdl, int __y) noexcept
1967  { return chrono::year(__y) / __mdl; }
1968  };
1969 
1970  // year_month_day ctor from year_month_day_last
1971  constexpr
1972  year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
1973  : _M_y{__ymdl.year()}, _M_m{__ymdl.month()}, _M_d{__ymdl.day()}
1974  { }
1975 
1976  constexpr bool
1977  year_month_day::ok() const noexcept
1978  {
1979  if (!_M_y.ok() || !_M_m.ok())
1980  return false;
1981  return chrono::day{1} <= _M_d && _M_d <= (_M_y / _M_m / last).day();
1982  }
1983 
1984  // YEAR_MONTH_WEEKDAY
1985 
1986  class year_month_weekday
1987  {
1988  private:
1989  chrono::year _M_y;
1990  chrono::month _M_m;
1991  chrono::weekday_indexed _M_wdi;
1992 
1993  static constexpr year_month_weekday
1994  _S_from_sys_days(const sys_days& __dp)
1995  {
1996  year_month_day __ymd{__dp};
1997  chrono::weekday __wd{__dp};
1998  auto __index = __wd[(unsigned{__ymd.day()} - 1) / 7 + 1];
1999  return {__ymd.year(), __ymd.month(), __index};
2000  }
2001 
2002  public:
2003  year_month_weekday() = default;
2004 
2005  constexpr
2006  year_month_weekday(const chrono::year& __y, const chrono::month& __m,
2007  const chrono::weekday_indexed& __wdi) noexcept
2008  : _M_y{__y}, _M_m{__m}, _M_wdi{__wdi}
2009  { }
2010 
2011  constexpr
2012  year_month_weekday(const sys_days& __dp) noexcept
2013  : year_month_weekday{_S_from_sys_days(__dp)}
2014  { }
2015 
2016  explicit constexpr
2017  year_month_weekday(const local_days& __dp) noexcept
2018  : year_month_weekday{sys_days{__dp.time_since_epoch()}}
2019  { }
2020 
2021  template<typename = __detail::__months_years_conversion_disambiguator>
2022  constexpr year_month_weekday&
2023  operator+=(const months& __m) noexcept
2024  {
2025  *this = *this + __m;
2026  return *this;
2027  }
2028 
2029  template<typename = __detail::__months_years_conversion_disambiguator>
2030  constexpr year_month_weekday&
2031  operator-=(const months& __m) noexcept
2032  {
2033  *this = *this - __m;
2034  return *this;
2035  }
2036 
2037  constexpr year_month_weekday&
2038  operator+=(const years& __y) noexcept
2039  {
2040  *this = *this + __y;
2041  return *this;
2042  }
2043 
2044  constexpr year_month_weekday&
2045  operator-=(const years& __y) noexcept
2046  {
2047  *this = *this - __y;
2048  return *this;
2049  }
2050 
2051  constexpr chrono::year
2052  year() const noexcept
2053  { return _M_y; }
2054 
2055  constexpr chrono::month
2056  month() const noexcept
2057  { return _M_m; }
2058 
2059  constexpr chrono::weekday
2060  weekday() const noexcept
2061  { return _M_wdi.weekday(); }
2062 
2063  constexpr unsigned
2064  index() const noexcept
2065  { return _M_wdi.index(); }
2066 
2067  constexpr chrono::weekday_indexed
2068  weekday_indexed() const noexcept
2069  { return _M_wdi; }
2070 
2071  constexpr
2072  operator sys_days() const noexcept
2073  {
2074  auto __d = sys_days{year() / month() / 1};
2075  return __d + (weekday() - chrono::weekday(__d)
2076  + days{(static_cast<int>(index())-1)*7});
2077  }
2078 
2079  explicit constexpr
2080  operator local_days() const noexcept
2081  { return local_days{sys_days{*this}.time_since_epoch()}; }
2082 
2083  constexpr bool
2084  ok() const noexcept
2085  {
2086  if (!_M_y.ok() || !_M_m.ok() || !_M_wdi.ok())
2087  return false;
2088  if (_M_wdi.index() <= 4)
2089  return true;
2090  days __d = (_M_wdi.weekday()
2091  - chrono::weekday{sys_days{_M_y / _M_m / 1}}
2092  + days((_M_wdi.index()-1)*7 + 1));
2093  __glibcxx_assert(__d.count() >= 1);
2094  return (unsigned)__d.count() <= (unsigned)(_M_y / _M_m / last).day();
2095  }
2096 
2097  friend constexpr bool
2098  operator==(const year_month_weekday& __x,
2099  const year_month_weekday& __y) noexcept
2100  {
2101  return __x.year() == __y.year()
2102  && __x.month() == __y.month()
2103  && __x.weekday_indexed() == __y.weekday_indexed();
2104  }
2105 
2106  template<typename = __detail::__months_years_conversion_disambiguator>
2107  friend constexpr year_month_weekday
2108  operator+(const year_month_weekday& __ymwd, const months& __dm) noexcept
2109  {
2110  return ((__ymwd.year() / __ymwd.month() + __dm)
2111  / __ymwd.weekday_indexed());
2112  }
2113 
2114  template<typename = __detail::__months_years_conversion_disambiguator>
2115  friend constexpr year_month_weekday
2116  operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept
2117  { return __ymwd + __dm; }
2118 
2119  friend constexpr year_month_weekday
2120  operator+(const year_month_weekday& __ymwd, const years& __dy) noexcept
2121  { return {__ymwd.year() + __dy, __ymwd.month(), __ymwd.weekday_indexed()}; }
2122 
2123  friend constexpr year_month_weekday
2124  operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept
2125  { return __ymwd + __dy; }
2126 
2127  template<typename = __detail::__months_years_conversion_disambiguator>
2128  friend constexpr year_month_weekday
2129  operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept
2130  { return __ymwd + -__dm; }
2131 
2132  friend constexpr year_month_weekday
2133  operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept
2134  { return __ymwd + -__dy; }
2135 
2136  friend constexpr year_month_weekday
2137  operator/(const year_month& __ym,
2138  const chrono::weekday_indexed& __wdi) noexcept
2139  { return {__ym.year(), __ym.month(), __wdi}; }
2140 
2141  friend constexpr year_month_weekday
2142  operator/(const chrono::year& __y, const month_weekday& __mwd) noexcept
2143  { return {__y, __mwd.month(), __mwd.weekday_indexed()}; }
2144 
2145  friend constexpr year_month_weekday
2146  operator/(int __y, const month_weekday& __mwd) noexcept
2147  { return chrono::year(__y) / __mwd; }
2148 
2149  friend constexpr year_month_weekday
2150  operator/(const month_weekday& __mwd, const chrono::year& __y) noexcept
2151  { return __y / __mwd; }
2152 
2153  friend constexpr year_month_weekday
2154  operator/(const month_weekday& __mwd, int __y) noexcept
2155  { return chrono::year(__y) / __mwd; }
2156  };
2157 
2158  // YEAR_MONTH_WEEKDAY_LAST
2159 
2160  class year_month_weekday_last
2161  {
2162  private:
2163  chrono::year _M_y;
2164  chrono::month _M_m;
2165  chrono::weekday_last _M_wdl;
2166 
2167  public:
2168  constexpr
2169  year_month_weekday_last(const chrono::year& __y, const chrono::month& __m,
2170  const chrono::weekday_last& __wdl) noexcept
2171  : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl}
2172  { }
2173 
2174  template<typename = __detail::__months_years_conversion_disambiguator>
2175  constexpr year_month_weekday_last&
2176  operator+=(const months& __m) noexcept
2177  {
2178  *this = *this + __m;
2179  return *this;
2180  }
2181 
2182  template<typename = __detail::__months_years_conversion_disambiguator>
2183  constexpr year_month_weekday_last&
2184  operator-=(const months& __m) noexcept
2185  {
2186  *this = *this - __m;
2187  return *this;
2188  }
2189 
2190  constexpr year_month_weekday_last&
2191  operator+=(const years& __y) noexcept
2192  {
2193  *this = *this + __y;
2194  return *this;
2195  }
2196 
2197  constexpr year_month_weekday_last&
2198  operator-=(const years& __y) noexcept
2199  {
2200  *this = *this - __y;
2201  return *this;
2202  }
2203 
2204  constexpr chrono::year
2205  year() const noexcept
2206  { return _M_y; }
2207 
2208  constexpr chrono::month
2209  month() const noexcept
2210  { return _M_m; }
2211 
2212  constexpr chrono::weekday
2213  weekday() const noexcept
2214  { return _M_wdl.weekday(); }
2215 
2216  constexpr chrono::weekday_last
2217  weekday_last() const noexcept
2218  { return _M_wdl; }
2219 
2220  constexpr
2221  operator sys_days() const noexcept
2222  {
2223  const auto __d = sys_days{_M_y / _M_m / last};
2224  return sys_days{(__d - (chrono::weekday{__d}
2225  - _M_wdl.weekday())).time_since_epoch()};
2226  }
2227 
2228  explicit constexpr
2229  operator local_days() const noexcept
2230  { return local_days{sys_days{*this}.time_since_epoch()}; }
2231 
2232  constexpr bool
2233  ok() const noexcept
2234  { return _M_y.ok() && _M_m.ok() && _M_wdl.ok(); }
2235 
2236  friend constexpr bool
2237  operator==(const year_month_weekday_last& __x,
2238  const year_month_weekday_last& __y) noexcept
2239  {
2240  return __x.year() == __y.year()
2241  && __x.month() == __y.month()
2242  && __x.weekday_last() == __y.weekday_last();
2243  }
2244 
2245  template<typename = __detail::__months_years_conversion_disambiguator>
2246  friend constexpr year_month_weekday_last
2247  operator+(const year_month_weekday_last& __ymwdl,
2248  const months& __dm) noexcept
2249  {
2250  return ((__ymwdl.year() / __ymwdl.month() + __dm)
2251  / __ymwdl.weekday_last());
2252  }
2253 
2254  template<typename = __detail::__months_years_conversion_disambiguator>
2255  friend constexpr year_month_weekday_last
2256  operator+(const months& __dm,
2257  const year_month_weekday_last& __ymwdl) noexcept
2258  { return __ymwdl + __dm; }
2259 
2260  friend constexpr year_month_weekday_last
2261  operator+(const year_month_weekday_last& __ymwdl,
2262  const years& __dy) noexcept
2263  { return {__ymwdl.year() + __dy, __ymwdl.month(), __ymwdl.weekday_last()}; }
2264 
2265  friend constexpr year_month_weekday_last
2266  operator+(const years& __dy,
2267  const year_month_weekday_last& __ymwdl) noexcept
2268  { return __ymwdl + __dy; }
2269 
2270  template<typename = __detail::__months_years_conversion_disambiguator>
2271  friend constexpr year_month_weekday_last
2272  operator-(const year_month_weekday_last& __ymwdl,
2273  const months& __dm) noexcept
2274  { return __ymwdl + -__dm; }
2275 
2276  friend constexpr year_month_weekday_last
2277  operator-(const year_month_weekday_last& __ymwdl,
2278  const years& __dy) noexcept
2279  { return __ymwdl + -__dy; }
2280 
2281  friend constexpr year_month_weekday_last
2282  operator/(const year_month& __ym,
2283  const chrono::weekday_last& __wdl) noexcept
2284  { return {__ym.year(), __ym.month(), __wdl}; }
2285 
2286  friend constexpr year_month_weekday_last
2287  operator/(const chrono::year& __y,
2288  const chrono::month_weekday_last& __mwdl) noexcept
2289  { return {__y, __mwdl.month(), __mwdl.weekday_last()}; }
2290 
2291  friend constexpr year_month_weekday_last
2292  operator/(int __y, const chrono::month_weekday_last& __mwdl) noexcept
2293  { return chrono::year(__y) / __mwdl; }
2294 
2295  friend constexpr year_month_weekday_last
2296  operator/(const chrono::month_weekday_last& __mwdl,
2297  const chrono::year& __y) noexcept
2298  { return __y / __mwdl; }
2299 
2300  friend constexpr year_month_weekday_last
2301  operator/(const chrono::month_weekday_last& __mwdl, int __y) noexcept
2302  { return chrono::year(__y) / __mwdl; }
2303  };
2304 
2305  // HH_MM_SS
2306 
2307  /// @cond undocumented
2308  namespace __detail
2309  {
2310  consteval long long
2311  __pow10(unsigned __n)
2312  {
2313  long long __r = 1;
2314  while (__n-- > 0)
2315  __r *= 10;
2316  return __r;
2317  }
2318  }
2319  /// @endcond
2320 
2321  /** Utility for splitting a duration into hours, minutes, and seconds
2322  *
2323  * This is a convenience type that provides accessors for the constituent
2324  * parts (hours, minutes, seconds and subseconds) of a duration.
2325  *
2326  * @since C++20
2327  */
2328  template<typename _Duration>
2329  class hh_mm_ss
2330  {
2331  static_assert( __is_duration<_Duration>::value );
2332 
2333  private:
2334  static consteval int
2335  _S_fractional_width()
2336  {
2337  auto __den = _Duration::period::den;
2338  const int __multiplicity_2 = std::__countr_zero((uintmax_t)__den);
2339  __den >>= __multiplicity_2;
2340  int __multiplicity_5 = 0;
2341  while ((__den % 5) == 0)
2342  {
2343  ++__multiplicity_5;
2344  __den /= 5;
2345  }
2346  if (__den != 1)
2347  return 6;
2348 
2349  int __width = (__multiplicity_2 > __multiplicity_5
2350  ? __multiplicity_2 : __multiplicity_5);
2351  if (__width > 18)
2352  __width = 18;
2353  return __width;
2354  }
2355 
2356  constexpr
2357  hh_mm_ss(_Duration __d, bool __is_neg)
2358  : _M_h (duration_cast<chrono::hours>(__d)),
2359  _M_m (duration_cast<chrono::minutes>(__d - hours())),
2360  _M_s (duration_cast<chrono::seconds>(__d - hours() - minutes())),
2361  _M_is_neg(__is_neg)
2362  {
2363  auto __ss = __d - hours() - minutes() - seconds();
2364  if constexpr (treat_as_floating_point_v<typename precision::rep>)
2365  _M_ss._M_r = __ss.count();
2366  else if constexpr (precision::period::den != 1)
2367  _M_ss._M_r = duration_cast<precision>(__ss).count();
2368  }
2369 
2370  // _GLIBCXX_RESOLVE_LIB_DEFECTS
2371  // 4274. hh_mm_ss constructor is ill-formed for unsigned durations
2372  static constexpr _Duration
2373  _S_abs(_Duration __d)
2374  {
2375  if constexpr (numeric_limits<typename _Duration::rep>::is_signed)
2376  return chrono::abs(__d);
2377  else
2378  return __d;
2379  }
2380 
2381  public:
2382  static constexpr unsigned fractional_width = {_S_fractional_width()};
2383 
2384  using precision
2385  = duration<common_type_t<typename _Duration::rep,
2386  chrono::seconds::rep>,
2387  ratio<1, __detail::__pow10(fractional_width)>>;
2388 
2389  constexpr hh_mm_ss() noexcept = default;
2390 
2391  constexpr explicit
2392  hh_mm_ss(_Duration __d)
2393  : hh_mm_ss(_S_abs(__d), __d < _Duration::zero())
2394  { }
2395 
2396  constexpr bool
2397  is_negative() const noexcept
2398  {
2399  if constexpr (!_S_is_unsigned)
2400  return _M_is_neg;
2401  else
2402  return false;
2403  }
2404 
2405  constexpr chrono::hours
2406  hours() const noexcept
2407  { return _M_h; }
2408 
2409  constexpr chrono::minutes
2410  minutes() const noexcept
2411  { return _M_m; }
2412 
2413  constexpr chrono::seconds
2414  seconds() const noexcept
2415  { return _M_s; }
2416 
2417  constexpr precision
2418  subseconds() const noexcept
2419  { return static_cast<precision>(_M_ss); }
2420 
2421  constexpr explicit
2422  operator precision() const noexcept
2423  { return to_duration(); }
2424 
2425  constexpr precision
2426  to_duration() const noexcept
2427  {
2428  if constexpr (!_S_is_unsigned)
2429  if (_M_is_neg)
2430  return -(_M_h + _M_m + _M_s + subseconds());
2431  return _M_h + _M_m + _M_s + subseconds();
2432  }
2433 
2434  private:
2435  static constexpr bool _S_is_unsigned
2436  = __and_v<is_integral<typename _Duration::rep>,
2437  is_unsigned<typename _Duration::rep>>;
2438 
2439  template<typename _Ratio>
2440  using __byte_duration = duration<unsigned char, _Ratio>;
2441 
2442  // The type of the _M_ss member that holds the subsecond precision.
2443  template<typename _Dur>
2444  struct __subseconds
2445  {
2446  typename _Dur::rep _M_r{};
2447 
2448  constexpr explicit
2449  operator _Dur() const noexcept
2450  { return _Dur(_M_r); }
2451  };
2452 
2453  // An empty class if this precision doesn't need subseconds.
2454  template<typename _Rep>
2455  requires (!treat_as_floating_point_v<_Rep>)
2456  struct __subseconds<duration<_Rep, ratio<1>>>
2457  {
2458  constexpr explicit
2459  operator duration<_Rep, ratio<1>>() const noexcept
2460  { return {}; }
2461  };
2462 
2463  template<typename _Rep, typename _Period>
2464  requires (!treat_as_floating_point_v<_Rep>)
2465  && ratio_less_v<_Period, ratio<1, 1>>
2466  && ratio_greater_equal_v<_Period, ratio<1, 250>>
2467  struct __subseconds<duration<_Rep, _Period>>
2468  {
2469  unsigned char _M_r{};
2470 
2471  constexpr explicit
2472  operator duration<_Rep, _Period>() const noexcept
2473  { return duration<_Rep, _Period>(_M_r); }
2474  };
2475 
2476  template<typename _Rep, typename _Period>
2477  requires (!treat_as_floating_point_v<_Rep>)
2478  && ratio_less_v<_Period, ratio<1, 250>>
2479  && ratio_greater_equal_v<_Period, ratio<1, 4000000000>>
2480  struct __subseconds<duration<_Rep, _Period>>
2481  {
2482  uint_least32_t _M_r{};
2483 
2484  constexpr explicit
2485  operator duration<_Rep, _Period>() const noexcept
2486  { return duration<_Rep, _Period>(_M_r); }
2487  };
2488 
2489  chrono::hours _M_h{};
2490  __byte_duration<ratio<60>> _M_m{};
2491  __byte_duration<ratio<1>> _M_s{};
2492  bool _M_is_neg{};
2493  __subseconds<precision> _M_ss{};
2494  };
2495 
2496  // 12/24 HOURS FUNCTIONS
2497 
2498  /// True if a `chrono::hours` value represents a time before midday.
2499  constexpr bool
2500  is_am(const hours& __h) noexcept
2501  { return 0h <= __h && __h <= 11h; }
2502 
2503  /// True if a `chrono::hours` value represents a time after midday.
2504  constexpr bool
2505  is_pm(const hours& __h) noexcept
2506  { return 12h <= __h && __h <= 23h; }
2507 
2508  /// Convert a 24-hour time into a 12-hour time.
2509  constexpr hours
2510  make12(const hours& __h) noexcept
2511  {
2512  if (__h == 0h)
2513  return 12h;
2514  else if (__h > 12h)
2515  return __h - 12h;
2516  return __h;
2517  }
2518 
2519  /// Convert a 12-hour time and p.m. flag into a 24-hour time.
2520  constexpr hours
2521  make24(const hours& __h, bool __is_pm) noexcept
2522  {
2523  if (!__is_pm)
2524  {
2525  if (__h == 12h)
2526  return 0h;
2527  else
2528  return __h;
2529  }
2530  else
2531  {
2532  if (__h == 12h)
2533  return __h;
2534  else
2535  return __h + 12h;
2536  }
2537  }
2538 
2539 #if _GLIBCXX_HOSTED
2540 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
2541  // C++20 [time.zones] Time zones
2542 
2543  struct tzdb;
2544 
2545  struct sys_info
2546  {
2547  sys_seconds begin;
2548  sys_seconds end;
2549  seconds offset;
2550  minutes save;
2551  string abbrev;
2552  };
2553 
2554  struct local_info
2555  {
2556  static constexpr int unique = 0;
2557  static constexpr int nonexistent = 1;
2558  static constexpr int ambiguous = 2;
2559 
2560  int result;
2561  sys_info first;
2562  sys_info second;
2563  };
2564 
2565  class nonexistent_local_time : public runtime_error
2566  {
2567  public:
2568  template<typename _Duration>
2569  nonexistent_local_time(const local_time<_Duration>& __tp,
2570  const local_info& __i)
2571  : runtime_error(_S_make_what_str(__tp, __i))
2572  { __glibcxx_assert(__i.result == local_info::nonexistent); }
2573 
2574  private:
2575  template<typename _Duration>
2576  static string
2577  _S_make_what_str(const local_time<_Duration>& __tp,
2578  const local_info& __i)
2579  {
2580  std::ostringstream __os;
2581  __os << __tp << " is in a gap between\n"
2582  << local_seconds(__i.first.end.time_since_epoch())
2583  + __i.first.offset << ' ' << __i.first.abbrev << " and\n"
2584  << local_seconds(__i.second.begin.time_since_epoch())
2585  + __i.second.offset << ' ' << __i.second.abbrev
2586  << " which are both equivalent to\n"
2587  << __i.first.end << " UTC";
2588  return std::move(__os).str();
2589  }
2590  };
2591 
2592  class ambiguous_local_time : public runtime_error
2593  {
2594  public:
2595  template<typename _Duration>
2596  ambiguous_local_time(const local_time<_Duration>& __tp,
2597  const local_info& __i)
2598  : runtime_error(_S_make_what_str(__tp, __i))
2599  { __glibcxx_assert(__i.result == local_info::ambiguous); }
2600 
2601  private:
2602  template<typename _Duration>
2603  static string
2604  _S_make_what_str(const local_time<_Duration>& __tp,
2605  const local_info& __i)
2606  {
2607  std::ostringstream __os;
2608  __os << __tp << " is ambiguous. It could be\n"
2609  << __tp << ' ' << __i.first.abbrev << " == "
2610  << __tp - __i.first.offset << " UTC or\n"
2611  << __tp << ' ' << __i.second.abbrev << " == "
2612  << __tp - __i.second.offset << " UTC";
2613  return std::move(__os).str();
2614  }
2615  };
2616 
2617  /// @cond undocumented
2618  template<typename _Duration>
2619  [[noreturn]] void
2620  __throw_bad_local_time(const local_time<_Duration>& __tp,
2621  const local_info& __i)
2622  {
2623 #if __cpp_exceptions
2624  if (__i.result == local_info::nonexistent)
2625  throw nonexistent_local_time(__tp, __i);
2626  throw ambiguous_local_time(__tp, __i);
2627 #else
2628  __builtin_abort();
2629 #endif
2630  }
2631  /// @endcond
2632 
2633  enum class choose { earliest, latest };
2634 
2635  class time_zone
2636  {
2637  public:
2638  time_zone(time_zone&&) = default;
2639  time_zone& operator=(time_zone&&) = default;
2640 
2641  ~time_zone();
2642 
2643  [[nodiscard]]
2644  string_view name() const noexcept { return _M_name; }
2645 
2646  template<typename _Duration>
2647  sys_info
2648  get_info(const sys_time<_Duration>& __st) const
2649  { return _M_get_sys_info(chrono::floor<seconds>(__st)); }
2650 
2651  template<typename _Duration>
2652  local_info
2653  get_info(const local_time<_Duration>& __tp) const
2654  { return _M_get_local_info(chrono::floor<seconds>(__tp)); }
2655 
2656  template<typename _Duration>
2657  sys_time<common_type_t<_Duration, seconds>>
2658  to_sys(const local_time<_Duration>& __tp) const
2659  {
2660  local_info __info = get_info(__tp);
2661 
2662  if (__info.result != local_info::unique)
2663  __throw_bad_local_time(__tp, __info);
2664 
2665  return sys_time<_Duration>(__tp.time_since_epoch())
2666  - __info.first.offset;
2667  }
2668 
2669  template<typename _Duration>
2670  sys_time<common_type_t<_Duration, seconds>>
2671  to_sys(const local_time<_Duration>& __tp, choose __z) const
2672  {
2673  local_info __info = get_info(__tp);
2674 
2675  if (__info.result == local_info::nonexistent)
2676  return __info.first.end; // Last second of the previous sys_info.
2677 
2678  sys_time<_Duration> __st(__tp.time_since_epoch());
2679 
2680  if (__info.result == local_info::ambiguous && __z == choose::latest)
2681  return __st - __info.second.offset; // Time in the later sys_info.
2682  // else if __z == earliest, use __info.first.offset as below:
2683 
2684  return __st - __info.first.offset;
2685  }
2686 
2687  template<typename _Duration>
2688  local_time<common_type_t<_Duration, seconds>>
2689  to_local(const sys_time<_Duration>& __tp) const
2690  {
2691  auto __d = (__tp + get_info(__tp).offset).time_since_epoch();
2692  return local_time<common_type_t<_Duration, seconds>>(__d);
2693  }
2694 
2695  [[nodiscard]] friend bool
2696  operator==(const time_zone& __x, const time_zone& __y) noexcept
2697  { return __x._M_name == __y._M_name; }
2698 
2699  [[nodiscard]] friend strong_ordering
2700  operator<=>(const time_zone& __x, const time_zone& __y) noexcept
2701  { return __x._M_name <=> __y._M_name; }
2702 
2703  private:
2704  sys_info _M_get_sys_info(sys_seconds) const;
2705  local_info _M_get_local_info(local_seconds) const;
2706 
2707  friend const tzdb& reload_tzdb();
2708  friend struct tzdb;
2709  friend class tzdb_list;
2710 
2711  struct _Impl;
2712 
2713  explicit time_zone(unique_ptr<_Impl> __p);
2714  string _M_name;
2715  unique_ptr<_Impl> _M_impl;
2716  };
2717 
2718  const time_zone* locate_zone(string_view __tz_name);
2719  const time_zone* current_zone();
2720 
2721  /** The list of `chrono::tzdb` objects
2722  *
2723  * A single object of this type is constructed by the C++ runtime,
2724  * and can be accessed by calling `chrono::get_tzdb_list()`.
2725  *
2726  * The front of the list is the current `tzdb` object and can be accessed
2727  * via `chrono::get_tzdb_list().front()` or `chrono::get_tzdb()` or
2728  * `*chrono::get_tzdb_list().begin()`.
2729  *
2730  * The `chrono::reload_tzdb()` function will check for a newer version
2731  * and if found, insert it at the front of the list.
2732  *
2733  * @since C++20
2734  */
2735  class tzdb_list
2736  {
2737  struct _Node;
2738 
2739  public:
2740  tzdb_list(const tzdb_list&) = delete;
2741  tzdb_list& operator=(const tzdb_list&) = delete;
2742 
2743  /** An iterator into the `tzdb_list`
2744  *
2745  * As a extension, in libstdc++ each `tzdb` is reference-counted
2746  * and the `const_iterator` type shares ownership of the object it
2747  * refers to. This ensures that a `tzdb` erased from the list will
2748  * not be destroyed while there is an iterator that refers to it.
2749  */
2750  class const_iterator
2751  {
2752  public:
2753  using value_type = tzdb;
2754  using reference = const tzdb&;
2755  using pointer = const tzdb*;
2756  using difference_type = ptrdiff_t;
2757  using iterator_category = forward_iterator_tag;
2758 
2759  constexpr const_iterator() = default;
2760  const_iterator(const const_iterator&) = default;
2761  const_iterator(const_iterator&&) = default;
2762  const_iterator& operator=(const const_iterator&) = default;
2763  const_iterator& operator=(const_iterator&&) = default;
2764 
2765  reference operator*() const noexcept;
2766  pointer operator->() const noexcept { return &**this; }
2767  const_iterator& operator++();
2768  const_iterator operator++(int);
2769 
2770  bool operator==(const const_iterator&) const noexcept = default;
2771 
2772  private:
2773  explicit const_iterator(const shared_ptr<_Node>&) noexcept;
2774 
2775  friend class tzdb_list;
2776 
2777  shared_ptr<_Node> _M_node;
2778  void* _M_reserved = nullptr;
2779  };
2780 
2781  /** Access the current `tzdb` at the front of the list.
2782  *
2783  * This returns a reference to the same object as `chrono::get_tzdb()`.
2784  *
2785  * @returns A reference to the current tzdb object.
2786  * @since C++20
2787  */
2788  const tzdb& front() const noexcept;
2789 
2790  /** Remove the tzdb object _after_ the one the iterator refers to.
2791  *
2792  * Calling this function concurrently with any of `front()`, `begin()`,
2793  * or `end()` does not cause a data race, but in general this function
2794  * is not thread-safe. The behaviour may be undefined if erasing an
2795  * element from the list while another thread is calling the same
2796  * function, or incrementing an iterator into the list, or accessing
2797  * the element being erased (unless it is accessed through an iterator).
2798  *
2799  * @param __p A dereferenceable iterator.
2800  * @returns An iterator the element after the one that was erased
2801  * (or `end()` if there is no such element).
2802  * @since C++20
2803  */
2804  const_iterator erase_after(const_iterator __p);
2805 
2806  const_iterator begin() const noexcept;
2807  const_iterator end() const noexcept { return {}; }
2808  const_iterator cbegin() const noexcept { return begin(); }
2809  const_iterator cend() const noexcept { return end(); }
2810 
2811  private:
2812  constexpr explicit tzdb_list(nullptr_t);
2813 
2814  friend tzdb_list& get_tzdb_list();
2815  friend const tzdb& get_tzdb();
2816  friend const tzdb& reload_tzdb();
2817  friend struct tzdb;
2818  friend class leap_second;
2819  friend struct time_zone::_Impl;
2820  friend class time_zone_link;
2821  };
2822 
2823  class time_zone_link
2824  {
2825  public:
2826  time_zone_link(time_zone_link&&) = default;
2827  time_zone_link& operator=(time_zone_link&&) = default;
2828 
2829  string_view name() const noexcept { return _M_name; }
2830  string_view target() const noexcept { return _M_target; }
2831 
2832  friend bool
2833  operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept
2834  { return __x.name() == __y.name(); }
2835 
2836  friend strong_ordering
2837  operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept
2838  { return __x.name() <=> __y.name(); }
2839 
2840  private:
2841  friend const tzdb& reload_tzdb();
2842  friend struct tzdb_list::_Node;
2843 
2844  explicit time_zone_link(nullptr_t) { }
2845 
2846  string _M_name;
2847  string _M_target;
2848  };
2849 
2850  class leap_second
2851  {
2852  public:
2853  leap_second(const leap_second&) = default;
2854  leap_second& operator=(const leap_second&) = default;
2855 
2856  [[nodiscard]]
2857  constexpr sys_seconds
2858  date() const noexcept
2859  {
2860  if (_M_s >= _M_s.zero()) [[likely]]
2861  return sys_seconds(_M_s);
2862  return sys_seconds(-_M_s);
2863  }
2864 
2865  [[nodiscard]]
2866  constexpr seconds
2867  value() const noexcept
2868  {
2869  if (_M_s >= _M_s.zero()) [[likely]]
2870  return seconds(1);
2871  return seconds(-1);
2872  }
2873 
2874  // This can be defaulted because the database will never contain two
2875  // leap_second objects with the same date but different signs.
2876  [[nodiscard]] friend constexpr bool
2877  operator==(const leap_second&, const leap_second&) noexcept = default;
2878 
2879  [[nodiscard]] friend constexpr strong_ordering
2880  operator<=>(const leap_second& __x, const leap_second& __y) noexcept
2881  { return __x.date() <=> __y.date(); }
2882 
2883  template<typename _Duration>
2884  [[nodiscard]] friend constexpr bool
2885  operator==(const leap_second& __x,
2886  const sys_time<_Duration>& __y) noexcept
2887  { return __x.date() == __y; }
2888 
2889  template<typename _Duration>
2890  [[nodiscard]] friend constexpr bool
2891  operator<(const leap_second& __x,
2892  const sys_time<_Duration>& __y) noexcept
2893  { return __x.date() < __y; }
2894 
2895  template<typename _Duration>
2896  [[nodiscard]] friend constexpr bool
2897  operator<(const sys_time<_Duration>& __x,
2898  const leap_second& __y) noexcept
2899  { return __x < __y.date(); }
2900 
2901  template<typename _Duration>
2902  [[nodiscard]] friend constexpr bool
2903  operator>(const leap_second& __x,
2904  const sys_time<_Duration>& __y) noexcept
2905  { return __y < __x.date(); }
2906 
2907  template<typename _Duration>
2908  [[nodiscard]] friend constexpr bool
2909  operator>(const sys_time<_Duration>& __x,
2910  const leap_second& __y) noexcept
2911  { return __y.date() < __x; }
2912 
2913  template<typename _Duration>
2914  [[nodiscard]] friend constexpr bool
2915  operator<=(const leap_second& __x,
2916  const sys_time<_Duration>& __y) noexcept
2917  { return !(__y < __x.date()); }
2918 
2919  template<typename _Duration>
2920  [[nodiscard]] friend constexpr bool
2921  operator<=(const sys_time<_Duration>& __x,
2922  const leap_second& __y) noexcept
2923  { return !(__y.date() < __x); }
2924 
2925  template<typename _Duration>
2926  [[nodiscard]] friend constexpr bool
2927  operator>=(const leap_second& __x,
2928  const sys_time<_Duration>& __y) noexcept
2929  { return !(__x.date() < __y); }
2930 
2931  template<typename _Duration>
2932  [[nodiscard]] friend constexpr bool
2933  operator>=(const sys_time<_Duration>& __x,
2934  const leap_second& __y) noexcept
2935  { return !(__x < __y.date()); }
2936 
2937  // This is a simplified form of the constraint specified in the standard,
2938  // three_way_comparable_with<sys_seconds, sys_time<_Duration>>.
2939  template<three_way_comparable_with<seconds> _Duration>
2940  [[nodiscard]] friend constexpr auto
2941  operator<=>(const leap_second& __x,
2942  const sys_time<_Duration>& __y) noexcept
2943  { return __x.date() <=> __y; }
2944 
2945  private:
2946  explicit leap_second(seconds::rep __s) : _M_s(__s) { }
2947 
2948  friend struct tzdb_list::_Node;
2949 
2950  friend const tzdb& reload_tzdb();
2951 
2952  template<typename _Duration>
2953  friend leap_second_info
2954  get_leap_second_info(const utc_time<_Duration>&);
2955 
2956  seconds _M_s; // == date().time_since_epoch() * value().count()
2957  };
2958 
2959  template<class _Tp> struct zoned_traits { };
2960 
2961  template<>
2962  struct zoned_traits<const time_zone*>
2963  {
2964  static const time_zone*
2965  default_zone()
2966  { return std::chrono::locate_zone("UTC"); }
2967 
2968  static const time_zone*
2969  locate_zone(string_view __name)
2970  { return std::chrono::locate_zone(__name); }
2971  };
2972 
2973  struct tzdb
2974  {
2975  string version;
2976  _GLIBCXX_STD_C::vector<time_zone> zones;
2977  _GLIBCXX_STD_C::vector<time_zone_link> links;
2978  _GLIBCXX_STD_C::vector<leap_second> leap_seconds;
2979 
2980  const time_zone*
2981  locate_zone(string_view __tz_name) const;
2982 
2983  const time_zone*
2984  current_zone() const;
2985 
2986  private:
2987  friend const tzdb& reload_tzdb();
2988  friend class time_zone;
2989  friend struct tzdb_list::_Node;
2990  };
2991 
2992  tzdb_list& get_tzdb_list();
2993  const tzdb& get_tzdb();
2994 
2995  const tzdb& reload_tzdb();
2996  string remote_version();
2997 
2998  template<typename _Duration, typename _TimeZonePtr = const time_zone*>
2999  class zoned_time
3000  {
3001  static_assert(__is_duration_v<_Duration>);
3002 
3003  using _Traits = zoned_traits<_TimeZonePtr>;
3004 
3005  // Every constructor that accepts a string_view as its first parameter
3006  // does not participate in class template argument deduction.
3007  using string_view = type_identity_t<std::string_view>;
3008 
3009  public:
3010  using duration = common_type_t<_Duration, seconds>;
3011 
3012  zoned_time() requires requires { _Traits::default_zone(); }
3013  { }
3014 
3015  zoned_time(const zoned_time&) = default;
3016  zoned_time& operator=(const zoned_time&) = default;
3017 
3018  zoned_time(const sys_time<_Duration>& __st)
3019  requires requires { _Traits::default_zone(); }
3020  : _M_tp(__st)
3021  { }
3022 
3023  explicit
3024  zoned_time(_TimeZonePtr __z) : _M_zone(std::move(__z)) { }
3025 
3026  explicit
3027  zoned_time(string_view __name)
3028  requires requires {
3029  _TimeZonePtr{_Traits::locate_zone(std::string_view{})};
3030  }
3031  : _M_zone(_Traits::locate_zone(__name))
3032  { }
3033 
3034  template<typename _Duration2>
3035  zoned_time(const zoned_time<_Duration2, _TimeZonePtr>& __zt)
3036  requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3037  : _M_zone(__zt._M_zone), _M_tp(__zt._M_tp)
3038  { }
3039 
3040  zoned_time(_TimeZonePtr __z, const sys_time<_Duration>& __st)
3041  : _M_zone(std::move(__z)), _M_tp(__st)
3042  { }
3043 
3044  zoned_time(string_view __name, const sys_time<_Duration>& __st)
3045  : zoned_time(_Traits::locate_zone(__name), __st)
3046  { }
3047 
3048  zoned_time(_TimeZonePtr __z, const local_time<_Duration>& __tp)
3049  requires requires {
3050  { __z->to_sys(__tp) } -> convertible_to<sys_time<_Duration>>;
3051  }
3052  : _M_zone(std::move(__z)), _M_tp(_M_zone->to_sys(__tp))
3053  { }
3054 
3055  zoned_time(string_view __name, const local_time<_Duration>& __tp)
3056  requires requires (_TimeZonePtr __z) {
3057  { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3058  { __z->to_sys(__tp) } -> convertible_to<sys_time<_Duration>>;
3059  }
3060  : zoned_time(_Traits::locate_zone(__name), __tp)
3061  { }
3062 
3063  zoned_time(_TimeZonePtr __z, const local_time<_Duration>& __tp,
3064  choose __c)
3065  requires requires {
3066  { __z->to_sys(__tp, __c) } -> convertible_to<sys_time<_Duration>>;
3067  }
3068  : _M_zone(std::move(__z)), _M_tp(_M_zone->to_sys(__tp, __c))
3069  { }
3070 
3071  zoned_time(string_view __name, const local_time<_Duration>& __tp,
3072  choose __c)
3073  requires requires (_TimeZonePtr __z) {
3074  { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3075  { __z->to_sys(__tp, __c) } -> convertible_to<sys_time<_Duration>>;
3076  }
3077  : _M_zone(_Traits::locate_zone(__name)),
3078  _M_tp(_M_zone->to_sys(__tp, __c))
3079  { }
3080 
3081  template<typename _Duration2, typename _TimeZonePtr2>
3082  zoned_time(_TimeZonePtr __z,
3083  const zoned_time<_Duration2, _TimeZonePtr2>& __zt)
3084  requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3085  : _M_zone(__z), _M_tp(__zt._M_tp)
3086  { }
3087 
3088  template<typename _Duration2, typename _TimeZonePtr2>
3089  zoned_time(_TimeZonePtr __z,
3090  const zoned_time<_Duration2, _TimeZonePtr2>& __zt,
3091  choose)
3092  requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3093  : _M_zone(__z), _M_tp(__zt._M_tp)
3094  { }
3095 
3096  template<typename _Duration2, typename _TimeZonePtr2>
3097  zoned_time(string_view __name,
3098  const zoned_time<_Duration2, _TimeZonePtr2>& __zt)
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  template<typename _Duration2, typename _TimeZonePtr2>
3107  zoned_time(string_view __name,
3108  const zoned_time<_Duration2, _TimeZonePtr2>& __zt,
3109  choose)
3110  requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3111  && requires {
3112  { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3113  }
3114  : _M_zone(_Traits::locate_zone(__name)), _M_tp(__zt._M_tp)
3115  { }
3116 
3117  zoned_time&
3118  operator=(const sys_time<_Duration>& __st)
3119  {
3120  _M_tp = __st;
3121  return *this;
3122  }
3123 
3124  zoned_time&
3125  operator=(const local_time<_Duration>& __lt)
3126  {
3127  _M_tp = _M_zone->to_sys(__lt);
3128  return *this;
3129  }
3130 
3131  [[nodiscard]]
3132  operator sys_time<duration>() const { return _M_tp; }
3133 
3134  [[nodiscard]]
3135  explicit operator local_time<duration>() const
3136  { return get_local_time(); }
3137 
3138  [[nodiscard]]
3139  _TimeZonePtr
3140  get_time_zone() const
3141  { return _M_zone; }
3142 
3143  [[nodiscard]]
3144  local_time<duration>
3145  get_local_time() const
3146  { return _M_zone->to_local(_M_tp); }
3147 
3148  [[nodiscard]]
3149  sys_time<duration>
3150  get_sys_time() const
3151  { return _M_tp; }
3152 
3153  [[nodiscard]]
3154  sys_info
3155  get_info() const
3156  { return _M_zone->get_info(_M_tp); }
3157 
3158  [[nodiscard]] friend bool
3159  operator==(const zoned_time&, const zoned_time&) = default;
3160 
3161  private:
3162  _TimeZonePtr _M_zone{ _Traits::default_zone() };
3163  sys_time<duration> _M_tp{};
3164 
3165  template<typename _Duration2, typename _TimeZonePtr2>
3166  friend class zoned_time;
3167  };
3168 
3169  zoned_time() -> zoned_time<seconds>;
3170 
3171  template<typename _Duration>
3172  zoned_time(sys_time<_Duration>)
3173  -> zoned_time<common_type_t<_Duration, seconds>>;
3174 
3175  /// @cond undocumented
3176  template<typename _TimeZonePtrOrName>
3177  using __time_zone_representation
3178  = __conditional_t<is_convertible_v<_TimeZonePtrOrName, string_view>,
3179  const time_zone*,
3180  remove_cvref_t<_TimeZonePtrOrName>>;
3181  /// @endcond
3182 
3183  template<typename _TimeZonePtrOrName>
3184  zoned_time(_TimeZonePtrOrName&&)
3185  -> zoned_time<seconds, __time_zone_representation<_TimeZonePtrOrName>>;
3186 
3187  template<typename _TimeZonePtrOrName, typename _Duration>
3188  zoned_time(_TimeZonePtrOrName&&, sys_time<_Duration>)
3189  -> zoned_time<common_type_t<_Duration, seconds>,
3190  __time_zone_representation<_TimeZonePtrOrName>>;
3191 
3192  template<typename _TimeZonePtrOrName, typename _Duration>
3193  zoned_time(_TimeZonePtrOrName&&, local_time<_Duration>,
3194  choose = choose::earliest)
3195  -> zoned_time<common_type_t<_Duration, seconds>,
3196  __time_zone_representation<_TimeZonePtrOrName>>;
3197 
3198  template<typename _Duration, typename _TimeZonePtrOrName,
3199  typename _TimeZonePtr2>
3200  zoned_time(_TimeZonePtrOrName&&, zoned_time<_Duration, _TimeZonePtr2>,
3201  choose = choose::earliest)
3202  -> zoned_time<common_type_t<_Duration, seconds>,
3203  __time_zone_representation<_TimeZonePtrOrName>>;
3204 
3205  template<typename _Dur1, typename _TZPtr1, typename _Dur2, typename _TZPtr2>
3206  [[nodiscard]]
3207  inline bool
3208  operator==(const zoned_time<_Dur1, _TZPtr1>& __x,
3209  const zoned_time<_Dur2, _TZPtr2>& __y)
3210  {
3211  return __x.get_time_zone() == __y.get_time_zone()
3212  && __x.get_sys_time() == __y.get_sys_time();
3213  }
3214 
3215  using zoned_seconds = zoned_time<seconds>;
3216 #endif // _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3217 
3218 namespace __detail
3219 {
3220  inline leap_second_info
3221  __get_leap_second_info(sys_seconds __ss, bool __is_utc)
3222  {
3223  if (__ss < sys_seconds{}) [[unlikely]]
3224  return {};
3225 
3226  const seconds::rep __leaps[] {
3227  78796800, // 1 Jul 1972
3228  94694400, // 1 Jan 1973
3229  126230400, // 1 Jan 1974
3230  157766400, // 1 Jan 1975
3231  189302400, // 1 Jan 1976
3232  220924800, // 1 Jan 1977
3233  252460800, // 1 Jan 1978
3234  283996800, // 1 Jan 1979
3235  315532800, // 1 Jan 1980
3236  362793600, // 1 Jul 1981
3237  394329600, // 1 Jul 1982
3238  425865600, // 1 Jul 1983
3239  489024000, // 1 Jul 1985
3240  567993600, // 1 Jan 1988
3241  631152000, // 1 Jan 1990
3242  662688000, // 1 Jan 1991
3243  709948800, // 1 Jul 1992
3244  741484800, // 1 Jul 1993
3245  773020800, // 1 Jul 1994
3246  820454400, // 1 Jan 1996
3247  867715200, // 1 Jul 1997
3248  915148800, // 1 Jan 1999
3249  1136073600, // 1 Jan 2006
3250  1230768000, // 1 Jan 2009
3251  1341100800, // 1 Jul 2012
3252  1435708800, // 1 Jul 2015
3253  1483228800, // 1 Jan 2017
3254  };
3255  // The list above is known to be valid until (at least) this date
3256  // and only contains positive leap seconds.
3257  constexpr sys_seconds __expires(1798416000s); // 2026-12-28 00:00:00 UTC
3258 
3259 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3260  if (__ss > __expires)
3261  {
3262  // Use updated leap_seconds from tzdb.
3263  size_t __n = std::size(__leaps);
3264 
3265  auto __db = get_tzdb_list().begin();
3266  auto __first = __db->leap_seconds.begin() + __n;
3267  auto __last = __db->leap_seconds.end();
3268  auto __pos = std::upper_bound(__first, __last, __ss);
3269  seconds __elapsed(__n);
3270  for (auto __i = __first; __i != __pos; ++__i)
3271  __elapsed += __i->value();
3272 
3273  if (__is_utc)
3274  {
3275  // Convert utc_time to sys_time:
3276  __ss -= __elapsed;
3277  // See if that sys_time is before (or during) previous leap sec:
3278  if (__pos != __first && __ss < __pos[-1])
3279  {
3280  if ((__ss + 1s) >= __pos[-1])
3281  return {true, __elapsed};
3282  __elapsed -= __pos[-1].value();
3283  }
3284  }
3285  return {false, __elapsed};
3286  }
3287  else
3288 #endif
3289  {
3290  seconds::rep __s = __ss.time_since_epoch().count();
3291  const seconds::rep* __first = std::begin(__leaps);
3292  const seconds::rep* __last = std::end(__leaps);
3293 
3294  // Don't bother searching the list if we're after the last one.
3295  if (__s > (__last[-1] + (__last - __first) + 1))
3296  return { false, seconds(__last - __first) };
3297 
3298  auto __pos = std::upper_bound(__first, __last, __s);
3299  seconds __elapsed{__pos - __first};
3300  if (__is_utc)
3301  {
3302  // Convert utc_time to sys_time:
3303  __s -= __elapsed.count();
3304  // See if that sys_time is before (or during) previous leap sec:
3305  if (__pos != __first && __s < __pos[-1])
3306  {
3307  if ((__s + 1) >= __pos[-1])
3308  return {true, __elapsed};
3309  --__elapsed;
3310  }
3311  }
3312  return {false, __elapsed};
3313  }
3314  }
3315 } // namespace __detail
3316 
3317  template<typename _Duration>
3318  [[nodiscard]]
3319  inline leap_second_info
3320  get_leap_second_info(const utc_time<_Duration>& __ut)
3321  {
3322  auto __s = chrono::duration_cast<seconds>(__ut.time_since_epoch());
3323  return __detail::__get_leap_second_info(sys_seconds(__s), true);
3324  }
3325 
3326  template<typename _Duration>
3327  [[nodiscard]]
3328  inline utc_time<common_type_t<_Duration, seconds>>
3329  utc_clock::from_sys(const sys_time<_Duration>& __t)
3330  {
3331  using _CDur = common_type_t<_Duration, seconds>;
3332  auto __s = chrono::time_point_cast<seconds>(__t);
3333  const auto __li = __detail::__get_leap_second_info(__s, false);
3334  return utc_time<_CDur>{__t.time_since_epoch()} + __li.elapsed;
3335  }
3336 #endif // _GLIBCXX_HOSTED
3337 
3338  /// @} group chrono
3339 #endif // C++20
3340  } // namespace chrono
3341 
3342 #if __glibcxx_chrono_cxx20 >= 202306 // C++26
3343  // Hash support [time.hash]
3344 
3345  template<typename _Tp>
3346  concept __is_nothrow_copy_hashable = requires(const _Tp& __t) {
3347  { hash<_Tp>{}(_Tp(__t)) } noexcept -> same_as<size_t>;
3348  };
3349 
3350  namespace chrono {
3351 
3352  /// @cond undocumented
3353  template<typename _T1, typename... _Ts>
3354  [[__gnu__::__always_inline__]]
3355  constexpr auto
3356  __pack_ints(_T1 __v1, _Ts... __vs)
3357  {
3358  using _ResT = decltype([] {
3359  constexpr size_t __tsize = (sizeof(_T1) + ... + sizeof(_Ts));
3360  if constexpr (__tsize <= 1)
3361  return static_cast<unsigned char>(0);
3362  else if constexpr (__tsize <= 2)
3363  return static_cast<__UINT16_TYPE__>(0);
3364  else if constexpr (__tsize <= 4)
3365  return static_cast<__UINT32_TYPE__>(0);
3366  else if constexpr (__tsize <= 8)
3367  return static_cast<__UINT64_TYPE__>(0);
3368  else
3369  static_assert(__tsize <= 8);
3370  }());
3371 
3372  _ResT __res = __v1;
3373  ((__res = (__res << (sizeof(_Ts) * __CHAR_BIT__) | _ResT(__vs))), ...);
3374  return __res;
3375  }
3376 
3377  template<typename _Tp>
3378  [[__gnu__::__always_inline__]]
3379  constexpr auto
3380  __as_int(_Tp __val)
3381  {
3382  if constexpr (is_same_v<_Tp, year>)
3383  return static_cast<unsigned short>(static_cast<int>(__val));
3384  else if constexpr (is_same_v<_Tp, month> || is_same_v<_Tp, day>)
3385  return static_cast<unsigned char>(static_cast<unsigned>(__val));
3386  else if constexpr (is_same_v<_Tp, weekday>)
3387  return static_cast<unsigned char>(__val.c_encoding());
3388  else if constexpr (is_same_v<_Tp, weekday_indexed>)
3389  return __pack_ints(chrono::__as_int(__val.weekday()),
3390  static_cast<unsigned char>(__val.index()));
3391  else if constexpr (is_same_v<_Tp, weekday_last>)
3392  return chrono::__as_int(__val.weekday());
3393  else
3394  static_assert(false);
3395  }
3396 
3397  template<typename _Arg, typename... _Args>
3398  size_t
3399  __int_hash(_Arg __arg, _Args... __args)
3400  {
3401  static_assert((is_integral_v<_Arg> && ... && is_integral_v<_Args>));
3402 
3403  // TODO consider using a better quality hasher
3404  using _Hasher = _Hash_impl;
3405  size_t __result = _Hasher::hash(__arg);
3406  ((__result = _Hasher::__hash_combine(__args, __result)), ...);
3407  return __result;
3408  }
3409 
3410  template<typename... _Tps>
3411  [[__gnu__::__always_inline__]]
3412  inline size_t
3413  __hash(_Tps... __vals)
3414  {
3415  if constexpr (sizeof...(_Tps) == 1)
3416  return chrono::__int_hash(chrono::__as_int(__vals)...);
3417  else
3418  {
3419  auto __res = chrono::__pack_ints(chrono::__as_int(__vals)...);
3420  return chrono::__int_hash(__res);
3421  }
3422  }
3423  /// @endcond
3424  } // namespace chrono
3425 
3426  // duration
3427  template<typename _Rep, typename _Period>
3428  requires __is_hash_enabled_for<_Rep>
3429  struct hash<chrono::duration<_Rep, _Period>>
3430  {
3431  size_t
3432  operator()(const chrono::duration<_Rep, _Period>& __val) const
3433  noexcept(__is_nothrow_copy_hashable<_Rep>)
3434  {
3435  if constexpr (is_integral_v<_Rep>)
3436  return chrono::__int_hash(__val.count());
3437  else
3438  return hash<_Rep>{}(__val.count());
3439  }
3440  };
3441 
3442  template<typename _Rep, typename _Period>
3443  struct __is_fast_hash<hash<chrono::duration<_Rep, _Period>>>
3444  : __is_fast_hash<hash<_Rep>>
3445  {};
3446 
3447  // time_point
3448  template<typename _Clock, typename _Dur>
3449  requires __is_hash_enabled_for<_Dur>
3450  struct hash<chrono::time_point<_Clock, _Dur>>
3451  {
3452  size_t
3453  operator()(const chrono::time_point<_Clock, _Dur>& __val) const
3454  noexcept(__is_nothrow_copy_hashable<_Dur>)
3455  { return hash<_Dur>{}(__val.time_since_epoch()); }
3456  };
3457 
3458  template<typename _Clock, typename _Dur>
3459  struct __is_fast_hash<hash<chrono::time_point<_Clock, _Dur>>>
3460  : __is_fast_hash<hash<_Dur>>
3461  {};
3462 
3463  // day
3464  template<>
3465  struct hash<chrono::day>
3466  {
3467  size_t
3468  operator()(chrono::day __val) const noexcept
3469  { return chrono::__hash(__val); }
3470  };
3471 
3472  // month
3473  template<>
3474  struct hash<chrono::month>
3475  {
3476  size_t
3477  operator()(chrono::month __val) const noexcept
3478  { return chrono::__hash(__val); }
3479  };
3480 
3481  // year
3482  template<>
3483  struct hash<chrono::year>
3484  {
3485  size_t
3486  operator()(chrono::year __val) const noexcept
3487  { return chrono::__hash(__val); }
3488  };
3489 
3490  // weekday
3491  template<>
3492  struct hash<chrono::weekday>
3493  {
3494  size_t
3495  operator()(chrono::weekday __val) const noexcept
3496  { return chrono::__hash(__val); }
3497  };
3498 
3499  // weekday_indexed
3500  template<>
3501  struct hash<chrono::weekday_indexed>
3502  {
3503  size_t
3504  operator()(chrono::weekday_indexed __val) const noexcept
3505  { return chrono::__hash(__val); }
3506  };
3507 
3508  // weekday_last
3509  template<>
3510  struct hash<chrono::weekday_last>
3511  {
3512  size_t
3513  operator()(chrono::weekday_last __val) const noexcept
3514  { return chrono::__hash(__val); }
3515  };
3516 
3517  // month_day
3518  template<>
3519  struct hash<chrono::month_day>
3520  {
3521  size_t
3522  operator()(chrono::month_day __val) const noexcept
3523  { return chrono::__hash(__val.month(), __val.day()); }
3524  };
3525 
3526  // month_day_last
3527  template<>
3528  struct hash<chrono::month_day_last>
3529  {
3530  size_t operator()(chrono::month_day_last __val) const noexcept
3531  { return chrono::__hash(__val.month()); }
3532  };
3533 
3534  // month_weekday
3535  template<>
3536  struct hash<chrono::month_weekday>
3537  {
3538  size_t
3539  operator()(chrono::month_weekday __val) const noexcept
3540  { return chrono::__hash(__val.month(), __val.weekday_indexed()); }
3541  };
3542 
3543  // month_weekday_last
3544  template<>
3545  struct hash<chrono::month_weekday_last>
3546  {
3547  size_t
3548  operator()(chrono::month_weekday_last __val) const noexcept
3549  { return chrono::__hash(__val.month(), __val.weekday_last()); }
3550  };
3551 
3552  // year_month
3553  template<>
3554  struct hash<chrono::year_month>
3555  {
3556  size_t
3557  operator()(chrono::year_month __val) const noexcept
3558  { return chrono::__hash(__val.year(), __val.month()); }
3559  };
3560 
3561  // year_month_day
3562  template<>
3563  struct hash<chrono::year_month_day>
3564  {
3565  size_t
3566  operator()(chrono::year_month_day __val) const noexcept
3567  { return chrono::__hash(__val.year(), __val.month(), __val.day()); }
3568  };
3569 
3570  // year_month_day_last
3571  template<>
3572  struct hash<chrono::year_month_day_last>
3573  {
3574  size_t
3575  operator()(chrono::year_month_day_last __val) const noexcept
3576  { return chrono::__hash(__val.year(), __val.month()); }
3577  };
3578 
3579  // year_month_weekday
3580  template<>
3581  struct hash<chrono::year_month_weekday>
3582  {
3583  size_t
3584  operator()(chrono::year_month_weekday __val) const noexcept
3585  {
3586  return chrono::__hash(__val.year(), __val.month(),
3587  __val.weekday_indexed());
3588  }
3589  };
3590 
3591  // year_month_weekday_last
3592  template<>
3593  struct hash<chrono::year_month_weekday_last>
3594  {
3595  size_t
3596  operator()(chrono::year_month_weekday_last __val) const noexcept
3597  {
3598  return chrono::__hash(__val.year(), __val.month(),
3599  __val.weekday_last());
3600  }
3601  };
3602 
3603 #if _GLIBCXX_HOSTED
3604 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3605  // zoned_time
3606  template<typename _Duration, typename _TimeZonePtr>
3607  requires __is_hash_enabled_for<
3608  typename chrono::zoned_time<_Duration, _TimeZonePtr>::duration>
3609  && __is_hash_enabled_for<_TimeZonePtr>
3610  struct hash<chrono::zoned_time<_Duration, _TimeZonePtr>>
3611  {
3612  private:
3613  using _ActualDuration =
3614  typename chrono::zoned_time<_Duration, _TimeZonePtr>::duration;
3615 
3616  public:
3617  size_t
3618  operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __val) const
3619  noexcept(__is_nothrow_copy_hashable<_ActualDuration>
3620  && __is_nothrow_copy_hashable<_TimeZonePtr>)
3621  {
3622  const auto __iduration = [&] {
3623  const _ActualDuration __sd = __val.get_sys_time().time_since_epoch();
3624  if constexpr (is_integral_v<typename _ActualDuration::rep>)
3625  return __sd.count();
3626  else
3627  return hash<_ActualDuration>{}(__sd);
3628  }();
3629 
3630  const auto __izone = [&] {
3631  const _TimeZonePtr __tz = __val.get_time_zone();
3632  if constexpr (is_same_v<_TimeZonePtr, const chrono::time_zone*>)
3633  return reinterpret_cast<uintptr_t>(__tz);
3634  else
3635  return hash<_TimeZonePtr>{}(__tz);
3636  }();
3637 
3638  return chrono::__int_hash(__iduration, __izone);
3639  }
3640  };
3641 
3642  template<typename _Duration, typename _TimeZonePtr>
3643  struct __is_fast_hash<hash<chrono::zoned_time<_Duration, _TimeZonePtr>>>
3644  : __and_<__is_fast_hash<hash<
3645  typename chrono::zoned_time<_Duration, _TimeZonePtr>::duration>>,
3646  __is_fast_hash<hash<_TimeZonePtr>>>
3647  {};
3648 
3649  // leap_second
3650  template<>
3651  struct hash<chrono::leap_second>
3652  {
3653  size_t
3654  operator()(chrono::leap_second __val) const noexcept
3655  {
3656  return chrono::__int_hash(
3657  __val.date().time_since_epoch().count(),
3658  __val.value().count());
3659  }
3660  };
3661 #endif // _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3662 #endif // _GLIBCXX_HOSTED
3663 #endif // __glibcxx_chrono_cxx20 >= 202306
3664 
3665 #ifdef __glibcxx_chrono_cxx20
3666  inline namespace literals
3667  {
3668  inline namespace chrono_literals
3669  {
3670  /// @addtogroup chrono
3671  /// @{
3672 #pragma GCC diagnostic push
3673 #pragma GCC diagnostic ignored "-Wliteral-suffix"
3674  /// Literal suffix for creating chrono::day objects.
3675  /// @since C++20
3676  constexpr chrono::day
3677  operator""d(unsigned long long __d) noexcept
3678  { return chrono::day{static_cast<unsigned>(__d)}; }
3679 
3680  /// Literal suffix for creating chrono::year objects.
3681  /// @since C++20
3682  constexpr chrono::year
3683  operator""y(unsigned long long __y) noexcept
3684  { return chrono::year{static_cast<int>(__y)}; }
3685 #pragma GCC diagnostic pop
3686  /// @}
3687  } // inline namespace chrono_literals
3688  } // inline namespace literals
3689 #endif // C++20
3690 
3691 _GLIBCXX_END_NAMESPACE_VERSION
3692 } // namespace std
3693 
3694 #if defined __glibcxx_chrono_cxx20 && _GLIBCXX_HOSTED
3695 # include <bits/chrono_io.h>
3696 #endif
3697 
3698 #endif // C++11
3699 
3700 #endif //_GLIBCXX_CHRONO