1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___CHRONO_CALENDAR_H 11 #define _LIBCPP___CHRONO_CALENDAR_H 12 13 #include <__chrono/duration.h> 14 #include <__chrono/system_clock.h> 15 #include <__chrono/time_point.h> 16 #include <__config> 17 #include <limits> 18 #include <ratio> 19 #include <type_traits> 20 21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 22 #pragma GCC system_header 23 #endif 24 25 _LIBCPP_PUSH_MACROS 26 #include <__undef_macros> 27 28 #if _LIBCPP_STD_VER > 17 29 30 _LIBCPP_BEGIN_NAMESPACE_STD 31 32 namespace chrono 33 { 34 35 struct local_t {}; 36 template<class Duration> 37 using local_time = time_point<local_t, Duration>; 38 using local_seconds = local_time<seconds>; 39 using local_days = local_time<days>; 40 41 struct last_spec { explicit last_spec() = default; }; 42 43 class day { 44 private: 45 unsigned char __d; 46 public: 47 day() = default; 48 explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {} 49 inline constexpr day& operator++() noexcept { ++__d; return *this; } 50 inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } 51 inline constexpr day& operator--() noexcept { --__d; return *this; } 52 inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; } 53 constexpr day& operator+=(const days& __dd) noexcept; 54 constexpr day& operator-=(const days& __dd) noexcept; 55 explicit inline constexpr operator unsigned() const noexcept { return __d; } 56 inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; } 57 }; 58 59 60 inline constexpr 61 bool operator==(const day& __lhs, const day& __rhs) noexcept 62 { return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } 63 64 inline constexpr 65 bool operator!=(const day& __lhs, const day& __rhs) noexcept 66 { return !(__lhs == __rhs); } 67 68 inline constexpr 69 bool operator< (const day& __lhs, const day& __rhs) noexcept 70 { return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } 71 72 inline constexpr 73 bool operator> (const day& __lhs, const day& __rhs) noexcept 74 { return __rhs < __lhs; } 75 76 inline constexpr 77 bool operator<=(const day& __lhs, const day& __rhs) noexcept 78 { return !(__rhs < __lhs);} 79 80 inline constexpr 81 bool operator>=(const day& __lhs, const day& __rhs) noexcept 82 { return !(__lhs < __rhs); } 83 84 inline constexpr 85 day operator+ (const day& __lhs, const days& __rhs) noexcept 86 { return day(static_cast<unsigned>(__lhs) + __rhs.count()); } 87 88 inline constexpr 89 day operator+ (const days& __lhs, const day& __rhs) noexcept 90 { return __rhs + __lhs; } 91 92 inline constexpr 93 day operator- (const day& __lhs, const days& __rhs) noexcept 94 { return __lhs + -__rhs; } 95 96 inline constexpr 97 days operator-(const day& __lhs, const day& __rhs) noexcept 98 { return days(static_cast<int>(static_cast<unsigned>(__lhs)) - 99 static_cast<int>(static_cast<unsigned>(__rhs))); } 100 101 inline constexpr day& day::operator+=(const days& __dd) noexcept 102 { *this = *this + __dd; return *this; } 103 104 inline constexpr day& day::operator-=(const days& __dd) noexcept 105 { *this = *this - __dd; return *this; } 106 107 108 class month { 109 private: 110 unsigned char __m; 111 public: 112 month() = default; 113 explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {} 114 inline constexpr month& operator++() noexcept { ++__m; return *this; } 115 inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } 116 inline constexpr month& operator--() noexcept { --__m; return *this; } 117 inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } 118 constexpr month& operator+=(const months& __m1) noexcept; 119 constexpr month& operator-=(const months& __m1) noexcept; 120 explicit inline constexpr operator unsigned() const noexcept { return __m; } 121 inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; } 122 }; 123 124 125 inline constexpr 126 bool operator==(const month& __lhs, const month& __rhs) noexcept 127 { return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } 128 129 inline constexpr 130 bool operator!=(const month& __lhs, const month& __rhs) noexcept 131 { return !(__lhs == __rhs); } 132 133 inline constexpr 134 bool operator< (const month& __lhs, const month& __rhs) noexcept 135 { return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } 136 137 inline constexpr 138 bool operator> (const month& __lhs, const month& __rhs) noexcept 139 { return __rhs < __lhs; } 140 141 inline constexpr 142 bool operator<=(const month& __lhs, const month& __rhs) noexcept 143 { return !(__rhs < __lhs); } 144 145 inline constexpr 146 bool operator>=(const month& __lhs, const month& __rhs) noexcept 147 { return !(__lhs < __rhs); } 148 149 inline constexpr 150 month operator+ (const month& __lhs, const months& __rhs) noexcept 151 { 152 auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1); 153 auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; 154 return month{static_cast<unsigned>(__mu - __yr * 12 + 1)}; 155 } 156 157 inline constexpr 158 month operator+ (const months& __lhs, const month& __rhs) noexcept 159 { return __rhs + __lhs; } 160 161 inline constexpr 162 month operator- (const month& __lhs, const months& __rhs) noexcept 163 { return __lhs + -__rhs; } 164 165 inline constexpr 166 months operator-(const month& __lhs, const month& __rhs) noexcept 167 { 168 auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs); 169 return months(__dm <= 11 ? __dm : __dm + 12); 170 } 171 172 inline constexpr month& month::operator+=(const months& __dm) noexcept 173 { *this = *this + __dm; return *this; } 174 175 inline constexpr month& month::operator-=(const months& __dm) noexcept 176 { *this = *this - __dm; return *this; } 177 178 179 class year { 180 private: 181 short __y; 182 public: 183 year() = default; 184 explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {} 185 186 inline constexpr year& operator++() noexcept { ++__y; return *this; } 187 inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; } 188 inline constexpr year& operator--() noexcept { --__y; return *this; } 189 inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; } 190 constexpr year& operator+=(const years& __dy) noexcept; 191 constexpr year& operator-=(const years& __dy) noexcept; 192 inline constexpr year operator+() const noexcept { return *this; } 193 inline constexpr year operator-() const noexcept { return year{-__y}; } 194 195 inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); } 196 explicit inline constexpr operator int() const noexcept { return __y; } 197 constexpr bool ok() const noexcept; 198 static inline constexpr year min() noexcept { return year{-32767}; } 199 static inline constexpr year max() noexcept { return year{ 32767}; } 200 }; 201 202 203 inline constexpr 204 bool operator==(const year& __lhs, const year& __rhs) noexcept 205 { return static_cast<int>(__lhs) == static_cast<int>(__rhs); } 206 207 inline constexpr 208 bool operator!=(const year& __lhs, const year& __rhs) noexcept 209 { return !(__lhs == __rhs); } 210 211 inline constexpr 212 bool operator< (const year& __lhs, const year& __rhs) noexcept 213 { return static_cast<int>(__lhs) < static_cast<int>(__rhs); } 214 215 inline constexpr 216 bool operator> (const year& __lhs, const year& __rhs) noexcept 217 { return __rhs < __lhs; } 218 219 inline constexpr 220 bool operator<=(const year& __lhs, const year& __rhs) noexcept 221 { return !(__rhs < __lhs); } 222 223 inline constexpr 224 bool operator>=(const year& __lhs, const year& __rhs) noexcept 225 { return !(__lhs < __rhs); } 226 227 inline constexpr 228 year operator+ (const year& __lhs, const years& __rhs) noexcept 229 { return year(static_cast<int>(__lhs) + __rhs.count()); } 230 231 inline constexpr 232 year operator+ (const years& __lhs, const year& __rhs) noexcept 233 { return __rhs + __lhs; } 234 235 inline constexpr 236 year operator- (const year& __lhs, const years& __rhs) noexcept 237 { return __lhs + -__rhs; } 238 239 inline constexpr 240 years operator-(const year& __lhs, const year& __rhs) noexcept 241 { return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; } 242 243 244 inline constexpr year& year::operator+=(const years& __dy) noexcept 245 { *this = *this + __dy; return *this; } 246 247 inline constexpr year& year::operator-=(const years& __dy) noexcept 248 { *this = *this - __dy; return *this; } 249 250 inline constexpr bool year::ok() const noexcept 251 { return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); } 252 253 class weekday_indexed; 254 class weekday_last; 255 256 class weekday { 257 private: 258 unsigned char __wd; 259 static constexpr unsigned char __weekday_from_days(int __days) noexcept; 260 public: 261 weekday() = default; 262 inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {} 263 inline constexpr weekday(const sys_days& __sysd) noexcept 264 : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {} 265 inline explicit constexpr weekday(const local_days& __locd) noexcept 266 : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {} 267 268 inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; } 269 inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } 270 inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; } 271 inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } 272 constexpr weekday& operator+=(const days& __dd) noexcept; 273 constexpr weekday& operator-=(const days& __dd) noexcept; 274 inline constexpr unsigned c_encoding() const noexcept { return __wd; } 275 inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; } 276 inline constexpr bool ok() const noexcept { return __wd <= 6; } 277 constexpr weekday_indexed operator[](unsigned __index) const noexcept; 278 constexpr weekday_last operator[](last_spec) const noexcept; 279 }; 280 281 282 // https://howardhinnant.github.io/date_algorithms.html#weekday_from_days 283 inline constexpr 284 unsigned char weekday::__weekday_from_days(int __days) noexcept 285 { 286 return static_cast<unsigned char>( 287 static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) 288 ); 289 } 290 291 inline constexpr 292 bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept 293 { return __lhs.c_encoding() == __rhs.c_encoding(); } 294 295 inline constexpr 296 bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept 297 { return !(__lhs == __rhs); } 298 299 inline constexpr 300 bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept 301 { return __lhs.c_encoding() < __rhs.c_encoding(); } 302 303 inline constexpr 304 bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept 305 { return __rhs < __lhs; } 306 307 inline constexpr 308 bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept 309 { return !(__rhs < __lhs);} 310 311 inline constexpr 312 bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept 313 { return !(__lhs < __rhs); } 314 315 constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept 316 { 317 auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count(); 318 auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; 319 return weekday{static_cast<unsigned>(__mu - __yr * 7)}; 320 } 321 322 constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept 323 { return __rhs + __lhs; } 324 325 constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept 326 { return __lhs + -__rhs; } 327 328 constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept 329 { 330 const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); 331 const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; 332 return days{__wdu - __wk * 7}; 333 } 334 335 inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept 336 { *this = *this + __dd; return *this; } 337 338 inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept 339 { *this = *this - __dd; return *this; } 340 341 342 class weekday_indexed { 343 private: 344 chrono::weekday __wd; 345 unsigned char __idx; 346 public: 347 weekday_indexed() = default; 348 inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept 349 : __wd{__wdval}, __idx(__idxval) {} 350 inline constexpr chrono::weekday weekday() const noexcept { return __wd; } 351 inline constexpr unsigned index() const noexcept { return __idx; } 352 inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; } 353 }; 354 355 inline constexpr 356 bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept 357 { return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } 358 359 inline constexpr 360 bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept 361 { return !(__lhs == __rhs); } 362 363 364 class weekday_last { 365 private: 366 chrono::weekday __wd; 367 public: 368 explicit constexpr weekday_last(const chrono::weekday& __val) noexcept 369 : __wd{__val} {} 370 constexpr chrono::weekday weekday() const noexcept { return __wd; } 371 constexpr bool ok() const noexcept { return __wd.ok(); } 372 }; 373 374 inline constexpr 375 bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept 376 { return __lhs.weekday() == __rhs.weekday(); } 377 378 inline constexpr 379 bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept 380 { return !(__lhs == __rhs); } 381 382 inline constexpr 383 weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } 384 385 inline constexpr 386 weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } 387 388 389 inline constexpr last_spec last{}; 390 inline constexpr weekday Sunday{0}; 391 inline constexpr weekday Monday{1}; 392 inline constexpr weekday Tuesday{2}; 393 inline constexpr weekday Wednesday{3}; 394 inline constexpr weekday Thursday{4}; 395 inline constexpr weekday Friday{5}; 396 inline constexpr weekday Saturday{6}; 397 398 inline constexpr month January{1}; 399 inline constexpr month February{2}; 400 inline constexpr month March{3}; 401 inline constexpr month April{4}; 402 inline constexpr month May{5}; 403 inline constexpr month June{6}; 404 inline constexpr month July{7}; 405 inline constexpr month August{8}; 406 inline constexpr month September{9}; 407 inline constexpr month October{10}; 408 inline constexpr month November{11}; 409 inline constexpr month December{12}; 410 411 412 class month_day { 413 private: 414 chrono::month __m; 415 chrono::day __d; 416 public: 417 month_day() = default; 418 constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept 419 : __m{__mval}, __d{__dval} {} 420 inline constexpr chrono::month month() const noexcept { return __m; } 421 inline constexpr chrono::day day() const noexcept { return __d; } 422 constexpr bool ok() const noexcept; 423 }; 424 425 inline constexpr 426 bool month_day::ok() const noexcept 427 { 428 if (!__m.ok()) return false; 429 const unsigned __dval = static_cast<unsigned>(__d); 430 if (__dval < 1 || __dval > 31) return false; 431 if (__dval <= 29) return true; 432 // Now we've got either 30 or 31 433 const unsigned __mval = static_cast<unsigned>(__m); 434 if (__mval == 2) return false; 435 if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) 436 return __dval == 30; 437 return true; 438 } 439 440 inline constexpr 441 bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept 442 { return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } 443 444 inline constexpr 445 bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept 446 { return !(__lhs == __rhs); } 447 448 inline constexpr 449 month_day operator/(const month& __lhs, const day& __rhs) noexcept 450 { return month_day{__lhs, __rhs}; } 451 452 constexpr 453 month_day operator/(const day& __lhs, const month& __rhs) noexcept 454 { return __rhs / __lhs; } 455 456 inline constexpr 457 month_day operator/(const month& __lhs, int __rhs) noexcept 458 { return __lhs / day(__rhs); } 459 460 constexpr 461 month_day operator/(int __lhs, const day& __rhs) noexcept 462 { return month(__lhs) / __rhs; } 463 464 constexpr 465 month_day operator/(const day& __lhs, int __rhs) noexcept 466 { return month(__rhs) / __lhs; } 467 468 469 inline constexpr 470 bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept 471 { return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); } 472 473 inline constexpr 474 bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept 475 { return __rhs < __lhs; } 476 477 inline constexpr 478 bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept 479 { return !(__rhs < __lhs);} 480 481 inline constexpr 482 bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept 483 { return !(__lhs < __rhs); } 484 485 486 487 class month_day_last { 488 private: 489 chrono::month __m; 490 public: 491 explicit constexpr month_day_last(const chrono::month& __val) noexcept 492 : __m{__val} {} 493 inline constexpr chrono::month month() const noexcept { return __m; } 494 inline constexpr bool ok() const noexcept { return __m.ok(); } 495 }; 496 497 inline constexpr 498 bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept 499 { return __lhs.month() == __rhs.month(); } 500 501 inline constexpr 502 bool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept 503 { return !(__lhs == __rhs); } 504 505 inline constexpr 506 bool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept 507 { return __lhs.month() < __rhs.month(); } 508 509 inline constexpr 510 bool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept 511 { return __rhs < __lhs; } 512 513 inline constexpr 514 bool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept 515 { return !(__rhs < __lhs);} 516 517 inline constexpr 518 bool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept 519 { return !(__lhs < __rhs); } 520 521 inline constexpr 522 month_day_last operator/(const month& __lhs, last_spec) noexcept 523 { return month_day_last{__lhs}; } 524 525 inline constexpr 526 month_day_last operator/(last_spec, const month& __rhs) noexcept 527 { return month_day_last{__rhs}; } 528 529 inline constexpr 530 month_day_last operator/(int __lhs, last_spec) noexcept 531 { return month_day_last{month(__lhs)}; } 532 533 inline constexpr 534 month_day_last operator/(last_spec, int __rhs) noexcept 535 { return month_day_last{month(__rhs)}; } 536 537 538 class month_weekday { 539 private: 540 chrono::month __m; 541 chrono::weekday_indexed __wdi; 542 public: 543 constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept 544 : __m{__mval}, __wdi{__wdival} {} 545 inline constexpr chrono::month month() const noexcept { return __m; } 546 inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } 547 inline constexpr bool ok() const noexcept { return __m.ok() && __wdi.ok(); } 548 }; 549 550 inline constexpr 551 bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept 552 { return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } 553 554 inline constexpr 555 bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept 556 { return !(__lhs == __rhs); } 557 558 inline constexpr 559 month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept 560 { return month_weekday{__lhs, __rhs}; } 561 562 inline constexpr 563 month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept 564 { return month_weekday{month(__lhs), __rhs}; } 565 566 inline constexpr 567 month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept 568 { return month_weekday{__rhs, __lhs}; } 569 570 inline constexpr 571 month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept 572 { return month_weekday{month(__rhs), __lhs}; } 573 574 575 class month_weekday_last { 576 chrono::month __m; 577 chrono::weekday_last __wdl; 578 public: 579 constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept 580 : __m{__mval}, __wdl{__wdlval} {} 581 inline constexpr chrono::month month() const noexcept { return __m; } 582 inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } 583 inline constexpr bool ok() const noexcept { return __m.ok() && __wdl.ok(); } 584 }; 585 586 inline constexpr 587 bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept 588 { return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } 589 590 inline constexpr 591 bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept 592 { return !(__lhs == __rhs); } 593 594 595 inline constexpr 596 month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept 597 { return month_weekday_last{__lhs, __rhs}; } 598 599 inline constexpr 600 month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept 601 { return month_weekday_last{month(__lhs), __rhs}; } 602 603 inline constexpr 604 month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept 605 { return month_weekday_last{__rhs, __lhs}; } 606 607 inline constexpr 608 month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept 609 { return month_weekday_last{month(__rhs), __lhs}; } 610 611 612 class year_month { 613 chrono::year __y; 614 chrono::month __m; 615 public: 616 year_month() = default; 617 constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept 618 : __y{__yval}, __m{__mval} {} 619 inline constexpr chrono::year year() const noexcept { return __y; } 620 inline constexpr chrono::month month() const noexcept { return __m; } 621 inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; } 622 inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; } 623 inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; } 624 inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; } 625 inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); } 626 }; 627 628 inline constexpr 629 year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; } 630 631 inline constexpr 632 year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; } 633 634 inline constexpr 635 bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept 636 { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); } 637 638 inline constexpr 639 bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept 640 { return !(__lhs == __rhs); } 641 642 inline constexpr 643 bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept 644 { return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); } 645 646 inline constexpr 647 bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept 648 { return __rhs < __lhs; } 649 650 inline constexpr 651 bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept 652 { return !(__rhs < __lhs);} 653 654 inline constexpr 655 bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept 656 { return !(__lhs < __rhs); } 657 658 constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept 659 { 660 int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count(); 661 const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12; 662 __dmi = __dmi - __dy * 12 + 1; 663 return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi)); 664 } 665 666 constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept 667 { return __rhs + __lhs; } 668 669 constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept 670 { return (__lhs.year() + __rhs) / __lhs.month(); } 671 672 constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept 673 { return __rhs + __lhs; } 674 675 constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept 676 { return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); } 677 678 constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept 679 { return __lhs + -__rhs; } 680 681 constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept 682 { return __lhs + -__rhs; } 683 684 class year_month_day_last; 685 686 class year_month_day { 687 private: 688 chrono::year __y; 689 chrono::month __m; 690 chrono::day __d; 691 public: 692 year_month_day() = default; 693 inline constexpr year_month_day( 694 const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept 695 : __y{__yval}, __m{__mval}, __d{__dval} {} 696 constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; 697 inline constexpr year_month_day(const sys_days& __sysd) noexcept 698 : year_month_day(__from_days(__sysd.time_since_epoch())) {} 699 inline explicit constexpr year_month_day(const local_days& __locd) noexcept 700 : year_month_day(__from_days(__locd.time_since_epoch())) {} 701 702 constexpr year_month_day& operator+=(const months& __dm) noexcept; 703 constexpr year_month_day& operator-=(const months& __dm) noexcept; 704 constexpr year_month_day& operator+=(const years& __dy) noexcept; 705 constexpr year_month_day& operator-=(const years& __dy) noexcept; 706 707 inline constexpr chrono::year year() const noexcept { return __y; } 708 inline constexpr chrono::month month() const noexcept { return __m; } 709 inline constexpr chrono::day day() const noexcept { return __d; } 710 inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } 711 inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } 712 713 constexpr bool ok() const noexcept; 714 715 static constexpr year_month_day __from_days(days __d) noexcept; 716 constexpr days __to_days() const noexcept; 717 }; 718 719 720 // https://howardhinnant.github.io/date_algorithms.html#civil_from_days 721 inline constexpr 722 year_month_day 723 year_month_day::__from_days(days __d) noexcept 724 { 725 static_assert(numeric_limits<unsigned>::digits >= 18, ""); 726 static_assert(numeric_limits<int>::digits >= 20 , ""); 727 const int __z = __d.count() + 719468; 728 const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; 729 const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096] 730 const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] 731 const int __yr = static_cast<int>(__yoe) + __era * 400; 732 const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] 733 const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] 734 const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] 735 const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] 736 return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; 737 } 738 739 // https://howardhinnant.github.io/date_algorithms.html#days_from_civil 740 inline constexpr days year_month_day::__to_days() const noexcept 741 { 742 static_assert(numeric_limits<unsigned>::digits >= 18, ""); 743 static_assert(numeric_limits<int>::digits >= 20 , ""); 744 745 const int __yr = static_cast<int>(__y) - (__m <= February); 746 const unsigned __mth = static_cast<unsigned>(__m); 747 const unsigned __dy = static_cast<unsigned>(__d); 748 749 const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; 750 const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399] 751 const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] 752 const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] 753 return days{__era * 146097 + static_cast<int>(__doe) - 719468}; 754 } 755 756 inline constexpr 757 bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept 758 { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } 759 760 inline constexpr 761 bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept 762 { return !(__lhs == __rhs); } 763 764 inline constexpr 765 bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept 766 { 767 if (__lhs.year() < __rhs.year()) return true; 768 if (__lhs.year() > __rhs.year()) return false; 769 if (__lhs.month() < __rhs.month()) return true; 770 if (__lhs.month() > __rhs.month()) return false; 771 return __lhs.day() < __rhs.day(); 772 } 773 774 inline constexpr 775 bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept 776 { return __rhs < __lhs; } 777 778 inline constexpr 779 bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept 780 { return !(__rhs < __lhs);} 781 782 inline constexpr 783 bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept 784 { return !(__lhs < __rhs); } 785 786 inline constexpr 787 year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept 788 { return year_month_day{__lhs.year(), __lhs.month(), __rhs}; } 789 790 inline constexpr 791 year_month_day operator/(const year_month& __lhs, int __rhs) noexcept 792 { return __lhs / day(__rhs); } 793 794 inline constexpr 795 year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept 796 { return __lhs / __rhs.month() / __rhs.day(); } 797 798 inline constexpr 799 year_month_day operator/(int __lhs, const month_day& __rhs) noexcept 800 { return year(__lhs) / __rhs; } 801 802 inline constexpr 803 year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept 804 { return __rhs / __lhs; } 805 806 inline constexpr 807 year_month_day operator/(const month_day& __lhs, int __rhs) noexcept 808 { return year(__rhs) / __lhs; } 809 810 811 inline constexpr 812 year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept 813 { return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); } 814 815 inline constexpr 816 year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept 817 { return __rhs + __lhs; } 818 819 inline constexpr 820 year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept 821 { return __lhs + -__rhs; } 822 823 inline constexpr 824 year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept 825 { return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); } 826 827 inline constexpr 828 year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept 829 { return __rhs + __lhs; } 830 831 inline constexpr 832 year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept 833 { return __lhs + -__rhs; } 834 835 inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } 836 inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } 837 inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } 838 inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } 839 840 class year_month_day_last { 841 private: 842 chrono::year __y; 843 chrono::month_day_last __mdl; 844 public: 845 constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept 846 : __y{__yval}, __mdl{__mdlval} {} 847 848 constexpr year_month_day_last& operator+=(const months& __m) noexcept; 849 constexpr year_month_day_last& operator-=(const months& __m) noexcept; 850 constexpr year_month_day_last& operator+=(const years& __y) noexcept; 851 constexpr year_month_day_last& operator-=(const years& __y) noexcept; 852 853 inline constexpr chrono::year year() const noexcept { return __y; } 854 inline constexpr chrono::month month() const noexcept { return __mdl.month(); } 855 inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; } 856 constexpr chrono::day day() const noexcept; 857 inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } 858 inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } 859 inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); } 860 }; 861 862 inline constexpr 863 chrono::day year_month_day_last::day() const noexcept 864 { 865 constexpr chrono::day __d[] = 866 { 867 chrono::day(31), chrono::day(28), chrono::day(31), 868 chrono::day(30), chrono::day(31), chrono::day(30), 869 chrono::day(31), chrono::day(31), chrono::day(30), 870 chrono::day(31), chrono::day(30), chrono::day(31) 871 }; 872 return (month() != February || !__y.is_leap()) && month().ok() ? 873 __d[static_cast<unsigned>(month()) - 1] : chrono::day{29}; 874 } 875 876 inline constexpr 877 bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept 878 { return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } 879 880 inline constexpr 881 bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept 882 { return !(__lhs == __rhs); } 883 884 inline constexpr 885 bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept 886 { 887 if (__lhs.year() < __rhs.year()) return true; 888 if (__lhs.year() > __rhs.year()) return false; 889 return __lhs.month_day_last() < __rhs.month_day_last(); 890 } 891 892 inline constexpr 893 bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept 894 { return __rhs < __lhs; } 895 896 inline constexpr 897 bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept 898 { return !(__rhs < __lhs);} 899 900 inline constexpr 901 bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept 902 { return !(__lhs < __rhs); } 903 904 inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept 905 { return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; } 906 907 inline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept 908 { return year_month_day_last{__lhs, __rhs}; } 909 910 inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept 911 { return year_month_day_last{year{__lhs}, __rhs}; } 912 913 inline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept 914 { return __rhs / __lhs; } 915 916 inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept 917 { return year{__rhs} / __lhs; } 918 919 920 inline constexpr 921 year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept 922 { return (__lhs.year() / __lhs.month() + __rhs) / last; } 923 924 inline constexpr 925 year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept 926 { return __rhs + __lhs; } 927 928 inline constexpr 929 year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept 930 { return __lhs + (-__rhs); } 931 932 inline constexpr 933 year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept 934 { return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; } 935 936 inline constexpr 937 year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept 938 { return __rhs + __lhs; } 939 940 inline constexpr 941 year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept 942 { return __lhs + (-__rhs); } 943 944 inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } 945 inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } 946 inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } 947 inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } 948 949 inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept 950 : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {} 951 952 inline constexpr bool year_month_day::ok() const noexcept 953 { 954 if (!__y.ok() || !__m.ok()) return false; 955 return chrono::day{1} <= __d && __d <= (__y / __m / last).day(); 956 } 957 958 class year_month_weekday { 959 chrono::year __y; 960 chrono::month __m; 961 chrono::weekday_indexed __wdi; 962 public: 963 year_month_weekday() = default; 964 constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, 965 const chrono::weekday_indexed& __wdival) noexcept 966 : __y{__yval}, __m{__mval}, __wdi{__wdival} {} 967 constexpr year_month_weekday(const sys_days& __sysd) noexcept 968 : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} 969 inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept 970 : year_month_weekday(__from_days(__locd.time_since_epoch())) {} 971 constexpr year_month_weekday& operator+=(const months& m) noexcept; 972 constexpr year_month_weekday& operator-=(const months& m) noexcept; 973 constexpr year_month_weekday& operator+=(const years& y) noexcept; 974 constexpr year_month_weekday& operator-=(const years& y) noexcept; 975 976 inline constexpr chrono::year year() const noexcept { return __y; } 977 inline constexpr chrono::month month() const noexcept { return __m; } 978 inline constexpr chrono::weekday weekday() const noexcept { return __wdi.weekday(); } 979 inline constexpr unsigned index() const noexcept { return __wdi.index(); } 980 inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } 981 982 inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } 983 inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } 984 inline constexpr bool ok() const noexcept 985 { 986 if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false; 987 if (__wdi.index() <= 4) return true; 988 auto __nth_weekday_day = 989 __wdi.weekday() - 990 chrono::weekday{static_cast<sys_days>(__y / __m / 1)} + 991 days{(__wdi.index() - 1) * 7 + 1}; 992 return static_cast<unsigned>(__nth_weekday_day.count()) <= 993 static_cast<unsigned>((__y / __m / last).day()); 994 } 995 996 static constexpr year_month_weekday __from_days(days __d) noexcept; 997 constexpr days __to_days() const noexcept; 998 }; 999 1000 inline constexpr 1001 year_month_weekday year_month_weekday::__from_days(days __d) noexcept 1002 { 1003 const sys_days __sysd{__d}; 1004 const chrono::weekday __wd = chrono::weekday(__sysd); 1005 const year_month_day __ymd = year_month_day(__sysd); 1006 return year_month_weekday{__ymd.year(), __ymd.month(), 1007 __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]}; 1008 } 1009 1010 inline constexpr 1011 days year_month_weekday::__to_days() const noexcept 1012 { 1013 const sys_days __sysd = sys_days(__y/__m/1); 1014 return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7})) 1015 .time_since_epoch(); 1016 } 1017 1018 inline constexpr 1019 bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept 1020 { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } 1021 1022 inline constexpr 1023 bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept 1024 { return !(__lhs == __rhs); } 1025 1026 inline constexpr 1027 year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept 1028 { return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } 1029 1030 inline constexpr 1031 year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept 1032 { return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; } 1033 1034 inline constexpr 1035 year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept 1036 { return year(__lhs) / __rhs; } 1037 1038 inline constexpr 1039 year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept 1040 { return __rhs / __lhs; } 1041 1042 inline constexpr 1043 year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept 1044 { return year(__rhs) / __lhs; } 1045 1046 1047 inline constexpr 1048 year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept 1049 { return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); } 1050 1051 inline constexpr 1052 year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept 1053 { return __rhs + __lhs; } 1054 1055 inline constexpr 1056 year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept 1057 { return __lhs + (-__rhs); } 1058 1059 inline constexpr 1060 year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept 1061 { return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; } 1062 1063 inline constexpr 1064 year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept 1065 { return __rhs + __lhs; } 1066 1067 inline constexpr 1068 year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept 1069 { return __lhs + (-__rhs); } 1070 1071 1072 inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } 1073 inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } 1074 inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } 1075 inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } 1076 1077 class year_month_weekday_last { 1078 private: 1079 chrono::year __y; 1080 chrono::month __m; 1081 chrono::weekday_last __wdl; 1082 public: 1083 constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval, 1084 const chrono::weekday_last& __wdlval) noexcept 1085 : __y{__yval}, __m{__mval}, __wdl{__wdlval} {} 1086 constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; 1087 constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; 1088 constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; 1089 constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; 1090 1091 inline constexpr chrono::year year() const noexcept { return __y; } 1092 inline constexpr chrono::month month() const noexcept { return __m; } 1093 inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); } 1094 inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } 1095 inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } 1096 inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } 1097 inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); } 1098 1099 constexpr days __to_days() const noexcept; 1100 1101 }; 1102 1103 inline constexpr 1104 days year_month_weekday_last::__to_days() const noexcept 1105 { 1106 const sys_days __last = sys_days{__y/__m/last}; 1107 return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch(); 1108 1109 } 1110 1111 inline constexpr 1112 bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept 1113 { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } 1114 1115 inline constexpr 1116 bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept 1117 { return !(__lhs == __rhs); } 1118 1119 1120 inline constexpr 1121 year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept 1122 { return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } 1123 1124 inline constexpr 1125 year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept 1126 { return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; } 1127 1128 inline constexpr 1129 year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept 1130 { return year(__lhs) / __rhs; } 1131 1132 inline constexpr 1133 year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept 1134 { return __rhs / __lhs; } 1135 1136 inline constexpr 1137 year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept 1138 { return year(__rhs) / __lhs; } 1139 1140 1141 inline constexpr 1142 year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept 1143 { return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); } 1144 1145 inline constexpr 1146 year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept 1147 { return __rhs + __lhs; } 1148 1149 inline constexpr 1150 year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept 1151 { return __lhs + (-__rhs); } 1152 1153 inline constexpr 1154 year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept 1155 { return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; } 1156 1157 inline constexpr 1158 year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept 1159 { return __rhs + __lhs; } 1160 1161 inline constexpr 1162 year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept 1163 { return __lhs + (-__rhs); } 1164 1165 inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } 1166 inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } 1167 inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } 1168 inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } 1169 1170 1171 template <class _Duration> 1172 class hh_mm_ss 1173 { 1174 private: 1175 static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); 1176 using __CommonType = common_type_t<_Duration, chrono::seconds>; 1177 1178 static constexpr uint64_t __pow10(unsigned __exp) 1179 { 1180 uint64_t __ret = 1; 1181 for (unsigned __i = 0; __i < __exp; ++__i) 1182 __ret *= 10U; 1183 return __ret; 1184 } 1185 1186 static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) 1187 { 1188 if (__n >= 2 && __d != 0 && __w < 19) 1189 return 1 + __width(__n, __d % __n * 10, __w+1); 1190 return 0; 1191 } 1192 1193 public: 1194 static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ? 1195 __width(__CommonType::period::den) : 6u; 1196 using precision = duration<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>; 1197 1198 constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} 1199 1200 constexpr explicit hh_mm_ss(_Duration __d) noexcept : 1201 __is_neg(__d < _Duration(0)), 1202 __h(duration_cast<chrono::hours> (abs(__d))), 1203 __m(duration_cast<chrono::minutes>(abs(__d) - hours())), 1204 __s(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())), 1205 __f(duration_cast<precision> (abs(__d) - hours() - minutes() - seconds())) 1206 {} 1207 1208 constexpr bool is_negative() const noexcept { return __is_neg; } 1209 constexpr chrono::hours hours() const noexcept { return __h; } 1210 constexpr chrono::minutes minutes() const noexcept { return __m; } 1211 constexpr chrono::seconds seconds() const noexcept { return __s; } 1212 constexpr precision subseconds() const noexcept { return __f; } 1213 1214 constexpr precision to_duration() const noexcept 1215 { 1216 auto __dur = __h + __m + __s + __f; 1217 return __is_neg ? -__dur : __dur; 1218 } 1219 1220 constexpr explicit operator precision() const noexcept { return to_duration(); } 1221 1222 private: 1223 bool __is_neg; 1224 chrono::hours __h; 1225 chrono::minutes __m; 1226 chrono::seconds __s; 1227 precision __f; 1228 }; 1229 1230 constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } 1231 constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } 1232 1233 constexpr hours make12(const hours& __h) noexcept 1234 { 1235 if (__h == hours( 0)) return hours(12); 1236 else if (__h <= hours(12)) return __h; 1237 else return __h - hours(12); 1238 } 1239 1240 constexpr hours make24(const hours& __h, bool __is_pm) noexcept 1241 { 1242 if (__is_pm) 1243 return __h == hours(12) ? __h : __h + hours(12); 1244 else 1245 return __h == hours(12) ? hours(0) : __h; 1246 } 1247 1248 } // namespace chrono 1249 1250 inline namespace literals 1251 { 1252 inline namespace chrono_literals 1253 { 1254 constexpr chrono::day operator ""d(unsigned long long __d) noexcept 1255 { 1256 return chrono::day(static_cast<unsigned>(__d)); 1257 } 1258 1259 constexpr chrono::year operator ""y(unsigned long long __y) noexcept 1260 { 1261 return chrono::year(static_cast<int>(__y)); 1262 } 1263 } // namespace chrono_literals 1264 } // namespace literals 1265 1266 namespace chrono { // hoist the literals into namespace std::chrono 1267 using namespace literals::chrono_literals; 1268 } // namespace chrono 1269 1270 _LIBCPP_END_NAMESPACE_STD 1271 1272 #endif // _LIBCPP_STD_VER > 17 1273 1274 _LIBCPP_POP_MACROS 1275 1276 #endif // _LIBCPP___CHRONO_CALENDAR_H 1277