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