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