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