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