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