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