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