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