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