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