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