blob: 90c9b0829a1f54bba46ec434d5396ac2586415df [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
Louis Dionne9bd93882021-11-17 16:25:01 -05002//===----------------------------------------------------------------------===//
Howard Hinnantc51e1022010-05-11 19:42:16 +00003//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_CHRONO
11#define _LIBCPP_CHRONO
12
13/*
14 chrono synopsis
15
16namespace std
17{
18namespace chrono
19{
20
21template <class ToDuration, class Rep, class Period>
Howard Hinnantcf3143c2012-07-13 19:17:27 +000022constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +000023ToDuration
24duration_cast(const duration<Rep, Period>& fd);
25
26template <class Rep> struct treat_as_floating_point : is_floating_point<Rep> {};
27
Marshall Clowf1bf62f2018-01-02 17:17:01 +000028template <class Rep> inline constexpr bool treat_as_floating_point_v
Marshall Clow59581f02015-11-30 05:39:30 +000029 = treat_as_floating_point<Rep>::value; // C++17
30
Howard Hinnantc51e1022010-05-11 19:42:16 +000031template <class Rep>
32struct duration_values
33{
34public:
Marshall Clowb1296bd2018-11-13 17:22:41 +000035 static constexpr Rep zero(); // noexcept in C++20
36 static constexpr Rep max(); // noexcept in C++20
37 static constexpr Rep min(); // noexcept in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000038};
39
40// duration
41
42template <class Rep, class Period = ratio<1>>
43class duration
44{
45 static_assert(!__is_duration<Rep>::value, "A duration representation can not be a duration");
46 static_assert(__is_ratio<Period>::value, "Second template parameter of duration must be a std::ratio");
47 static_assert(Period::num > 0, "duration period must be positive");
48public:
49 typedef Rep rep;
Marshall Clow76200b22017-03-21 18:38:57 +000050 typedef typename _Period::type period;
Howard Hinnantc51e1022010-05-11 19:42:16 +000051
Howard Hinnantcf3143c2012-07-13 19:17:27 +000052 constexpr duration() = default;
Howard Hinnantc51e1022010-05-11 19:42:16 +000053 template <class Rep2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +000054 constexpr explicit duration(const Rep2& r,
Howard Hinnantc51e1022010-05-11 19:42:16 +000055 typename enable_if
56 <
57 is_convertible<Rep2, rep>::value &&
58 (treat_as_floating_point<rep>::value ||
59 !treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value)
60 >::type* = 0);
61
62 // conversions
63 template <class Rep2, class Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +000064 constexpr duration(const duration<Rep2, Period2>& d,
Howard Hinnantc51e1022010-05-11 19:42:16 +000065 typename enable_if
66 <
67 treat_as_floating_point<rep>::value ||
68 ratio_divide<Period2, period>::type::den == 1
69 >::type* = 0);
70
71 // observer
72
Howard Hinnantcf3143c2012-07-13 19:17:27 +000073 constexpr rep count() const;
Howard Hinnantc51e1022010-05-11 19:42:16 +000074
75 // arithmetic
76
Marshall Clow76200b22017-03-21 18:38:57 +000077 constexpr common_type<duration>::type operator+() const;
78 constexpr common_type<duration>::type operator-() const;
Marshall Clowdf247eb2018-08-29 23:02:15 +000079 constexpr duration& operator++(); // constexpr in C++17
80 constexpr duration operator++(int); // constexpr in C++17
81 constexpr duration& operator--(); // constexpr in C++17
82 constexpr duration operator--(int); // constexpr in C++17
Howard Hinnantc51e1022010-05-11 19:42:16 +000083
Marshall Clowdf247eb2018-08-29 23:02:15 +000084 constexpr duration& operator+=(const duration& d); // constexpr in C++17
85 constexpr duration& operator-=(const duration& d); // constexpr in C++17
Howard Hinnantc51e1022010-05-11 19:42:16 +000086
Marshall Clowdf247eb2018-08-29 23:02:15 +000087 duration& operator*=(const rep& rhs); // constexpr in C++17
88 duration& operator/=(const rep& rhs); // constexpr in C++17
89 duration& operator%=(const rep& rhs); // constexpr in C++17
90 duration& operator%=(const duration& rhs); // constexpr in C++17
Howard Hinnantc51e1022010-05-11 19:42:16 +000091
92 // special values
93
Marshall Clowb1296bd2018-11-13 17:22:41 +000094 static constexpr duration zero(); // noexcept in C++20
95 static constexpr duration min(); // noexcept in C++20
96 static constexpr duration max(); // noexcept in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +000097};
98
99typedef duration<long long, nano> nanoseconds;
100typedef duration<long long, micro> microseconds;
101typedef duration<long long, milli> milliseconds;
102typedef duration<long long > seconds;
103typedef duration< long, ratio< 60> > minutes;
104typedef duration< long, ratio<3600> > hours;
105
106template <class Clock, class Duration = typename Clock::duration>
107class time_point
108{
109public:
110 typedef Clock clock;
111 typedef Duration duration;
112 typedef typename duration::rep rep;
113 typedef typename duration::period period;
114private:
115 duration d_; // exposition only
116
117public:
Marshall Clow5c459c92013-07-31 19:32:19 +0000118 time_point(); // has value "epoch" // constexpr in C++14
119 explicit time_point(const duration& d); // same as time_point() + d // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000120
121 // conversions
122 template <class Duration2>
Marshall Clow5c459c92013-07-31 19:32:19 +0000123 time_point(const time_point<clock, Duration2>& t); // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000124
125 // observer
126
Marshall Clow5c459c92013-07-31 19:32:19 +0000127 duration time_since_epoch() const; // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000128
129 // arithmetic
130
Marshall Clowdf247eb2018-08-29 23:02:15 +0000131 time_point& operator+=(const duration& d); // constexpr in C++17
132 time_point& operator-=(const duration& d); // constexpr in C++17
Howard Hinnantc51e1022010-05-11 19:42:16 +0000133
134 // special values
135
Marshall Clowb1296bd2018-11-13 17:22:41 +0000136 static constexpr time_point min(); // noexcept in C++20
137 static constexpr time_point max(); // noexcept in C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +0000138};
139
140} // chrono
141
142// common_type traits
143template <class Rep1, class Period1, class Rep2, class Period2>
144 struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>>;
145
146template <class Clock, class Duration1, class Duration2>
147 struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>>;
148
149namespace chrono {
150
151// duration arithmetic
152template <class Rep1, class Period1, class Rep2, class Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000153 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000154 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
155 operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
156template <class Rep1, class Period1, class Rep2, class Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000157 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000158 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
159 operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
160template <class Rep1, class Period, class Rep2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000161 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000162 duration<typename common_type<Rep1, Rep2>::type, Period>
163 operator*(const duration<Rep1, Period>& d, const Rep2& s);
164template <class Rep1, class Period, class Rep2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000165 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000166 duration<typename common_type<Rep1, Rep2>::type, Period>
167 operator*(const Rep1& s, const duration<Rep2, Period>& d);
168template <class Rep1, class Period, class Rep2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000169 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000170 duration<typename common_type<Rep1, Rep2>::type, Period>
171 operator/(const duration<Rep1, Period>& d, const Rep2& s);
172template <class Rep1, class Period1, class Rep2, class Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000173 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000174 typename common_type<Rep1, Rep2>::type
175 operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
176
177// duration comparisons
178template <class Rep1, class Period1, class Rep2, class Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000179 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000180 bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
181template <class Rep1, class Period1, class Rep2, class Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000182 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000183 bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
184template <class Rep1, class Period1, class Rep2, class Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000185 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000186 bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
187template <class Rep1, class Period1, class Rep2, class Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000188 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000189 bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
190template <class Rep1, class Period1, class Rep2, class Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000191 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000192 bool operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
193template <class Rep1, class Period1, class Rep2, class Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000194 constexpr
Howard Hinnantc51e1022010-05-11 19:42:16 +0000195 bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
196
197// duration_cast
198template <class ToDuration, class Rep, class Period>
199 ToDuration duration_cast(const duration<Rep, Period>& d);
200
Marshall Clowf2eabaf2015-11-05 19:33:59 +0000201template <class ToDuration, class Rep, class Period>
202 constexpr ToDuration floor(const duration<Rep, Period>& d); // C++17
203template <class ToDuration, class Rep, class Period>
204 constexpr ToDuration ceil(const duration<Rep, Period>& d); // C++17
205template <class ToDuration, class Rep, class Period>
206 constexpr ToDuration round(const duration<Rep, Period>& d); // C++17
207
Marshall Clow40ca0c12018-07-18 17:37:51 +0000208// duration I/O is elsewhere
209
Marshall Clow5c459c92013-07-31 19:32:19 +0000210// time_point arithmetic (all constexpr in C++14)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000211template <class Clock, class Duration1, class Rep2, class Period2>
212 time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
213 operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
214template <class Rep1, class Period1, class Clock, class Duration2>
215 time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
216 operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
217template <class Clock, class Duration1, class Rep2, class Period2>
218 time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
219 operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
220template <class Clock, class Duration1, class Duration2>
221 typename common_type<Duration1, Duration2>::type
222 operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
223
Marshall Clow5c459c92013-07-31 19:32:19 +0000224// time_point comparisons (all constexpr in C++14)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000225template <class Clock, class Duration1, class Duration2>
226 bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
227template <class Clock, class Duration1, class Duration2>
228 bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
229template <class Clock, class Duration1, class Duration2>
230 bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
231template <class Clock, class Duration1, class Duration2>
232 bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
233template <class Clock, class Duration1, class Duration2>
234 bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
235template <class Clock, class Duration1, class Duration2>
236 bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
237
Marshall Clow5c459c92013-07-31 19:32:19 +0000238// time_point_cast (constexpr in C++14)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000239
240template <class ToDuration, class Clock, class Duration>
241 time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
242
Marshall Clowf2eabaf2015-11-05 19:33:59 +0000243template <class ToDuration, class Clock, class Duration>
244 constexpr time_point<Clock, ToDuration>
245 floor(const time_point<Clock, Duration>& tp); // C++17
246
247template <class ToDuration, class Clock, class Duration>
248 constexpr time_point<Clock, ToDuration>
249 ceil(const time_point<Clock, Duration>& tp); // C++17
250
251template <class ToDuration, class Clock, class Duration>
252 constexpr time_point<Clock, ToDuration>
253 round(const time_point<Clock, Duration>& tp); // C++17
254
255template <class Rep, class Period>
256 constexpr duration<Rep, Period> abs(duration<Rep, Period> d); // C++17
Marshall Clow40ca0c12018-07-18 17:37:51 +0000257
Howard Hinnantc51e1022010-05-11 19:42:16 +0000258// Clocks
259
260class system_clock
261{
262public:
263 typedef microseconds duration;
264 typedef duration::rep rep;
265 typedef duration::period period;
266 typedef chrono::time_point<system_clock> time_point;
Marshall Clow5c459c92013-07-31 19:32:19 +0000267 static const bool is_steady = false; // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000268
Howard Hinnantaa54ac42011-05-28 18:34:36 +0000269 static time_point now() noexcept;
270 static time_t to_time_t (const time_point& __t) noexcept;
271 static time_point from_time_t(time_t __t) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000272};
273
Marshall Clow40ca0c12018-07-18 17:37:51 +0000274template <class Duration>
275 using sys_time = time_point<system_clock, Duration>; // C++20
276using sys_seconds = sys_time<seconds>; // C++20
277using sys_days = sys_time<days>; // C++20
278
Louis Dionneb35fab82021-11-08 15:30:32 -0500279class file_clock // C++20
280{
281public:
282 typedef see-below rep;
283 typedef nano period;
284 typedef chrono::duration<rep, period> duration;
285 typedef chrono::time_point<file_clock> time_point;
286 static constexpr bool is_steady = false;
287
288 static time_point now() noexcept;
289
290 template<class Duration>
291 static sys_time<see-below> to_sys(const file_time<Duration>&);
292
293 template<class Duration>
294 static file_time<see-below> from_sys(const sys_time<Duration>&);
295};
Marshall Clow40ca0c12018-07-18 17:37:51 +0000296
297template<class Duration>
298 using file_time = time_point<file_clock, Duration>; // C++20
299
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000300class steady_clock
Howard Hinnantc51e1022010-05-11 19:42:16 +0000301{
302public:
303 typedef nanoseconds duration;
304 typedef duration::rep rep;
305 typedef duration::period period;
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000306 typedef chrono::time_point<steady_clock, duration> time_point;
Marshall Clow5c459c92013-07-31 19:32:19 +0000307 static const bool is_steady = true; // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000308
Howard Hinnantaa54ac42011-05-28 18:34:36 +0000309 static time_point now() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000310};
311
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000312typedef steady_clock high_resolution_clock;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000313
Marshall Clow40ca0c12018-07-18 17:37:51 +0000314// 25.7.8, local time // C++20
315struct local_t {};
316template<class Duration>
317 using local_time = time_point<local_t, Duration>;
318using local_seconds = local_time<seconds>;
319using local_days = local_time<days>;
320
Marshall Clow40ca0c12018-07-18 17:37:51 +0000321// 25.8.2, class last_spec // C++20
322struct last_spec;
323
324// 25.8.3, class day // C++20
325
326class day;
327constexpr bool operator==(const day& x, const day& y) noexcept;
328constexpr bool operator!=(const day& x, const day& y) noexcept;
329constexpr bool operator< (const day& x, const day& y) noexcept;
330constexpr bool operator> (const day& x, const day& y) noexcept;
331constexpr bool operator<=(const day& x, const day& y) noexcept;
332constexpr bool operator>=(const day& x, const day& y) noexcept;
333constexpr day operator+(const day& x, const days& y) noexcept;
334constexpr day operator+(const days& x, const day& y) noexcept;
335constexpr day operator-(const day& x, const days& y) noexcept;
336constexpr days operator-(const day& x, const day& y) noexcept;
337
338// 25.8.4, class month // C++20
339class month;
340constexpr bool operator==(const month& x, const month& y) noexcept;
341constexpr bool operator!=(const month& x, const month& y) noexcept;
342constexpr bool operator< (const month& x, const month& y) noexcept;
343constexpr bool operator> (const month& x, const month& y) noexcept;
344constexpr bool operator<=(const month& x, const month& y) noexcept;
345constexpr bool operator>=(const month& x, const month& y) noexcept;
346constexpr month operator+(const month& x, const months& y) noexcept;
347constexpr month operator+(const months& x, const month& y) noexcept;
348constexpr month operator-(const month& x, const months& y) noexcept;
349constexpr months operator-(const month& x, const month& y) noexcept;
350
351// 25.8.5, class year // C++20
352class year;
353constexpr bool operator==(const year& x, const year& y) noexcept;
354constexpr bool operator!=(const year& x, const year& y) noexcept;
355constexpr bool operator< (const year& x, const year& y) noexcept;
356constexpr bool operator> (const year& x, const year& y) noexcept;
357constexpr bool operator<=(const year& x, const year& y) noexcept;
358constexpr bool operator>=(const year& x, const year& y) noexcept;
359constexpr year operator+(const year& x, const years& y) noexcept;
360constexpr year operator+(const years& x, const year& y) noexcept;
361constexpr year operator-(const year& x, const years& y) noexcept;
362constexpr years operator-(const year& x, const year& y) noexcept;
363
364// 25.8.6, class weekday // C++20
365class weekday;
366
367constexpr bool operator==(const weekday& x, const weekday& y) noexcept;
368constexpr bool operator!=(const weekday& x, const weekday& y) noexcept;
369constexpr weekday operator+(const weekday& x, const days& y) noexcept;
370constexpr weekday operator+(const days& x, const weekday& y) noexcept;
371constexpr weekday operator-(const weekday& x, const days& y) noexcept;
372constexpr days operator-(const weekday& x, const weekday& y) noexcept;
373
374// 25.8.7, class weekday_indexed // C++20
375
376class weekday_indexed;
377constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;
378constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept;
379
380// 25.8.8, class weekday_last // C++20
381class weekday_last;
382
383constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept;
384constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept;
385
386// 25.8.9, class month_day // C++20
387class month_day;
388
389constexpr bool operator==(const month_day& x, const month_day& y) noexcept;
390constexpr bool operator!=(const month_day& x, const month_day& y) noexcept;
391constexpr bool operator< (const month_day& x, const month_day& y) noexcept;
392constexpr bool operator> (const month_day& x, const month_day& y) noexcept;
393constexpr bool operator<=(const month_day& x, const month_day& y) noexcept;
394constexpr bool operator>=(const month_day& x, const month_day& y) noexcept;
395
396
397// 25.8.10, class month_day_last // C++20
398class month_day_last;
399
400constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept;
401constexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept;
402constexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept;
403constexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept;
404constexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept;
405constexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept;
406
407// 25.8.11, class month_weekday // C++20
408class month_weekday;
409
410constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
411constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept;
412
413// 25.8.12, class month_weekday_last // C++20
414class month_weekday_last;
415
416constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
417constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept;
418
419
420// 25.8.13, class year_month // C++20
421class year_month;
422
423constexpr bool operator==(const year_month& x, const year_month& y) noexcept;
424constexpr bool operator!=(const year_month& x, const year_month& y) noexcept;
425constexpr bool operator< (const year_month& x, const year_month& y) noexcept;
426constexpr bool operator> (const year_month& x, const year_month& y) noexcept;
427constexpr bool operator<=(const year_month& x, const year_month& y) noexcept;
428constexpr bool operator>=(const year_month& x, const year_month& y) noexcept;
429
430constexpr year_month operator+(const year_month& ym, const months& dm) noexcept;
431constexpr year_month operator+(const months& dm, const year_month& ym) noexcept;
432constexpr year_month operator-(const year_month& ym, const months& dm) noexcept;
433constexpr months operator-(const year_month& x, const year_month& y) noexcept;
434constexpr year_month operator+(const year_month& ym, const years& dy) noexcept;
435constexpr year_month operator+(const years& dy, const year_month& ym) noexcept;
436constexpr year_month operator-(const year_month& ym, const years& dy) noexcept;
437
438// 25.8.14, class year_month_day class // C++20
439year_month_day;
440
441constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept;
442constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept;
443constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept;
444constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept;
445constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept;
446constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept;
447
448constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept;
449constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept;
450constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept;
451constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept;
452constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
453constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
454
455
456// 25.8.15, class year_month_day_last // C++20
457class year_month_day_last;
458
459constexpr bool operator==(const year_month_day_last& x,
460 const year_month_day_last& y) noexcept;
461constexpr bool operator!=(const year_month_day_last& x,
462 const year_month_day_last& y) noexcept;
463constexpr bool operator< (const year_month_day_last& x,
464 const year_month_day_last& y) noexcept;
465constexpr bool operator> (const year_month_day_last& x,
466 const year_month_day_last& y) noexcept;
467constexpr bool operator<=(const year_month_day_last& x,
468 const year_month_day_last& y) noexcept;
469constexpr bool operator>=(const year_month_day_last& x,
470 const year_month_day_last& y) noexcept;
471
472constexpr year_month_day_last
473 operator+(const year_month_day_last& ymdl, const months& dm) noexcept;
474constexpr year_month_day_last
475 operator+(const months& dm, const year_month_day_last& ymdl) noexcept;
476constexpr year_month_day_last
477 operator+(const year_month_day_last& ymdl, const years& dy) noexcept;
478constexpr year_month_day_last
479 operator+(const years& dy, const year_month_day_last& ymdl) noexcept;
480constexpr year_month_day_last
481 operator-(const year_month_day_last& ymdl, const months& dm) noexcept;
482constexpr year_month_day_last
483 operator-(const year_month_day_last& ymdl, const years& dy) noexcept;
484
485// 25.8.16, class year_month_weekday // C++20
486class year_month_weekday;
487
488constexpr bool operator==(const year_month_weekday& x,
489 const year_month_weekday& y) noexcept;
490constexpr bool operator!=(const year_month_weekday& x,
491 const year_month_weekday& y) noexcept;
492
493constexpr year_month_weekday
494 operator+(const year_month_weekday& ymwd, const months& dm) noexcept;
495constexpr year_month_weekday
496 operator+(const months& dm, const year_month_weekday& ymwd) noexcept;
497constexpr year_month_weekday
498 operator+(const year_month_weekday& ymwd, const years& dy) noexcept;
499constexpr year_month_weekday
500 operator+(const years& dy, const year_month_weekday& ymwd) noexcept;
501constexpr year_month_weekday
502 operator-(const year_month_weekday& ymwd, const months& dm) noexcept;
503constexpr year_month_weekday
504 operator-(const year_month_weekday& ymwd, const years& dy) noexcept;
505
506// 25.8.17, class year_month_weekday_last // C++20
507class year_month_weekday_last;
508
509constexpr bool operator==(const year_month_weekday_last& x,
510 const year_month_weekday_last& y) noexcept;
511constexpr bool operator!=(const year_month_weekday_last& x,
512 const year_month_weekday_last& y) noexcept;
513constexpr year_month_weekday_last
514 operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
515constexpr year_month_weekday_last
516 operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept;
517constexpr year_month_weekday_last
518 operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
519constexpr year_month_weekday_last
520 operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept;
521constexpr year_month_weekday_last
522 operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
523constexpr year_month_weekday_last
524 operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
Louis Dionne44bcff92018-08-03 22:36:53 +0000525
Marshall Clow40ca0c12018-07-18 17:37:51 +0000526// 25.8.18, civil calendar conventional syntax operators // C++20
527constexpr year_month
528 operator/(const year& y, const month& m) noexcept;
529constexpr year_month
530 operator/(const year& y, int m) noexcept;
531constexpr month_day
532 operator/(const month& m, const day& d) noexcept;
533constexpr month_day
534 operator/(const month& m, int d) noexcept;
535constexpr month_day
536 operator/(int m, const day& d) noexcept;
537constexpr month_day
538 operator/(const day& d, const month& m) noexcept;
539constexpr month_day
540 operator/(const day& d, int m) noexcept;
541constexpr month_day_last
542 operator/(const month& m, last_spec) noexcept;
543constexpr month_day_last
544 operator/(int m, last_spec) noexcept;
545constexpr month_day_last
546 operator/(last_spec, const month& m) noexcept;
547constexpr month_day_last
548 operator/(last_spec, int m) noexcept;
549constexpr month_weekday
550 operator/(const month& m, const weekday_indexed& wdi) noexcept;
551constexpr month_weekday
552 operator/(int m, const weekday_indexed& wdi) noexcept;
553constexpr month_weekday
554 operator/(const weekday_indexed& wdi, const month& m) noexcept;
555constexpr month_weekday
556 operator/(const weekday_indexed& wdi, int m) noexcept;
557constexpr month_weekday_last
558 operator/(const month& m, const weekday_last& wdl) noexcept;
559constexpr month_weekday_last
560 operator/(int m, const weekday_last& wdl) noexcept;
561constexpr month_weekday_last
562 operator/(const weekday_last& wdl, const month& m) noexcept;
563constexpr month_weekday_last
564 operator/(const weekday_last& wdl, int m) noexcept;
565constexpr year_month_day
566 operator/(const year_month& ym, const day& d) noexcept;
567constexpr year_month_day
568 operator/(const year_month& ym, int d) noexcept;
569constexpr year_month_day
570 operator/(const year& y, const month_day& md) noexcept;
571constexpr year_month_day
572 operator/(int y, const month_day& md) noexcept;
573constexpr year_month_day
574 operator/(const month_day& md, const year& y) noexcept;
575constexpr year_month_day
576 operator/(const month_day& md, int y) noexcept;
577constexpr year_month_day_last
578 operator/(const year_month& ym, last_spec) noexcept;
579constexpr year_month_day_last
580 operator/(const year& y, const month_day_last& mdl) noexcept;
581constexpr year_month_day_last
582 operator/(int y, const month_day_last& mdl) noexcept;
583constexpr year_month_day_last
584 operator/(const month_day_last& mdl, const year& y) noexcept;
585constexpr year_month_day_last
586 operator/(const month_day_last& mdl, int y) noexcept;
587constexpr year_month_weekday
588 operator/(const year_month& ym, const weekday_indexed& wdi) noexcept;
589constexpr year_month_weekday
590 operator/(const year& y, const month_weekday& mwd) noexcept;
591constexpr year_month_weekday
592 operator/(int y, const month_weekday& mwd) noexcept;
593constexpr year_month_weekday
594 operator/(const month_weekday& mwd, const year& y) noexcept;
595constexpr year_month_weekday
596 operator/(const month_weekday& mwd, int y) noexcept;
597constexpr year_month_weekday_last
598 operator/(const year_month& ym, const weekday_last& wdl) noexcept;
599constexpr year_month_weekday_last
600 operator/(const year& y, const month_weekday_last& mwdl) noexcept;
601constexpr year_month_weekday_last
602 operator/(int y, const month_weekday_last& mwdl) noexcept;
603constexpr year_month_weekday_last
604 operator/(const month_weekday_last& mwdl, const year& y) noexcept;
605constexpr year_month_weekday_last
Louis Dionne44bcff92018-08-03 22:36:53 +0000606 operator/(const month_weekday_last& mwdl, int y) noexcept;
Marshall Clow40ca0c12018-07-18 17:37:51 +0000607
Marshall Clow748d1a62019-08-08 14:36:07 +0000608// 26.9, class template hh_mm_ss
609template <class Duration>
610class hh_mm_ss
611{
612 bool is_neg; // exposition only
613 chrono::hours h; // exposition only
614 chrono::minutes m; // exposition only
615 chrono::seconds s; // exposition only
616 precision ss; // exposition only
Marshall Clow40ca0c12018-07-18 17:37:51 +0000617
Marshall Clow748d1a62019-08-08 14:36:07 +0000618public:
619 static unsigned constexpr fractional_width = see below;
620 using precision = see below;
621
622 constexpr hh_mm_ss() noexcept : hh_mm_ss{Duration::zero()} {}
623 constexpr explicit hh_mm_ss(Duration d) noexcept;
624
625 constexpr bool is_negative() const noexcept;
626 constexpr chrono::hours hours() const noexcept;
627 constexpr chrono::minutes minutes() const noexcept;
628 constexpr chrono::seconds seconds() const noexcept;
629 constexpr precision subseconds() const noexcept;
630
631 constexpr explicit operator precision() const noexcept;
632 constexpr precision to_duration() const noexcept;
633};
634
Marshall Clow748d1a62019-08-08 14:36:07 +0000635// 26.10, 12/24 hour functions
636constexpr bool is_am(hours const& h) noexcept;
637constexpr bool is_pm(hours const& h) noexcept;
638constexpr hours make12(const hours& h) noexcept;
639constexpr hours make24(const hours& h, bool is_pm) noexcept;
640
Marshall Clow40ca0c12018-07-18 17:37:51 +0000641// 25.10.5, class time_zone // C++20
642enum class choose {earliest, latest};
643class time_zone;
644bool operator==(const time_zone& x, const time_zone& y) noexcept;
645bool operator!=(const time_zone& x, const time_zone& y) noexcept;
646bool operator<(const time_zone& x, const time_zone& y) noexcept;
647bool operator>(const time_zone& x, const time_zone& y) noexcept;
648bool operator<=(const time_zone& x, const time_zone& y) noexcept;
649bool operator>=(const time_zone& x, const time_zone& y) noexcept;
Louis Dionne44bcff92018-08-03 22:36:53 +0000650
Marshall Clow26058352018-10-16 17:27:54 +0000651// calendrical constants
Louis Dionne44bcff92018-08-03 22:36:53 +0000652inline constexpr last_spec last{}; // C++20
Marshall Clow40ca0c12018-07-18 17:37:51 +0000653inline constexpr chrono::weekday Sunday{0}; // C++20
654inline constexpr chrono::weekday Monday{1}; // C++20
655inline constexpr chrono::weekday Tuesday{2}; // C++20
656inline constexpr chrono::weekday Wednesday{3}; // C++20
657inline constexpr chrono::weekday Thursday{4}; // C++20
658inline constexpr chrono::weekday Friday{5}; // C++20
659inline constexpr chrono::weekday Saturday{6}; // C++20
660
661inline constexpr chrono::month January{1}; // C++20
662inline constexpr chrono::month February{2}; // C++20
663inline constexpr chrono::month March{3}; // C++20
664inline constexpr chrono::month April{4}; // C++20
665inline constexpr chrono::month May{5}; // C++20
666inline constexpr chrono::month June{6}; // C++20
667inline constexpr chrono::month July{7}; // C++20
668inline constexpr chrono::month August{8}; // C++20
669inline constexpr chrono::month September{9}; // C++20
670inline constexpr chrono::month October{10}; // C++20
671inline constexpr chrono::month November{11}; // C++20
672inline constexpr chrono::month December{12}; // C++20
Howard Hinnantc51e1022010-05-11 19:42:16 +0000673} // chrono
674
Marshall Clow40ca0c12018-07-18 17:37:51 +0000675inline namespace literals {
676 inline namespace chrono_literals {
Marshall Clow2ac805a2017-08-09 15:42:50 +0000677constexpr chrono::hours operator ""h(unsigned long long); // C++14
678constexpr chrono::duration<unspecified , ratio<3600,1>> operator ""h(long double); // C++14
679constexpr chrono::minutes operator ""min(unsigned long long); // C++14
680constexpr chrono::duration<unspecified , ratio<60,1>> operator ""min(long double); // C++14
681constexpr chrono::seconds operator ""s(unsigned long long); // C++14
682constexpr chrono::duration<unspecified > operator ""s(long double); // C++14
683constexpr chrono::milliseconds operator ""ms(unsigned long long); // C++14
684constexpr chrono::duration<unspecified , milli> operator ""ms(long double); // C++14
685constexpr chrono::microseconds operator ""us(unsigned long long); // C++14
686constexpr chrono::duration<unspecified , micro> operator ""us(long double); // C++14
687constexpr chrono::nanoseconds operator ""ns(unsigned long long); // C++14
688constexpr chrono::duration<unspecified , nano> operator ""ns(long double); // C++14
Marshall Clow40ca0c12018-07-18 17:37:51 +0000689constexpr chrono::day operator ""d(unsigned long long d) noexcept; // C++20
690constexpr chrono::year operator ""y(unsigned long long y) noexcept; // C++20
691} // chrono_literals
692} // literals
Marshall Cloweb41e5c2013-07-24 21:18:14 +0000693
Howard Hinnantc51e1022010-05-11 19:42:16 +0000694} // std
695*/
696
Louis Dionne73912b22020-11-04 15:01:25 -0500697#include <__availability>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400698#include <__config>
Arthur O'Dwyer7deec122021-03-24 18:19:12 -0400699#include <compare>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000700#include <ctime>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000701#include <limits>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400702#include <ratio>
703#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000704#include <version>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000705
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000706#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000707#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000708#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000709
Eric Fiselierf4433a32017-05-31 22:07:49 +0000710_LIBCPP_PUSH_MACROS
711#include <__undef_macros>
712
Eric Fiselier4dcc2542018-12-21 04:30:04 +0000713#ifndef _LIBCPP_CXX03_LANG
Eric Fiselier049273c2018-12-21 03:54:57 +0000714_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
715struct _FilesystemClock;
716_LIBCPP_END_NAMESPACE_FILESYSTEM
Eric Fiselier4dcc2542018-12-21 04:30:04 +0000717#endif // !_LIBCPP_CXX03_LANG
Eric Fiselierf4433a32017-05-31 22:07:49 +0000718
Howard Hinnantc51e1022010-05-11 19:42:16 +0000719_LIBCPP_BEGIN_NAMESPACE_STD
720
721namespace chrono
722{
723
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000724template <class _Rep, class _Period = ratio<1> > class _LIBCPP_TEMPLATE_VIS duration;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000725
Howard Hinnantf39463b2010-05-18 17:32:30 +0000726template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000727struct __is_duration : false_type {};
728
729template <class _Rep, class _Period>
730struct __is_duration<duration<_Rep, _Period> > : true_type {};
731
732template <class _Rep, class _Period>
733struct __is_duration<const duration<_Rep, _Period> > : true_type {};
734
735template <class _Rep, class _Period>
736struct __is_duration<volatile duration<_Rep, _Period> > : true_type {};
737
738template <class _Rep, class _Period>
739struct __is_duration<const volatile duration<_Rep, _Period> > : true_type {};
740
Nikolas Klauserd26407a2021-12-02 14:12:51 +0100741} // namespace chrono
Howard Hinnantc51e1022010-05-11 19:42:16 +0000742
743template <class _Rep1, class _Period1, class _Rep2, class _Period2>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000744struct _LIBCPP_TEMPLATE_VIS common_type<chrono::duration<_Rep1, _Period1>,
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000745 chrono::duration<_Rep2, _Period2> >
Howard Hinnantc51e1022010-05-11 19:42:16 +0000746{
747 typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
748 typename __ratio_gcd<_Period1, _Period2>::type> type;
749};
750
751namespace chrono {
752
753// duration_cast
754
755template <class _FromDuration, class _ToDuration,
756 class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type,
757 bool = _Period::num == 1,
758 bool = _Period::den == 1>
759struct __duration_cast;
760
761template <class _FromDuration, class _ToDuration, class _Period>
762struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true>
763{
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000764 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000765 _ToDuration operator()(const _FromDuration& __fd) const
766 {
767 return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count()));
768 }
769};
770
771template <class _FromDuration, class _ToDuration, class _Period>
772struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false>
773{
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000774 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000775 _ToDuration operator()(const _FromDuration& __fd) const
776 {
777 typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
778 return _ToDuration(static_cast<typename _ToDuration::rep>(
779 static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den)));
780 }
781};
782
783template <class _FromDuration, class _ToDuration, class _Period>
784struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true>
785{
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000786 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000787 _ToDuration operator()(const _FromDuration& __fd) const
788 {
789 typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
790 return _ToDuration(static_cast<typename _ToDuration::rep>(
791 static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)));
792 }
793};
794
795template <class _FromDuration, class _ToDuration, class _Period>
796struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false>
797{
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000798 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000799 _ToDuration operator()(const _FromDuration& __fd) const
800 {
801 typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
802 return _ToDuration(static_cast<typename _ToDuration::rep>(
803 static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)
804 / static_cast<_Ct>(_Period::den)));
805 }
806};
807
808template <class _ToDuration, class _Rep, class _Period>
809inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000810_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000811typename enable_if
812<
813 __is_duration<_ToDuration>::value,
814 _ToDuration
815>::type
816duration_cast(const duration<_Rep, _Period>& __fd)
817{
818 return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);
819}
820
Howard Hinnant874ad9a2010-09-21 21:28:23 +0000821template <class _Rep>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000822struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {};
Howard Hinnantc51e1022010-05-11 19:42:16 +0000823
Louis Dionne7acc4fd2021-09-22 09:46:19 -0400824#if _LIBCPP_STD_VER > 14
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000825template <class _Rep>
Louis Dionne559be102021-09-22 09:35:32 -0400826inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value;
Marshall Clow59581f02015-11-30 05:39:30 +0000827#endif
828
Howard Hinnantc51e1022010-05-11 19:42:16 +0000829template <class _Rep>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000830struct _LIBCPP_TEMPLATE_VIS duration_values
Howard Hinnantc51e1022010-05-11 19:42:16 +0000831{
832public:
Marshall Clowb1296bd2018-11-13 17:22:41 +0000833 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);}
834 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();}
835 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000836};
837
Marshall Clowf2eabaf2015-11-05 19:33:59 +0000838#if _LIBCPP_STD_VER > 14
839template <class _ToDuration, class _Rep, class _Period>
840inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
841typename enable_if
842<
843 __is_duration<_ToDuration>::value,
844 _ToDuration
845>::type
846floor(const duration<_Rep, _Period>& __d)
847{
848 _ToDuration __t = duration_cast<_ToDuration>(__d);
849 if (__t > __d)
850 __t = __t - _ToDuration{1};
851 return __t;
852}
853
854template <class _ToDuration, class _Rep, class _Period>
855inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
856typename enable_if
857<
858 __is_duration<_ToDuration>::value,
859 _ToDuration
860>::type
861ceil(const duration<_Rep, _Period>& __d)
862{
863 _ToDuration __t = duration_cast<_ToDuration>(__d);
864 if (__t < __d)
865 __t = __t + _ToDuration{1};
866 return __t;
867}
868
869template <class _ToDuration, class _Rep, class _Period>
870inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
871typename enable_if
872<
873 __is_duration<_ToDuration>::value,
874 _ToDuration
875>::type
876round(const duration<_Rep, _Period>& __d)
877{
878 _ToDuration __lower = floor<_ToDuration>(__d);
879 _ToDuration __upper = __lower + _ToDuration{1};
880 auto __lowerDiff = __d - __lower;
881 auto __upperDiff = __upper - __d;
882 if (__lowerDiff < __upperDiff)
883 return __lower;
884 if (__lowerDiff > __upperDiff)
885 return __upper;
886 return __lower.count() & 1 ? __upper : __lower;
887}
888#endif
889
Howard Hinnantc51e1022010-05-11 19:42:16 +0000890// duration
891
892template <class _Rep, class _Period>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000893class _LIBCPP_TEMPLATE_VIS duration
Howard Hinnantc51e1022010-05-11 19:42:16 +0000894{
895 static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration");
896 static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio");
897 static_assert(_Period::num > 0, "duration period must be positive");
Howard Hinnant0a51e152013-08-31 16:51:56 +0000898
899 template <class _R1, class _R2>
900 struct __no_overflow
901 {
902 private:
903 static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
904 static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
905 static const intmax_t __n1 = _R1::num / __gcd_n1_n2;
906 static const intmax_t __d1 = _R1::den / __gcd_d1_d2;
907 static const intmax_t __n2 = _R2::num / __gcd_n1_n2;
908 static const intmax_t __d2 = _R2::den / __gcd_d1_d2;
909 static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);
910
911 template <intmax_t _Xp, intmax_t _Yp, bool __overflow>
912 struct __mul // __overflow == false
913 {
914 static const intmax_t value = _Xp * _Yp;
915 };
916
917 template <intmax_t _Xp, intmax_t _Yp>
918 struct __mul<_Xp, _Yp, true>
919 {
920 static const intmax_t value = 1;
921 };
922
923 public:
924 static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1);
925 typedef ratio<__mul<__n1, __d2, !value>::value,
926 __mul<__n2, __d1, !value>::value> type;
927 };
Louis Dionne44bcff92018-08-03 22:36:53 +0000928
Howard Hinnantc51e1022010-05-11 19:42:16 +0000929public:
930 typedef _Rep rep;
Marshall Clow76200b22017-03-21 18:38:57 +0000931 typedef typename _Period::type period;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000932private:
933 rep __rep_;
934public:
935
Marshall Clow5c459c92013-07-31 19:32:19 +0000936 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselier07b2b552016-11-18 06:42:17 +0000937#ifndef _LIBCPP_CXX03_LANG
Marshall Clow2e89c4d2019-09-23 06:16:41 +0000938 duration() = default;
Marshall Clow3dbcf132013-07-31 19:39:37 +0000939#else
940 duration() {}
Marshall Clow5c459c92013-07-31 19:32:19 +0000941#endif
942
Howard Hinnantc51e1022010-05-11 19:42:16 +0000943 template <class _Rep2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000944 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000945 explicit duration(const _Rep2& __r,
946 typename enable_if
947 <
948 is_convertible<_Rep2, rep>::value &&
949 (treat_as_floating_point<rep>::value ||
950 !treat_as_floating_point<_Rep2>::value)
Bruce Mitchener170d8972020-11-24 12:53:53 -0500951 >::type* = nullptr)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000952 : __rep_(__r) {}
953
954 // conversions
955 template <class _Rep2, class _Period2>
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000956 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000957 duration(const duration<_Rep2, _Period2>& __d,
958 typename enable_if
959 <
Howard Hinnant0a51e152013-08-31 16:51:56 +0000960 __no_overflow<_Period2, period>::value && (
Howard Hinnantc51e1022010-05-11 19:42:16 +0000961 treat_as_floating_point<rep>::value ||
Howard Hinnant0a51e152013-08-31 16:51:56 +0000962 (__no_overflow<_Period2, period>::type::den == 1 &&
963 !treat_as_floating_point<_Rep2>::value))
Bruce Mitchener170d8972020-11-24 12:53:53 -0500964 >::type* = nullptr)
Arthur O'Dwyer9b374cc2021-05-10 13:19:07 -0400965 : __rep_(chrono::duration_cast<duration>(__d).count()) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000966
967 // observer
968
Howard Hinnantcf3143c2012-07-13 19:17:27 +0000969 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000970
971 // arithmetic
972
Marshall Clow76200b22017-03-21 18:38:57 +0000973 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {return typename common_type<duration>::type(*this);}
974 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {return typename common_type<duration>::type(-__rep_);}
Marshall Clow5c87ad02017-01-04 23:03:24 +0000975 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator++() {++__rep_; return *this;}
976 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator++(int) {return duration(__rep_++);}
977 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator--() {--__rep_; return *this;}
978 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator--(int) {return duration(__rep_--);}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000979
Marshall Clow5c87ad02017-01-04 23:03:24 +0000980 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;}
981 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000982
Marshall Clow5c87ad02017-01-04 23:03:24 +0000983 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;}
984 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;}
985 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;}
986 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000987
988 // special values
989
Marshall Clowb1296bd2018-11-13 17:22:41 +0000990 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values<rep>::zero());}
991 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values<rep>::min());}
992 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values<rep>::max());}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000993};
994
995typedef duration<long long, nano> nanoseconds;
996typedef duration<long long, micro> microseconds;
997typedef duration<long long, milli> milliseconds;
998typedef duration<long long > seconds;
999typedef duration< long, ratio< 60> > minutes;
1000typedef duration< long, ratio<3600> > hours;
Marshall Clow26058352018-10-16 17:27:54 +00001001#if _LIBCPP_STD_VER > 17
1002typedef duration< int, ratio_multiply<ratio<24>, hours::period>> days;
1003typedef duration< int, ratio_multiply<ratio<7>, days::period>> weeks;
1004typedef duration< int, ratio_multiply<ratio<146097, 400>, days::period>> years;
1005typedef duration< int, ratio_divide<years::period, ratio<12>>> months;
1006#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001007// Duration ==
1008
1009template <class _LhsDuration, class _RhsDuration>
1010struct __duration_eq
1011{
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001012 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Howard Hinnant12967fb2013-06-28 18:09:35 +00001013 bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00001014 {
1015 typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
1016 return _Ct(__lhs).count() == _Ct(__rhs).count();
1017 }
1018};
1019
1020template <class _LhsDuration>
1021struct __duration_eq<_LhsDuration, _LhsDuration>
1022{
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001023 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Howard Hinnant12967fb2013-06-28 18:09:35 +00001024 bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00001025 {return __lhs.count() == __rhs.count();}
1026};
1027
1028template <class _Rep1, class _Period1, class _Rep2, class _Period2>
1029inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001030_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001031bool
1032operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1033{
1034 return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
1035}
1036
1037// Duration !=
1038
1039template <class _Rep1, class _Period1, class _Rep2, class _Period2>
1040inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001041_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001042bool
1043operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1044{
1045 return !(__lhs == __rhs);
1046}
1047
1048// Duration <
1049
1050template <class _LhsDuration, class _RhsDuration>
1051struct __duration_lt
1052{
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001053 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Howard Hinnant12967fb2013-06-28 18:09:35 +00001054 bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00001055 {
1056 typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
1057 return _Ct(__lhs).count() < _Ct(__rhs).count();
1058 }
1059};
1060
1061template <class _LhsDuration>
1062struct __duration_lt<_LhsDuration, _LhsDuration>
1063{
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001064 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Howard Hinnant12967fb2013-06-28 18:09:35 +00001065 bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00001066 {return __lhs.count() < __rhs.count();}
1067};
1068
1069template <class _Rep1, class _Period1, class _Rep2, class _Period2>
1070inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001071_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001072bool
1073operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1074{
1075 return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
1076}
1077
1078// Duration >
1079
1080template <class _Rep1, class _Period1, class _Rep2, class _Period2>
1081inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001082_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001083bool
1084operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1085{
1086 return __rhs < __lhs;
1087}
1088
1089// Duration <=
1090
1091template <class _Rep1, class _Period1, class _Rep2, class _Period2>
1092inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001093_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001094bool
1095operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1096{
1097 return !(__rhs < __lhs);
1098}
1099
1100// Duration >=
1101
1102template <class _Rep1, class _Period1, class _Rep2, class _Period2>
1103inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001104_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001105bool
1106operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1107{
1108 return !(__lhs < __rhs);
1109}
1110
1111// Duration +
1112
1113template <class _Rep1, class _Period1, class _Rep2, class _Period2>
1114inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001115_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001116typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
1117operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1118{
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001119 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
1120 return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001121}
1122
1123// Duration -
1124
1125template <class _Rep1, class _Period1, class _Rep2, class _Period2>
1126inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001127_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001128typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
1129operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1130{
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001131 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
1132 return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count());
Howard Hinnantc51e1022010-05-11 19:42:16 +00001133}
1134
1135// Duration *
1136
1137template <class _Rep1, class _Period, class _Rep2>
1138inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001139_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001140typename enable_if
1141<
1142 is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
1143 duration<typename common_type<_Rep1, _Rep2>::type, _Period>
1144>::type
1145operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
1146{
1147 typedef typename common_type<_Rep1, _Rep2>::type _Cr;
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001148 typedef duration<_Cr, _Period> _Cd;
1149 return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001150}
1151
1152template <class _Rep1, class _Period, class _Rep2>
1153inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001154_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001155typename enable_if
1156<
1157 is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value,
1158 duration<typename common_type<_Rep1, _Rep2>::type, _Period>
1159>::type
1160operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)
1161{
1162 return __d * __s;
1163}
1164
1165// Duration /
1166
Howard Hinnantc51e1022010-05-11 19:42:16 +00001167template <class _Rep1, class _Period, class _Rep2>
1168inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001169_LIBCPP_CONSTEXPR
Marshall Clowb8f3cd02019-04-01 16:38:02 +00001170typename enable_if
1171<
1172 !__is_duration<_Rep2>::value &&
1173 is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
1174 duration<typename common_type<_Rep1, _Rep2>::type, _Period>
1175>::type
Howard Hinnantc51e1022010-05-11 19:42:16 +00001176operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
1177{
1178 typedef typename common_type<_Rep1, _Rep2>::type _Cr;
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001179 typedef duration<_Cr, _Period> _Cd;
1180 return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001181}
1182
1183template <class _Rep1, class _Period1, class _Rep2, class _Period2>
1184inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001185_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001186typename common_type<_Rep1, _Rep2>::type
1187operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1188{
1189 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct;
1190 return _Ct(__lhs).count() / _Ct(__rhs).count();
1191}
1192
1193// Duration %
1194
1195template <class _Rep1, class _Period, class _Rep2>
1196inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001197_LIBCPP_CONSTEXPR
Marshall Clowb8f3cd02019-04-01 16:38:02 +00001198typename enable_if
1199<
1200 !__is_duration<_Rep2>::value &&
1201 is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
1202 duration<typename common_type<_Rep1, _Rep2>::type, _Period>
1203>::type
Howard Hinnantc51e1022010-05-11 19:42:16 +00001204operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
1205{
1206 typedef typename common_type<_Rep1, _Rep2>::type _Cr;
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001207 typedef duration<_Cr, _Period> _Cd;
1208 return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001209}
1210
1211template <class _Rep1, class _Period1, class _Rep2, class _Period2>
1212inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001213_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +00001214typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
1215operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1216{
Howard Hinnantcf3143c2012-07-13 19:17:27 +00001217 typedef typename common_type<_Rep1, _Rep2>::type _Cr;
1218 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
1219 return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001220}
1221
1222//////////////////////////////////////////////////////////
1223///////////////////// time_point /////////////////////////
1224//////////////////////////////////////////////////////////
1225
1226template <class _Clock, class _Duration = typename _Clock::duration>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001227class _LIBCPP_TEMPLATE_VIS time_point
Howard Hinnantc51e1022010-05-11 19:42:16 +00001228{
1229 static_assert(__is_duration<_Duration>::value,
1230 "Second template parameter of time_point must be a std::chrono::duration");
1231public:
1232 typedef _Clock clock;
1233 typedef _Duration duration;
1234 typedef typename duration::rep rep;
1235 typedef typename duration::period period;
1236private:
1237 duration __d_;
1238
1239public:
Marshall Clow5c459c92013-07-31 19:32:19 +00001240 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {}
1241 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001242
1243 // conversions
1244 template <class _Duration2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001245 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001246 time_point(const time_point<clock, _Duration2>& t,
1247 typename enable_if
1248 <
1249 is_convertible<_Duration2, duration>::value
Bruce Mitchener170d8972020-11-24 12:53:53 -05001250 >::type* = nullptr)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001251 : __d_(t.time_since_epoch()) {}
1252
1253 // observer
1254
Marshall Clow5c459c92013-07-31 19:32:19 +00001255 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001256
1257 // arithmetic
1258
Marshall Clowdf247eb2018-08-29 23:02:15 +00001259 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;}
1260 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001261
1262 // special values
1263
Marshall Clowb1296bd2018-11-13 17:22:41 +00001264 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());}
1265 _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001266};
1267
Nikolas Klauserd26407a2021-12-02 14:12:51 +01001268} // namespace chrono
Howard Hinnantc51e1022010-05-11 19:42:16 +00001269
1270template <class _Clock, class _Duration1, class _Duration2>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001271struct _LIBCPP_TEMPLATE_VIS common_type<chrono::time_point<_Clock, _Duration1>,
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001272 chrono::time_point<_Clock, _Duration2> >
Howard Hinnantc51e1022010-05-11 19:42:16 +00001273{
1274 typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type;
1275};
1276
1277namespace chrono {
1278
1279template <class _ToDuration, class _Clock, class _Duration>
Marshall Clow5c459c92013-07-31 19:32:19 +00001280inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001281time_point<_Clock, _ToDuration>
1282time_point_cast(const time_point<_Clock, _Duration>& __t)
1283{
Arthur O'Dwyer9b374cc2021-05-10 13:19:07 -04001284 return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001285}
1286
Marshall Clowf2eabaf2015-11-05 19:33:59 +00001287#if _LIBCPP_STD_VER > 14
1288template <class _ToDuration, class _Clock, class _Duration>
1289inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1290typename enable_if
1291<
1292 __is_duration<_ToDuration>::value,
1293 time_point<_Clock, _ToDuration>
1294>::type
1295floor(const time_point<_Clock, _Duration>& __t)
1296{
1297 return time_point<_Clock, _ToDuration>{floor<_ToDuration>(__t.time_since_epoch())};
1298}
1299
1300template <class _ToDuration, class _Clock, class _Duration>
1301inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1302typename enable_if
1303<
1304 __is_duration<_ToDuration>::value,
1305 time_point<_Clock, _ToDuration>
1306>::type
1307ceil(const time_point<_Clock, _Duration>& __t)
1308{
1309 return time_point<_Clock, _ToDuration>{ceil<_ToDuration>(__t.time_since_epoch())};
1310}
1311
1312template <class _ToDuration, class _Clock, class _Duration>
1313inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1314typename enable_if
1315<
1316 __is_duration<_ToDuration>::value,
1317 time_point<_Clock, _ToDuration>
1318>::type
1319round(const time_point<_Clock, _Duration>& __t)
1320{
1321 return time_point<_Clock, _ToDuration>{round<_ToDuration>(__t.time_since_epoch())};
1322}
1323
1324template <class _Rep, class _Period>
1325inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1326typename enable_if
1327<
1328 numeric_limits<_Rep>::is_signed,
1329 duration<_Rep, _Period>
1330>::type
1331abs(duration<_Rep, _Period> __d)
1332{
Marshall Clow46a4ce82019-07-26 15:10:46 +00001333 return __d >= __d.zero() ? +__d : -__d;
Marshall Clowf2eabaf2015-11-05 19:33:59 +00001334}
1335#endif
1336
Howard Hinnantc51e1022010-05-11 19:42:16 +00001337// time_point ==
1338
1339template <class _Clock, class _Duration1, class _Duration2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001340inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001341bool
1342operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1343{
1344 return __lhs.time_since_epoch() == __rhs.time_since_epoch();
1345}
1346
1347// time_point !=
1348
1349template <class _Clock, class _Duration1, class _Duration2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001350inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001351bool
1352operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1353{
1354 return !(__lhs == __rhs);
1355}
1356
1357// time_point <
1358
1359template <class _Clock, class _Duration1, class _Duration2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001360inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001361bool
1362operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1363{
1364 return __lhs.time_since_epoch() < __rhs.time_since_epoch();
1365}
1366
1367// time_point >
1368
1369template <class _Clock, class _Duration1, class _Duration2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001370inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001371bool
1372operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1373{
1374 return __rhs < __lhs;
1375}
1376
1377// time_point <=
1378
1379template <class _Clock, class _Duration1, class _Duration2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001380inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001381bool
1382operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1383{
1384 return !(__rhs < __lhs);
1385}
1386
1387// time_point >=
1388
1389template <class _Clock, class _Duration1, class _Duration2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001390inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001391bool
1392operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1393{
1394 return !(__lhs < __rhs);
1395}
1396
1397// time_point operator+(time_point x, duration y);
1398
1399template <class _Clock, class _Duration1, class _Rep2, class _Period2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001400inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001401time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
1402operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1403{
1404 typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
Marshall Clow5c459c92013-07-31 19:32:19 +00001405 return _Tr (__lhs.time_since_epoch() + __rhs);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001406}
1407
1408// time_point operator+(duration x, time_point y);
1409
1410template <class _Rep1, class _Period1, class _Clock, class _Duration2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001411inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001412time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
1413operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1414{
1415 return __rhs + __lhs;
1416}
1417
1418// time_point operator-(time_point x, duration y);
1419
1420template <class _Clock, class _Duration1, class _Rep2, class _Period2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001421inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001422time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
1423operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1424{
Marshall Clow78dbe462016-11-14 18:22:19 +00001425 typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret;
1426 return _Ret(__lhs.time_since_epoch() -__rhs);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001427}
1428
1429// duration operator-(time_point x, time_point y);
1430
1431template <class _Clock, class _Duration1, class _Duration2>
Marshall Clow5c459c92013-07-31 19:32:19 +00001432inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +00001433typename common_type<_Duration1, _Duration2>::type
1434operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1435{
1436 return __lhs.time_since_epoch() - __rhs.time_since_epoch();
1437}
1438
1439//////////////////////////////////////////////////////////
1440/////////////////////// clocks ///////////////////////////
1441//////////////////////////////////////////////////////////
1442
Howard Hinnant8331b762013-03-06 23:30:19 +00001443class _LIBCPP_TYPE_VIS system_clock
Howard Hinnantc51e1022010-05-11 19:42:16 +00001444{
1445public:
1446 typedef microseconds duration;
1447 typedef duration::rep rep;
1448 typedef duration::period period;
1449 typedef chrono::time_point<system_clock> time_point;
Marshall Clow5c459c92013-07-31 19:32:19 +00001450 static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001451
Howard Hinnantaa54ac42011-05-28 18:34:36 +00001452 static time_point now() _NOEXCEPT;
1453 static time_t to_time_t (const time_point& __t) _NOEXCEPT;
1454 static time_point from_time_t(time_t __t) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001455};
1456
Jonathan Roelofscce96eb2014-09-02 21:14:38 +00001457#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
Howard Hinnant8331b762013-03-06 23:30:19 +00001458class _LIBCPP_TYPE_VIS steady_clock
Howard Hinnantc51e1022010-05-11 19:42:16 +00001459{
1460public:
1461 typedef nanoseconds duration;
1462 typedef duration::rep rep;
1463 typedef duration::period period;
Howard Hinnantc8dbd222010-11-20 19:16:30 +00001464 typedef chrono::time_point<steady_clock, duration> time_point;
Marshall Clow5c459c92013-07-31 19:32:19 +00001465 static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001466
Howard Hinnantaa54ac42011-05-28 18:34:36 +00001467 static time_point now() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001468};
1469
Howard Hinnantc8dbd222010-11-20 19:16:30 +00001470typedef steady_clock high_resolution_clock;
Jonathan Roelofscce96eb2014-09-02 21:14:38 +00001471#else
1472typedef system_clock high_resolution_clock;
1473#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001474
Marshall Clow26058352018-10-16 17:27:54 +00001475#if _LIBCPP_STD_VER > 17
Eric Fiselier049273c2018-12-21 03:54:57 +00001476// [time.clock.file], type file_clock
1477using file_clock = _VSTD_FS::_FilesystemClock;
1478
1479template<class _Duration>
1480using file_time = time_point<file_clock, _Duration>;
Marshall Clow26058352018-10-16 17:27:54 +00001481
Marshall Clow188b3342019-01-11 15:12:04 +00001482
1483template <class _Duration>
1484using sys_time = time_point<system_clock, _Duration>;
1485using sys_seconds = sys_time<seconds>;
1486using sys_days = sys_time<days>;
1487
1488struct local_t {};
1489template<class Duration>
1490using local_time = time_point<local_t, Duration>;
1491using local_seconds = local_time<seconds>;
1492using local_days = local_time<days>;
1493
1494
Eric Fiselier28bc4292019-03-21 01:48:15 +00001495struct last_spec { explicit last_spec() = default; };
Marshall Clow26058352018-10-16 17:27:54 +00001496
Eric Fiselier28bc4292019-03-21 01:48:15 +00001497class day {
Marshall Clow26058352018-10-16 17:27:54 +00001498private:
1499 unsigned char __d;
1500public:
1501 day() = default;
1502 explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {}
1503 inline constexpr day& operator++() noexcept { ++__d; return *this; }
1504 inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; }
1505 inline constexpr day& operator--() noexcept { --__d; return *this; }
1506 inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; }
1507 constexpr day& operator+=(const days& __dd) noexcept;
1508 constexpr day& operator-=(const days& __dd) noexcept;
1509 explicit inline constexpr operator unsigned() const noexcept { return __d; }
1510 inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; }
1511 };
1512
1513
1514inline constexpr
1515bool operator==(const day& __lhs, const day& __rhs) noexcept
1516{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
1517
1518inline constexpr
1519bool operator!=(const day& __lhs, const day& __rhs) noexcept
1520{ return !(__lhs == __rhs); }
1521
1522inline constexpr
1523bool operator< (const day& __lhs, const day& __rhs) noexcept
1524{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
1525
1526inline constexpr
1527bool operator> (const day& __lhs, const day& __rhs) noexcept
1528{ return __rhs < __lhs; }
1529
1530inline constexpr
1531bool operator<=(const day& __lhs, const day& __rhs) noexcept
1532{ return !(__rhs < __lhs);}
1533
1534inline constexpr
1535bool operator>=(const day& __lhs, const day& __rhs) noexcept
1536{ return !(__lhs < __rhs); }
1537
1538inline constexpr
1539day operator+ (const day& __lhs, const days& __rhs) noexcept
1540{ return day(static_cast<unsigned>(__lhs) + __rhs.count()); }
1541
1542inline constexpr
1543day operator+ (const days& __lhs, const day& __rhs) noexcept
1544{ return __rhs + __lhs; }
1545
1546inline constexpr
1547day operator- (const day& __lhs, const days& __rhs) noexcept
1548{ return __lhs + -__rhs; }
1549
1550inline constexpr
1551days operator-(const day& __lhs, const day& __rhs) noexcept
1552{ return days(static_cast<int>(static_cast<unsigned>(__lhs)) -
1553 static_cast<int>(static_cast<unsigned>(__rhs))); }
1554
1555inline constexpr day& day::operator+=(const days& __dd) noexcept
1556{ *this = *this + __dd; return *this; }
1557
1558inline constexpr day& day::operator-=(const days& __dd) noexcept
1559{ *this = *this - __dd; return *this; }
1560
1561
Eric Fiselier28bc4292019-03-21 01:48:15 +00001562class month {
Marshall Clow26058352018-10-16 17:27:54 +00001563private:
1564 unsigned char __m;
1565public:
1566 month() = default;
1567 explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {}
1568 inline constexpr month& operator++() noexcept { ++__m; return *this; }
1569 inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; }
1570 inline constexpr month& operator--() noexcept { --__m; return *this; }
1571 inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; }
1572 constexpr month& operator+=(const months& __m1) noexcept;
1573 constexpr month& operator-=(const months& __m1) noexcept;
1574 explicit inline constexpr operator unsigned() const noexcept { return __m; }
1575 inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; }
1576};
1577
1578
1579inline constexpr
1580bool operator==(const month& __lhs, const month& __rhs) noexcept
1581{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
1582
1583inline constexpr
1584bool operator!=(const month& __lhs, const month& __rhs) noexcept
1585{ return !(__lhs == __rhs); }
1586
1587inline constexpr
1588bool operator< (const month& __lhs, const month& __rhs) noexcept
1589{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
1590
1591inline constexpr
1592bool operator> (const month& __lhs, const month& __rhs) noexcept
1593{ return __rhs < __lhs; }
1594
1595inline constexpr
1596bool operator<=(const month& __lhs, const month& __rhs) noexcept
1597{ return !(__rhs < __lhs); }
1598
1599inline constexpr
1600bool operator>=(const month& __lhs, const month& __rhs) noexcept
1601{ return !(__lhs < __rhs); }
1602
1603inline constexpr
1604month operator+ (const month& __lhs, const months& __rhs) noexcept
1605{
1606 auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1);
1607 auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12;
1608 return month{static_cast<unsigned>(__mu - __yr * 12 + 1)};
1609}
1610
1611inline constexpr
1612month operator+ (const months& __lhs, const month& __rhs) noexcept
1613{ return __rhs + __lhs; }
1614
1615inline constexpr
1616month operator- (const month& __lhs, const months& __rhs) noexcept
1617{ return __lhs + -__rhs; }
1618
1619inline constexpr
1620months operator-(const month& __lhs, const month& __rhs) noexcept
1621{
1622 auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs);
1623 return months(__dm <= 11 ? __dm : __dm + 12);
1624}
1625
1626inline constexpr month& month::operator+=(const months& __dm) noexcept
1627{ *this = *this + __dm; return *this; }
1628
1629inline constexpr month& month::operator-=(const months& __dm) noexcept
1630{ *this = *this - __dm; return *this; }
1631
1632
Eric Fiselier28bc4292019-03-21 01:48:15 +00001633class year {
Marshall Clow26058352018-10-16 17:27:54 +00001634private:
1635 short __y;
1636public:
1637 year() = default;
1638 explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {}
1639
Eric Fiselierebdb6b42019-02-10 18:29:00 +00001640 inline constexpr year& operator++() noexcept { ++__y; return *this; }
1641 inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; }
1642 inline constexpr year& operator--() noexcept { --__y; return *this; }
1643 inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; }
Marshall Clow26058352018-10-16 17:27:54 +00001644 constexpr year& operator+=(const years& __dy) noexcept;
1645 constexpr year& operator-=(const years& __dy) noexcept;
1646 inline constexpr year operator+() const noexcept { return *this; }
Eric Fiselierebdb6b42019-02-10 18:29:00 +00001647 inline constexpr year operator-() const noexcept { return year{-__y}; }
Marshall Clow26058352018-10-16 17:27:54 +00001648
1649 inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); }
1650 explicit inline constexpr operator int() const noexcept { return __y; }
1651 constexpr bool ok() const noexcept;
1652 static inline constexpr year min() noexcept { return year{-32767}; }
1653 static inline constexpr year max() noexcept { return year{ 32767}; }
1654};
1655
1656
1657inline constexpr
1658bool operator==(const year& __lhs, const year& __rhs) noexcept
1659{ return static_cast<int>(__lhs) == static_cast<int>(__rhs); }
1660
1661inline constexpr
1662bool operator!=(const year& __lhs, const year& __rhs) noexcept
1663{ return !(__lhs == __rhs); }
1664
1665inline constexpr
1666bool operator< (const year& __lhs, const year& __rhs) noexcept
1667{ return static_cast<int>(__lhs) < static_cast<int>(__rhs); }
1668
1669inline constexpr
1670bool operator> (const year& __lhs, const year& __rhs) noexcept
1671{ return __rhs < __lhs; }
1672
1673inline constexpr
1674bool operator<=(const year& __lhs, const year& __rhs) noexcept
1675{ return !(__rhs < __lhs); }
1676
1677inline constexpr
1678bool operator>=(const year& __lhs, const year& __rhs) noexcept
1679{ return !(__lhs < __rhs); }
1680
1681inline constexpr
1682year operator+ (const year& __lhs, const years& __rhs) noexcept
1683{ return year(static_cast<int>(__lhs) + __rhs.count()); }
1684
1685inline constexpr
1686year operator+ (const years& __lhs, const year& __rhs) noexcept
1687{ return __rhs + __lhs; }
1688
1689inline constexpr
1690year operator- (const year& __lhs, const years& __rhs) noexcept
1691{ return __lhs + -__rhs; }
1692
1693inline constexpr
1694years operator-(const year& __lhs, const year& __rhs) noexcept
1695{ return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; }
1696
1697
1698inline constexpr year& year::operator+=(const years& __dy) noexcept
1699{ *this = *this + __dy; return *this; }
1700
1701inline constexpr year& year::operator-=(const years& __dy) noexcept
1702{ *this = *this - __dy; return *this; }
1703
1704inline constexpr bool year::ok() const noexcept
1705{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); }
1706
Eric Fiselier28bc4292019-03-21 01:48:15 +00001707class weekday_indexed;
1708class weekday_last;
Marshall Clow26058352018-10-16 17:27:54 +00001709
Eric Fiselier28bc4292019-03-21 01:48:15 +00001710class weekday {
Marshall Clow26058352018-10-16 17:27:54 +00001711private:
1712 unsigned char __wd;
Joe Loserf43160b2021-10-19 14:21:25 -04001713 static constexpr unsigned char __weekday_from_days(int __days) noexcept;
Marshall Clow26058352018-10-16 17:27:54 +00001714public:
1715 weekday() = default;
Marshall Clowc0194d52019-07-25 03:26:05 +00001716 inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {}
Marshall Clow188b3342019-01-11 15:12:04 +00001717 inline constexpr weekday(const sys_days& __sysd) noexcept
1718 : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {}
1719 inline explicit constexpr weekday(const local_days& __locd) noexcept
1720 : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {}
1721
Marshall Clow26058352018-10-16 17:27:54 +00001722 inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; }
1723 inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; }
1724 inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; }
1725 inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; }
1726 constexpr weekday& operator+=(const days& __dd) noexcept;
1727 constexpr weekday& operator-=(const days& __dd) noexcept;
Marshall Clowc0194d52019-07-25 03:26:05 +00001728 inline constexpr unsigned c_encoding() const noexcept { return __wd; }
1729 inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; }
Marshall Clow26058352018-10-16 17:27:54 +00001730 inline constexpr bool ok() const noexcept { return __wd <= 6; }
Marshall Clow188b3342019-01-11 15:12:04 +00001731 constexpr weekday_indexed operator[](unsigned __index) const noexcept;
1732 constexpr weekday_last operator[](last_spec) const noexcept;
Marshall Clow26058352018-10-16 17:27:54 +00001733};
1734
Marshall Clow188b3342019-01-11 15:12:04 +00001735
1736// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days
1737inline constexpr
1738unsigned char weekday::__weekday_from_days(int __days) noexcept
1739{
1740 return static_cast<unsigned char>(
1741 static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6)
1742 );
1743}
1744
Marshall Clow26058352018-10-16 17:27:54 +00001745inline constexpr
1746bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept
Marshall Clowc0194d52019-07-25 03:26:05 +00001747{ return __lhs.c_encoding() == __rhs.c_encoding(); }
Marshall Clow26058352018-10-16 17:27:54 +00001748
1749inline constexpr
1750bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept
1751{ return !(__lhs == __rhs); }
1752
1753inline constexpr
1754bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept
Marshall Clowc0194d52019-07-25 03:26:05 +00001755{ return __lhs.c_encoding() < __rhs.c_encoding(); }
Marshall Clow26058352018-10-16 17:27:54 +00001756
1757inline constexpr
1758bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept
1759{ return __rhs < __lhs; }
1760
1761inline constexpr
1762bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept
1763{ return !(__rhs < __lhs);}
1764
1765inline constexpr
1766bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept
1767{ return !(__lhs < __rhs); }
1768
1769constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept
1770{
Marshall Clowc0194d52019-07-25 03:26:05 +00001771 auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count();
Marshall Clow26058352018-10-16 17:27:54 +00001772 auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7;
1773 return weekday{static_cast<unsigned>(__mu - __yr * 7)};
1774}
1775
1776constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept
1777{ return __rhs + __lhs; }
1778
1779constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept
1780{ return __lhs + -__rhs; }
1781
1782constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept
1783{
Marshall Clowc0194d52019-07-25 03:26:05 +00001784 const int __wdu = __lhs.c_encoding() - __rhs.c_encoding();
Marshall Clow26058352018-10-16 17:27:54 +00001785 const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7;
1786 return days{__wdu - __wk * 7};
1787}
1788
1789inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept
1790{ *this = *this + __dd; return *this; }
1791
1792inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept
1793{ *this = *this - __dd; return *this; }
1794
1795
Eric Fiselier28bc4292019-03-21 01:48:15 +00001796class weekday_indexed {
Marshall Clow26058352018-10-16 17:27:54 +00001797private:
Arthur O'Dwyer9b374cc2021-05-10 13:19:07 -04001798 chrono::weekday __wd;
Marshall Clow26058352018-10-16 17:27:54 +00001799 unsigned char __idx;
1800public:
1801 weekday_indexed() = default;
Arthur O'Dwyer9b374cc2021-05-10 13:19:07 -04001802 inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept
Marshall Clow26058352018-10-16 17:27:54 +00001803 : __wd{__wdval}, __idx(__idxval) {}
Arthur O'Dwyer9b374cc2021-05-10 13:19:07 -04001804 inline constexpr chrono::weekday weekday() const noexcept { return __wd; }
Marshall Clow26058352018-10-16 17:27:54 +00001805 inline constexpr unsigned index() const noexcept { return __idx; }
1806 inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; }
1807};
1808
1809inline constexpr
1810bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
1811{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); }
1812
1813inline constexpr
1814bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
1815{ return !(__lhs == __rhs); }
1816
1817
Eric Fiselier28bc4292019-03-21 01:48:15 +00001818class weekday_last {
Marshall Clow26058352018-10-16 17:27:54 +00001819private:
Arthur O'Dwyer9b374cc2021-05-10 13:19:07 -04001820 chrono::weekday __wd;
Marshall Clow26058352018-10-16 17:27:54 +00001821public:
Arthur O'Dwyer9b374cc2021-05-10 13:19:07 -04001822 explicit constexpr weekday_last(const chrono::weekday& __val) noexcept
Marshall Clow26058352018-10-16 17:27:54 +00001823 : __wd{__val} {}
Arthur O'Dwyer9b374cc2021-05-10 13:19:07 -04001824 constexpr chrono::weekday weekday() const noexcept { return __wd; }
Marshall Clow26058352018-10-16 17:27:54 +00001825 constexpr bool ok() const noexcept { return __wd.ok(); }
1826};
1827
1828inline constexpr
1829bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
1830{ return __lhs.weekday() == __rhs.weekday(); }
1831
1832inline constexpr
1833bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
1834{ return !(__lhs == __rhs); }
1835
1836inline constexpr
1837weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; }
1838
Louis Dionne173f29e2019-05-29 16:01:36 +00001839inline constexpr
Marshall Clow26058352018-10-16 17:27:54 +00001840weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; }
1841
1842
1843inline constexpr last_spec last{};
1844inline constexpr weekday Sunday{0};
1845inline constexpr weekday Monday{1};
1846inline constexpr weekday Tuesday{2};
1847inline constexpr weekday Wednesday{3};
1848inline constexpr weekday Thursday{4};
1849inline constexpr weekday Friday{5};
1850inline constexpr weekday Saturday{6};
1851
1852inline constexpr month January{1};
1853inline constexpr month February{2};
1854inline constexpr month March{3};
1855inline constexpr month April{4};
1856inline constexpr month May{5};
1857inline constexpr month June{6};
1858inline constexpr month July{7};
1859inline constexpr month August{8};
1860inline constexpr month September{9};
1861inline constexpr month October{10};
1862inline constexpr month November{11};
1863inline constexpr month December{12};
1864
1865
Eric Fiselier28bc4292019-03-21 01:48:15 +00001866class month_day {
Marshall Clow26058352018-10-16 17:27:54 +00001867private:
1868 chrono::month __m;
1869 chrono::day __d;
1870public:
1871 month_day() = default;
1872 constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept
1873 : __m{__mval}, __d{__dval} {}
1874 inline constexpr chrono::month month() const noexcept { return __m; }
1875 inline constexpr chrono::day day() const noexcept { return __d; }
1876 constexpr bool ok() const noexcept;
1877};
1878
1879inline constexpr
1880bool month_day::ok() const noexcept
1881{
1882 if (!__m.ok()) return false;
1883 const unsigned __dval = static_cast<unsigned>(__d);
1884 if (__dval < 1 || __dval > 31) return false;
1885 if (__dval <= 29) return true;
1886// Now we've got either 30 or 31
1887 const unsigned __mval = static_cast<unsigned>(__m);
1888 if (__mval == 2) return false;
1889 if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11)
1890 return __dval == 30;
1891 return true;
1892}
1893
1894inline constexpr
1895bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept
1896{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
1897
1898inline constexpr
1899bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept
1900{ return !(__lhs == __rhs); }
1901
1902inline constexpr
1903month_day operator/(const month& __lhs, const day& __rhs) noexcept
1904{ return month_day{__lhs, __rhs}; }
1905
1906constexpr
1907month_day operator/(const day& __lhs, const month& __rhs) noexcept
1908{ return __rhs / __lhs; }
1909
1910inline constexpr
1911month_day operator/(const month& __lhs, int __rhs) noexcept
1912{ return __lhs / day(__rhs); }
1913
1914constexpr
1915month_day operator/(int __lhs, const day& __rhs) noexcept
1916{ return month(__lhs) / __rhs; }
1917
1918constexpr
1919month_day operator/(const day& __lhs, int __rhs) noexcept
1920{ return month(__rhs) / __lhs; }
1921
1922
1923inline constexpr
1924bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept
1925{ return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); }
1926
1927inline constexpr
1928bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept
1929{ return __rhs < __lhs; }
1930
1931inline constexpr
1932bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept
1933{ return !(__rhs < __lhs);}
1934
1935inline constexpr
1936bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept
1937{ return !(__lhs < __rhs); }
1938
1939
1940
Eric Fiselier28bc4292019-03-21 01:48:15 +00001941class month_day_last {
Marshall Clow26058352018-10-16 17:27:54 +00001942private:
1943 chrono::month __m;
1944public:
1945 explicit constexpr month_day_last(const chrono::month& __val) noexcept
1946 : __m{__val} {}
1947 inline constexpr chrono::month month() const noexcept { return __m; }
1948 inline constexpr bool ok() const noexcept { return __m.ok(); }
1949};
1950
1951inline constexpr
1952bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
1953{ return __lhs.month() == __rhs.month(); }
1954
1955inline constexpr
1956bool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
1957{ return !(__lhs == __rhs); }
1958
1959inline constexpr
1960bool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept
1961{ return __lhs.month() < __rhs.month(); }
1962
1963inline constexpr
1964bool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept
1965{ return __rhs < __lhs; }
1966
1967inline constexpr
1968bool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
1969{ return !(__rhs < __lhs);}
1970
1971inline constexpr
1972bool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
1973{ return !(__lhs < __rhs); }
1974
1975inline constexpr
1976month_day_last operator/(const month& __lhs, last_spec) noexcept
1977{ return month_day_last{__lhs}; }
1978
1979inline constexpr
1980month_day_last operator/(last_spec, const month& __rhs) noexcept
1981{ return month_day_last{__rhs}; }
1982
1983inline constexpr
1984month_day_last operator/(int __lhs, last_spec) noexcept
1985{ return month_day_last{month(__lhs)}; }
1986
1987inline constexpr
1988month_day_last operator/(last_spec, int __rhs) noexcept
1989{ return month_day_last{month(__rhs)}; }
1990
1991
Eric Fiselier28bc4292019-03-21 01:48:15 +00001992class month_weekday {
Marshall Clow26058352018-10-16 17:27:54 +00001993private:
1994 chrono::month __m;
1995 chrono::weekday_indexed __wdi;
1996public:
1997 month_weekday() = default;
1998 constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept
1999 : __m{__mval}, __wdi{__wdival} {}
2000 inline constexpr chrono::month month() const noexcept { return __m; }
2001 inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
2002 inline constexpr bool ok() const noexcept { return __m.ok() && __wdi.ok(); }
2003};
2004
2005inline constexpr
2006bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
2007{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
2008
2009inline constexpr
2010bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
2011{ return !(__lhs == __rhs); }
2012
2013inline constexpr
2014month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept
2015{ return month_weekday{__lhs, __rhs}; }
2016
2017inline constexpr
2018month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept
2019{ return month_weekday{month(__lhs), __rhs}; }
2020
2021inline constexpr
2022month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept
2023{ return month_weekday{__rhs, __lhs}; }
2024
2025inline constexpr
2026month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept
2027{ return month_weekday{month(__rhs), __lhs}; }
2028
2029
Eric Fiselier28bc4292019-03-21 01:48:15 +00002030class month_weekday_last {
Marshall Clow26058352018-10-16 17:27:54 +00002031 chrono::month __m;
2032 chrono::weekday_last __wdl;
2033 public:
2034 constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept
2035 : __m{__mval}, __wdl{__wdlval} {}
2036 inline constexpr chrono::month month() const noexcept { return __m; }
2037 inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; }
2038 inline constexpr bool ok() const noexcept { return __m.ok() && __wdl.ok(); }
2039};
2040
2041inline constexpr
2042bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
2043{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
2044
2045inline constexpr
2046bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
2047{ return !(__lhs == __rhs); }
2048
2049
2050inline constexpr
2051month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept
2052{ return month_weekday_last{__lhs, __rhs}; }
2053
2054inline constexpr
2055month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept
2056{ return month_weekday_last{month(__lhs), __rhs}; }
2057
2058inline constexpr
2059month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept
2060{ return month_weekday_last{__rhs, __lhs}; }
2061
2062inline constexpr
2063month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept
2064{ return month_weekday_last{month(__rhs), __lhs}; }
2065
2066
Eric Fiselier28bc4292019-03-21 01:48:15 +00002067class year_month {
Marshall Clow26058352018-10-16 17:27:54 +00002068 chrono::year __y;
2069 chrono::month __m;
2070public:
2071 year_month() = default;
2072 constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept
2073 : __y{__yval}, __m{__mval} {}
2074 inline constexpr chrono::year year() const noexcept { return __y; }
2075 inline constexpr chrono::month month() const noexcept { return __m; }
2076 inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; }
2077 inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; }
2078 inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; }
2079 inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; }
2080 inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); }
2081};
2082
2083inline constexpr
2084year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; }
2085
2086inline constexpr
2087year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; }
2088
2089inline constexpr
2090bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept
2091{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); }
2092
2093inline constexpr
2094bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept
2095{ return !(__lhs == __rhs); }
2096
2097inline constexpr
2098bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept
2099{ return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); }
2100
2101inline constexpr
2102bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept
2103{ return __rhs < __lhs; }
2104
2105inline constexpr
2106bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept
2107{ return !(__rhs < __lhs);}
2108
2109inline constexpr
2110bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept
2111{ return !(__lhs < __rhs); }
2112
2113constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept
2114{
2115 int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count();
2116 const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12;
2117 __dmi = __dmi - __dy * 12 + 1;
2118 return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi));
2119}
2120
2121constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept
2122{ return __rhs + __lhs; }
2123
2124constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept
2125{ return (__lhs.year() + __rhs) / __lhs.month(); }
2126
2127constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept
2128{ return __rhs + __lhs; }
2129
2130constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept
2131{ return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); }
2132
2133constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept
2134{ return __lhs + -__rhs; }
2135
2136constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept
2137{ return __lhs + -__rhs; }
2138
Marshall Clow188b3342019-01-11 15:12:04 +00002139class year_month_day_last;
Marshall Clow26058352018-10-16 17:27:54 +00002140
Eric Fiselier28bc4292019-03-21 01:48:15 +00002141class year_month_day {
Marshall Clow26058352018-10-16 17:27:54 +00002142private:
2143 chrono::year __y;
2144 chrono::month __m;
2145 chrono::day __d;
2146public:
2147 year_month_day() = default;
2148 inline constexpr year_month_day(
2149 const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept
Louis Dionne173f29e2019-05-29 16:01:36 +00002150 : __y{__yval}, __m{__mval}, __d{__dval} {}
Marshall Clow188b3342019-01-11 15:12:04 +00002151 constexpr year_month_day(const year_month_day_last& __ymdl) noexcept;
2152 inline constexpr year_month_day(const sys_days& __sysd) noexcept
2153 : year_month_day(__from_days(__sysd.time_since_epoch())) {}
2154 inline explicit constexpr year_month_day(const local_days& __locd) noexcept
2155 : year_month_day(__from_days(__locd.time_since_epoch())) {}
2156
Marshall Clow26058352018-10-16 17:27:54 +00002157 constexpr year_month_day& operator+=(const months& __dm) noexcept;
2158 constexpr year_month_day& operator-=(const months& __dm) noexcept;
2159 constexpr year_month_day& operator+=(const years& __dy) noexcept;
2160 constexpr year_month_day& operator-=(const years& __dy) noexcept;
Marshall Clow26058352018-10-16 17:27:54 +00002161
Marshall Clow188b3342019-01-11 15:12:04 +00002162 inline constexpr chrono::year year() const noexcept { return __y; }
2163 inline constexpr chrono::month month() const noexcept { return __m; }
2164 inline constexpr chrono::day day() const noexcept { return __d; }
2165 inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
2166 inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
2167
2168 constexpr bool ok() const noexcept;
2169
2170 static constexpr year_month_day __from_days(days __d) noexcept;
2171 constexpr days __to_days() const noexcept;
Marshall Clow26058352018-10-16 17:27:54 +00002172};
2173
Marshall Clow188b3342019-01-11 15:12:04 +00002174
2175// https://howardhinnant.github.io/date_algorithms.html#civil_from_days
2176inline constexpr
2177year_month_day
2178year_month_day::__from_days(days __d) noexcept
2179{
Arthur O'Dwyer57f65ce2021-02-15 16:10:28 -05002180 static_assert(numeric_limits<unsigned>::digits >= 18, "");
2181 static_assert(numeric_limits<int>::digits >= 20 , "");
Marshall Clow188b3342019-01-11 15:12:04 +00002182 const int __z = __d.count() + 719468;
2183 const int __era = (__z >= 0 ? __z : __z - 146096) / 146097;
2184 const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096]
2185 const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399]
2186 const int __yr = static_cast<int>(__yoe) + __era * 400;
2187 const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365]
2188 const unsigned __mp = (5 * __doy + 2)/153; // [0, 11]
2189 const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31]
2190 const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12]
2191 return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}};
2192}
2193
2194// https://howardhinnant.github.io/date_algorithms.html#days_from_civil
2195inline constexpr days year_month_day::__to_days() const noexcept
2196{
Arthur O'Dwyer57f65ce2021-02-15 16:10:28 -05002197 static_assert(numeric_limits<unsigned>::digits >= 18, "");
2198 static_assert(numeric_limits<int>::digits >= 20 , "");
Marshall Clow188b3342019-01-11 15:12:04 +00002199
2200 const int __yr = static_cast<int>(__y) - (__m <= February);
2201 const unsigned __mth = static_cast<unsigned>(__m);
2202 const unsigned __dy = static_cast<unsigned>(__d);
2203
2204 const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400;
2205 const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399]
2206 const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365]
2207 const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096]
2208 return days{__era * 146097 + static_cast<int>(__doe) - 719468};
2209}
2210
Marshall Clow26058352018-10-16 17:27:54 +00002211inline constexpr
2212bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2213{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
2214
2215inline constexpr
2216bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2217{ return !(__lhs == __rhs); }
2218
2219inline constexpr
2220bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2221{
2222 if (__lhs.year() < __rhs.year()) return true;
2223 if (__lhs.year() > __rhs.year()) return false;
2224 if (__lhs.month() < __rhs.month()) return true;
2225 if (__lhs.month() > __rhs.month()) return false;
2226 return __lhs.day() < __rhs.day();
2227}
2228
2229inline constexpr
2230bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2231{ return __rhs < __lhs; }
2232
2233inline constexpr
2234bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2235{ return !(__rhs < __lhs);}
2236
2237inline constexpr
2238bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2239{ return !(__lhs < __rhs); }
2240
2241inline constexpr
2242year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept
2243{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; }
2244
2245inline constexpr
2246year_month_day operator/(const year_month& __lhs, int __rhs) noexcept
2247{ return __lhs / day(__rhs); }
2248
2249inline constexpr
2250year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept
2251{ return __lhs / __rhs.month() / __rhs.day(); }
2252
2253inline constexpr
2254year_month_day operator/(int __lhs, const month_day& __rhs) noexcept
2255{ return year(__lhs) / __rhs; }
2256
2257inline constexpr
2258year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept
2259{ return __rhs / __lhs; }
2260
2261inline constexpr
2262year_month_day operator/(const month_day& __lhs, int __rhs) noexcept
2263{ return year(__rhs) / __lhs; }
2264
2265
2266inline constexpr
2267year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept
2268{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); }
2269
2270inline constexpr
2271year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept
2272{ return __rhs + __lhs; }
2273
2274inline constexpr
2275year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept
2276{ return __lhs + -__rhs; }
2277
2278inline constexpr
2279year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept
2280{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); }
2281
2282inline constexpr
2283year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept
2284{ return __rhs + __lhs; }
2285
2286inline constexpr
2287year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept
2288{ return __lhs + -__rhs; }
2289
2290inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
2291inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
2292inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
2293inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
2294
Eric Fiselier28bc4292019-03-21 01:48:15 +00002295class year_month_day_last {
Marshall Clow26058352018-10-16 17:27:54 +00002296private:
2297 chrono::year __y;
2298 chrono::month_day_last __mdl;
2299public:
2300 constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept
2301 : __y{__yval}, __mdl{__mdlval} {}
2302
2303 constexpr year_month_day_last& operator+=(const months& __m) noexcept;
2304 constexpr year_month_day_last& operator-=(const months& __m) noexcept;
2305 constexpr year_month_day_last& operator+=(const years& __y) noexcept;
2306 constexpr year_month_day_last& operator-=(const years& __y) noexcept;
2307
Marshall Clow188b3342019-01-11 15:12:04 +00002308 inline constexpr chrono::year year() const noexcept { return __y; }
2309 inline constexpr chrono::month month() const noexcept { return __mdl.month(); }
2310 inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; }
2311 constexpr chrono::day day() const noexcept;
2312 inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; }
2313 inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; }
2314 inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); }
Marshall Clow26058352018-10-16 17:27:54 +00002315};
2316
2317inline constexpr
Marshall Clow188b3342019-01-11 15:12:04 +00002318chrono::day year_month_day_last::day() const noexcept
2319{
2320 constexpr chrono::day __d[] =
2321 {
2322 chrono::day(31), chrono::day(28), chrono::day(31),
2323 chrono::day(30), chrono::day(31), chrono::day(30),
2324 chrono::day(31), chrono::day(31), chrono::day(30),
2325 chrono::day(31), chrono::day(30), chrono::day(31)
2326 };
Louis Dionned473e692020-06-09 12:31:12 -04002327 return (month() != February || !__y.is_leap()) && month().ok() ?
Marshall Clow188b3342019-01-11 15:12:04 +00002328 __d[static_cast<unsigned>(month()) - 1] : chrono::day{29};
2329}
2330
2331inline constexpr
Marshall Clow26058352018-10-16 17:27:54 +00002332bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2333{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); }
2334
2335inline constexpr
2336bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2337{ return !(__lhs == __rhs); }
2338
2339inline constexpr
2340bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2341{
2342 if (__lhs.year() < __rhs.year()) return true;
2343 if (__lhs.year() > __rhs.year()) return false;
2344 return __lhs.month_day_last() < __rhs.month_day_last();
2345}
2346
2347inline constexpr
2348bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2349{ return __rhs < __lhs; }
2350
2351inline constexpr
2352bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2353{ return !(__rhs < __lhs);}
2354
2355inline constexpr
2356bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2357{ return !(__lhs < __rhs); }
2358
2359inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept
2360{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; }
2361
2362inline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept
2363{ return year_month_day_last{__lhs, __rhs}; }
2364
2365inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept
2366{ return year_month_day_last{year{__lhs}, __rhs}; }
2367
2368inline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept
2369{ return __rhs / __lhs; }
2370
2371inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept
2372{ return year{__rhs} / __lhs; }
2373
2374
2375inline constexpr
2376year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept
2377{ return (__lhs.year() / __lhs.month() + __rhs) / last; }
2378
2379inline constexpr
2380year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept
2381{ return __rhs + __lhs; }
2382
2383inline constexpr
2384year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept
2385{ return __lhs + (-__rhs); }
2386
2387inline constexpr
2388year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept
2389{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; }
2390
2391inline constexpr
2392year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept
2393{ return __rhs + __lhs; }
2394
2395inline constexpr
2396year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept
2397{ return __lhs + (-__rhs); }
2398
2399inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
2400inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
2401inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
2402inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
2403
Marshall Clow188b3342019-01-11 15:12:04 +00002404inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
Louis Dionne173f29e2019-05-29 16:01:36 +00002405 : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {}
Marshall Clow188b3342019-01-11 15:12:04 +00002406
2407inline constexpr bool year_month_day::ok() const noexcept
2408{
2409 if (!__y.ok() || !__m.ok()) return false;
2410 return chrono::day{1} <= __d && __d <= (__y / __m / last).day();
2411}
2412
Eric Fiselier28bc4292019-03-21 01:48:15 +00002413class year_month_weekday {
Marshall Clow26058352018-10-16 17:27:54 +00002414 chrono::year __y;
2415 chrono::month __m;
2416 chrono::weekday_indexed __wdi;
2417public:
2418 year_month_weekday() = default;
2419 constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval,
2420 const chrono::weekday_indexed& __wdival) noexcept
2421 : __y{__yval}, __m{__mval}, __wdi{__wdival} {}
Marshall Clow188b3342019-01-11 15:12:04 +00002422 constexpr year_month_weekday(const sys_days& __sysd) noexcept
2423 : year_month_weekday(__from_days(__sysd.time_since_epoch())) {}
2424 inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept
2425 : year_month_weekday(__from_days(__locd.time_since_epoch())) {}
Marshall Clow26058352018-10-16 17:27:54 +00002426 constexpr year_month_weekday& operator+=(const months& m) noexcept;
2427 constexpr year_month_weekday& operator-=(const months& m) noexcept;
2428 constexpr year_month_weekday& operator+=(const years& y) noexcept;
2429 constexpr year_month_weekday& operator-=(const years& y) noexcept;
2430
2431 inline constexpr chrono::year year() const noexcept { return __y; }
2432 inline constexpr chrono::month month() const noexcept { return __m; }
2433 inline constexpr chrono::weekday weekday() const noexcept { return __wdi.weekday(); }
2434 inline constexpr unsigned index() const noexcept { return __wdi.index(); }
2435 inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
2436
Marshall Clow188b3342019-01-11 15:12:04 +00002437 inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
2438 inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
Marshall Clow26058352018-10-16 17:27:54 +00002439 inline constexpr bool ok() const noexcept
2440 {
2441 if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false;
Marek Kurdej05d672b2019-11-15 13:04:47 +01002442 if (__wdi.index() <= 4) return true;
2443 auto __nth_weekday_day =
2444 __wdi.weekday() -
2445 chrono::weekday{static_cast<sys_days>(__y / __m / 1)} +
2446 days{(__wdi.index() - 1) * 7 + 1};
2447 return static_cast<unsigned>(__nth_weekday_day.count()) <=
2448 static_cast<unsigned>((__y / __m / last).day());
Marshall Clow26058352018-10-16 17:27:54 +00002449 }
Marshall Clow188b3342019-01-11 15:12:04 +00002450
2451 static constexpr year_month_weekday __from_days(days __d) noexcept;
2452 constexpr days __to_days() const noexcept;
Marshall Clow26058352018-10-16 17:27:54 +00002453};
2454
2455inline constexpr
Marshall Clow188b3342019-01-11 15:12:04 +00002456year_month_weekday year_month_weekday::__from_days(days __d) noexcept
2457{
2458 const sys_days __sysd{__d};
2459 const chrono::weekday __wd = chrono::weekday(__sysd);
2460 const year_month_day __ymd = year_month_day(__sysd);
Louis Dionne173f29e2019-05-29 16:01:36 +00002461 return year_month_weekday{__ymd.year(), __ymd.month(),
Marshall Clow188b3342019-01-11 15:12:04 +00002462 __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]};
2463}
2464
2465inline constexpr
2466days year_month_weekday::__to_days() const noexcept
2467{
2468 const sys_days __sysd = sys_days(__y/__m/1);
2469 return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7}))
2470 .time_since_epoch();
2471}
2472
2473inline constexpr
Marshall Clow26058352018-10-16 17:27:54 +00002474bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
2475{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
2476
2477inline constexpr
2478bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
2479{ return !(__lhs == __rhs); }
2480
2481inline constexpr
2482year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept
2483{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; }
2484
2485inline constexpr
2486year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept
2487{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; }
2488
2489inline constexpr
2490year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept
2491{ return year(__lhs) / __rhs; }
2492
2493inline constexpr
2494year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept
2495{ return __rhs / __lhs; }
2496
2497inline constexpr
2498year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept
2499{ return year(__rhs) / __lhs; }
2500
2501
2502inline constexpr
2503year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept
2504{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); }
2505
2506inline constexpr
2507year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept
2508{ return __rhs + __lhs; }
2509
2510inline constexpr
2511year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept
2512{ return __lhs + (-__rhs); }
2513
2514inline constexpr
2515year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept
2516{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; }
2517
2518inline constexpr
2519year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept
2520{ return __rhs + __lhs; }
2521
2522inline constexpr
2523year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept
2524{ return __lhs + (-__rhs); }
2525
2526
2527inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
2528inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
2529inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
2530inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
2531
Eric Fiselier28bc4292019-03-21 01:48:15 +00002532class year_month_weekday_last {
Marshall Clow26058352018-10-16 17:27:54 +00002533private:
2534 chrono::year __y;
2535 chrono::month __m;
2536 chrono::weekday_last __wdl;
2537public:
2538 constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval,
2539 const chrono::weekday_last& __wdlval) noexcept
2540 : __y{__yval}, __m{__mval}, __wdl{__wdlval} {}
2541 constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept;
2542 constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept;
2543 constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept;
2544 constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept;
2545
2546 inline constexpr chrono::year year() const noexcept { return __y; }
2547 inline constexpr chrono::month month() const noexcept { return __m; }
2548 inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); }
2549 inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; }
Marshall Clow188b3342019-01-11 15:12:04 +00002550 inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
2551 inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
Marshall Clow26058352018-10-16 17:27:54 +00002552 inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); }
Louis Dionne173f29e2019-05-29 16:01:36 +00002553
Marshall Clow188b3342019-01-11 15:12:04 +00002554 constexpr days __to_days() const noexcept;
Louis Dionne173f29e2019-05-29 16:01:36 +00002555
Marshall Clow26058352018-10-16 17:27:54 +00002556};
2557
2558inline constexpr
Marshall Clow188b3342019-01-11 15:12:04 +00002559days year_month_weekday_last::__to_days() const noexcept
2560{
2561 const sys_days __last = sys_days{__y/__m/last};
2562 return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch();
2563
2564}
2565
2566inline constexpr
Marshall Clow26058352018-10-16 17:27:54 +00002567bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
2568{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
2569
2570inline constexpr
2571bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
2572{ return !(__lhs == __rhs); }
2573
2574
2575inline constexpr
2576year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept
2577{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; }
2578
2579inline constexpr
2580year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept
2581{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; }
2582
2583inline constexpr
2584year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept
2585{ return year(__lhs) / __rhs; }
2586
2587inline constexpr
2588year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept
2589{ return __rhs / __lhs; }
2590
2591inline constexpr
2592year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept
Louis Dionne173f29e2019-05-29 16:01:36 +00002593{ return year(__rhs) / __lhs; }
Marshall Clow26058352018-10-16 17:27:54 +00002594
2595
2596inline constexpr
2597year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
2598{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); }
2599
2600inline constexpr
2601year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept
2602{ return __rhs + __lhs; }
2603
2604inline constexpr
2605year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
2606{ return __lhs + (-__rhs); }
2607
2608inline constexpr
2609year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
2610{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; }
2611
2612inline constexpr
2613year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept
2614{ return __rhs + __lhs; }
2615
2616inline constexpr
2617year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
2618{ return __lhs + (-__rhs); }
2619
2620inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
2621inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
2622inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
2623inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
2624
Marshall Clow748d1a62019-08-08 14:36:07 +00002625
2626template <class _Duration>
2627class hh_mm_ss
2628{
2629private:
2630 static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration");
2631 using __CommonType = common_type_t<_Duration, chrono::seconds>;
2632
2633 static constexpr uint64_t __pow10(unsigned __exp)
2634 {
2635 uint64_t __ret = 1;
2636 for (unsigned __i = 0; __i < __exp; ++__i)
2637 __ret *= 10U;
2638 return __ret;
2639 }
2640
2641 static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0)
2642 {
2643 if (__n >= 2 && __d != 0 && __w < 19)
2644 return 1 + __width(__n, __d % __n * 10, __w+1);
2645 return 0;
2646 }
2647
2648public:
2649 static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ?
2650 __width(__CommonType::period::den) : 6u;
2651 using precision = duration<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>;
2652
2653 constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {}
2654
2655 constexpr explicit hh_mm_ss(_Duration __d) noexcept :
2656 __is_neg(__d < _Duration(0)),
2657 __h(duration_cast<chrono::hours> (abs(__d))),
2658 __m(duration_cast<chrono::minutes>(abs(__d) - hours())),
2659 __s(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())),
2660 __f(duration_cast<precision> (abs(__d) - hours() - minutes() - seconds()))
2661 {}
2662
2663 constexpr bool is_negative() const noexcept { return __is_neg; }
2664 constexpr chrono::hours hours() const noexcept { return __h; }
2665 constexpr chrono::minutes minutes() const noexcept { return __m; }
2666 constexpr chrono::seconds seconds() const noexcept { return __s; }
2667 constexpr precision subseconds() const noexcept { return __f; }
2668
2669 constexpr precision to_duration() const noexcept
2670 {
2671 auto __dur = __h + __m + __s + __f;
2672 return __is_neg ? -__dur : __dur;
2673 }
2674
2675 constexpr explicit operator precision() const noexcept { return to_duration(); }
2676
2677private:
2678 bool __is_neg;
2679 chrono::hours __h;
2680 chrono::minutes __m;
2681 chrono::seconds __s;
2682 precision __f;
2683};
2684
2685constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); }
2686constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); }
2687
2688constexpr hours make12(const hours& __h) noexcept
2689{
2690 if (__h == hours( 0)) return hours(12);
2691 else if (__h <= hours(12)) return __h;
2692 else return __h - hours(12);
2693}
2694
2695constexpr hours make24(const hours& __h, bool __is_pm) noexcept
2696{
2697 if (__is_pm)
2698 return __h == hours(12) ? __h : __h + hours(12);
2699 else
2700 return __h == hours(12) ? hours(0) : __h;
2701}
2702
Marshall Clow26058352018-10-16 17:27:54 +00002703#endif // _LIBCPP_STD_VER > 17
Nikolas Klauserd26407a2021-12-02 14:12:51 +01002704} // namespace chrono
Howard Hinnantc51e1022010-05-11 19:42:16 +00002705
Marshall Clowac868372013-10-05 21:18:32 +00002706#if _LIBCPP_STD_VER > 11
2707// Suffixes for duration literals [time.duration.literals]
2708inline namespace literals
Louis Dionne44bcff92018-08-03 22:36:53 +00002709{
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002710 inline namespace chrono_literals
2711 {
2712
Marshall Clow2ac805a2017-08-09 15:42:50 +00002713 constexpr chrono::hours operator""h(unsigned long long __h)
Howard Hinnant5c167562013-08-07 19:39:48 +00002714 {
2715 return chrono::hours(static_cast<chrono::hours::rep>(__h));
2716 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002717
Marshall Clow2ac805a2017-08-09 15:42:50 +00002718 constexpr chrono::duration<long double, ratio<3600,1>> operator""h(long double __h)
Howard Hinnant5c167562013-08-07 19:39:48 +00002719 {
2720 return chrono::duration<long double, ratio<3600,1>>(__h);
2721 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002722
2723
Marshall Clow2ac805a2017-08-09 15:42:50 +00002724 constexpr chrono::minutes operator""min(unsigned long long __m)
Howard Hinnant5c167562013-08-07 19:39:48 +00002725 {
2726 return chrono::minutes(static_cast<chrono::minutes::rep>(__m));
2727 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002728
Marshall Clow2ac805a2017-08-09 15:42:50 +00002729 constexpr chrono::duration<long double, ratio<60,1>> operator""min(long double __m)
Howard Hinnant5c167562013-08-07 19:39:48 +00002730 {
2731 return chrono::duration<long double, ratio<60,1>> (__m);
2732 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002733
2734
Marshall Clow2ac805a2017-08-09 15:42:50 +00002735 constexpr chrono::seconds operator""s(unsigned long long __s)
Howard Hinnant5c167562013-08-07 19:39:48 +00002736 {
2737 return chrono::seconds(static_cast<chrono::seconds::rep>(__s));
2738 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002739
Marshall Clow2ac805a2017-08-09 15:42:50 +00002740 constexpr chrono::duration<long double> operator""s(long double __s)
Howard Hinnant5c167562013-08-07 19:39:48 +00002741 {
2742 return chrono::duration<long double> (__s);
2743 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002744
2745
Marshall Clow2ac805a2017-08-09 15:42:50 +00002746 constexpr chrono::milliseconds operator""ms(unsigned long long __ms)
Howard Hinnant5c167562013-08-07 19:39:48 +00002747 {
2748 return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms));
2749 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002750
Marshall Clow2ac805a2017-08-09 15:42:50 +00002751 constexpr chrono::duration<long double, milli> operator""ms(long double __ms)
Howard Hinnant5c167562013-08-07 19:39:48 +00002752 {
2753 return chrono::duration<long double, milli>(__ms);
2754 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002755
2756
Marshall Clow2ac805a2017-08-09 15:42:50 +00002757 constexpr chrono::microseconds operator""us(unsigned long long __us)
Howard Hinnant5c167562013-08-07 19:39:48 +00002758 {
2759 return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us));
2760 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002761
Marshall Clow2ac805a2017-08-09 15:42:50 +00002762 constexpr chrono::duration<long double, micro> operator""us(long double __us)
Howard Hinnant5c167562013-08-07 19:39:48 +00002763 {
2764 return chrono::duration<long double, micro> (__us);
2765 }
Louis Dionne44bcff92018-08-03 22:36:53 +00002766
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002767
Marshall Clow2ac805a2017-08-09 15:42:50 +00002768 constexpr chrono::nanoseconds operator""ns(unsigned long long __ns)
Howard Hinnant5c167562013-08-07 19:39:48 +00002769 {
2770 return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns));
2771 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002772
Marshall Clow2ac805a2017-08-09 15:42:50 +00002773 constexpr chrono::duration<long double, nano> operator""ns(long double __ns)
Howard Hinnant5c167562013-08-07 19:39:48 +00002774 {
2775 return chrono::duration<long double, nano> (__ns);
2776 }
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002777
Louis Dionne3e0c4332021-08-31 10:49:06 -04002778#if _LIBCPP_STD_VER > 17
Marshall Clow26058352018-10-16 17:27:54 +00002779 constexpr chrono::day operator ""d(unsigned long long __d) noexcept
2780 {
2781 return chrono::day(static_cast<unsigned>(__d));
2782 }
Louis Dionne173f29e2019-05-29 16:01:36 +00002783
Marshall Clow26058352018-10-16 17:27:54 +00002784 constexpr chrono::year operator ""y(unsigned long long __y) noexcept
2785 {
2786 return chrono::year(static_cast<int>(__y));
2787 }
2788#endif
Nikolas Klauserd26407a2021-12-02 14:12:51 +01002789} // namespace chrono_literals
2790} // namespace literals
Marshall Clowac868372013-10-05 21:18:32 +00002791
2792namespace chrono { // hoist the literals into namespace std::chrono
2793 using namespace literals::chrono_literals;
Nikolas Klauserd26407a2021-12-02 14:12:51 +01002794} // namespace chrono
Marshall Clowac868372013-10-05 21:18:32 +00002795
Marshall Cloweb41e5c2013-07-24 21:18:14 +00002796#endif
2797
Howard Hinnantc51e1022010-05-11 19:42:16 +00002798_LIBCPP_END_NAMESPACE_STD
2799
Eric Fiselier049273c2018-12-21 03:54:57 +00002800#ifndef _LIBCPP_CXX03_LANG
2801_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2802struct _FilesystemClock {
2803#if !defined(_LIBCPP_HAS_NO_INT128)
2804 typedef __int128_t rep;
2805 typedef nano period;
2806#else
2807 typedef long long rep;
2808 typedef nano period;
2809#endif
2810
2811 typedef chrono::duration<rep, period> duration;
2812 typedef chrono::time_point<_FilesystemClock> time_point;
2813
Louis Dionne0ba10dc2019-08-13 15:02:53 +00002814 _LIBCPP_EXPORTED_FROM_ABI
Eric Fiselier049273c2018-12-21 03:54:57 +00002815 static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
2816
Louis Dionnef6bf76a2019-03-20 21:18:14 +00002817 _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept;
Louis Dionneb35fab82021-11-08 15:30:32 -05002818
2819#if _LIBCPP_STD_VER > 17
2820 template <class _Duration>
2821 _LIBCPP_HIDE_FROM_ABI
2822 static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) {
2823 return chrono::sys_time<_Duration>(__t.time_since_epoch());
2824 }
2825
2826 template <class _Duration>
2827 _LIBCPP_HIDE_FROM_ABI
2828 static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) {
2829 return chrono::file_time<_Duration>(__t.time_since_epoch());
2830 }
2831#endif // _LIBCPP_STD_VER > 17
Eric Fiselier049273c2018-12-21 03:54:57 +00002832};
2833_LIBCPP_END_NAMESPACE_FILESYSTEM
2834#endif // !_LIBCPP_CXX03_LANG
2835
Eric Fiselierf4433a32017-05-31 22:07:49 +00002836_LIBCPP_POP_MACROS
2837
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002838#endif // _LIBCPP_CHRONO