xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/chrono (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1// <chrono> -*- C++ -*-
2
3// Copyright (C) 2008-2022 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#if __cplusplus < 201103L
36# include <bits/c++0x_warning.h>
37#else
38
39#include <bits/chrono.h>
40#if __cplusplus > 201703L
41# include <sstream> // ostringstream
42# include <bits/charconv.h>
43#endif
44
45namespace std _GLIBCXX_VISIBILITY(default)
46{
47_GLIBCXX_BEGIN_NAMESPACE_VERSION
48
49  /**
50   * @defgroup chrono Time
51   * @ingroup utilities
52   *
53   * Classes and functions for time.
54   *
55   * @since C++11
56   */
57
58  /** @namespace std::chrono
59   *  @brief ISO C++ 2011 namespace for date and time utilities
60   *  @ingroup chrono
61   */
62  namespace chrono
63  {
64#if __cplusplus >= 202002L
65    /// @addtogroup chrono
66    /// @{
67    struct local_t { };
68    template<typename _Duration>
69      using local_time = time_point<local_t, _Duration>;
70    using local_seconds = local_time<seconds>;
71    using local_days = local_time<days>;
72
73    class utc_clock;
74    class tai_clock;
75    class gps_clock;
76
77    template<typename _Duration>
78      using utc_time = time_point<utc_clock, _Duration>;
79    using utc_seconds = utc_time<seconds>;
80
81    template<typename _Duration>
82      using tai_time = time_point<tai_clock, _Duration>;
83    using tai_seconds = tai_time<seconds>;
84
85    template<typename _Duration>
86      using gps_time = time_point<gps_clock, _Duration>;
87    using gps_seconds = gps_time<seconds>;
88
89    template<> struct is_clock<utc_clock> : true_type { };
90    template<> struct is_clock<tai_clock> : true_type { };
91    template<> struct is_clock<gps_clock> : true_type { };
92
93    template<> inline constexpr bool is_clock_v<utc_clock> = true;
94    template<> inline constexpr bool is_clock_v<tai_clock> = true;
95    template<> inline constexpr bool is_clock_v<gps_clock> = true;
96
97    struct leap_second_info
98    {
99      bool is_leap_second;
100      seconds elapsed;
101    };
102
103    // CALENDRICAL TYPES
104
105    // CLASS DECLARATIONS
106    class day;
107    class month;
108    class year;
109    class weekday;
110    class weekday_indexed;
111    class weekday_last;
112    class month_day;
113    class month_day_last;
114    class month_weekday;
115    class month_weekday_last;
116    class year_month;
117    class year_month_day;
118    class year_month_day_last;
119    class year_month_weekday;
120    class year_month_weekday_last;
121
122    struct last_spec
123    {
124      explicit last_spec() = default;
125
126      friend constexpr month_day_last
127      operator/(int __m, last_spec) noexcept;
128
129      friend constexpr month_day_last
130      operator/(last_spec, int __m) noexcept;
131    };
132
133    inline constexpr last_spec last{};
134
135    namespace __detail
136    {
137      // Helper to __add_modulo and __sub_modulo.
138      template <unsigned __d, typename _Tp>
139      consteval auto
140      __modulo_offset()
141      {
142	using _Up = make_unsigned_t<_Tp>;
143	auto constexpr __a = _Up(-1) - _Up(255 + __d - 2);
144	auto constexpr __b = _Up(__d * (__a / __d) - 1);
145	// Notice: b <= a - 1 <= _Up(-1) - (255 + d - 1) and b % d = d - 1.
146	return _Up(-1) - __b; // >= 255 + d - 1
147      }
148
149      // Compute the remainder of the Euclidean division of __x + __y divided by
150      // __d without overflowing.  Typically, __x <= 255 + d - 1 is sum of
151      // weekday/month with a shift in [0, d - 1] and __y is a duration count.
152      template <unsigned __d, typename _Tp>
153      constexpr unsigned
154      __add_modulo(unsigned __x, _Tp __y)
155      {
156	using _Up = make_unsigned_t<_Tp>;
157	// For __y >= 0, _Up(__y) has the same mathematical value as __y and
158	// this function simply returns (__x + _Up(__y)) % d.  Typically, this
159	// doesn't overflow since the range of _Up contains many more positive
160	// values than _Tp's.  For __y < 0, _Up(__y) has a mathematical value in
161	// the upper-half range of _Up so that adding a positive value to it
162	// might overflow.  Moreover, most likely, _Up(__y) != __y mod d.  To
163	// fix both issues we subtract from _Up(__y) an __offset >=
164	// 255 + d - 1 to make room for the addition to __x and shift the modulo
165	// to the correct value.
166	auto const __offset = __y >= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
167	return (__x + _Up(__y) - __offset) % __d;
168      }
169
170      // Similar to __add_modulo but for __x - __y.
171      template <unsigned __d, typename _Tp>
172      constexpr unsigned
173      __sub_modulo(unsigned __x, _Tp __y)
174      {
175	using _Up = make_unsigned_t<_Tp>;
176	auto const __offset = __y <= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
177	return (__x - _Up(__y) - __offset) % __d;
178      }
179
180      inline constexpr unsigned __days_per_month[12]
181	= { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
182    }
183
184    // DAY
185
186    class day
187    {
188    private:
189      unsigned char _M_d;
190
191    public:
192      day() = default;
193
194      explicit constexpr
195      day(unsigned __d) noexcept
196      : _M_d(__d)
197      { }
198
199      constexpr day&
200      operator++() noexcept
201      {
202	++_M_d;
203	return *this;
204      }
205
206      constexpr day
207      operator++(int) noexcept
208      {
209	auto __ret = *this;
210	++(*this);
211	return __ret;
212      }
213
214      constexpr day&
215      operator--() noexcept
216      {
217	--_M_d;
218	return *this;
219      }
220
221      constexpr day
222      operator--(int) noexcept
223      {
224	auto __ret = *this;
225	--(*this);
226	return __ret;
227      }
228
229      constexpr day&
230      operator+=(const days& __d) noexcept
231      {
232	*this = *this + __d;
233	return *this;
234      }
235
236      constexpr day&
237      operator-=(const days& __d) noexcept
238      {
239	*this = *this - __d;
240	return *this;
241      }
242
243      constexpr explicit
244      operator unsigned() const noexcept
245      { return _M_d; }
246
247      constexpr bool
248      ok() const noexcept
249      { return 1 <= _M_d && _M_d <= 31; }
250
251      friend constexpr bool
252      operator==(const day& __x, const day& __y) noexcept
253      { return unsigned{__x} == unsigned{__y}; }
254
255      friend constexpr strong_ordering
256      operator<=>(const day& __x, const day& __y) noexcept
257      { return unsigned{__x} <=> unsigned{__y}; }
258
259      friend constexpr day
260      operator+(const day& __x, const days& __y) noexcept
261      { return day(unsigned{__x} + __y.count()); }
262
263      friend constexpr day
264      operator+(const days& __x, const day& __y) noexcept
265      { return __y + __x; }
266
267      friend constexpr day
268      operator-(const day& __x, const days& __y) noexcept
269      { return __x + -__y; }
270
271      friend constexpr days
272      operator-(const day& __x, const day& __y) noexcept
273      { return days{int(unsigned{__x}) - int(unsigned{__y})}; }
274
275      friend constexpr month_day
276      operator/(const month& __m, const day& __d) noexcept;
277
278      friend constexpr month_day
279      operator/(int __m, const day& __d) noexcept;
280
281      friend constexpr month_day
282      operator/(const day& __d, const month& __m) noexcept;
283
284      friend constexpr month_day
285      operator/(const day& __d, int __m) noexcept;
286
287      friend constexpr year_month_day
288      operator/(const year_month& __ym, const day& __d) noexcept;
289
290      // TODO: Implement operator<<, to_stream, from_stream.
291    };
292
293    // MONTH
294
295    class month
296    {
297    private:
298      unsigned char _M_m;
299
300    public:
301      month() = default;
302
303      explicit constexpr
304      month(unsigned __m) noexcept
305      : _M_m(__m)
306      { }
307
308      constexpr month&
309      operator++() noexcept
310      {
311	*this += months{1};
312	return *this;
313      }
314
315      constexpr month
316      operator++(int) noexcept
317      {
318	auto __ret = *this;
319	++(*this);
320	return __ret;
321      }
322
323      constexpr month&
324      operator--() noexcept
325      {
326	*this -= months{1};
327	return *this;
328      }
329
330      constexpr month
331      operator--(int) noexcept
332      {
333	auto __ret = *this;
334	--(*this);
335	return __ret;
336      }
337
338      constexpr month&
339      operator+=(const months& __m) noexcept
340      {
341	*this = *this + __m;
342	return *this;
343      }
344
345      constexpr month&
346      operator-=(const months& __m) noexcept
347      {
348	*this = *this - __m;
349	return *this;
350      }
351
352      explicit constexpr
353      operator unsigned() const noexcept
354      { return _M_m; }
355
356      constexpr bool
357      ok() const noexcept
358      { return 1 <= _M_m && _M_m <= 12; }
359
360      friend constexpr bool
361      operator==(const month& __x, const month& __y) noexcept
362      { return unsigned{__x} == unsigned{__y}; }
363
364      friend constexpr strong_ordering
365      operator<=>(const month& __x, const month& __y) noexcept
366      { return unsigned{__x} <=> unsigned{__y}; }
367
368      friend constexpr month
369      operator+(const month& __x, const months& __y) noexcept
370      {
371	// modulo(x + (y - 1), 12) = modulo(x + (y - 1) + 12, 12)
372	//                         = modulo((x + 11) + y    , 12)
373	return month{1 + __detail::__add_modulo<12>(
374	  unsigned{__x} + 11, __y.count())};
375      }
376
377      friend constexpr month
378      operator+(const months& __x,  const month& __y) noexcept
379      { return __y + __x; }
380
381      friend constexpr month
382      operator-(const month& __x, const months& __y) noexcept
383      {
384	// modulo(x + (-y - 1), 12) = modulo(x + (-y - 1) + 12, 12)
385	//                          = modulo((x + 11) - y     , 12)
386	return month{1 + __detail::__sub_modulo<12>(
387	  unsigned{__x} + 11, __y.count())};
388      }
389
390      friend constexpr months
391      operator-(const month& __x,  const month& __y) noexcept
392      {
393	const auto __dm = int(unsigned(__x)) - int(unsigned(__y));
394	return months{__dm < 0 ? 12 + __dm : __dm};
395      }
396
397      friend constexpr year_month
398      operator/(const year& __y, const month& __m) noexcept;
399
400      friend constexpr month_day
401      operator/(const month& __m, int __d) noexcept;
402
403      friend constexpr month_day_last
404      operator/(const month& __m, last_spec) noexcept;
405
406      friend constexpr month_day_last
407      operator/(last_spec, const month& __m) noexcept;
408
409      friend constexpr month_weekday
410      operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
411
412      friend constexpr month_weekday
413      operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
414
415      friend constexpr month_weekday_last
416      operator/(const month& __m, const weekday_last& __wdl) noexcept;
417
418      friend constexpr month_weekday_last
419      operator/(const weekday_last& __wdl, const month& __m) noexcept;
420
421      // TODO: Implement operator<<, to_stream, from_stream.
422    };
423
424    inline constexpr month January{1};
425    inline constexpr month February{2};
426    inline constexpr month March{3};
427    inline constexpr month April{4};
428    inline constexpr month May{5};
429    inline constexpr month June{6};
430    inline constexpr month July{7};
431    inline constexpr month August{8};
432    inline constexpr month September{9};
433    inline constexpr month October{10};
434    inline constexpr month November{11};
435    inline constexpr month December{12};
436
437    // YEAR
438
439    class year
440    {
441    private:
442      short _M_y;
443
444    public:
445      year() = default;
446
447      explicit constexpr
448      year(int __y) noexcept
449      : _M_y{static_cast<short>(__y)}
450      { }
451
452      static constexpr year
453      min() noexcept
454      { return year{-32767}; }
455
456      static constexpr year
457      max() noexcept
458      { return year{32767}; }
459
460      constexpr year&
461      operator++() noexcept
462      {
463	++_M_y;
464	return *this;
465      }
466
467      constexpr year
468      operator++(int) noexcept
469      {
470	auto __ret = *this;
471	++(*this);
472	return __ret;
473      }
474
475      constexpr year&
476      operator--() noexcept
477      {
478	--_M_y;
479	return *this;
480      }
481
482      constexpr year
483      operator--(int) noexcept
484      {
485	auto __ret = *this;
486	--(*this);
487	return __ret;
488      }
489
490      constexpr year&
491      operator+=(const years& __y) noexcept
492      {
493	*this = *this + __y;
494	return *this;
495      }
496
497      constexpr year&
498      operator-=(const years& __y) noexcept
499      {
500	*this = *this - __y;
501	return *this;
502      }
503
504      constexpr year
505      operator+() const noexcept
506      { return *this; }
507
508      constexpr year
509      operator-() const noexcept
510      { return year{-_M_y}; }
511
512      constexpr bool
513      is_leap() const noexcept
514      {
515	// Testing divisibility by 100 first gives better performance [1], i.e.,
516	//     return _M_y % 100 == 0 ? _M_y % 400 == 0 : _M_y % 16 == 0;
517	// Furthermore, if _M_y % 100 == 0, then _M_y % 400 == 0 is equivalent
518	// to _M_y % 16 == 0, so we can simplify it to
519	//     return _M_y % 100 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0.  // #1
520	// Similarly, we can replace 100 with 25 (which is good since
521	// _M_y % 25 == 0 requires one fewer instruction than _M_y % 100 == 0
522	// [2]):
523	//     return _M_y % 25 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0.  // #2
524	// Indeed, first assume _M_y % 4 != 0.  Then _M_y % 16 != 0 and hence,
525	// _M_y % 4 == 0 and _M_y % 16 == 0 are both false.  Therefore, #2
526	// returns false as it should (regardless of _M_y % 25.) Now assume
527	// _M_y % 4 == 0.  In this case, _M_y % 25 == 0 if, and only if,
528	// _M_y % 100 == 0, that is, #1 and #2 are equivalent.  Finally, #2 is
529	// equivalent to
530	//     return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0.
531
532	// References:
533	// [1] https://github.com/cassioneri/calendar
534	// [2] https://godbolt.org/z/55G8rn77e
535	// [3] https://gcc.gnu.org/pipermail/libstdc++/2021-June/052815.html
536
537	return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0;
538      }
539
540      explicit constexpr
541      operator int() const noexcept
542      { return _M_y; }
543
544      constexpr bool
545      ok() const noexcept
546      { return min()._M_y <= _M_y && _M_y <= max()._M_y; }
547
548      friend constexpr bool
549      operator==(const year& __x, const year& __y) noexcept
550      { return int{__x} == int{__y}; }
551
552      friend constexpr strong_ordering
553      operator<=>(const year& __x, const year& __y) noexcept
554      { return int{__x} <=> int{__y}; }
555
556      friend constexpr year
557      operator+(const year& __x, const years& __y) noexcept
558      { return year{int{__x} + static_cast<int>(__y.count())}; }
559
560      friend constexpr year
561      operator+(const years& __x, const year& __y) noexcept
562      { return __y + __x; }
563
564      friend constexpr year
565      operator-(const year& __x, const years& __y) noexcept
566      { return __x + -__y; }
567
568      friend constexpr years
569      operator-(const year& __x, const year& __y) noexcept
570      { return years{int{__x} - int{__y}}; }
571
572      friend constexpr year_month
573      operator/(const year& __y, int __m) noexcept;
574
575      friend constexpr year_month_day
576      operator/(const year& __y, const month_day& __md) noexcept;
577
578      friend constexpr year_month_day
579      operator/(const month_day& __md, const year& __y) noexcept;
580
581      friend constexpr year_month_day_last
582      operator/(const year& __y, const month_day_last& __mdl) noexcept;
583
584      friend constexpr year_month_day_last
585      operator/(const month_day_last& __mdl, const year& __y) noexcept;
586
587      friend constexpr year_month_weekday
588      operator/(const year& __y, const month_weekday& __mwd) noexcept;
589
590      friend constexpr year_month_weekday
591      operator/(const month_weekday& __mwd, const year& __y) noexcept;
592
593      friend constexpr year_month_weekday_last
594      operator/(const year& __y, const month_weekday_last& __mwdl) noexcept;
595
596      friend constexpr year_month_weekday_last
597      operator/(const month_weekday_last& __mwdl, const year& __y) noexcept;
598
599      // TODO: Implement operator<<, to_stream, from_stream.
600    };
601
602    // WEEKDAY
603
604    class weekday
605    {
606    private:
607      unsigned char _M_wd;
608
609      static constexpr weekday
610      _S_from_days(const days& __d)
611      {
612	return weekday{__detail::__add_modulo<7>(4, __d.count())};
613      }
614
615    public:
616      weekday() = default;
617
618      explicit constexpr
619      weekday(unsigned __wd) noexcept
620      : _M_wd(__wd == 7 ? 0 : __wd) // __wd % 7 ?
621      { }
622
623      constexpr
624      weekday(const sys_days& __dp) noexcept
625      : weekday{_S_from_days(__dp.time_since_epoch())}
626      { }
627
628      explicit constexpr
629      weekday(const local_days& __dp) noexcept
630      : weekday{sys_days{__dp.time_since_epoch()}}
631      { }
632
633      constexpr weekday&
634      operator++() noexcept
635      {
636	*this += days{1};
637	return *this;
638      }
639
640      constexpr weekday
641      operator++(int) noexcept
642      {
643	auto __ret = *this;
644	++(*this);
645	return __ret;
646      }
647
648      constexpr weekday&
649      operator--() noexcept
650      {
651	*this -= days{1};
652	return *this;
653      }
654
655      constexpr weekday
656      operator--(int) noexcept
657      {
658	auto __ret = *this;
659	--(*this);
660	return __ret;
661      }
662
663      constexpr weekday&
664      operator+=(const days& __d) noexcept
665      {
666	*this = *this + __d;
667	return *this;
668      }
669
670      constexpr weekday&
671      operator-=(const days& __d) noexcept
672      {
673	*this = *this - __d;
674	return *this;
675      }
676
677      constexpr unsigned
678      c_encoding() const noexcept
679      { return _M_wd; }
680
681      constexpr unsigned
682      iso_encoding() const noexcept
683      { return _M_wd == 0u ? 7u : _M_wd; }
684
685      constexpr bool
686      ok() const noexcept
687      { return _M_wd <= 6; }
688
689      constexpr weekday_indexed
690      operator[](unsigned __index) const noexcept;
691
692      constexpr weekday_last
693      operator[](last_spec) const noexcept;
694
695      friend constexpr bool
696      operator==(const weekday& __x, const weekday& __y) noexcept
697      { return __x._M_wd == __y._M_wd; }
698
699      friend constexpr weekday
700      operator+(const weekday& __x, const days& __y) noexcept
701      {
702	return weekday{__detail::__add_modulo<7>(__x._M_wd, __y.count())};
703      }
704
705      friend constexpr weekday
706      operator+(const days& __x, const weekday& __y) noexcept
707      { return __y + __x; }
708
709      friend constexpr weekday
710      operator-(const weekday& __x, const days& __y) noexcept
711      {
712	return weekday{__detail::__sub_modulo<7>(__x._M_wd, __y.count())};
713      }
714
715      friend constexpr days
716      operator-(const weekday& __x, const weekday& __y) noexcept
717      {
718	const auto __n = __x.c_encoding() - __y.c_encoding();
719	return static_cast<int>(__n) >= 0 ? days{__n} : days{__n + 7};
720      }
721
722      // TODO: operator<<, from_stream.
723    };
724
725    inline constexpr weekday Sunday{0};
726    inline constexpr weekday Monday{1};
727    inline constexpr weekday Tuesday{2};
728    inline constexpr weekday Wednesday{3};
729    inline constexpr weekday Thursday{4};
730    inline constexpr weekday Friday{5};
731    inline constexpr weekday Saturday{6};
732
733    // WEEKDAY_INDEXED
734
735    class weekday_indexed
736    {
737    private:
738      chrono::weekday _M_wd;
739      unsigned char _M_index;
740
741    public:
742      weekday_indexed() = default;
743
744      constexpr
745      weekday_indexed(const chrono::weekday& __wd, unsigned __index) noexcept
746      : _M_wd(__wd), _M_index(__index)
747      { }
748
749      constexpr chrono::weekday
750      weekday() const noexcept
751      { return _M_wd; }
752
753      constexpr unsigned
754      index() const noexcept
755      { return _M_index; };
756
757      constexpr bool
758      ok() const noexcept
759      { return _M_wd.ok() && 1 <= _M_index && _M_index <= 5; }
760
761      friend constexpr bool
762      operator==(const weekday_indexed& __x, const weekday_indexed& __y) noexcept
763      { return __x.weekday() == __y.weekday() && __x.index() == __y.index(); }
764
765      friend constexpr month_weekday
766      operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
767
768      friend constexpr month_weekday
769      operator/(int __m, const weekday_indexed& __wdi) noexcept;
770
771      friend constexpr month_weekday
772      operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
773
774      friend constexpr month_weekday
775      operator/(const weekday_indexed& __wdi, int __m) noexcept;
776
777      friend constexpr year_month_weekday
778      operator/(const year_month& __ym, const weekday_indexed& __wdi) noexcept;
779
780      // TODO: Implement operator<<.
781    };
782
783    constexpr weekday_indexed
784    weekday::operator[](unsigned __index) const noexcept
785    { return {*this, __index}; }
786
787    // WEEKDAY_LAST
788
789    class weekday_last
790    {
791    private:
792      chrono::weekday _M_wd;
793
794    public:
795      explicit constexpr
796      weekday_last(const chrono::weekday& __wd) noexcept
797      : _M_wd{__wd}
798      { }
799
800      constexpr chrono::weekday
801      weekday() const noexcept
802      { return _M_wd; }
803
804      constexpr bool
805      ok() const noexcept
806      { return _M_wd.ok(); }
807
808      friend constexpr bool
809      operator==(const weekday_last& __x, const weekday_last& __y) noexcept
810      { return __x.weekday() == __y.weekday(); }
811
812      friend constexpr month_weekday_last
813      operator/(int __m, const weekday_last& __wdl) noexcept;
814
815      friend constexpr month_weekday_last
816      operator/(const weekday_last& __wdl, int __m) noexcept;
817
818      friend constexpr year_month_weekday_last
819      operator/(const year_month& __ym, const weekday_last& __wdl) noexcept;
820
821      // TODO: Implement operator<<.
822    };
823
824    constexpr weekday_last
825    weekday::operator[](last_spec) const noexcept
826    { return weekday_last{*this}; }
827
828    // MONTH_DAY
829
830    class month_day
831    {
832    private:
833      chrono::month _M_m;
834      chrono::day _M_d;
835
836    public:
837      month_day() = default;
838
839      constexpr
840      month_day(const chrono::month& __m, const chrono::day& __d) noexcept
841      : _M_m{__m}, _M_d{__d}
842      { }
843
844      constexpr chrono::month
845      month() const noexcept
846      { return _M_m; }
847
848      constexpr chrono::day
849      day() const noexcept
850      { return _M_d; }
851
852      constexpr bool
853      ok() const noexcept
854      {
855	return _M_m.ok()
856	  && 1u <= unsigned(_M_d)
857	  && unsigned(_M_d) <= __detail::__days_per_month[unsigned(_M_m) - 1];
858      }
859
860      friend constexpr bool
861      operator==(const month_day& __x, const month_day& __y) noexcept
862      { return __x.month() == __y.month() && __x.day() == __y.day(); }
863
864      friend constexpr strong_ordering
865      operator<=>(const month_day& __x, const month_day& __y) noexcept
866	= default;
867
868      friend constexpr month_day
869      operator/(const chrono::month& __m, const chrono::day& __d) noexcept
870      { return {__m, __d}; }
871
872      friend constexpr month_day
873      operator/(const chrono::month& __m, int __d) noexcept
874      { return {__m, chrono::day(unsigned(__d))}; }
875
876      friend constexpr month_day
877      operator/(int __m, const chrono::day& __d) noexcept
878      { return {chrono::month(unsigned(__m)), __d}; }
879
880      friend constexpr month_day
881      operator/(const chrono::day& __d, const chrono::month& __m) noexcept
882      { return {__m, __d}; }
883
884      friend constexpr month_day
885      operator/(const chrono::day& __d, int __m) noexcept
886      { return {chrono::month(unsigned(__m)), __d}; }
887
888      friend constexpr year_month_day
889      operator/(int __y, const month_day& __md) noexcept;
890
891      friend constexpr year_month_day
892      operator/(const month_day& __md, int __y) noexcept;
893
894      // TODO: Implement operator<<, from_stream.
895    };
896
897    // MONTH_DAY_LAST
898
899    class month_day_last
900    {
901    private:
902      chrono::month _M_m;
903
904    public:
905      explicit constexpr
906      month_day_last(const chrono::month& __m) noexcept
907      : _M_m{__m}
908      { }
909
910      constexpr chrono::month
911      month() const noexcept
912      { return _M_m; }
913
914      constexpr bool
915      ok() const noexcept
916      { return _M_m.ok(); }
917
918      friend constexpr bool
919      operator==(const month_day_last& __x, const month_day_last& __y) noexcept
920      { return __x.month() == __y.month(); }
921
922      friend constexpr strong_ordering
923      operator<=>(const month_day_last& __x, const month_day_last& __y) noexcept
924	= default;
925
926      friend constexpr month_day_last
927      operator/(const chrono::month& __m, last_spec) noexcept
928      { return month_day_last{__m}; }
929
930      friend constexpr month_day_last
931      operator/(int __m, last_spec) noexcept
932      { return chrono::month(unsigned(__m)) / last; }
933
934      friend constexpr month_day_last
935      operator/(last_spec, const chrono::month& __m) noexcept
936      { return __m / last; }
937
938      friend constexpr month_day_last
939      operator/(last_spec, int __m) noexcept
940      { return __m / last; }
941
942      friend constexpr year_month_day_last
943      operator/(int __y, const month_day_last& __mdl) noexcept;
944
945      friend constexpr year_month_day_last
946      operator/(const month_day_last& __mdl, int __y) noexcept;
947
948      // TODO: Implement operator<<.
949    };
950
951    // MONTH_WEEKDAY
952
953    class month_weekday
954    {
955    private:
956      chrono::month _M_m;
957      chrono::weekday_indexed _M_wdi;
958
959    public:
960      constexpr
961      month_weekday(const chrono::month& __m,
962		    const chrono::weekday_indexed& __wdi) noexcept
963      : _M_m{__m}, _M_wdi{__wdi}
964      { }
965
966      constexpr chrono::month
967      month() const noexcept
968      { return _M_m; }
969
970      constexpr chrono::weekday_indexed
971      weekday_indexed() const noexcept
972      { return _M_wdi; }
973
974      constexpr bool
975      ok() const noexcept
976      { return _M_m.ok() && _M_wdi.ok(); }
977
978      friend constexpr bool
979      operator==(const month_weekday& __x, const month_weekday& __y) noexcept
980      {
981	return __x.month() == __y.month()
982	  && __x.weekday_indexed() == __y.weekday_indexed();
983      }
984
985      friend constexpr month_weekday
986      operator/(const chrono::month& __m,
987		const chrono::weekday_indexed& __wdi) noexcept
988      { return {__m, __wdi}; }
989
990      friend constexpr month_weekday
991      operator/(int __m, const chrono::weekday_indexed& __wdi) noexcept
992      { return chrono::month(unsigned(__m)) / __wdi; }
993
994      friend constexpr month_weekday
995      operator/(const chrono::weekday_indexed& __wdi,
996		const chrono::month& __m) noexcept
997      { return __m / __wdi; }
998
999      friend constexpr month_weekday
1000      operator/(const chrono::weekday_indexed& __wdi, int __m) noexcept
1001      { return __m / __wdi; }
1002
1003      friend constexpr year_month_weekday
1004      operator/(int __y, const month_weekday& __mwd) noexcept;
1005
1006      friend constexpr year_month_weekday
1007      operator/(const month_weekday& __mwd, int __y) noexcept;
1008
1009      // TODO: Implement operator<<.
1010    };
1011
1012    // MONTH_WEEKDAY_LAST
1013
1014    class month_weekday_last
1015    {
1016    private:
1017      chrono::month _M_m;
1018      chrono::weekday_last _M_wdl;
1019
1020    public:
1021      constexpr
1022      month_weekday_last(const chrono::month& __m,
1023			 const chrono::weekday_last& __wdl) noexcept
1024      :_M_m{__m}, _M_wdl{__wdl}
1025      { }
1026
1027      constexpr chrono::month
1028      month() const noexcept
1029      { return _M_m; }
1030
1031      constexpr chrono::weekday_last
1032      weekday_last() const noexcept
1033      { return _M_wdl; }
1034
1035      constexpr bool
1036      ok() const noexcept
1037      { return _M_m.ok() && _M_wdl.ok(); }
1038
1039      friend constexpr bool
1040      operator==(const month_weekday_last& __x,
1041		 const month_weekday_last& __y) noexcept
1042      {
1043	return __x.month() == __y.month()
1044	  && __x.weekday_last() == __y.weekday_last();
1045      }
1046
1047      friend constexpr month_weekday_last
1048      operator/(const chrono::month& __m,
1049		const chrono::weekday_last& __wdl) noexcept
1050      { return {__m, __wdl}; }
1051
1052      friend constexpr month_weekday_last
1053      operator/(int __m, const chrono::weekday_last& __wdl) noexcept
1054      { return chrono::month(unsigned(__m)) / __wdl; }
1055
1056      friend constexpr month_weekday_last
1057      operator/(const chrono::weekday_last& __wdl,
1058		const chrono::month& __m) noexcept
1059      { return __m / __wdl; }
1060
1061      friend constexpr month_weekday_last
1062      operator/(const chrono::weekday_last& __wdl, int __m) noexcept
1063      { return chrono::month(unsigned(__m)) / __wdl; }
1064
1065      friend constexpr year_month_weekday_last
1066      operator/(int __y, const month_weekday_last& __mwdl) noexcept;
1067
1068      friend constexpr year_month_weekday_last
1069      operator/(const month_weekday_last& __mwdl, int __y) noexcept;
1070
1071      // TODO: Implement operator<<.
1072    };
1073
1074    // YEAR_MONTH
1075
1076    namespace __detail
1077    {
1078      // [time.cal.ym], [time.cal.ymd], etc constrain the 'months'-based
1079      // addition/subtraction operator overloads like so:
1080      //
1081      //   Constraints: if the argument supplied by the caller for the months
1082      //   parameter is convertible to years, its implicit conversion sequence
1083      //   to years is worse than its implicit conversion sequence to months.
1084      //
1085      // We realize this constraint by templatizing the 'months'-based
1086      // overloads (using a dummy defaulted template parameter), so that
1087      // overload resolution doesn't select the 'months'-based overload unless
1088      // the implicit conversion sequence to 'months' is better than that to
1089      // 'years'.
1090      using __months_years_conversion_disambiguator = void;
1091    }
1092
1093    class year_month
1094    {
1095    private:
1096      chrono::year _M_y;
1097      chrono::month _M_m;
1098
1099    public:
1100      year_month() = default;
1101
1102      constexpr
1103      year_month(const chrono::year& __y, const chrono::month& __m) noexcept
1104      : _M_y{__y}, _M_m{__m}
1105      { }
1106
1107      constexpr chrono::year
1108      year() const noexcept
1109      { return _M_y; }
1110
1111      constexpr chrono::month
1112      month() const noexcept
1113      { return _M_m; }
1114
1115      template<typename = __detail::__months_years_conversion_disambiguator>
1116	constexpr year_month&
1117	operator+=(const months& __dm) noexcept
1118	{
1119	  *this = *this + __dm;
1120	  return *this;
1121	}
1122
1123      template<typename = __detail::__months_years_conversion_disambiguator>
1124	constexpr year_month&
1125	operator-=(const months& __dm) noexcept
1126	{
1127	  *this = *this - __dm;
1128	  return *this;
1129	}
1130
1131      constexpr year_month&
1132      operator+=(const years& __dy)  noexcept
1133      {
1134	*this = *this + __dy;
1135	return *this;
1136      }
1137
1138      constexpr year_month&
1139      operator-=(const years& __dy)  noexcept
1140      {
1141	*this = *this - __dy;
1142	return *this;
1143      }
1144
1145      constexpr bool
1146      ok() const noexcept
1147      { return _M_y.ok() && _M_m.ok(); }
1148
1149      friend constexpr bool
1150      operator==(const year_month& __x, const year_month& __y) noexcept
1151      { return __x.year() == __y.year() && __x.month() == __y.month(); }
1152
1153      friend constexpr strong_ordering
1154      operator<=>(const year_month& __x, const year_month& __y) noexcept
1155	= default;
1156
1157      template<typename = __detail::__months_years_conversion_disambiguator>
1158	friend constexpr year_month
1159	operator+(const year_month& __ym, const months& __dm) noexcept
1160	{
1161	  // TODO: Optimize?
1162	  auto __m = __ym.month() + __dm;
1163	  auto __i = int(unsigned(__ym.month())) - 1 + __dm.count();
1164	  auto __y = (__i < 0
1165		      ? __ym.year() + years{(__i - 11) / 12}
1166		      : __ym.year() + years{__i / 12});
1167	  return __y / __m;
1168	}
1169
1170      template<typename = __detail::__months_years_conversion_disambiguator>
1171	friend constexpr year_month
1172	operator+(const months& __dm, const year_month& __ym) noexcept
1173	{ return __ym + __dm; }
1174
1175      template<typename = __detail::__months_years_conversion_disambiguator>
1176	friend constexpr year_month
1177	operator-(const year_month& __ym, const months& __dm) noexcept
1178	{ return __ym + -__dm; }
1179
1180      friend constexpr months
1181      operator-(const year_month& __x, const year_month& __y) noexcept
1182      {
1183	return (__x.year() - __y.year()
1184		+ months{static_cast<int>(unsigned{__x.month()})
1185			 - static_cast<int>(unsigned{__y.month()})});
1186      }
1187
1188      friend constexpr year_month
1189      operator+(const year_month& __ym, const years& __dy) noexcept
1190      { return (__ym.year() + __dy) / __ym.month(); }
1191
1192      friend constexpr year_month
1193      operator+(const years& __dy, const year_month& __ym) noexcept
1194      { return __ym + __dy; }
1195
1196      friend constexpr year_month
1197      operator-(const year_month& __ym, const years& __dy) noexcept
1198      { return __ym + -__dy; }
1199
1200      friend constexpr year_month
1201      operator/(const chrono::year& __y, const chrono::month& __m) noexcept
1202      { return {__y, __m}; }
1203
1204      friend constexpr year_month
1205      operator/(const chrono::year& __y, int __m) noexcept
1206      { return {__y, chrono::month(unsigned(__m))}; }
1207
1208      friend constexpr year_month_day
1209      operator/(const year_month& __ym, int __d) noexcept;
1210
1211      friend constexpr year_month_day_last
1212      operator/(const year_month& __ym, last_spec) noexcept;
1213
1214      // TODO: Implement operator<<, from_stream.
1215    };
1216
1217    // YEAR_MONTH_DAY
1218
1219    class year_month_day
1220    {
1221    private:
1222      chrono::year _M_y;
1223      chrono::month _M_m;
1224      chrono::day _M_d;
1225
1226      static constexpr year_month_day _S_from_days(const days& __dp) noexcept;
1227
1228      constexpr days _M_days_since_epoch() const noexcept;
1229
1230    public:
1231      year_month_day() = default;
1232
1233      constexpr
1234      year_month_day(const chrono::year& __y, const chrono::month& __m,
1235		     const chrono::day& __d) noexcept
1236      : _M_y{__y}, _M_m{__m}, _M_d{__d}
1237      { }
1238
1239      constexpr
1240      year_month_day(const year_month_day_last& __ymdl) noexcept;
1241
1242      constexpr
1243      year_month_day(const sys_days& __dp) noexcept
1244      : year_month_day(_S_from_days(__dp.time_since_epoch()))
1245      { }
1246
1247      explicit constexpr
1248      year_month_day(const local_days& __dp) noexcept
1249      : year_month_day(sys_days{__dp.time_since_epoch()})
1250      { }
1251
1252      template<typename = __detail::__months_years_conversion_disambiguator>
1253	constexpr year_month_day&
1254	operator+=(const months& __m) noexcept
1255	{
1256	  *this = *this + __m;
1257	  return *this;
1258	}
1259
1260      template<typename = __detail::__months_years_conversion_disambiguator>
1261	constexpr year_month_day&
1262	operator-=(const months& __m) noexcept
1263	{
1264	  *this = *this - __m;
1265	  return *this;
1266	}
1267
1268      constexpr year_month_day&
1269      operator+=(const years& __y) noexcept
1270      {
1271	*this = *this + __y;
1272	return *this;
1273      }
1274
1275      constexpr year_month_day&
1276      operator-=(const years& __y) noexcept
1277      {
1278	*this = *this - __y;
1279	return *this;
1280      }
1281
1282      constexpr chrono::year
1283      year() const noexcept
1284      { return _M_y; }
1285
1286      constexpr chrono::month
1287      month() const noexcept
1288      { return _M_m; }
1289
1290      constexpr chrono::day
1291      day() const noexcept
1292      { return _M_d; }
1293
1294      constexpr
1295      operator sys_days() const noexcept
1296      { return sys_days{_M_days_since_epoch()}; }
1297
1298      explicit constexpr
1299      operator local_days() const noexcept
1300      { return local_days{sys_days{*this}.time_since_epoch()}; }
1301
1302      constexpr bool ok() const noexcept;
1303
1304      friend constexpr bool
1305      operator==(const year_month_day& __x, const year_month_day& __y) noexcept
1306      {
1307	return __x.year() == __y.year()
1308	  && __x.month() == __y.month()
1309	  && __x.day() == __y.day();
1310      }
1311
1312      friend constexpr strong_ordering
1313      operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept
1314	= default;
1315
1316      template<typename = __detail::__months_years_conversion_disambiguator>
1317	friend constexpr year_month_day
1318	operator+(const year_month_day& __ymd, const months& __dm) noexcept
1319	{ return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); }
1320
1321      template<typename = __detail::__months_years_conversion_disambiguator>
1322	friend constexpr year_month_day
1323	operator+(const months& __dm, const year_month_day& __ymd) noexcept
1324	{ return __ymd + __dm; }
1325
1326      friend constexpr year_month_day
1327      operator+(const year_month_day& __ymd, const years& __dy) noexcept
1328      { return (__ymd.year() + __dy) / __ymd.month() / __ymd.day(); }
1329
1330      friend constexpr year_month_day
1331      operator+(const years& __dy, const year_month_day& __ymd) noexcept
1332      { return __ymd + __dy; }
1333
1334      template<typename = __detail::__months_years_conversion_disambiguator>
1335	friend constexpr year_month_day
1336	operator-(const year_month_day& __ymd, const months& __dm) noexcept
1337	{ return __ymd + -__dm; }
1338
1339      friend constexpr year_month_day
1340      operator-(const year_month_day& __ymd, const years& __dy) noexcept
1341      { return __ymd + -__dy; }
1342
1343      friend constexpr year_month_day
1344      operator/(const year_month& __ym, const chrono::day& __d) noexcept
1345      { return {__ym.year(), __ym.month(), __d}; }
1346
1347      friend constexpr year_month_day
1348      operator/(const year_month& __ym, int __d) noexcept
1349      { return __ym / chrono::day{unsigned(__d)}; }
1350
1351      friend constexpr year_month_day
1352      operator/(const chrono::year& __y, const month_day& __md) noexcept
1353      { return __y / __md.month() / __md.day(); }
1354
1355      friend constexpr year_month_day
1356      operator/(int __y, const month_day& __md) noexcept
1357      { return chrono::year{__y} / __md; }
1358
1359      friend constexpr year_month_day
1360      operator/(const month_day& __md, const chrono::year& __y) noexcept
1361      { return __y / __md; }
1362
1363      friend constexpr year_month_day
1364      operator/(const month_day& __md, int __y) noexcept
1365      { return chrono::year(__y) / __md; }
1366
1367      // TODO: Implement operator<<, from_stream.
1368    };
1369
1370    // Construct from days since 1970/01/01.
1371    // Proposition 6.3 of Neri and Schneider,
1372    // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1373    // https://arxiv.org/abs/2102.06959
1374    constexpr year_month_day
1375    year_month_day::_S_from_days(const days& __dp) noexcept
1376    {
1377      constexpr auto __z2    = static_cast<uint32_t>(-1468000);
1378      constexpr auto __r2_e3 = static_cast<uint32_t>(536895458);
1379
1380      const auto __r0 = static_cast<uint32_t>(__dp.count()) + __r2_e3;
1381
1382      const auto __n1 = 4 * __r0 + 3;
1383      const auto __q1 = __n1 / 146097;
1384      const auto __r1 = __n1 % 146097 / 4;
1385
1386      constexpr auto __p32 = static_cast<uint64_t>(1) << 32;
1387      const auto __n2 = 4 * __r1 + 3;
1388      const auto __u2 = static_cast<uint64_t>(2939745) * __n2;
1389      const auto __q2 = static_cast<uint32_t>(__u2 / __p32);
1390      const auto __r2 = static_cast<uint32_t>(__u2 % __p32) / 2939745 / 4;
1391
1392      constexpr auto __p16 = static_cast<uint32_t>(1) << 16;
1393      const auto __n3 = 2141 * __r2 + 197913;
1394      const auto __q3 = __n3 / __p16;
1395      const auto __r3 = __n3 % __p16 / 2141;
1396
1397      const auto __y0 = 100 * __q1 + __q2;
1398      const auto __m0 = __q3;
1399      const auto __d0 = __r3;
1400
1401      const auto __j  = __r2 >= 306;
1402      const auto __y1 = __y0 + __j;
1403      const auto __m1 = __j ? __m0 - 12 : __m0;
1404      const auto __d1 = __d0 + 1;
1405
1406      return year_month_day{chrono::year{static_cast<int>(__y1 + __z2)},
1407			    chrono::month{__m1}, chrono::day{__d1}};
1408    }
1409
1410    // Days since 1970/01/01.
1411    // Proposition 6.2 of Neri and Schneider,
1412    // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1413    // https://arxiv.org/abs/2102.06959
1414    constexpr days
1415    year_month_day::_M_days_since_epoch() const noexcept
1416    {
1417      auto constexpr __z2    = static_cast<uint32_t>(-1468000);
1418      auto constexpr __r2_e3 = static_cast<uint32_t>(536895458);
1419
1420      const auto __y1 = static_cast<uint32_t>(static_cast<int>(_M_y)) - __z2;
1421      const auto __m1 = static_cast<uint32_t>(static_cast<unsigned>(_M_m));
1422      const auto __d1 = static_cast<uint32_t>(static_cast<unsigned>(_M_d));
1423
1424      const auto __j  = static_cast<uint32_t>(__m1 < 3);
1425      const auto __y0 = __y1 - __j;
1426      const auto __m0 = __j ? __m1 + 12 : __m1;
1427      const auto __d0 = __d1 - 1;
1428
1429      const auto __q1 = __y0 / 100;
1430      const auto __yc = 1461 * __y0 / 4 - __q1 + __q1 / 4;
1431      const auto __mc = (979 *__m0 - 2919) / 32;
1432      const auto __dc = __d0;
1433
1434      return days{static_cast<int32_t>(__yc + __mc + __dc - __r2_e3)};
1435    }
1436
1437    // YEAR_MONTH_DAY_LAST
1438
1439    class year_month_day_last
1440    {
1441    private:
1442      chrono::year _M_y;
1443      chrono::month_day_last _M_mdl;
1444
1445    public:
1446      constexpr
1447      year_month_day_last(const chrono::year& __y,
1448			  const chrono::month_day_last& __mdl) noexcept
1449      : _M_y{__y}, _M_mdl{__mdl}
1450      { }
1451
1452      template<typename = __detail::__months_years_conversion_disambiguator>
1453	constexpr year_month_day_last&
1454	operator+=(const months& __m) noexcept
1455	{
1456	  *this = *this + __m;
1457	  return *this;
1458	}
1459
1460      template<typename = __detail::__months_years_conversion_disambiguator>
1461	constexpr year_month_day_last&
1462	operator-=(const months& __m) noexcept
1463	{
1464	  *this = *this - __m;
1465	  return *this;
1466	}
1467
1468      constexpr year_month_day_last&
1469      operator+=(const years& __y)  noexcept
1470      {
1471	*this = *this + __y;
1472	return *this;
1473      }
1474
1475      constexpr year_month_day_last&
1476      operator-=(const years& __y)  noexcept
1477      {
1478	*this = *this - __y;
1479	return *this;
1480      }
1481
1482      constexpr chrono::year
1483      year() const noexcept
1484      { return _M_y; }
1485
1486      constexpr chrono::month
1487      month() const noexcept
1488      { return _M_mdl.month(); }
1489
1490      constexpr chrono::month_day_last
1491      month_day_last() const noexcept
1492      { return _M_mdl; }
1493
1494      // Return A day representing the last day of this year, month pair.
1495      constexpr chrono::day
1496      day() const noexcept
1497      {
1498	const auto __m = static_cast<unsigned>(month());
1499
1500	// The result is unspecified if __m < 1 or __m > 12.  Hence, assume
1501	// 1 <= __m <= 12.  For __m != 2, day() == 30 or day() == 31 or, in
1502	// other words, day () == 30 | b, where b is in {0, 1}.
1503
1504	// If __m in {1, 3, 4, 5, 6, 7}, then b is 1 if, and only if, __m is
1505	// odd.  Hence, b = __m & 1 = (__m ^ 0) & 1.
1506
1507	// If __m in {8, 9, 10, 11, 12}, then b is 1 if, and only if, __m is
1508	// even.  Hence, b = (__m ^ 1) & 1.
1509
1510	// Therefore, b = (__m ^ c) & 1, where c = 0, if __m < 8, or c = 1 if
1511	// __m >= 8, that is, c = __m >> 3.
1512
1513	// Since 30 = (11110)_2 and __m <= 31 = (11111)_2, the "& 1" in b's
1514	// calculation is unnecessary.
1515
1516	// The performance of this implementation does not depend on look-up
1517	// tables being on the L1 cache.
1518	return chrono::day{__m != 2 ? (__m ^ (__m >> 3)) | 30
1519	  : _M_y.is_leap() ? 29 : 28};
1520      }
1521
1522      constexpr
1523      operator sys_days() const noexcept
1524      { return sys_days{year() / month() / day()}; }
1525
1526      explicit constexpr
1527      operator local_days() const noexcept
1528      { return local_days{sys_days{*this}.time_since_epoch()}; }
1529
1530      constexpr bool
1531      ok() const noexcept
1532      { return _M_y.ok() && _M_mdl.ok(); }
1533
1534      friend constexpr bool
1535      operator==(const year_month_day_last& __x,
1536		 const year_month_day_last& __y) noexcept
1537      {
1538	return __x.year() == __y.year()
1539	  && __x.month_day_last() == __y.month_day_last();
1540      }
1541
1542      friend constexpr strong_ordering
1543      operator<=>(const year_month_day_last& __x,
1544		  const year_month_day_last& __y) noexcept
1545	= default;
1546
1547      template<typename = __detail::__months_years_conversion_disambiguator>
1548	friend constexpr year_month_day_last
1549	operator+(const year_month_day_last& __ymdl,
1550		  const months& __dm) noexcept
1551	{ return (__ymdl.year() / __ymdl.month() + __dm) / last; }
1552
1553      template<typename = __detail::__months_years_conversion_disambiguator>
1554	friend constexpr year_month_day_last
1555	operator+(const months& __dm,
1556		  const year_month_day_last& __ymdl) noexcept
1557	{ return __ymdl + __dm; }
1558
1559      template<typename = __detail::__months_years_conversion_disambiguator>
1560	friend constexpr year_month_day_last
1561	operator-(const year_month_day_last& __ymdl,
1562		  const months& __dm) noexcept
1563	{ return __ymdl + -__dm; }
1564
1565      friend constexpr year_month_day_last
1566      operator+(const year_month_day_last& __ymdl,
1567		const years& __dy) noexcept
1568      { return {__ymdl.year() + __dy, __ymdl.month_day_last()}; }
1569
1570      friend constexpr year_month_day_last
1571      operator+(const years& __dy,
1572		const year_month_day_last& __ymdl) noexcept
1573      { return __ymdl + __dy; }
1574
1575      friend constexpr year_month_day_last
1576      operator-(const year_month_day_last& __ymdl,
1577		const years& __dy) noexcept
1578      { return __ymdl + -__dy; }
1579
1580      friend constexpr year_month_day_last
1581      operator/(const year_month& __ym, last_spec) noexcept
1582      { return {__ym.year(), chrono::month_day_last{__ym.month()}}; }
1583
1584      friend constexpr year_month_day_last
1585      operator/(const chrono::year& __y,
1586		const chrono::month_day_last& __mdl) noexcept
1587      { return {__y, __mdl}; }
1588
1589      friend constexpr year_month_day_last
1590      operator/(int __y, const chrono::month_day_last& __mdl) noexcept
1591      { return chrono::year(__y) / __mdl; }
1592
1593      friend constexpr year_month_day_last
1594      operator/(const chrono::month_day_last& __mdl,
1595		const chrono::year& __y) noexcept
1596      { return __y / __mdl; }
1597
1598      friend constexpr year_month_day_last
1599      operator/(const chrono::month_day_last& __mdl, int __y) noexcept
1600      { return chrono::year(__y) / __mdl; }
1601
1602      // TODO: Implement operator<<.
1603    };
1604
1605    // year_month_day ctor from year_month_day_last
1606    constexpr
1607    year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
1608    : _M_y{__ymdl.year()}, _M_m{__ymdl.month()}, _M_d{__ymdl.day()}
1609    { }
1610
1611    constexpr bool
1612    year_month_day::ok() const noexcept
1613    {
1614      if (!_M_y.ok() || !_M_m.ok())
1615	return false;
1616      return chrono::day{1} <= _M_d && _M_d <= (_M_y / _M_m / last).day();
1617    }
1618
1619    // YEAR_MONTH_WEEKDAY
1620
1621    class year_month_weekday
1622    {
1623    private:
1624      chrono::year _M_y;
1625      chrono::month _M_m;
1626      chrono::weekday_indexed _M_wdi;
1627
1628      static constexpr year_month_weekday
1629      _S_from_sys_days(const sys_days& __dp)
1630      {
1631	year_month_day __ymd{__dp};
1632	chrono::weekday __wd{__dp};
1633	auto __index = __wd[(unsigned{__ymd.day()} - 1) / 7 + 1];
1634	return {__ymd.year(), __ymd.month(), __index};
1635      }
1636
1637    public:
1638      year_month_weekday() = default;
1639
1640      constexpr
1641      year_month_weekday(const chrono::year& __y, const chrono::month& __m,
1642			 const chrono::weekday_indexed& __wdi) noexcept
1643      : _M_y{__y}, _M_m{__m}, _M_wdi{__wdi}
1644      { }
1645
1646      constexpr
1647      year_month_weekday(const sys_days& __dp) noexcept
1648      : year_month_weekday{_S_from_sys_days(__dp)}
1649      { }
1650
1651      explicit constexpr
1652      year_month_weekday(const local_days& __dp) noexcept
1653      : year_month_weekday{sys_days{__dp.time_since_epoch()}}
1654      { }
1655
1656      template<typename = __detail::__months_years_conversion_disambiguator>
1657	constexpr year_month_weekday&
1658	operator+=(const months& __m) noexcept
1659	{
1660	  *this = *this + __m;
1661	  return *this;
1662	}
1663
1664      template<typename = __detail::__months_years_conversion_disambiguator>
1665	constexpr year_month_weekday&
1666	operator-=(const months& __m) noexcept
1667	{
1668	  *this = *this - __m;
1669	  return *this;
1670	}
1671
1672      constexpr year_month_weekday&
1673      operator+=(const years& __y) noexcept
1674      {
1675	*this = *this + __y;
1676	return *this;
1677      }
1678
1679      constexpr year_month_weekday&
1680      operator-=(const years& __y) noexcept
1681      {
1682	*this = *this - __y;
1683	return *this;
1684      }
1685
1686      constexpr chrono::year
1687      year() const noexcept
1688      { return _M_y; }
1689
1690      constexpr chrono::month
1691      month() const noexcept
1692      { return _M_m; }
1693
1694      constexpr chrono::weekday
1695      weekday() const noexcept
1696      { return _M_wdi.weekday(); }
1697
1698      constexpr unsigned
1699      index() const noexcept
1700      { return _M_wdi.index(); }
1701
1702      constexpr chrono::weekday_indexed
1703      weekday_indexed() const noexcept
1704      { return _M_wdi; }
1705
1706      constexpr
1707      operator sys_days() const noexcept
1708      {
1709	auto __d = sys_days{year() / month() / 1};
1710	return __d + (weekday() - chrono::weekday(__d)
1711		      + days{(static_cast<int>(index())-1)*7});
1712      }
1713
1714      explicit constexpr
1715      operator local_days() const noexcept
1716      { return local_days{sys_days{*this}.time_since_epoch()}; }
1717
1718      constexpr bool
1719      ok() const noexcept
1720      {
1721	if (!_M_y.ok() || !_M_m.ok() || !_M_wdi.ok())
1722	  return false;
1723	if (_M_wdi.index() <= 4)
1724	  return true;
1725	days __d = (_M_wdi.weekday()
1726		    - chrono::weekday{sys_days{_M_y / _M_m / 1}}
1727		    + days((_M_wdi.index()-1)*7 + 1));
1728	__glibcxx_assert(__d.count() >= 1);
1729	return __d.count() <= unsigned{(_M_y / _M_m / last).day()};
1730      }
1731
1732      friend constexpr bool
1733      operator==(const year_month_weekday& __x,
1734		 const year_month_weekday& __y) noexcept
1735      {
1736	return __x.year() == __y.year()
1737	  && __x.month() == __y.month()
1738	  && __x.weekday_indexed() == __y.weekday_indexed();
1739      }
1740
1741      template<typename = __detail::__months_years_conversion_disambiguator>
1742	friend constexpr year_month_weekday
1743	operator+(const year_month_weekday& __ymwd, const months& __dm) noexcept
1744	{
1745	  return ((__ymwd.year() / __ymwd.month() + __dm)
1746		  / __ymwd.weekday_indexed());
1747	}
1748
1749      template<typename = __detail::__months_years_conversion_disambiguator>
1750	friend constexpr year_month_weekday
1751	operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept
1752	{ return __ymwd + __dm; }
1753
1754      friend constexpr year_month_weekday
1755      operator+(const year_month_weekday& __ymwd, const years& __dy) noexcept
1756      { return {__ymwd.year() + __dy, __ymwd.month(), __ymwd.weekday_indexed()}; }
1757
1758      friend constexpr year_month_weekday
1759      operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept
1760      { return __ymwd + __dy; }
1761
1762      template<typename = __detail::__months_years_conversion_disambiguator>
1763	friend constexpr year_month_weekday
1764	operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept
1765	{ return __ymwd + -__dm; }
1766
1767      friend constexpr year_month_weekday
1768      operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept
1769      { return __ymwd + -__dy; }
1770
1771      friend constexpr year_month_weekday
1772      operator/(const year_month& __ym,
1773		const chrono::weekday_indexed& __wdi) noexcept
1774      { return {__ym.year(), __ym.month(), __wdi}; }
1775
1776      friend constexpr year_month_weekday
1777      operator/(const chrono::year& __y, const month_weekday& __mwd) noexcept
1778      { return {__y, __mwd.month(), __mwd.weekday_indexed()}; }
1779
1780      friend constexpr year_month_weekday
1781      operator/(int __y, const month_weekday& __mwd) noexcept
1782      { return chrono::year(__y) / __mwd; }
1783
1784      friend constexpr year_month_weekday
1785      operator/(const month_weekday& __mwd, const chrono::year& __y) noexcept
1786      { return __y / __mwd; }
1787
1788      friend constexpr year_month_weekday
1789      operator/(const month_weekday& __mwd, int __y) noexcept
1790      { return chrono::year(__y) / __mwd; }
1791
1792      // TODO: Implement operator<<.
1793    };
1794
1795    // YEAR_MONTH_WEEKDAY_LAST
1796
1797    class year_month_weekday_last
1798    {
1799    private:
1800      chrono::year _M_y;
1801      chrono::month _M_m;
1802      chrono::weekday_last _M_wdl;
1803
1804    public:
1805      constexpr
1806      year_month_weekday_last(const chrono::year& __y, const chrono::month& __m,
1807			      const chrono::weekday_last& __wdl) noexcept
1808      : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl}
1809      { }
1810
1811      template<typename = __detail::__months_years_conversion_disambiguator>
1812	constexpr year_month_weekday_last&
1813	operator+=(const months& __m) noexcept
1814	{
1815	  *this = *this + __m;
1816	  return *this;
1817	}
1818
1819      template<typename = __detail::__months_years_conversion_disambiguator>
1820	constexpr year_month_weekday_last&
1821	operator-=(const months& __m) noexcept
1822	{
1823	  *this = *this - __m;
1824	  return *this;
1825	}
1826
1827      constexpr year_month_weekday_last&
1828      operator+=(const years& __y)  noexcept
1829      {
1830	*this = *this + __y;
1831	return *this;
1832      }
1833
1834      constexpr year_month_weekday_last&
1835      operator-=(const years& __y)  noexcept
1836      {
1837	*this = *this - __y;
1838	return *this;
1839      }
1840
1841      constexpr chrono::year
1842      year() const noexcept
1843      { return _M_y; }
1844
1845      constexpr chrono::month
1846      month() const noexcept
1847      { return _M_m; }
1848
1849      constexpr chrono::weekday
1850      weekday() const noexcept
1851      { return _M_wdl.weekday(); }
1852
1853      constexpr chrono::weekday_last
1854      weekday_last() const noexcept
1855      { return _M_wdl; }
1856
1857      constexpr
1858      operator sys_days() const noexcept
1859      {
1860	const auto __d = sys_days{_M_y / _M_m / last};
1861	return sys_days{(__d - (chrono::weekday{__d}
1862				- _M_wdl.weekday())).time_since_epoch()};
1863      }
1864
1865      explicit constexpr
1866      operator local_days() const noexcept
1867      { return local_days{sys_days{*this}.time_since_epoch()}; }
1868
1869      constexpr bool
1870      ok() const noexcept
1871      { return _M_y.ok() && _M_m.ok() && _M_wdl.ok(); }
1872
1873      friend constexpr bool
1874      operator==(const year_month_weekday_last& __x,
1875		 const year_month_weekday_last& __y) noexcept
1876      {
1877	return __x.year() == __y.year()
1878	  && __x.month() == __y.month()
1879	  && __x.weekday_last() == __y.weekday_last();
1880      }
1881
1882      template<typename = __detail::__months_years_conversion_disambiguator>
1883	friend constexpr year_month_weekday_last
1884	operator+(const year_month_weekday_last& __ymwdl,
1885		  const months& __dm) noexcept
1886	{
1887	  return ((__ymwdl.year() / __ymwdl.month() + __dm)
1888		  / __ymwdl.weekday_last());
1889	}
1890
1891      template<typename = __detail::__months_years_conversion_disambiguator>
1892	friend constexpr year_month_weekday_last
1893	operator+(const months& __dm,
1894		  const year_month_weekday_last& __ymwdl) noexcept
1895	{ return __ymwdl + __dm; }
1896
1897      friend constexpr year_month_weekday_last
1898      operator+(const year_month_weekday_last& __ymwdl,
1899		const years& __dy) noexcept
1900      { return {__ymwdl.year() + __dy, __ymwdl.month(), __ymwdl.weekday_last()}; }
1901
1902      friend constexpr year_month_weekday_last
1903      operator+(const years& __dy,
1904		const year_month_weekday_last& __ymwdl) noexcept
1905      { return __ymwdl + __dy; }
1906
1907      template<typename = __detail::__months_years_conversion_disambiguator>
1908	friend constexpr year_month_weekday_last
1909	operator-(const year_month_weekday_last& __ymwdl,
1910		  const months& __dm) noexcept
1911	{ return __ymwdl + -__dm; }
1912
1913      friend constexpr year_month_weekday_last
1914      operator-(const year_month_weekday_last& __ymwdl,
1915		const years& __dy) noexcept
1916      { return __ymwdl + -__dy; }
1917
1918      friend constexpr year_month_weekday_last
1919      operator/(const year_month& __ym,
1920		const chrono::weekday_last& __wdl) noexcept
1921      { return {__ym.year(), __ym.month(), __wdl}; }
1922
1923      friend constexpr year_month_weekday_last
1924      operator/(const chrono::year& __y,
1925		const chrono::month_weekday_last& __mwdl) noexcept
1926      { return {__y, __mwdl.month(), __mwdl.weekday_last()}; }
1927
1928      friend constexpr year_month_weekday_last
1929      operator/(int __y, const chrono::month_weekday_last& __mwdl) noexcept
1930      { return chrono::year(__y) / __mwdl; }
1931
1932      friend constexpr year_month_weekday_last
1933      operator/(const chrono::month_weekday_last& __mwdl,
1934		const chrono::year& __y) noexcept
1935      { return __y / __mwdl; }
1936
1937      friend constexpr year_month_weekday_last
1938      operator/(const chrono::month_weekday_last& __mwdl, int __y) noexcept
1939      { return chrono::year(__y) / __mwdl; }
1940
1941      // TODO: Implement operator<<.
1942    };
1943
1944    // HH_MM_SS
1945
1946    namespace __detail
1947    {
1948      consteval long long
1949      __pow10(unsigned __n)
1950      {
1951	long long __r = 1;
1952	while (__n-- > 0)
1953	  __r *= 10;
1954	return __r;
1955      }
1956    }
1957
1958    template<typename _Duration>
1959      class hh_mm_ss
1960      {
1961      private:
1962	static constexpr int
1963	_S_fractional_width()
1964	{
1965	  int __multiplicity_2 = 0;
1966	  int __multiplicity_5 = 0;
1967	  auto __den = _Duration::period::den;
1968	  while ((__den % 2) == 0)
1969	    {
1970	      ++__multiplicity_2;
1971	      __den /= 2;
1972	    }
1973	  while ((__den % 5) == 0)
1974	    {
1975	      ++__multiplicity_5;
1976	      __den /= 5;
1977	    }
1978	  if (__den != 1)
1979	    return 6;
1980
1981	  int __width = (__multiplicity_2 > __multiplicity_5
1982			 ? __multiplicity_2 : __multiplicity_5);
1983	  if (__width > 18)
1984	    __width = 18;
1985	  return __width;
1986	}
1987
1988	constexpr
1989	hh_mm_ss(_Duration __d, bool __is_neg)
1990	: _M_is_neg(__is_neg),
1991	  _M_h (duration_cast<chrono::hours>(__d)),
1992	  _M_m (duration_cast<chrono::minutes>(__d - hours())),
1993	  _M_s (duration_cast<chrono::seconds>(__d - hours() - minutes()))
1994	{
1995	  auto __ss = __d - hours() - minutes() - seconds();
1996	  if constexpr (treat_as_floating_point_v<typename precision::rep>)
1997	    _M_ss = __ss;
1998	  else
1999	    _M_ss = duration_cast<precision>(__ss);
2000	}
2001
2002	static constexpr _Duration
2003	_S_abs(_Duration __d)
2004	{
2005	  if constexpr (numeric_limits<typename _Duration::rep>::is_signed)
2006	    return chrono::abs(__d);
2007	  else
2008	    return __d;
2009	}
2010
2011      public:
2012	static constexpr unsigned fractional_width = {_S_fractional_width()};
2013
2014	using precision
2015	  = duration<common_type_t<typename _Duration::rep,
2016				   chrono::seconds::rep>,
2017		     ratio<1, __detail::__pow10(fractional_width)>>;
2018
2019	constexpr
2020	hh_mm_ss() noexcept
2021	: hh_mm_ss{_Duration::zero()}
2022	{ }
2023
2024	constexpr explicit
2025	hh_mm_ss(_Duration __d)
2026	: hh_mm_ss(_S_abs(__d), __d < _Duration::zero())
2027	{ }
2028
2029	constexpr bool
2030	is_negative() const noexcept
2031	{ return _M_is_neg; }
2032
2033	constexpr chrono::hours
2034	hours() const noexcept
2035	{ return _M_h; }
2036
2037	constexpr chrono::minutes
2038	minutes() const noexcept
2039	{ return _M_m; }
2040
2041	constexpr chrono::seconds
2042	seconds() const noexcept
2043	{ return _M_s; }
2044
2045	constexpr precision
2046	subseconds() const noexcept
2047	{ return _M_ss; }
2048
2049	constexpr explicit
2050	operator precision() const noexcept
2051	{ return to_duration(); }
2052
2053	constexpr precision
2054	to_duration() const noexcept
2055	{
2056	  if (_M_is_neg)
2057	    return -(_M_h + _M_m + _M_s + _M_ss);
2058	  else
2059	    return _M_h + _M_m + _M_s + _M_ss;
2060	}
2061
2062	// TODO: Implement operator<<.
2063
2064      private:
2065	bool _M_is_neg;
2066	chrono::hours _M_h;
2067	chrono::minutes _M_m;
2068	chrono::seconds _M_s;
2069	precision _M_ss;
2070      };
2071
2072    // 12/24 HOURS FUNCTIONS
2073
2074    constexpr bool
2075    is_am(const hours& __h) noexcept
2076    { return 0h <= __h && __h <= 11h; }
2077
2078    constexpr bool
2079    is_pm(const hours& __h) noexcept
2080    { return 12h <= __h && __h <= 23h; }
2081
2082    constexpr hours
2083    make12(const hours& __h) noexcept
2084    {
2085      if (__h == 0h)
2086	return 12h;
2087      else if (__h > 12h)
2088	return __h - 12h;
2089      return __h;
2090    }
2091
2092    constexpr hours
2093    make24(const hours& __h, bool __is_pm) noexcept
2094    {
2095      if (!__is_pm)
2096	{
2097	  if (__h == 12h)
2098	    return 0h;
2099	  else
2100	    return __h;
2101	}
2102      else
2103	{
2104	  if (__h == 12h)
2105	    return __h;
2106	  else
2107	    return __h + 12h;
2108	}
2109    }
2110    /// @} group chrono
2111#endif // C++20
2112  } // namespace chrono
2113
2114#if __cplusplus >= 202002L
2115  inline namespace literals
2116  {
2117  inline namespace chrono_literals
2118  {
2119    /// @addtogroup chrono
2120    /// @{
2121#pragma GCC diagnostic push
2122#pragma GCC diagnostic ignored "-Wliteral-suffix"
2123    /// Literal suffix for creating chrono::day objects.
2124    /// @since C++20
2125    constexpr chrono::day
2126    operator""d(unsigned long long __d) noexcept
2127    { return chrono::day{static_cast<unsigned>(__d)}; }
2128
2129    /// Literal suffix for creating chrono::year objects.
2130    /// @since C++20
2131    constexpr chrono::year
2132    operator""y(unsigned long long __y) noexcept
2133    { return chrono::year{static_cast<int>(__y)}; }
2134#pragma GCC diagnostic pop
2135    /// @}
2136  } // inline namespace chrono_literals
2137  } // inline namespace literals
2138
2139  namespace chrono
2140  {
2141    /// @addtogroup chrono
2142    /// @{
2143
2144    /// @cond undocumented
2145    namespace __detail
2146    {
2147      template<typename _Period>
2148	const char*
2149	__units_suffix_misc(char* __buf, size_t __n) noexcept
2150	{
2151	  namespace __tc = std::__detail;
2152	  char* __p = __buf;
2153	  __p[0] = '[';
2154	  unsigned __nlen = __tc::__to_chars_len((uintmax_t)_Period::num);
2155	  __tc::__to_chars_10_impl(__p + 1, __nlen, (uintmax_t)_Period::num);
2156	  __p += 1 + __nlen;
2157	  if constexpr (_Period::den != 1)
2158	    {
2159	      __p[0] = '/';
2160	      unsigned __dlen = __tc::__to_chars_len((uintmax_t)_Period::den);
2161	      __tc::__to_chars_10_impl(__p + 1, __dlen, (uintmax_t)_Period::den);
2162	      __p += 1 + __dlen;
2163	    }
2164	  __p[0] = ']';
2165	  __p[1] = 's';
2166	  __p[2] = '\0';
2167	  return __buf;
2168	}
2169
2170      template<typename _Period, typename _CharT>
2171	auto
2172	__units_suffix(char* __buf, size_t __n) noexcept
2173	{
2174#define _GLIBCXX_UNITS_SUFFIX(period, suffix) \
2175	if constexpr (is_same_v<_Period, period>)	\
2176	  {						\
2177	    if constexpr (is_same_v<_CharT, wchar_t>)	\
2178	      return L##suffix;				\
2179	    else					\
2180	      return suffix;				\
2181	  }						\
2182	else
2183
2184	  _GLIBCXX_UNITS_SUFFIX(atto, "as")
2185	  _GLIBCXX_UNITS_SUFFIX(femto, "fs")
2186	  _GLIBCXX_UNITS_SUFFIX(pico, "ps")
2187	  _GLIBCXX_UNITS_SUFFIX(nano, "ns")
2188	  _GLIBCXX_UNITS_SUFFIX(micro, "\u00b5s")
2189	  _GLIBCXX_UNITS_SUFFIX(milli, "ms")
2190	  _GLIBCXX_UNITS_SUFFIX(centi, "cs")
2191	  _GLIBCXX_UNITS_SUFFIX(deci, "ds")
2192	  _GLIBCXX_UNITS_SUFFIX(ratio<1>, "s")
2193	  _GLIBCXX_UNITS_SUFFIX(deca, "das")
2194	  _GLIBCXX_UNITS_SUFFIX(hecto, "hs")
2195	  _GLIBCXX_UNITS_SUFFIX(kilo, "ks")
2196	  _GLIBCXX_UNITS_SUFFIX(mega, "Ms")
2197	  _GLIBCXX_UNITS_SUFFIX(giga, "Gs")
2198	  _GLIBCXX_UNITS_SUFFIX(tera, "Ts")
2199	  _GLIBCXX_UNITS_SUFFIX(tera, "Ts")
2200	  _GLIBCXX_UNITS_SUFFIX(peta, "Ps")
2201	  _GLIBCXX_UNITS_SUFFIX(exa, "Es")
2202	  _GLIBCXX_UNITS_SUFFIX(ratio<60>, "min")
2203	  _GLIBCXX_UNITS_SUFFIX(ratio<3600>, "h")
2204	  _GLIBCXX_UNITS_SUFFIX(ratio<86400>, "d")
2205#undef _GLIBCXX_UNITS_SUFFIX
2206	  return __detail::__units_suffix_misc<_Period>(__buf, __n);
2207	}
2208    } // namespace __detail
2209    /// @endcond
2210
2211    template<typename _CharT, typename _Traits,
2212	     typename _Rep, typename _Period>
2213      inline basic_ostream<_CharT, _Traits>&
2214      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2215		const duration<_Rep, _Period>& __d)
2216      {
2217	using period = typename _Period::type;
2218	char __buf[sizeof("[/]s") + 2 * numeric_limits<intmax_t>::digits10];
2219	std::basic_ostringstream<_CharT, _Traits> __s;
2220	__s.flags(__os.flags());
2221	__s.imbue(__os.getloc());
2222	__s.precision(__os.precision());
2223	__s << __d.count();
2224	__s << __detail::__units_suffix<period, _CharT>(__buf, sizeof(__buf));
2225	__os << std::move(__s).str();
2226	return __os;
2227      }
2228
2229    // TODO: from_stream for duration
2230
2231    /// @} group chrono
2232  } // namespace chrono
2233#endif // C++20
2234
2235_GLIBCXX_END_NAMESPACE_VERSION
2236} // namespace std
2237
2238#endif // C++11
2239
2240#endif //_GLIBCXX_CHRONO
2241