xref: /freebsd/contrib/llvm-project/libcxx/include/chrono (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric// -*- C++ -*-
2*0b57cec5SDimitry Andric//===---------------------------- chrono ----------------------------------===//
3*0b57cec5SDimitry Andric//
4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*0b57cec5SDimitry Andric//
8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9*0b57cec5SDimitry Andric
10*0b57cec5SDimitry Andric#ifndef _LIBCPP_CHRONO
11*0b57cec5SDimitry Andric#define _LIBCPP_CHRONO
12*0b57cec5SDimitry Andric
13*0b57cec5SDimitry Andric/*
14*0b57cec5SDimitry Andric    chrono synopsis
15*0b57cec5SDimitry Andric
16*0b57cec5SDimitry Andricnamespace std
17*0b57cec5SDimitry Andric{
18*0b57cec5SDimitry Andricnamespace chrono
19*0b57cec5SDimitry Andric{
20*0b57cec5SDimitry Andric
21*0b57cec5SDimitry Andrictemplate <class ToDuration, class Rep, class Period>
22*0b57cec5SDimitry Andricconstexpr
23*0b57cec5SDimitry AndricToDuration
24*0b57cec5SDimitry Andricduration_cast(const duration<Rep, Period>& fd);
25*0b57cec5SDimitry Andric
26*0b57cec5SDimitry Andrictemplate <class Rep> struct treat_as_floating_point : is_floating_point<Rep> {};
27*0b57cec5SDimitry Andric
28*0b57cec5SDimitry Andrictemplate <class Rep> inline constexpr bool treat_as_floating_point_v
29*0b57cec5SDimitry Andric    = treat_as_floating_point<Rep>::value;                       // C++17
30*0b57cec5SDimitry Andric
31*0b57cec5SDimitry Andrictemplate <class Rep>
32*0b57cec5SDimitry Andricstruct duration_values
33*0b57cec5SDimitry Andric{
34*0b57cec5SDimitry Andricpublic:
35*0b57cec5SDimitry Andric    static constexpr Rep zero(); // noexcept in C++20
36*0b57cec5SDimitry Andric    static constexpr Rep max();  // noexcept in C++20
37*0b57cec5SDimitry Andric    static constexpr Rep min();  // noexcept in C++20
38*0b57cec5SDimitry Andric};
39*0b57cec5SDimitry Andric
40*0b57cec5SDimitry Andric// duration
41*0b57cec5SDimitry Andric
42*0b57cec5SDimitry Andrictemplate <class Rep, class Period = ratio<1>>
43*0b57cec5SDimitry Andricclass duration
44*0b57cec5SDimitry Andric{
45*0b57cec5SDimitry Andric    static_assert(!__is_duration<Rep>::value, "A duration representation can not be a duration");
46*0b57cec5SDimitry Andric    static_assert(__is_ratio<Period>::value, "Second template parameter of duration must be a std::ratio");
47*0b57cec5SDimitry Andric    static_assert(Period::num > 0, "duration period must be positive");
48*0b57cec5SDimitry Andricpublic:
49*0b57cec5SDimitry Andric    typedef Rep rep;
50*0b57cec5SDimitry Andric    typedef typename _Period::type period;
51*0b57cec5SDimitry Andric
52*0b57cec5SDimitry Andric    constexpr duration() = default;
53*0b57cec5SDimitry Andric    template <class Rep2>
54*0b57cec5SDimitry Andric        constexpr explicit duration(const Rep2& r,
55*0b57cec5SDimitry Andric            typename enable_if
56*0b57cec5SDimitry Andric            <
57*0b57cec5SDimitry Andric               is_convertible<Rep2, rep>::value &&
58*0b57cec5SDimitry Andric               (treat_as_floating_point<rep>::value ||
59*0b57cec5SDimitry Andric               !treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value)
60*0b57cec5SDimitry Andric            >::type* = 0);
61*0b57cec5SDimitry Andric
62*0b57cec5SDimitry Andric    // conversions
63*0b57cec5SDimitry Andric    template <class Rep2, class Period2>
64*0b57cec5SDimitry Andric        constexpr duration(const duration<Rep2, Period2>& d,
65*0b57cec5SDimitry Andric            typename enable_if
66*0b57cec5SDimitry Andric            <
67*0b57cec5SDimitry Andric                treat_as_floating_point<rep>::value ||
68*0b57cec5SDimitry Andric                ratio_divide<Period2, period>::type::den == 1
69*0b57cec5SDimitry Andric            >::type* = 0);
70*0b57cec5SDimitry Andric
71*0b57cec5SDimitry Andric    // observer
72*0b57cec5SDimitry Andric
73*0b57cec5SDimitry Andric    constexpr rep count() const;
74*0b57cec5SDimitry Andric
75*0b57cec5SDimitry Andric    // arithmetic
76*0b57cec5SDimitry Andric
77*0b57cec5SDimitry Andric    constexpr common_type<duration>::type  operator+() const;
78*0b57cec5SDimitry Andric    constexpr common_type<duration>::type  operator-() const;
79*0b57cec5SDimitry Andric    constexpr duration& operator++();    // constexpr in C++17
80*0b57cec5SDimitry Andric    constexpr duration  operator++(int); // constexpr in C++17
81*0b57cec5SDimitry Andric    constexpr duration& operator--();    // constexpr in C++17
82*0b57cec5SDimitry Andric    constexpr duration  operator--(int); // constexpr in C++17
83*0b57cec5SDimitry Andric
84*0b57cec5SDimitry Andric    constexpr duration& operator+=(const duration& d);  // constexpr in C++17
85*0b57cec5SDimitry Andric    constexpr duration& operator-=(const duration& d);  // constexpr in C++17
86*0b57cec5SDimitry Andric
87*0b57cec5SDimitry Andric    duration& operator*=(const rep& rhs);       // constexpr in C++17
88*0b57cec5SDimitry Andric    duration& operator/=(const rep& rhs);       // constexpr in C++17
89*0b57cec5SDimitry Andric    duration& operator%=(const rep& rhs);       // constexpr in C++17
90*0b57cec5SDimitry Andric    duration& operator%=(const duration& rhs);  // constexpr in C++17
91*0b57cec5SDimitry Andric
92*0b57cec5SDimitry Andric    // special values
93*0b57cec5SDimitry Andric
94*0b57cec5SDimitry Andric    static constexpr duration zero(); // noexcept in C++20
95*0b57cec5SDimitry Andric    static constexpr duration min();  // noexcept in C++20
96*0b57cec5SDimitry Andric    static constexpr duration max();  // noexcept in C++20
97*0b57cec5SDimitry Andric};
98*0b57cec5SDimitry Andric
99*0b57cec5SDimitry Andrictypedef duration<long long,         nano> nanoseconds;
100*0b57cec5SDimitry Andrictypedef duration<long long,        micro> microseconds;
101*0b57cec5SDimitry Andrictypedef duration<long long,        milli> milliseconds;
102*0b57cec5SDimitry Andrictypedef duration<long long              > seconds;
103*0b57cec5SDimitry Andrictypedef duration<     long, ratio<  60> > minutes;
104*0b57cec5SDimitry Andrictypedef duration<     long, ratio<3600> > hours;
105*0b57cec5SDimitry Andric
106*0b57cec5SDimitry Andrictemplate <class Clock, class Duration = typename Clock::duration>
107*0b57cec5SDimitry Andricclass time_point
108*0b57cec5SDimitry Andric{
109*0b57cec5SDimitry Andricpublic:
110*0b57cec5SDimitry Andric    typedef Clock                     clock;
111*0b57cec5SDimitry Andric    typedef Duration                  duration;
112*0b57cec5SDimitry Andric    typedef typename duration::rep    rep;
113*0b57cec5SDimitry Andric    typedef typename duration::period period;
114*0b57cec5SDimitry Andricprivate:
115*0b57cec5SDimitry Andric    duration d_;  // exposition only
116*0b57cec5SDimitry Andric
117*0b57cec5SDimitry Andricpublic:
118*0b57cec5SDimitry Andric    time_point();  // has value "epoch" // constexpr in C++14
119*0b57cec5SDimitry Andric    explicit time_point(const duration& d);  // same as time_point() + d // constexpr in C++14
120*0b57cec5SDimitry Andric
121*0b57cec5SDimitry Andric    // conversions
122*0b57cec5SDimitry Andric    template <class Duration2>
123*0b57cec5SDimitry Andric       time_point(const time_point<clock, Duration2>& t); // constexpr in C++14
124*0b57cec5SDimitry Andric
125*0b57cec5SDimitry Andric    // observer
126*0b57cec5SDimitry Andric
127*0b57cec5SDimitry Andric    duration time_since_epoch() const; // constexpr in C++14
128*0b57cec5SDimitry Andric
129*0b57cec5SDimitry Andric    // arithmetic
130*0b57cec5SDimitry Andric
131*0b57cec5SDimitry Andric    time_point& operator+=(const duration& d); // constexpr in C++17
132*0b57cec5SDimitry Andric    time_point& operator-=(const duration& d); // constexpr in C++17
133*0b57cec5SDimitry Andric
134*0b57cec5SDimitry Andric    // special values
135*0b57cec5SDimitry Andric
136*0b57cec5SDimitry Andric    static constexpr time_point min();  // noexcept in C++20
137*0b57cec5SDimitry Andric    static constexpr time_point max();  // noexcept in C++20
138*0b57cec5SDimitry Andric};
139*0b57cec5SDimitry Andric
140*0b57cec5SDimitry Andric} // chrono
141*0b57cec5SDimitry Andric
142*0b57cec5SDimitry Andric// common_type traits
143*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Rep2, class Period2>
144*0b57cec5SDimitry Andric  struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>>;
145*0b57cec5SDimitry Andric
146*0b57cec5SDimitry Andrictemplate <class Clock, class Duration1, class Duration2>
147*0b57cec5SDimitry Andric  struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>>;
148*0b57cec5SDimitry Andric
149*0b57cec5SDimitry Andricnamespace chrono {
150*0b57cec5SDimitry Andric
151*0b57cec5SDimitry Andric
152*0b57cec5SDimitry Andrictemplate<class T> struct is_clock;  // C++20
153*0b57cec5SDimitry Andrictemplate<class T> inline constexpr bool is_clock_v = is_clock<T>::value;   // C++20
154*0b57cec5SDimitry Andric
155*0b57cec5SDimitry Andric
156*0b57cec5SDimitry Andric// duration arithmetic
157*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Rep2, class Period2>
158*0b57cec5SDimitry Andric  constexpr
159*0b57cec5SDimitry Andric  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
160*0b57cec5SDimitry Andric  operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
161*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Rep2, class Period2>
162*0b57cec5SDimitry Andric  constexpr
163*0b57cec5SDimitry Andric  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
164*0b57cec5SDimitry Andric  operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
165*0b57cec5SDimitry Andrictemplate <class Rep1, class Period, class Rep2>
166*0b57cec5SDimitry Andric  constexpr
167*0b57cec5SDimitry Andric  duration<typename common_type<Rep1, Rep2>::type, Period>
168*0b57cec5SDimitry Andric  operator*(const duration<Rep1, Period>& d, const Rep2& s);
169*0b57cec5SDimitry Andrictemplate <class Rep1, class Period, class Rep2>
170*0b57cec5SDimitry Andric  constexpr
171*0b57cec5SDimitry Andric  duration<typename common_type<Rep1, Rep2>::type, Period>
172*0b57cec5SDimitry Andric  operator*(const Rep1& s, const duration<Rep2, Period>& d);
173*0b57cec5SDimitry Andrictemplate <class Rep1, class Period, class Rep2>
174*0b57cec5SDimitry Andric  constexpr
175*0b57cec5SDimitry Andric  duration<typename common_type<Rep1, Rep2>::type, Period>
176*0b57cec5SDimitry Andric  operator/(const duration<Rep1, Period>& d, const Rep2& s);
177*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Rep2, class Period2>
178*0b57cec5SDimitry Andric  constexpr
179*0b57cec5SDimitry Andric  typename common_type<Rep1, Rep2>::type
180*0b57cec5SDimitry Andric  operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
181*0b57cec5SDimitry Andric
182*0b57cec5SDimitry Andric// duration comparisons
183*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Rep2, class Period2>
184*0b57cec5SDimitry Andric   constexpr
185*0b57cec5SDimitry Andric   bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
186*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Rep2, class Period2>
187*0b57cec5SDimitry Andric   constexpr
188*0b57cec5SDimitry Andric   bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
189*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Rep2, class Period2>
190*0b57cec5SDimitry Andric   constexpr
191*0b57cec5SDimitry Andric   bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
192*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Rep2, class Period2>
193*0b57cec5SDimitry Andric   constexpr
194*0b57cec5SDimitry Andric   bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
195*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Rep2, class Period2>
196*0b57cec5SDimitry Andric   constexpr
197*0b57cec5SDimitry Andric   bool operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
198*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Rep2, class Period2>
199*0b57cec5SDimitry Andric   constexpr
200*0b57cec5SDimitry Andric   bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
201*0b57cec5SDimitry Andric
202*0b57cec5SDimitry Andric// duration_cast
203*0b57cec5SDimitry Andrictemplate <class ToDuration, class Rep, class Period>
204*0b57cec5SDimitry Andric  ToDuration duration_cast(const duration<Rep, Period>& d);
205*0b57cec5SDimitry Andric
206*0b57cec5SDimitry Andrictemplate <class ToDuration, class Rep, class Period>
207*0b57cec5SDimitry Andric    constexpr ToDuration floor(const duration<Rep, Period>& d);    // C++17
208*0b57cec5SDimitry Andrictemplate <class ToDuration, class Rep, class Period>
209*0b57cec5SDimitry Andric    constexpr ToDuration ceil(const duration<Rep, Period>& d);     // C++17
210*0b57cec5SDimitry Andrictemplate <class ToDuration, class Rep, class Period>
211*0b57cec5SDimitry Andric    constexpr ToDuration round(const duration<Rep, Period>& d);    // C++17
212*0b57cec5SDimitry Andric
213*0b57cec5SDimitry Andric// duration I/O is elsewhere
214*0b57cec5SDimitry Andric
215*0b57cec5SDimitry Andric// time_point arithmetic (all constexpr in C++14)
216*0b57cec5SDimitry Andrictemplate <class Clock, class Duration1, class Rep2, class Period2>
217*0b57cec5SDimitry Andric  time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
218*0b57cec5SDimitry Andric  operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
219*0b57cec5SDimitry Andrictemplate <class Rep1, class Period1, class Clock, class Duration2>
220*0b57cec5SDimitry Andric  time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
221*0b57cec5SDimitry Andric  operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
222*0b57cec5SDimitry Andrictemplate <class Clock, class Duration1, class Rep2, class Period2>
223*0b57cec5SDimitry Andric  time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
224*0b57cec5SDimitry Andric  operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
225*0b57cec5SDimitry Andrictemplate <class Clock, class Duration1, class Duration2>
226*0b57cec5SDimitry Andric  typename common_type<Duration1, Duration2>::type
227*0b57cec5SDimitry Andric  operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
228*0b57cec5SDimitry Andric
229*0b57cec5SDimitry Andric// time_point comparisons (all constexpr in C++14)
230*0b57cec5SDimitry Andrictemplate <class Clock, class Duration1, class Duration2>
231*0b57cec5SDimitry Andric   bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
232*0b57cec5SDimitry Andrictemplate <class Clock, class Duration1, class Duration2>
233*0b57cec5SDimitry Andric   bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
234*0b57cec5SDimitry Andrictemplate <class Clock, class Duration1, class Duration2>
235*0b57cec5SDimitry Andric   bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
236*0b57cec5SDimitry Andrictemplate <class Clock, class Duration1, class Duration2>
237*0b57cec5SDimitry Andric   bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
238*0b57cec5SDimitry Andrictemplate <class Clock, class Duration1, class Duration2>
239*0b57cec5SDimitry Andric   bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
240*0b57cec5SDimitry Andrictemplate <class Clock, class Duration1, class Duration2>
241*0b57cec5SDimitry Andric   bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
242*0b57cec5SDimitry Andric
243*0b57cec5SDimitry Andric// time_point_cast (constexpr in C++14)
244*0b57cec5SDimitry Andric
245*0b57cec5SDimitry Andrictemplate <class ToDuration, class Clock, class Duration>
246*0b57cec5SDimitry Andric  time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
247*0b57cec5SDimitry Andric
248*0b57cec5SDimitry Andrictemplate <class ToDuration, class Clock, class Duration>
249*0b57cec5SDimitry Andric    constexpr time_point<Clock, ToDuration>
250*0b57cec5SDimitry Andric    floor(const time_point<Clock, Duration>& tp);                  // C++17
251*0b57cec5SDimitry Andric
252*0b57cec5SDimitry Andrictemplate <class ToDuration, class Clock, class Duration>
253*0b57cec5SDimitry Andric    constexpr time_point<Clock, ToDuration>
254*0b57cec5SDimitry Andric    ceil(const time_point<Clock, Duration>& tp);                   // C++17
255*0b57cec5SDimitry Andric
256*0b57cec5SDimitry Andrictemplate <class ToDuration, class Clock, class Duration>
257*0b57cec5SDimitry Andric    constexpr time_point<Clock, ToDuration>
258*0b57cec5SDimitry Andric    round(const time_point<Clock, Duration>& tp);                  // C++17
259*0b57cec5SDimitry Andric
260*0b57cec5SDimitry Andrictemplate <class Rep, class Period>
261*0b57cec5SDimitry Andric    constexpr duration<Rep, Period> abs(duration<Rep, Period> d);  // C++17
262*0b57cec5SDimitry Andric
263*0b57cec5SDimitry Andric// Clocks
264*0b57cec5SDimitry Andric
265*0b57cec5SDimitry Andricclass system_clock
266*0b57cec5SDimitry Andric{
267*0b57cec5SDimitry Andricpublic:
268*0b57cec5SDimitry Andric    typedef microseconds                     duration;
269*0b57cec5SDimitry Andric    typedef duration::rep                    rep;
270*0b57cec5SDimitry Andric    typedef duration::period                 period;
271*0b57cec5SDimitry Andric    typedef chrono::time_point<system_clock> time_point;
272*0b57cec5SDimitry Andric    static const bool is_steady =            false; // constexpr in C++14
273*0b57cec5SDimitry Andric
274*0b57cec5SDimitry Andric    static time_point now() noexcept;
275*0b57cec5SDimitry Andric    static time_t     to_time_t  (const time_point& __t) noexcept;
276*0b57cec5SDimitry Andric    static time_point from_time_t(time_t __t) noexcept;
277*0b57cec5SDimitry Andric};
278*0b57cec5SDimitry Andric
279*0b57cec5SDimitry Andrictemplate <class Duration>
280*0b57cec5SDimitry Andric  using sys_time  = time_point<system_clock, Duration>; // C++20
281*0b57cec5SDimitry Andricusing sys_seconds = sys_time<seconds>;                  // C++20
282*0b57cec5SDimitry Andricusing sys_days    = sys_time<days>;                     // C++20
283*0b57cec5SDimitry Andric
284*0b57cec5SDimitry Andricclass utc_clock;                                        // C++20
285*0b57cec5SDimitry Andric
286*0b57cec5SDimitry Andrictemplate <class Duration>
287*0b57cec5SDimitry Andric  using utc_time  = time_point<utc_clock, Duration>;    // C++20
288*0b57cec5SDimitry Andricusing utc_seconds = utc_time<seconds>;                  // C++20
289*0b57cec5SDimitry Andric
290*0b57cec5SDimitry Andricclass tai_clock;                                        // C++20
291*0b57cec5SDimitry Andric
292*0b57cec5SDimitry Andrictemplate <class Duration>
293*0b57cec5SDimitry Andric  using tai_time  = time_point<tai_clock, Duration>;    // C++20
294*0b57cec5SDimitry Andricusing tai_seconds = tai_time<seconds>;                  // C++20
295*0b57cec5SDimitry Andric
296*0b57cec5SDimitry Andricclass file_clock;                                       // C++20
297*0b57cec5SDimitry Andric
298*0b57cec5SDimitry Andrictemplate<class Duration>
299*0b57cec5SDimitry Andric  using file_time = time_point<file_clock, Duration>;   // C++20
300*0b57cec5SDimitry Andric
301*0b57cec5SDimitry Andricclass steady_clock
302*0b57cec5SDimitry Andric{
303*0b57cec5SDimitry Andricpublic:
304*0b57cec5SDimitry Andric    typedef nanoseconds                                   duration;
305*0b57cec5SDimitry Andric    typedef duration::rep                                 rep;
306*0b57cec5SDimitry Andric    typedef duration::period                              period;
307*0b57cec5SDimitry Andric    typedef chrono::time_point<steady_clock, duration>    time_point;
308*0b57cec5SDimitry Andric    static const bool is_steady =                         true; // constexpr in C++14
309*0b57cec5SDimitry Andric
310*0b57cec5SDimitry Andric    static time_point now() noexcept;
311*0b57cec5SDimitry Andric};
312*0b57cec5SDimitry Andric
313*0b57cec5SDimitry Andrictypedef steady_clock high_resolution_clock;
314*0b57cec5SDimitry Andric
315*0b57cec5SDimitry Andric// 25.7.8, local time           // C++20
316*0b57cec5SDimitry Andricstruct local_t {};
317*0b57cec5SDimitry Andrictemplate<class Duration>
318*0b57cec5SDimitry Andric  using local_time  = time_point<local_t, Duration>;
319*0b57cec5SDimitry Andricusing local_seconds = local_time<seconds>;
320*0b57cec5SDimitry Andricusing local_days    = local_time<days>;
321*0b57cec5SDimitry Andric
322*0b57cec5SDimitry Andric// 25.7.9, time_point conversions template<class DestClock, class SourceClock>    // C++20
323*0b57cec5SDimitry Andricstruct clock_time_conversion;
324*0b57cec5SDimitry Andric
325*0b57cec5SDimitry Andrictemplate<class DestClock, class SourceClock, class Duration>
326*0b57cec5SDimitry Andric  auto clock_cast(const time_point<SourceClock, Duration>& t);
327*0b57cec5SDimitry Andric
328*0b57cec5SDimitry Andric// 25.8.2, class last_spec    // C++20
329*0b57cec5SDimitry Andricstruct last_spec;
330*0b57cec5SDimitry Andric
331*0b57cec5SDimitry Andric// 25.8.3, class day          // C++20
332*0b57cec5SDimitry Andric
333*0b57cec5SDimitry Andricclass day;
334*0b57cec5SDimitry Andricconstexpr bool operator==(const day& x, const day& y) noexcept;
335*0b57cec5SDimitry Andricconstexpr bool operator!=(const day& x, const day& y) noexcept;
336*0b57cec5SDimitry Andricconstexpr bool operator< (const day& x, const day& y) noexcept;
337*0b57cec5SDimitry Andricconstexpr bool operator> (const day& x, const day& y) noexcept;
338*0b57cec5SDimitry Andricconstexpr bool operator<=(const day& x, const day& y) noexcept;
339*0b57cec5SDimitry Andricconstexpr bool operator>=(const day& x, const day& y) noexcept;
340*0b57cec5SDimitry Andricconstexpr day  operator+(const day&  x, const days& y) noexcept;
341*0b57cec5SDimitry Andricconstexpr day  operator+(const days& x, const day&  y) noexcept;
342*0b57cec5SDimitry Andricconstexpr day  operator-(const day&  x, const days& y) noexcept;
343*0b57cec5SDimitry Andricconstexpr days operator-(const day&  x, const day&  y) noexcept;
344*0b57cec5SDimitry Andric
345*0b57cec5SDimitry Andric// 25.8.4, class month    // C++20
346*0b57cec5SDimitry Andricclass month;
347*0b57cec5SDimitry Andricconstexpr bool operator==(const month& x, const month& y) noexcept;
348*0b57cec5SDimitry Andricconstexpr bool operator!=(const month& x, const month& y) noexcept;
349*0b57cec5SDimitry Andricconstexpr bool operator< (const month& x, const month& y) noexcept;
350*0b57cec5SDimitry Andricconstexpr bool operator> (const month& x, const month& y) noexcept;
351*0b57cec5SDimitry Andricconstexpr bool operator<=(const month& x, const month& y) noexcept;
352*0b57cec5SDimitry Andricconstexpr bool operator>=(const month& x, const month& y) noexcept;
353*0b57cec5SDimitry Andricconstexpr month  operator+(const month&  x, const months& y) noexcept;
354*0b57cec5SDimitry Andricconstexpr month  operator+(const months& x,  const month& y) noexcept;
355*0b57cec5SDimitry Andricconstexpr month  operator-(const month&  x, const months& y) noexcept;
356*0b57cec5SDimitry Andricconstexpr months operator-(const month&  x,  const month& y) noexcept;
357*0b57cec5SDimitry Andric
358*0b57cec5SDimitry Andric// 25.8.5, class year    // C++20
359*0b57cec5SDimitry Andricclass year;
360*0b57cec5SDimitry Andricconstexpr bool operator==(const year& x, const year& y) noexcept;
361*0b57cec5SDimitry Andricconstexpr bool operator!=(const year& x, const year& y) noexcept;
362*0b57cec5SDimitry Andricconstexpr bool operator< (const year& x, const year& y) noexcept;
363*0b57cec5SDimitry Andricconstexpr bool operator> (const year& x, const year& y) noexcept;
364*0b57cec5SDimitry Andricconstexpr bool operator<=(const year& x, const year& y) noexcept;
365*0b57cec5SDimitry Andricconstexpr bool operator>=(const year& x, const year& y) noexcept;
366*0b57cec5SDimitry Andricconstexpr year  operator+(const year&  x, const years& y) noexcept;
367*0b57cec5SDimitry Andricconstexpr year  operator+(const years& x, const year&  y) noexcept;
368*0b57cec5SDimitry Andricconstexpr year  operator-(const year&  x, const years& y) noexcept;
369*0b57cec5SDimitry Andricconstexpr years operator-(const year&  x, const year&  y) noexcept;
370*0b57cec5SDimitry Andric
371*0b57cec5SDimitry Andric// 25.8.6, class weekday    // C++20
372*0b57cec5SDimitry Andricclass weekday;
373*0b57cec5SDimitry Andric
374*0b57cec5SDimitry Andricconstexpr bool operator==(const weekday& x, const weekday& y) noexcept;
375*0b57cec5SDimitry Andricconstexpr bool operator!=(const weekday& x, const weekday& y) noexcept;
376*0b57cec5SDimitry Andricconstexpr weekday operator+(const weekday& x, const days&    y) noexcept;
377*0b57cec5SDimitry Andricconstexpr weekday operator+(const days&    x, const weekday& y) noexcept;
378*0b57cec5SDimitry Andricconstexpr weekday operator-(const weekday& x, const days&    y) noexcept;
379*0b57cec5SDimitry Andricconstexpr days    operator-(const weekday& x, const weekday& y) noexcept;
380*0b57cec5SDimitry Andric
381*0b57cec5SDimitry Andric// 25.8.7, class weekday_indexed    // C++20
382*0b57cec5SDimitry Andric
383*0b57cec5SDimitry Andricclass weekday_indexed;
384*0b57cec5SDimitry Andricconstexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;
385*0b57cec5SDimitry Andricconstexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept;
386*0b57cec5SDimitry Andric
387*0b57cec5SDimitry Andric// 25.8.8, class weekday_last    // C++20
388*0b57cec5SDimitry Andricclass weekday_last;
389*0b57cec5SDimitry Andric
390*0b57cec5SDimitry Andricconstexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept;
391*0b57cec5SDimitry Andricconstexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept;
392*0b57cec5SDimitry Andric
393*0b57cec5SDimitry Andric// 25.8.9, class month_day    // C++20
394*0b57cec5SDimitry Andricclass month_day;
395*0b57cec5SDimitry Andric
396*0b57cec5SDimitry Andricconstexpr bool operator==(const month_day& x, const month_day& y) noexcept;
397*0b57cec5SDimitry Andricconstexpr bool operator!=(const month_day& x, const month_day& y) noexcept;
398*0b57cec5SDimitry Andricconstexpr bool operator< (const month_day& x, const month_day& y) noexcept;
399*0b57cec5SDimitry Andricconstexpr bool operator> (const month_day& x, const month_day& y) noexcept;
400*0b57cec5SDimitry Andricconstexpr bool operator<=(const month_day& x, const month_day& y) noexcept;
401*0b57cec5SDimitry Andricconstexpr bool operator>=(const month_day& x, const month_day& y) noexcept;
402*0b57cec5SDimitry Andric
403*0b57cec5SDimitry Andric
404*0b57cec5SDimitry Andric// 25.8.10, class month_day_last    // C++20
405*0b57cec5SDimitry Andricclass month_day_last;
406*0b57cec5SDimitry Andric
407*0b57cec5SDimitry Andricconstexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept;
408*0b57cec5SDimitry Andricconstexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept;
409*0b57cec5SDimitry Andricconstexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept;
410*0b57cec5SDimitry Andricconstexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept;
411*0b57cec5SDimitry Andricconstexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept;
412*0b57cec5SDimitry Andricconstexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept;
413*0b57cec5SDimitry Andric
414*0b57cec5SDimitry Andric// 25.8.11, class month_weekday    // C++20
415*0b57cec5SDimitry Andricclass month_weekday;
416*0b57cec5SDimitry Andric
417*0b57cec5SDimitry Andricconstexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
418*0b57cec5SDimitry Andricconstexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept;
419*0b57cec5SDimitry Andric
420*0b57cec5SDimitry Andric// 25.8.12, class month_weekday_last    // C++20
421*0b57cec5SDimitry Andricclass month_weekday_last;
422*0b57cec5SDimitry Andric
423*0b57cec5SDimitry Andricconstexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
424*0b57cec5SDimitry Andricconstexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept;
425*0b57cec5SDimitry Andric
426*0b57cec5SDimitry Andric
427*0b57cec5SDimitry Andric// 25.8.13, class year_month    // C++20
428*0b57cec5SDimitry Andricclass year_month;
429*0b57cec5SDimitry Andric
430*0b57cec5SDimitry Andricconstexpr bool operator==(const year_month& x, const year_month& y) noexcept;
431*0b57cec5SDimitry Andricconstexpr bool operator!=(const year_month& x, const year_month& y) noexcept;
432*0b57cec5SDimitry Andricconstexpr bool operator< (const year_month& x, const year_month& y) noexcept;
433*0b57cec5SDimitry Andricconstexpr bool operator> (const year_month& x, const year_month& y) noexcept;
434*0b57cec5SDimitry Andricconstexpr bool operator<=(const year_month& x, const year_month& y) noexcept;
435*0b57cec5SDimitry Andricconstexpr bool operator>=(const year_month& x, const year_month& y) noexcept;
436*0b57cec5SDimitry Andric
437*0b57cec5SDimitry Andricconstexpr year_month operator+(const year_month& ym, const months& dm) noexcept;
438*0b57cec5SDimitry Andricconstexpr year_month operator+(const months& dm, const year_month& ym) noexcept;
439*0b57cec5SDimitry Andricconstexpr year_month operator-(const year_month& ym, const months& dm) noexcept;
440*0b57cec5SDimitry Andricconstexpr months operator-(const year_month& x, const year_month& y) noexcept;
441*0b57cec5SDimitry Andricconstexpr year_month operator+(const year_month& ym, const years& dy) noexcept;
442*0b57cec5SDimitry Andricconstexpr year_month operator+(const years& dy, const year_month& ym) noexcept;
443*0b57cec5SDimitry Andricconstexpr year_month operator-(const year_month& ym, const years& dy) noexcept;
444*0b57cec5SDimitry Andric
445*0b57cec5SDimitry Andric// 25.8.14, class year_month_day class    // C++20
446*0b57cec5SDimitry Andricyear_month_day;
447*0b57cec5SDimitry Andric
448*0b57cec5SDimitry Andricconstexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept;
449*0b57cec5SDimitry Andricconstexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept;
450*0b57cec5SDimitry Andricconstexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept;
451*0b57cec5SDimitry Andricconstexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept;
452*0b57cec5SDimitry Andricconstexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept;
453*0b57cec5SDimitry Andricconstexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept;
454*0b57cec5SDimitry Andric
455*0b57cec5SDimitry Andricconstexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept;
456*0b57cec5SDimitry Andricconstexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept;
457*0b57cec5SDimitry Andricconstexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept;
458*0b57cec5SDimitry Andricconstexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept;
459*0b57cec5SDimitry Andricconstexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
460*0b57cec5SDimitry Andricconstexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
461*0b57cec5SDimitry Andric
462*0b57cec5SDimitry Andric
463*0b57cec5SDimitry Andric// 25.8.15, class year_month_day_last    // C++20
464*0b57cec5SDimitry Andricclass year_month_day_last;
465*0b57cec5SDimitry Andric
466*0b57cec5SDimitry Andricconstexpr bool operator==(const year_month_day_last& x,
467*0b57cec5SDimitry Andric                          const year_month_day_last& y) noexcept;
468*0b57cec5SDimitry Andricconstexpr bool operator!=(const year_month_day_last& x,
469*0b57cec5SDimitry Andric                          const year_month_day_last& y) noexcept;
470*0b57cec5SDimitry Andricconstexpr bool operator< (const year_month_day_last& x,
471*0b57cec5SDimitry Andric                          const year_month_day_last& y) noexcept;
472*0b57cec5SDimitry Andricconstexpr bool operator> (const year_month_day_last& x,
473*0b57cec5SDimitry Andric                          const year_month_day_last& y) noexcept;
474*0b57cec5SDimitry Andricconstexpr bool operator<=(const year_month_day_last& x,
475*0b57cec5SDimitry Andric                          const year_month_day_last& y) noexcept;
476*0b57cec5SDimitry Andricconstexpr bool operator>=(const year_month_day_last& x,
477*0b57cec5SDimitry Andric                          const year_month_day_last& y) noexcept;
478*0b57cec5SDimitry Andric
479*0b57cec5SDimitry Andricconstexpr year_month_day_last
480*0b57cec5SDimitry Andric  operator+(const year_month_day_last& ymdl, const months& dm) noexcept;
481*0b57cec5SDimitry Andricconstexpr year_month_day_last
482*0b57cec5SDimitry Andric  operator+(const months& dm, const year_month_day_last& ymdl) noexcept;
483*0b57cec5SDimitry Andricconstexpr year_month_day_last
484*0b57cec5SDimitry Andric  operator+(const year_month_day_last& ymdl, const years& dy) noexcept;
485*0b57cec5SDimitry Andricconstexpr year_month_day_last
486*0b57cec5SDimitry Andric  operator+(const years& dy, const year_month_day_last& ymdl) noexcept;
487*0b57cec5SDimitry Andricconstexpr year_month_day_last
488*0b57cec5SDimitry Andric  operator-(const year_month_day_last& ymdl, const months& dm) noexcept;
489*0b57cec5SDimitry Andricconstexpr year_month_day_last
490*0b57cec5SDimitry Andric  operator-(const year_month_day_last& ymdl, const years& dy) noexcept;
491*0b57cec5SDimitry Andric
492*0b57cec5SDimitry Andric// 25.8.16, class year_month_weekday    // C++20
493*0b57cec5SDimitry Andricclass year_month_weekday;
494*0b57cec5SDimitry Andric
495*0b57cec5SDimitry Andricconstexpr bool operator==(const year_month_weekday& x,
496*0b57cec5SDimitry Andric                          const year_month_weekday& y) noexcept;
497*0b57cec5SDimitry Andricconstexpr bool operator!=(const year_month_weekday& x,
498*0b57cec5SDimitry Andric                          const year_month_weekday& y) noexcept;
499*0b57cec5SDimitry Andric
500*0b57cec5SDimitry Andricconstexpr year_month_weekday
501*0b57cec5SDimitry Andric  operator+(const year_month_weekday& ymwd, const months& dm) noexcept;
502*0b57cec5SDimitry Andricconstexpr year_month_weekday
503*0b57cec5SDimitry Andric  operator+(const months& dm, const year_month_weekday& ymwd) noexcept;
504*0b57cec5SDimitry Andricconstexpr year_month_weekday
505*0b57cec5SDimitry Andric  operator+(const year_month_weekday& ymwd, const years& dy) noexcept;
506*0b57cec5SDimitry Andricconstexpr year_month_weekday
507*0b57cec5SDimitry Andric  operator+(const years& dy, const year_month_weekday& ymwd) noexcept;
508*0b57cec5SDimitry Andricconstexpr year_month_weekday
509*0b57cec5SDimitry Andric  operator-(const year_month_weekday& ymwd, const months& dm) noexcept;
510*0b57cec5SDimitry Andricconstexpr year_month_weekday
511*0b57cec5SDimitry Andric  operator-(const year_month_weekday& ymwd, const years& dy) noexcept;
512*0b57cec5SDimitry Andric
513*0b57cec5SDimitry Andric// 25.8.17, class year_month_weekday_last    // C++20
514*0b57cec5SDimitry Andricclass year_month_weekday_last;
515*0b57cec5SDimitry Andric
516*0b57cec5SDimitry Andricconstexpr bool operator==(const year_month_weekday_last& x,
517*0b57cec5SDimitry Andric                          const year_month_weekday_last& y) noexcept;
518*0b57cec5SDimitry Andricconstexpr bool operator!=(const year_month_weekday_last& x,
519*0b57cec5SDimitry Andric                          const year_month_weekday_last& y) noexcept;
520*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
521*0b57cec5SDimitry Andric  operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
522*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
523*0b57cec5SDimitry Andric  operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept;
524*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
525*0b57cec5SDimitry Andric  operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
526*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
527*0b57cec5SDimitry Andric  operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept;
528*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
529*0b57cec5SDimitry Andric  operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
530*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
531*0b57cec5SDimitry Andric  operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
532*0b57cec5SDimitry Andric
533*0b57cec5SDimitry Andric// 25.8.18, civil calendar conventional syntax operators    // C++20
534*0b57cec5SDimitry Andricconstexpr year_month
535*0b57cec5SDimitry Andric  operator/(const year& y, const month& m) noexcept;
536*0b57cec5SDimitry Andricconstexpr year_month
537*0b57cec5SDimitry Andric  operator/(const year& y, int m) noexcept;
538*0b57cec5SDimitry Andricconstexpr month_day
539*0b57cec5SDimitry Andric  operator/(const month& m, const day& d) noexcept;
540*0b57cec5SDimitry Andricconstexpr month_day
541*0b57cec5SDimitry Andric  operator/(const month& m, int d) noexcept;
542*0b57cec5SDimitry Andricconstexpr month_day
543*0b57cec5SDimitry Andric  operator/(int m, const day& d) noexcept;
544*0b57cec5SDimitry Andricconstexpr month_day
545*0b57cec5SDimitry Andric  operator/(const day& d, const month& m) noexcept;
546*0b57cec5SDimitry Andricconstexpr month_day
547*0b57cec5SDimitry Andric  operator/(const day& d, int m) noexcept;
548*0b57cec5SDimitry Andricconstexpr month_day_last
549*0b57cec5SDimitry Andric  operator/(const month& m, last_spec) noexcept;
550*0b57cec5SDimitry Andricconstexpr month_day_last
551*0b57cec5SDimitry Andric  operator/(int m, last_spec) noexcept;
552*0b57cec5SDimitry Andricconstexpr month_day_last
553*0b57cec5SDimitry Andric  operator/(last_spec, const month& m) noexcept;
554*0b57cec5SDimitry Andricconstexpr month_day_last
555*0b57cec5SDimitry Andric  operator/(last_spec, int m) noexcept;
556*0b57cec5SDimitry Andricconstexpr month_weekday
557*0b57cec5SDimitry Andric  operator/(const month& m, const weekday_indexed& wdi) noexcept;
558*0b57cec5SDimitry Andricconstexpr month_weekday
559*0b57cec5SDimitry Andric  operator/(int m, const weekday_indexed& wdi) noexcept;
560*0b57cec5SDimitry Andricconstexpr month_weekday
561*0b57cec5SDimitry Andric  operator/(const weekday_indexed& wdi, const month& m) noexcept;
562*0b57cec5SDimitry Andricconstexpr month_weekday
563*0b57cec5SDimitry Andric  operator/(const weekday_indexed& wdi, int m) noexcept;
564*0b57cec5SDimitry Andricconstexpr month_weekday_last
565*0b57cec5SDimitry Andric  operator/(const month& m, const weekday_last& wdl) noexcept;
566*0b57cec5SDimitry Andricconstexpr month_weekday_last
567*0b57cec5SDimitry Andric  operator/(int m, const weekday_last& wdl) noexcept;
568*0b57cec5SDimitry Andricconstexpr month_weekday_last
569*0b57cec5SDimitry Andric  operator/(const weekday_last& wdl, const month& m) noexcept;
570*0b57cec5SDimitry Andricconstexpr month_weekday_last
571*0b57cec5SDimitry Andric  operator/(const weekday_last& wdl, int m) noexcept;
572*0b57cec5SDimitry Andricconstexpr year_month_day
573*0b57cec5SDimitry Andric  operator/(const year_month& ym, const day& d) noexcept;
574*0b57cec5SDimitry Andricconstexpr year_month_day
575*0b57cec5SDimitry Andric  operator/(const year_month& ym, int d) noexcept;
576*0b57cec5SDimitry Andricconstexpr year_month_day
577*0b57cec5SDimitry Andric  operator/(const year& y, const month_day& md) noexcept;
578*0b57cec5SDimitry Andricconstexpr year_month_day
579*0b57cec5SDimitry Andric  operator/(int y, const month_day& md) noexcept;
580*0b57cec5SDimitry Andricconstexpr year_month_day
581*0b57cec5SDimitry Andric  operator/(const month_day& md, const year& y) noexcept;
582*0b57cec5SDimitry Andricconstexpr year_month_day
583*0b57cec5SDimitry Andric  operator/(const month_day& md, int y) noexcept;
584*0b57cec5SDimitry Andricconstexpr year_month_day_last
585*0b57cec5SDimitry Andric  operator/(const year_month& ym, last_spec) noexcept;
586*0b57cec5SDimitry Andricconstexpr year_month_day_last
587*0b57cec5SDimitry Andric  operator/(const year& y, const month_day_last& mdl) noexcept;
588*0b57cec5SDimitry Andricconstexpr year_month_day_last
589*0b57cec5SDimitry Andric  operator/(int y, const month_day_last& mdl) noexcept;
590*0b57cec5SDimitry Andricconstexpr year_month_day_last
591*0b57cec5SDimitry Andric  operator/(const month_day_last& mdl, const year& y) noexcept;
592*0b57cec5SDimitry Andricconstexpr year_month_day_last
593*0b57cec5SDimitry Andric  operator/(const month_day_last& mdl, int y) noexcept;
594*0b57cec5SDimitry Andricconstexpr year_month_weekday
595*0b57cec5SDimitry Andric  operator/(const year_month& ym, const weekday_indexed& wdi) noexcept;
596*0b57cec5SDimitry Andricconstexpr year_month_weekday
597*0b57cec5SDimitry Andric  operator/(const year& y, const month_weekday& mwd) noexcept;
598*0b57cec5SDimitry Andricconstexpr year_month_weekday
599*0b57cec5SDimitry Andric  operator/(int y, const month_weekday& mwd) noexcept;
600*0b57cec5SDimitry Andricconstexpr year_month_weekday
601*0b57cec5SDimitry Andric  operator/(const month_weekday& mwd, const year& y) noexcept;
602*0b57cec5SDimitry Andricconstexpr year_month_weekday
603*0b57cec5SDimitry Andric  operator/(const month_weekday& mwd, int y) noexcept;
604*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
605*0b57cec5SDimitry Andric  operator/(const year_month& ym, const weekday_last& wdl) noexcept;
606*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
607*0b57cec5SDimitry Andric  operator/(const year& y, const month_weekday_last& mwdl) noexcept;
608*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
609*0b57cec5SDimitry Andric  operator/(int y, const month_weekday_last& mwdl) noexcept;
610*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
611*0b57cec5SDimitry Andric  operator/(const month_weekday_last& mwdl, const year& y) noexcept;
612*0b57cec5SDimitry Andricconstexpr year_month_weekday_last
613*0b57cec5SDimitry Andric  operator/(const month_weekday_last& mwdl, int y) noexcept;
614*0b57cec5SDimitry Andric
615*0b57cec5SDimitry Andric// 25.9, class template time_of_day    // C++20
616*0b57cec5SDimitry Andrictemplate<class Duration> class time_of_day;
617*0b57cec5SDimitry Andric
618*0b57cec5SDimitry Andrictemplate<> class time_of_day<hours>;
619*0b57cec5SDimitry Andrictemplate<> class time_of_day<minutes>;
620*0b57cec5SDimitry Andrictemplate<> class time_of_day<seconds>;
621*0b57cec5SDimitry Andrictemplate<class Rep, class Period> class time_of_day<duration<Rep, Period>>;
622*0b57cec5SDimitry Andric
623*0b57cec5SDimitry Andric// 25.10.2, time zone database     // C++20
624*0b57cec5SDimitry Andricstruct tzdb;
625*0b57cec5SDimitry Andricclass tzdb_list;
626*0b57cec5SDimitry Andric
627*0b57cec5SDimitry Andric// 25.10.2.3, time zone database access    // C++20
628*0b57cec5SDimitry Andricconst tzdb& get_tzdb();
629*0b57cec5SDimitry Andrictzdb_list& get_tzdb_list();
630*0b57cec5SDimitry Andricconst time_zone* locate_zone(string_view tz_name);
631*0b57cec5SDimitry Andricconst time_zone* current_zone();
632*0b57cec5SDimitry Andric
633*0b57cec5SDimitry Andric// 25.10.2.4, remote time zone database support    // C++20
634*0b57cec5SDimitry Andricconst tzdb& reload_tzdb();
635*0b57cec5SDimitry Andricstring remote_version();
636*0b57cec5SDimitry Andric
637*0b57cec5SDimitry Andric// 25.10.3, exception classes    // C++20
638*0b57cec5SDimitry Andricclass nonexistent_local_time;
639*0b57cec5SDimitry Andricclass ambiguous_local_time;
640*0b57cec5SDimitry Andric
641*0b57cec5SDimitry Andric// 25.10.4, information classes    // C++20
642*0b57cec5SDimitry Andricstruct sys_info;
643*0b57cec5SDimitry Andricstruct local_info;
644*0b57cec5SDimitry Andric
645*0b57cec5SDimitry Andric// 25.10.5, class time_zone    // C++20
646*0b57cec5SDimitry Andricenum class choose {earliest, latest};
647*0b57cec5SDimitry Andricclass time_zone;
648*0b57cec5SDimitry Andricbool operator==(const time_zone& x, const time_zone& y) noexcept;
649*0b57cec5SDimitry Andricbool operator!=(const time_zone& x, const time_zone& y) noexcept;
650*0b57cec5SDimitry Andricbool operator<(const time_zone& x, const time_zone& y) noexcept;
651*0b57cec5SDimitry Andricbool operator>(const time_zone& x, const time_zone& y) noexcept;
652*0b57cec5SDimitry Andricbool operator<=(const time_zone& x, const time_zone& y) noexcept;
653*0b57cec5SDimitry Andricbool operator>=(const time_zone& x, const time_zone& y) noexcept;
654*0b57cec5SDimitry Andric
655*0b57cec5SDimitry Andric// 25.10.6, class template zoned_traits    // C++20
656*0b57cec5SDimitry Andrictemplate<class T> struct zoned_traits;
657*0b57cec5SDimitry Andric
658*0b57cec5SDimitry Andric// 25.10.7, class template zoned_time    // C++20
659*0b57cec5SDimitry Andrictemplate<class Duration, class TimeZonePtr = const time_zone*> class zoned_time;
660*0b57cec5SDimitry Andricusing zoned_seconds = zoned_time<seconds>;
661*0b57cec5SDimitry Andric
662*0b57cec5SDimitry Andrictemplate<class Duration1, class Duration2, class TimeZonePtr>
663*0b57cec5SDimitry Andric  bool operator==(const zoned_time<Duration1, TimeZonePtr>& x,
664*0b57cec5SDimitry Andric                  const zoned_time<Duration2, TimeZonePtr>& y);
665*0b57cec5SDimitry Andrictemplate<class Duration1, class Duration2, class TimeZonePtr>
666*0b57cec5SDimitry Andric  bool operator!=(const zoned_time<Duration1, TimeZonePtr>& x,
667*0b57cec5SDimitry Andric                  const zoned_time<Duration2, TimeZonePtr>& y);
668*0b57cec5SDimitry Andric
669*0b57cec5SDimitry Andric// 25.10.8, leap second support    // C++20
670*0b57cec5SDimitry Andricclass leap;
671*0b57cec5SDimitry Andric
672*0b57cec5SDimitry Andricbool operator==(const leap& x, const leap& y);
673*0b57cec5SDimitry Andricbool operator!=(const leap& x, const leap& y);
674*0b57cec5SDimitry Andricbool operator< (const leap& x, const leap& y);
675*0b57cec5SDimitry Andricbool operator> (const leap& x, const leap& y);
676*0b57cec5SDimitry Andricbool operator<=(const leap& x, const leap& y);
677*0b57cec5SDimitry Andricbool operator>=(const leap& x, const leap& y);
678*0b57cec5SDimitry Andrictemplate<class Duration>
679*0b57cec5SDimitry Andric  bool operator==(const leap& x, const sys_time<Duration>& y);
680*0b57cec5SDimitry Andrictemplate<class Duration>
681*0b57cec5SDimitry Andric  bool operator==(const sys_time<Duration>& x, const leap& y);
682*0b57cec5SDimitry Andrictemplate<class Duration>
683*0b57cec5SDimitry Andric  bool operator!=(const leap& x, const sys_time<Duration>& y);
684*0b57cec5SDimitry Andrictemplate<class Duration>
685*0b57cec5SDimitry Andric  bool operator!=(const sys_time<Duration>& x, const leap& y);
686*0b57cec5SDimitry Andrictemplate<class Duration>
687*0b57cec5SDimitry Andric  bool operator< (const leap& x, const sys_time<Duration>& y);
688*0b57cec5SDimitry Andrictemplate<class Duration>
689*0b57cec5SDimitry Andric  bool operator< (const sys_time<Duration>& x, const leap& y);
690*0b57cec5SDimitry Andrictemplate<class Duration>
691*0b57cec5SDimitry Andric  bool operator> (const leap& x, const sys_time<Duration>& y);
692*0b57cec5SDimitry Andrictemplate<class Duration>
693*0b57cec5SDimitry Andric  bool operator> (const sys_time<Duration>& x, const leap& y);
694*0b57cec5SDimitry Andrictemplate<class Duration>
695*0b57cec5SDimitry Andric  bool operator<=(const leap& x, const sys_time<Duration>& y);
696*0b57cec5SDimitry Andrictemplate<class Duration>
697*0b57cec5SDimitry Andric  bool operator<=(const sys_time<Duration>& x, const leap& y);
698*0b57cec5SDimitry Andrictemplate<class Duration>
699*0b57cec5SDimitry Andric  bool operator>=(const leap& x, const sys_time<Duration>& y);
700*0b57cec5SDimitry Andrictemplate<class Duration>
701*0b57cec5SDimitry Andric  bool operator>=(const sys_time<Duration>& x, const leap& y);
702*0b57cec5SDimitry Andric
703*0b57cec5SDimitry Andric// 25.10.9, class link    // C++20
704*0b57cec5SDimitry Andricclass link;
705*0b57cec5SDimitry Andricbool operator==(const link& x, const link& y);
706*0b57cec5SDimitry Andricbool operator!=(const link& x, const link& y);
707*0b57cec5SDimitry Andricbool operator< (const link& x, const link& y);
708*0b57cec5SDimitry Andricbool operator> (const link& x, const link& y);
709*0b57cec5SDimitry Andricbool operator<=(const link& x, const link& y);
710*0b57cec5SDimitry Andricbool operator>=(const link& x, const link& y);
711*0b57cec5SDimitry Andric
712*0b57cec5SDimitry Andric// 25.11, formatting    // C++20
713*0b57cec5SDimitry Andrictemplate<class charT, class Streamable>
714*0b57cec5SDimitry Andric  basic_string<charT>
715*0b57cec5SDimitry Andric    format(const charT* fmt, const Streamable& s);
716*0b57cec5SDimitry Andric
717*0b57cec5SDimitry Andrictemplate<class charT, class Streamable>
718*0b57cec5SDimitry Andric  basic_string<charT>
719*0b57cec5SDimitry Andric    format(const locale& loc, const charT* fmt, const Streamable& s);
720*0b57cec5SDimitry Andric
721*0b57cec5SDimitry Andrictemplate<class charT, class traits, class Alloc, class Streamable>
722*0b57cec5SDimitry Andric  basic_string<charT, traits, Alloc>
723*0b57cec5SDimitry Andric    format(const basic_string<charT, traits, Alloc>& fmt, const Streamable& s);
724*0b57cec5SDimitry Andric
725*0b57cec5SDimitry Andrictemplate<class charT, class traits, class Alloc, class Streamable>
726*0b57cec5SDimitry Andric  basic_string<charT, traits, Alloc>
727*0b57cec5SDimitry Andric    format(const locale& loc, const basic_string<charT, traits, Alloc>& fmt,
728*0b57cec5SDimitry Andric           const Streamable& s);
729*0b57cec5SDimitry Andric
730*0b57cec5SDimitry Andric// 25.12, parsing    // C++20
731*0b57cec5SDimitry Andrictemplate<class charT, class traits, class Alloc, class Parsable>
732*0b57cec5SDimitry Andricunspecified
733*0b57cec5SDimitry Andric    parse(const basic_string<charT, traits, Alloc>& format, Parsable& tp);
734*0b57cec5SDimitry Andric
735*0b57cec5SDimitry Andrictemplate<class charT, class traits, class Alloc, class Parsable>
736*0b57cec5SDimitry Andricunspecified
737*0b57cec5SDimitry Andric    parse(const basic_string<charT, traits, Alloc>& format, Parsable& tp,
738*0b57cec5SDimitry Andric          basic_string<charT, traits, Alloc>& abbrev);
739*0b57cec5SDimitry Andric
740*0b57cec5SDimitry Andrictemplate<class charT, class traits, class Alloc, class Parsable>
741*0b57cec5SDimitry Andricunspecified
742*0b57cec5SDimitry Andric    parse(const basic_string<charT, traits, Alloc>& format, Parsable& tp,
743*0b57cec5SDimitry Andric          minutes& offset);
744*0b57cec5SDimitry Andric
745*0b57cec5SDimitry Andrictemplate<class charT, class traits, class Alloc, class Parsable>
746*0b57cec5SDimitry Andricunspecified
747*0b57cec5SDimitry Andric    parse(const basic_string<charT, traits, Alloc>& format, Parsable& tp,
748*0b57cec5SDimitry Andric          basic_string<charT, traits, Alloc>& abbrev, minutes& offset);
749*0b57cec5SDimitry Andric
750*0b57cec5SDimitry Andric// calendrical constants
751*0b57cec5SDimitry Andricinline constexpr last_spec                              last{};       // C++20
752*0b57cec5SDimitry Andricinline constexpr chrono::weekday                        Sunday{0};    // C++20
753*0b57cec5SDimitry Andricinline constexpr chrono::weekday                        Monday{1};    // C++20
754*0b57cec5SDimitry Andricinline constexpr chrono::weekday                        Tuesday{2};   // C++20
755*0b57cec5SDimitry Andricinline constexpr chrono::weekday                        Wednesday{3}; // C++20
756*0b57cec5SDimitry Andricinline constexpr chrono::weekday                        Thursday{4};  // C++20
757*0b57cec5SDimitry Andricinline constexpr chrono::weekday                        Friday{5};    // C++20
758*0b57cec5SDimitry Andricinline constexpr chrono::weekday                        Saturday{6};  // C++20
759*0b57cec5SDimitry Andric
760*0b57cec5SDimitry Andricinline constexpr chrono::month                          January{1};   // C++20
761*0b57cec5SDimitry Andricinline constexpr chrono::month                          February{2};  // C++20
762*0b57cec5SDimitry Andricinline constexpr chrono::month                          March{3};     // C++20
763*0b57cec5SDimitry Andricinline constexpr chrono::month                          April{4};     // C++20
764*0b57cec5SDimitry Andricinline constexpr chrono::month                          May{5};       // C++20
765*0b57cec5SDimitry Andricinline constexpr chrono::month                          June{6};      // C++20
766*0b57cec5SDimitry Andricinline constexpr chrono::month                          July{7};      // C++20
767*0b57cec5SDimitry Andricinline constexpr chrono::month                          August{8};    // C++20
768*0b57cec5SDimitry Andricinline constexpr chrono::month                          September{9}; // C++20
769*0b57cec5SDimitry Andricinline constexpr chrono::month                          October{10};  // C++20
770*0b57cec5SDimitry Andricinline constexpr chrono::month                          November{11}; // C++20
771*0b57cec5SDimitry Andricinline constexpr chrono::month                          December{12}; // C++20
772*0b57cec5SDimitry Andric}  // chrono
773*0b57cec5SDimitry Andric
774*0b57cec5SDimitry Andricinline namespace literals {
775*0b57cec5SDimitry Andric  inline namespace chrono_literals {
776*0b57cec5SDimitry Andricconstexpr chrono::hours                                 operator ""h(unsigned long long); // C++14
777*0b57cec5SDimitry Andricconstexpr chrono::duration<unspecified , ratio<3600,1>> operator ""h(long double); // C++14
778*0b57cec5SDimitry Andricconstexpr chrono::minutes                               operator ""min(unsigned long long); // C++14
779*0b57cec5SDimitry Andricconstexpr chrono::duration<unspecified , ratio<60,1>>   operator ""min(long double); // C++14
780*0b57cec5SDimitry Andricconstexpr chrono::seconds                               operator ""s(unsigned long long); // C++14
781*0b57cec5SDimitry Andricconstexpr chrono::duration<unspecified >                operator ""s(long double); // C++14
782*0b57cec5SDimitry Andricconstexpr chrono::milliseconds                          operator ""ms(unsigned long long); // C++14
783*0b57cec5SDimitry Andricconstexpr chrono::duration<unspecified , milli>         operator ""ms(long double); // C++14
784*0b57cec5SDimitry Andricconstexpr chrono::microseconds                          operator ""us(unsigned long long); // C++14
785*0b57cec5SDimitry Andricconstexpr chrono::duration<unspecified , micro>         operator ""us(long double); // C++14
786*0b57cec5SDimitry Andricconstexpr chrono::nanoseconds                           operator ""ns(unsigned long long); // C++14
787*0b57cec5SDimitry Andricconstexpr chrono::duration<unspecified , nano>          operator ""ns(long double); // C++14
788*0b57cec5SDimitry Andricconstexpr chrono::day                                   operator ""d(unsigned long long d) noexcept; // C++20
789*0b57cec5SDimitry Andricconstexpr chrono::year                                  operator ""y(unsigned long long y) noexcept; // C++20
790*0b57cec5SDimitry Andric}  // chrono_literals
791*0b57cec5SDimitry Andric}  // literals
792*0b57cec5SDimitry Andric
793*0b57cec5SDimitry Andric}  // std
794*0b57cec5SDimitry Andric*/
795*0b57cec5SDimitry Andric
796*0b57cec5SDimitry Andric#include <__config>
797*0b57cec5SDimitry Andric#include <ctime>
798*0b57cec5SDimitry Andric#include <type_traits>
799*0b57cec5SDimitry Andric#include <ratio>
800*0b57cec5SDimitry Andric#include <limits>
801*0b57cec5SDimitry Andric#include <version>
802*0b57cec5SDimitry Andric
803*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
804*0b57cec5SDimitry Andric#pragma GCC system_header
805*0b57cec5SDimitry Andric#endif
806*0b57cec5SDimitry Andric
807*0b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
808*0b57cec5SDimitry Andric#include <__undef_macros>
809*0b57cec5SDimitry Andric
810*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
811*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
812*0b57cec5SDimitry Andricstruct _FilesystemClock;
813*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_FILESYSTEM
814*0b57cec5SDimitry Andric#endif // !_LIBCPP_CXX03_LANG
815*0b57cec5SDimitry Andric
816*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
817*0b57cec5SDimitry Andric
818*0b57cec5SDimitry Andricnamespace chrono
819*0b57cec5SDimitry Andric{
820*0b57cec5SDimitry Andric
821*0b57cec5SDimitry Andrictemplate <class _Rep, class _Period = ratio<1> > class _LIBCPP_TEMPLATE_VIS duration;
822*0b57cec5SDimitry Andric
823*0b57cec5SDimitry Andrictemplate <class _Tp>
824*0b57cec5SDimitry Andricstruct __is_duration : false_type {};
825*0b57cec5SDimitry Andric
826*0b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
827*0b57cec5SDimitry Andricstruct __is_duration<duration<_Rep, _Period> > : true_type  {};
828*0b57cec5SDimitry Andric
829*0b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
830*0b57cec5SDimitry Andricstruct __is_duration<const duration<_Rep, _Period> > : true_type  {};
831*0b57cec5SDimitry Andric
832*0b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
833*0b57cec5SDimitry Andricstruct __is_duration<volatile duration<_Rep, _Period> > : true_type  {};
834*0b57cec5SDimitry Andric
835*0b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
836*0b57cec5SDimitry Andricstruct __is_duration<const volatile duration<_Rep, _Period> > : true_type  {};
837*0b57cec5SDimitry Andric
838*0b57cec5SDimitry Andric} // chrono
839*0b57cec5SDimitry Andric
840*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
841*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS common_type<chrono::duration<_Rep1, _Period1>,
842*0b57cec5SDimitry Andric                                         chrono::duration<_Rep2, _Period2> >
843*0b57cec5SDimitry Andric{
844*0b57cec5SDimitry Andric    typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
845*0b57cec5SDimitry Andric                             typename __ratio_gcd<_Period1, _Period2>::type> type;
846*0b57cec5SDimitry Andric};
847*0b57cec5SDimitry Andric
848*0b57cec5SDimitry Andricnamespace chrono {
849*0b57cec5SDimitry Andric
850*0b57cec5SDimitry Andric// duration_cast
851*0b57cec5SDimitry Andric
852*0b57cec5SDimitry Andrictemplate <class _FromDuration, class _ToDuration,
853*0b57cec5SDimitry Andric          class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type,
854*0b57cec5SDimitry Andric          bool = _Period::num == 1,
855*0b57cec5SDimitry Andric          bool = _Period::den == 1>
856*0b57cec5SDimitry Andricstruct __duration_cast;
857*0b57cec5SDimitry Andric
858*0b57cec5SDimitry Andrictemplate <class _FromDuration, class _ToDuration, class _Period>
859*0b57cec5SDimitry Andricstruct __duration_cast<_FromDuration, _ToDuration, _Period, true, true>
860*0b57cec5SDimitry Andric{
861*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
862*0b57cec5SDimitry Andric    _ToDuration operator()(const _FromDuration& __fd) const
863*0b57cec5SDimitry Andric    {
864*0b57cec5SDimitry Andric        return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count()));
865*0b57cec5SDimitry Andric    }
866*0b57cec5SDimitry Andric};
867*0b57cec5SDimitry Andric
868*0b57cec5SDimitry Andrictemplate <class _FromDuration, class _ToDuration, class _Period>
869*0b57cec5SDimitry Andricstruct __duration_cast<_FromDuration, _ToDuration, _Period, true, false>
870*0b57cec5SDimitry Andric{
871*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
872*0b57cec5SDimitry Andric    _ToDuration operator()(const _FromDuration& __fd) const
873*0b57cec5SDimitry Andric    {
874*0b57cec5SDimitry Andric        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
875*0b57cec5SDimitry Andric        return _ToDuration(static_cast<typename _ToDuration::rep>(
876*0b57cec5SDimitry Andric                           static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den)));
877*0b57cec5SDimitry Andric    }
878*0b57cec5SDimitry Andric};
879*0b57cec5SDimitry Andric
880*0b57cec5SDimitry Andrictemplate <class _FromDuration, class _ToDuration, class _Period>
881*0b57cec5SDimitry Andricstruct __duration_cast<_FromDuration, _ToDuration, _Period, false, true>
882*0b57cec5SDimitry Andric{
883*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
884*0b57cec5SDimitry Andric    _ToDuration operator()(const _FromDuration& __fd) const
885*0b57cec5SDimitry Andric    {
886*0b57cec5SDimitry Andric        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
887*0b57cec5SDimitry Andric        return _ToDuration(static_cast<typename _ToDuration::rep>(
888*0b57cec5SDimitry Andric                           static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)));
889*0b57cec5SDimitry Andric    }
890*0b57cec5SDimitry Andric};
891*0b57cec5SDimitry Andric
892*0b57cec5SDimitry Andrictemplate <class _FromDuration, class _ToDuration, class _Period>
893*0b57cec5SDimitry Andricstruct __duration_cast<_FromDuration, _ToDuration, _Period, false, false>
894*0b57cec5SDimitry Andric{
895*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
896*0b57cec5SDimitry Andric    _ToDuration operator()(const _FromDuration& __fd) const
897*0b57cec5SDimitry Andric    {
898*0b57cec5SDimitry Andric        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
899*0b57cec5SDimitry Andric        return _ToDuration(static_cast<typename _ToDuration::rep>(
900*0b57cec5SDimitry Andric                           static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)
901*0b57cec5SDimitry Andric                                                          / static_cast<_Ct>(_Period::den)));
902*0b57cec5SDimitry Andric    }
903*0b57cec5SDimitry Andric};
904*0b57cec5SDimitry Andric
905*0b57cec5SDimitry Andrictemplate <class _ToDuration, class _Rep, class _Period>
906*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
907*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
908*0b57cec5SDimitry Andrictypename enable_if
909*0b57cec5SDimitry Andric<
910*0b57cec5SDimitry Andric    __is_duration<_ToDuration>::value,
911*0b57cec5SDimitry Andric    _ToDuration
912*0b57cec5SDimitry Andric>::type
913*0b57cec5SDimitry Andricduration_cast(const duration<_Rep, _Period>& __fd)
914*0b57cec5SDimitry Andric{
915*0b57cec5SDimitry Andric    return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);
916*0b57cec5SDimitry Andric}
917*0b57cec5SDimitry Andric
918*0b57cec5SDimitry Andrictemplate <class _Rep>
919*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {};
920*0b57cec5SDimitry Andric
921*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
922*0b57cec5SDimitry Andrictemplate <class _Rep>
923*0b57cec5SDimitry Andric_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool treat_as_floating_point_v
924*0b57cec5SDimitry Andric    = treat_as_floating_point<_Rep>::value;
925*0b57cec5SDimitry Andric#endif
926*0b57cec5SDimitry Andric
927*0b57cec5SDimitry Andrictemplate <class _Rep>
928*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS duration_values
929*0b57cec5SDimitry Andric{
930*0b57cec5SDimitry Andricpublic:
931*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);}
932*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max()  _NOEXCEPT {return numeric_limits<_Rep>::max();}
933*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min()  _NOEXCEPT {return numeric_limits<_Rep>::lowest();}
934*0b57cec5SDimitry Andric};
935*0b57cec5SDimitry Andric
936*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
937*0b57cec5SDimitry Andrictemplate <class _ToDuration, class _Rep, class _Period>
938*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
939*0b57cec5SDimitry Andrictypename enable_if
940*0b57cec5SDimitry Andric<
941*0b57cec5SDimitry Andric    __is_duration<_ToDuration>::value,
942*0b57cec5SDimitry Andric    _ToDuration
943*0b57cec5SDimitry Andric>::type
944*0b57cec5SDimitry Andricfloor(const duration<_Rep, _Period>& __d)
945*0b57cec5SDimitry Andric{
946*0b57cec5SDimitry Andric    _ToDuration __t = duration_cast<_ToDuration>(__d);
947*0b57cec5SDimitry Andric    if (__t > __d)
948*0b57cec5SDimitry Andric        __t = __t - _ToDuration{1};
949*0b57cec5SDimitry Andric    return __t;
950*0b57cec5SDimitry Andric}
951*0b57cec5SDimitry Andric
952*0b57cec5SDimitry Andrictemplate <class _ToDuration, class _Rep, class _Period>
953*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
954*0b57cec5SDimitry Andrictypename enable_if
955*0b57cec5SDimitry Andric<
956*0b57cec5SDimitry Andric    __is_duration<_ToDuration>::value,
957*0b57cec5SDimitry Andric    _ToDuration
958*0b57cec5SDimitry Andric>::type
959*0b57cec5SDimitry Andricceil(const duration<_Rep, _Period>& __d)
960*0b57cec5SDimitry Andric{
961*0b57cec5SDimitry Andric    _ToDuration __t = duration_cast<_ToDuration>(__d);
962*0b57cec5SDimitry Andric    if (__t < __d)
963*0b57cec5SDimitry Andric        __t = __t + _ToDuration{1};
964*0b57cec5SDimitry Andric    return __t;
965*0b57cec5SDimitry Andric}
966*0b57cec5SDimitry Andric
967*0b57cec5SDimitry Andrictemplate <class _ToDuration, class _Rep, class _Period>
968*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
969*0b57cec5SDimitry Andrictypename enable_if
970*0b57cec5SDimitry Andric<
971*0b57cec5SDimitry Andric    __is_duration<_ToDuration>::value,
972*0b57cec5SDimitry Andric    _ToDuration
973*0b57cec5SDimitry Andric>::type
974*0b57cec5SDimitry Andricround(const duration<_Rep, _Period>& __d)
975*0b57cec5SDimitry Andric{
976*0b57cec5SDimitry Andric    _ToDuration __lower = floor<_ToDuration>(__d);
977*0b57cec5SDimitry Andric    _ToDuration __upper = __lower + _ToDuration{1};
978*0b57cec5SDimitry Andric    auto __lowerDiff = __d - __lower;
979*0b57cec5SDimitry Andric    auto __upperDiff = __upper - __d;
980*0b57cec5SDimitry Andric    if (__lowerDiff < __upperDiff)
981*0b57cec5SDimitry Andric        return __lower;
982*0b57cec5SDimitry Andric    if (__lowerDiff > __upperDiff)
983*0b57cec5SDimitry Andric        return __upper;
984*0b57cec5SDimitry Andric    return __lower.count() & 1 ? __upper : __lower;
985*0b57cec5SDimitry Andric}
986*0b57cec5SDimitry Andric#endif
987*0b57cec5SDimitry Andric
988*0b57cec5SDimitry Andric// duration
989*0b57cec5SDimitry Andric
990*0b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
991*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS duration
992*0b57cec5SDimitry Andric{
993*0b57cec5SDimitry Andric    static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration");
994*0b57cec5SDimitry Andric    static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio");
995*0b57cec5SDimitry Andric    static_assert(_Period::num > 0, "duration period must be positive");
996*0b57cec5SDimitry Andric
997*0b57cec5SDimitry Andric    template <class _R1, class _R2>
998*0b57cec5SDimitry Andric    struct __no_overflow
999*0b57cec5SDimitry Andric    {
1000*0b57cec5SDimitry Andric    private:
1001*0b57cec5SDimitry Andric        static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
1002*0b57cec5SDimitry Andric        static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
1003*0b57cec5SDimitry Andric        static const intmax_t __n1 = _R1::num / __gcd_n1_n2;
1004*0b57cec5SDimitry Andric        static const intmax_t __d1 = _R1::den / __gcd_d1_d2;
1005*0b57cec5SDimitry Andric        static const intmax_t __n2 = _R2::num / __gcd_n1_n2;
1006*0b57cec5SDimitry Andric        static const intmax_t __d2 = _R2::den / __gcd_d1_d2;
1007*0b57cec5SDimitry Andric        static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);
1008*0b57cec5SDimitry Andric
1009*0b57cec5SDimitry Andric        template <intmax_t _Xp, intmax_t _Yp, bool __overflow>
1010*0b57cec5SDimitry Andric        struct __mul    // __overflow == false
1011*0b57cec5SDimitry Andric        {
1012*0b57cec5SDimitry Andric            static const intmax_t value = _Xp * _Yp;
1013*0b57cec5SDimitry Andric        };
1014*0b57cec5SDimitry Andric
1015*0b57cec5SDimitry Andric        template <intmax_t _Xp, intmax_t _Yp>
1016*0b57cec5SDimitry Andric        struct __mul<_Xp, _Yp, true>
1017*0b57cec5SDimitry Andric        {
1018*0b57cec5SDimitry Andric            static const intmax_t value = 1;
1019*0b57cec5SDimitry Andric        };
1020*0b57cec5SDimitry Andric
1021*0b57cec5SDimitry Andric    public:
1022*0b57cec5SDimitry Andric        static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1);
1023*0b57cec5SDimitry Andric        typedef ratio<__mul<__n1, __d2, !value>::value,
1024*0b57cec5SDimitry Andric                      __mul<__n2, __d1, !value>::value> type;
1025*0b57cec5SDimitry Andric    };
1026*0b57cec5SDimitry Andric
1027*0b57cec5SDimitry Andricpublic:
1028*0b57cec5SDimitry Andric    typedef _Rep rep;
1029*0b57cec5SDimitry Andric    typedef typename _Period::type period;
1030*0b57cec5SDimitry Andricprivate:
1031*0b57cec5SDimitry Andric    rep __rep_;
1032*0b57cec5SDimitry Andricpublic:
1033*0b57cec5SDimitry Andric
1034*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1035*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1036*0b57cec5SDimitry Andric        duration() = default;
1037*0b57cec5SDimitry Andric#else
1038*0b57cec5SDimitry Andric        duration() {}
1039*0b57cec5SDimitry Andric#endif
1040*0b57cec5SDimitry Andric
1041*0b57cec5SDimitry Andric    template <class _Rep2>
1042*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1043*0b57cec5SDimitry Andric        explicit duration(const _Rep2& __r,
1044*0b57cec5SDimitry Andric            typename enable_if
1045*0b57cec5SDimitry Andric            <
1046*0b57cec5SDimitry Andric               is_convertible<_Rep2, rep>::value &&
1047*0b57cec5SDimitry Andric               (treat_as_floating_point<rep>::value ||
1048*0b57cec5SDimitry Andric               !treat_as_floating_point<_Rep2>::value)
1049*0b57cec5SDimitry Andric            >::type* = 0)
1050*0b57cec5SDimitry Andric                : __rep_(__r) {}
1051*0b57cec5SDimitry Andric
1052*0b57cec5SDimitry Andric    // conversions
1053*0b57cec5SDimitry Andric    template <class _Rep2, class _Period2>
1054*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1055*0b57cec5SDimitry Andric        duration(const duration<_Rep2, _Period2>& __d,
1056*0b57cec5SDimitry Andric            typename enable_if
1057*0b57cec5SDimitry Andric            <
1058*0b57cec5SDimitry Andric                __no_overflow<_Period2, period>::value && (
1059*0b57cec5SDimitry Andric                treat_as_floating_point<rep>::value ||
1060*0b57cec5SDimitry Andric                (__no_overflow<_Period2, period>::type::den == 1 &&
1061*0b57cec5SDimitry Andric                 !treat_as_floating_point<_Rep2>::value))
1062*0b57cec5SDimitry Andric            >::type* = 0)
1063*0b57cec5SDimitry Andric                : __rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}
1064*0b57cec5SDimitry Andric
1065*0b57cec5SDimitry Andric    // observer
1066*0b57cec5SDimitry Andric
1067*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;}
1068*0b57cec5SDimitry Andric
1069*0b57cec5SDimitry Andric    // arithmetic
1070*0b57cec5SDimitry Andric
1071*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {return typename common_type<duration>::type(*this);}
1072*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {return typename common_type<duration>::type(-__rep_);}
1073*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator++()      {++__rep_; return *this;}
1074*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration  operator++(int)   {return duration(__rep_++);}
1075*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator--()      {--__rep_; return *this;}
1076*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration  operator--(int)   {return duration(__rep_--);}
1077*0b57cec5SDimitry Andric
1078*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;}
1079*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;}
1080*0b57cec5SDimitry Andric
1081*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;}
1082*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;}
1083*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;}
1084*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;}
1085*0b57cec5SDimitry Andric
1086*0b57cec5SDimitry Andric    // special values
1087*0b57cec5SDimitry Andric
1088*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values<rep>::zero());}
1089*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min()  _NOEXCEPT {return duration(duration_values<rep>::min());}
1090*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max()  _NOEXCEPT {return duration(duration_values<rep>::max());}
1091*0b57cec5SDimitry Andric};
1092*0b57cec5SDimitry Andric
1093*0b57cec5SDimitry Andrictypedef duration<long long,         nano> nanoseconds;
1094*0b57cec5SDimitry Andrictypedef duration<long long,        micro> microseconds;
1095*0b57cec5SDimitry Andrictypedef duration<long long,        milli> milliseconds;
1096*0b57cec5SDimitry Andrictypedef duration<long long              > seconds;
1097*0b57cec5SDimitry Andrictypedef duration<     long, ratio<  60> > minutes;
1098*0b57cec5SDimitry Andrictypedef duration<     long, ratio<3600> > hours;
1099*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17
1100*0b57cec5SDimitry Andrictypedef duration<     int, ratio_multiply<ratio<24>, hours::period>>         days;
1101*0b57cec5SDimitry Andrictypedef duration<     int, ratio_multiply<ratio<7>,   days::period>>         weeks;
1102*0b57cec5SDimitry Andrictypedef duration<     int, ratio_multiply<ratio<146097, 400>, days::period>> years;
1103*0b57cec5SDimitry Andrictypedef duration<     int, ratio_divide<years::period, ratio<12>>>           months;
1104*0b57cec5SDimitry Andric#endif
1105*0b57cec5SDimitry Andric// Duration ==
1106*0b57cec5SDimitry Andric
1107*0b57cec5SDimitry Andrictemplate <class _LhsDuration, class _RhsDuration>
1108*0b57cec5SDimitry Andricstruct __duration_eq
1109*0b57cec5SDimitry Andric{
1110*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1111*0b57cec5SDimitry Andric    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const
1112*0b57cec5SDimitry Andric        {
1113*0b57cec5SDimitry Andric            typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
1114*0b57cec5SDimitry Andric            return _Ct(__lhs).count() == _Ct(__rhs).count();
1115*0b57cec5SDimitry Andric        }
1116*0b57cec5SDimitry Andric};
1117*0b57cec5SDimitry Andric
1118*0b57cec5SDimitry Andrictemplate <class _LhsDuration>
1119*0b57cec5SDimitry Andricstruct __duration_eq<_LhsDuration, _LhsDuration>
1120*0b57cec5SDimitry Andric{
1121*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1122*0b57cec5SDimitry Andric    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const
1123*0b57cec5SDimitry Andric        {return __lhs.count() == __rhs.count();}
1124*0b57cec5SDimitry Andric};
1125*0b57cec5SDimitry Andric
1126*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
1127*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1128*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1129*0b57cec5SDimitry Andricbool
1130*0b57cec5SDimitry Andricoperator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1131*0b57cec5SDimitry Andric{
1132*0b57cec5SDimitry Andric    return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
1133*0b57cec5SDimitry Andric}
1134*0b57cec5SDimitry Andric
1135*0b57cec5SDimitry Andric// Duration !=
1136*0b57cec5SDimitry Andric
1137*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
1138*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1139*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1140*0b57cec5SDimitry Andricbool
1141*0b57cec5SDimitry Andricoperator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1142*0b57cec5SDimitry Andric{
1143*0b57cec5SDimitry Andric    return !(__lhs == __rhs);
1144*0b57cec5SDimitry Andric}
1145*0b57cec5SDimitry Andric
1146*0b57cec5SDimitry Andric// Duration <
1147*0b57cec5SDimitry Andric
1148*0b57cec5SDimitry Andrictemplate <class _LhsDuration, class _RhsDuration>
1149*0b57cec5SDimitry Andricstruct __duration_lt
1150*0b57cec5SDimitry Andric{
1151*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1152*0b57cec5SDimitry Andric    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const
1153*0b57cec5SDimitry Andric        {
1154*0b57cec5SDimitry Andric            typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
1155*0b57cec5SDimitry Andric            return _Ct(__lhs).count() < _Ct(__rhs).count();
1156*0b57cec5SDimitry Andric        }
1157*0b57cec5SDimitry Andric};
1158*0b57cec5SDimitry Andric
1159*0b57cec5SDimitry Andrictemplate <class _LhsDuration>
1160*0b57cec5SDimitry Andricstruct __duration_lt<_LhsDuration, _LhsDuration>
1161*0b57cec5SDimitry Andric{
1162*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1163*0b57cec5SDimitry Andric    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const
1164*0b57cec5SDimitry Andric        {return __lhs.count() < __rhs.count();}
1165*0b57cec5SDimitry Andric};
1166*0b57cec5SDimitry Andric
1167*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
1168*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1169*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1170*0b57cec5SDimitry Andricbool
1171*0b57cec5SDimitry Andricoperator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1172*0b57cec5SDimitry Andric{
1173*0b57cec5SDimitry Andric    return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
1174*0b57cec5SDimitry Andric}
1175*0b57cec5SDimitry Andric
1176*0b57cec5SDimitry Andric// Duration >
1177*0b57cec5SDimitry Andric
1178*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
1179*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1180*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1181*0b57cec5SDimitry Andricbool
1182*0b57cec5SDimitry Andricoperator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1183*0b57cec5SDimitry Andric{
1184*0b57cec5SDimitry Andric    return __rhs < __lhs;
1185*0b57cec5SDimitry Andric}
1186*0b57cec5SDimitry Andric
1187*0b57cec5SDimitry Andric// Duration <=
1188*0b57cec5SDimitry Andric
1189*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
1190*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1191*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1192*0b57cec5SDimitry Andricbool
1193*0b57cec5SDimitry Andricoperator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1194*0b57cec5SDimitry Andric{
1195*0b57cec5SDimitry Andric    return !(__rhs < __lhs);
1196*0b57cec5SDimitry Andric}
1197*0b57cec5SDimitry Andric
1198*0b57cec5SDimitry Andric// Duration >=
1199*0b57cec5SDimitry Andric
1200*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
1201*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1202*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1203*0b57cec5SDimitry Andricbool
1204*0b57cec5SDimitry Andricoperator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1205*0b57cec5SDimitry Andric{
1206*0b57cec5SDimitry Andric    return !(__lhs < __rhs);
1207*0b57cec5SDimitry Andric}
1208*0b57cec5SDimitry Andric
1209*0b57cec5SDimitry Andric// Duration +
1210*0b57cec5SDimitry Andric
1211*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
1212*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1213*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1214*0b57cec5SDimitry Andrictypename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
1215*0b57cec5SDimitry Andricoperator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1216*0b57cec5SDimitry Andric{
1217*0b57cec5SDimitry Andric    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
1218*0b57cec5SDimitry Andric    return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count());
1219*0b57cec5SDimitry Andric}
1220*0b57cec5SDimitry Andric
1221*0b57cec5SDimitry Andric// Duration -
1222*0b57cec5SDimitry Andric
1223*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
1224*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1225*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1226*0b57cec5SDimitry Andrictypename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
1227*0b57cec5SDimitry Andricoperator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1228*0b57cec5SDimitry Andric{
1229*0b57cec5SDimitry Andric    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
1230*0b57cec5SDimitry Andric    return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count());
1231*0b57cec5SDimitry Andric}
1232*0b57cec5SDimitry Andric
1233*0b57cec5SDimitry Andric// Duration *
1234*0b57cec5SDimitry Andric
1235*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period, class _Rep2>
1236*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1237*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1238*0b57cec5SDimitry Andrictypename enable_if
1239*0b57cec5SDimitry Andric<
1240*0b57cec5SDimitry Andric    is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
1241*0b57cec5SDimitry Andric    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
1242*0b57cec5SDimitry Andric>::type
1243*0b57cec5SDimitry Andricoperator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
1244*0b57cec5SDimitry Andric{
1245*0b57cec5SDimitry Andric    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
1246*0b57cec5SDimitry Andric    typedef duration<_Cr, _Period> _Cd;
1247*0b57cec5SDimitry Andric    return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s));
1248*0b57cec5SDimitry Andric}
1249*0b57cec5SDimitry Andric
1250*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period, class _Rep2>
1251*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1252*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1253*0b57cec5SDimitry Andrictypename enable_if
1254*0b57cec5SDimitry Andric<
1255*0b57cec5SDimitry Andric    is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value,
1256*0b57cec5SDimitry Andric    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
1257*0b57cec5SDimitry Andric>::type
1258*0b57cec5SDimitry Andricoperator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)
1259*0b57cec5SDimitry Andric{
1260*0b57cec5SDimitry Andric    return __d * __s;
1261*0b57cec5SDimitry Andric}
1262*0b57cec5SDimitry Andric
1263*0b57cec5SDimitry Andric// Duration /
1264*0b57cec5SDimitry Andric
1265*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period, class _Rep2>
1266*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1267*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1268*0b57cec5SDimitry Andrictypename enable_if
1269*0b57cec5SDimitry Andric<
1270*0b57cec5SDimitry Andric    !__is_duration<_Rep2>::value &&
1271*0b57cec5SDimitry Andric      is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
1272*0b57cec5SDimitry Andric    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
1273*0b57cec5SDimitry Andric>::type
1274*0b57cec5SDimitry Andricoperator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
1275*0b57cec5SDimitry Andric{
1276*0b57cec5SDimitry Andric    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
1277*0b57cec5SDimitry Andric    typedef duration<_Cr, _Period> _Cd;
1278*0b57cec5SDimitry Andric    return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s));
1279*0b57cec5SDimitry Andric}
1280*0b57cec5SDimitry Andric
1281*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
1282*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1283*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1284*0b57cec5SDimitry Andrictypename common_type<_Rep1, _Rep2>::type
1285*0b57cec5SDimitry Andricoperator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1286*0b57cec5SDimitry Andric{
1287*0b57cec5SDimitry Andric    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct;
1288*0b57cec5SDimitry Andric    return _Ct(__lhs).count() / _Ct(__rhs).count();
1289*0b57cec5SDimitry Andric}
1290*0b57cec5SDimitry Andric
1291*0b57cec5SDimitry Andric// Duration %
1292*0b57cec5SDimitry Andric
1293*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period, class _Rep2>
1294*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1295*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1296*0b57cec5SDimitry Andrictypename enable_if
1297*0b57cec5SDimitry Andric<
1298*0b57cec5SDimitry Andric    !__is_duration<_Rep2>::value &&
1299*0b57cec5SDimitry Andric      is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
1300*0b57cec5SDimitry Andric    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
1301*0b57cec5SDimitry Andric>::type
1302*0b57cec5SDimitry Andricoperator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
1303*0b57cec5SDimitry Andric{
1304*0b57cec5SDimitry Andric    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
1305*0b57cec5SDimitry Andric    typedef duration<_Cr, _Period> _Cd;
1306*0b57cec5SDimitry Andric    return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s));
1307*0b57cec5SDimitry Andric}
1308*0b57cec5SDimitry Andric
1309*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Rep2, class _Period2>
1310*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1311*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
1312*0b57cec5SDimitry Andrictypename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
1313*0b57cec5SDimitry Andricoperator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1314*0b57cec5SDimitry Andric{
1315*0b57cec5SDimitry Andric    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
1316*0b57cec5SDimitry Andric    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
1317*0b57cec5SDimitry Andric    return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count()));
1318*0b57cec5SDimitry Andric}
1319*0b57cec5SDimitry Andric
1320*0b57cec5SDimitry Andric//////////////////////////////////////////////////////////
1321*0b57cec5SDimitry Andric///////////////////// time_point /////////////////////////
1322*0b57cec5SDimitry Andric//////////////////////////////////////////////////////////
1323*0b57cec5SDimitry Andric
1324*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration = typename _Clock::duration>
1325*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS time_point
1326*0b57cec5SDimitry Andric{
1327*0b57cec5SDimitry Andric    static_assert(__is_duration<_Duration>::value,
1328*0b57cec5SDimitry Andric                  "Second template parameter of time_point must be a std::chrono::duration");
1329*0b57cec5SDimitry Andricpublic:
1330*0b57cec5SDimitry Andric    typedef _Clock                    clock;
1331*0b57cec5SDimitry Andric    typedef _Duration                 duration;
1332*0b57cec5SDimitry Andric    typedef typename duration::rep    rep;
1333*0b57cec5SDimitry Andric    typedef typename duration::period period;
1334*0b57cec5SDimitry Andricprivate:
1335*0b57cec5SDimitry Andric    duration __d_;
1336*0b57cec5SDimitry Andric
1337*0b57cec5SDimitry Andricpublic:
1338*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {}
1339*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {}
1340*0b57cec5SDimitry Andric
1341*0b57cec5SDimitry Andric    // conversions
1342*0b57cec5SDimitry Andric    template <class _Duration2>
1343*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1344*0b57cec5SDimitry Andric    time_point(const time_point<clock, _Duration2>& t,
1345*0b57cec5SDimitry Andric        typename enable_if
1346*0b57cec5SDimitry Andric        <
1347*0b57cec5SDimitry Andric            is_convertible<_Duration2, duration>::value
1348*0b57cec5SDimitry Andric        >::type* = 0)
1349*0b57cec5SDimitry Andric            : __d_(t.time_since_epoch()) {}
1350*0b57cec5SDimitry Andric
1351*0b57cec5SDimitry Andric    // observer
1352*0b57cec5SDimitry Andric
1353*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;}
1354*0b57cec5SDimitry Andric
1355*0b57cec5SDimitry Andric    // arithmetic
1356*0b57cec5SDimitry Andric
1357*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;}
1358*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;}
1359*0b57cec5SDimitry Andric
1360*0b57cec5SDimitry Andric    // special values
1361*0b57cec5SDimitry Andric
1362*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());}
1363*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());}
1364*0b57cec5SDimitry Andric};
1365*0b57cec5SDimitry Andric
1366*0b57cec5SDimitry Andric} // chrono
1367*0b57cec5SDimitry Andric
1368*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration1, class _Duration2>
1369*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS common_type<chrono::time_point<_Clock, _Duration1>,
1370*0b57cec5SDimitry Andric                                         chrono::time_point<_Clock, _Duration2> >
1371*0b57cec5SDimitry Andric{
1372*0b57cec5SDimitry Andric    typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type;
1373*0b57cec5SDimitry Andric};
1374*0b57cec5SDimitry Andric
1375*0b57cec5SDimitry Andricnamespace chrono {
1376*0b57cec5SDimitry Andric
1377*0b57cec5SDimitry Andrictemplate <class _ToDuration, class _Clock, class _Duration>
1378*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1379*0b57cec5SDimitry Andrictime_point<_Clock, _ToDuration>
1380*0b57cec5SDimitry Andrictime_point_cast(const time_point<_Clock, _Duration>& __t)
1381*0b57cec5SDimitry Andric{
1382*0b57cec5SDimitry Andric    return time_point<_Clock, _ToDuration>(_VSTD::chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
1383*0b57cec5SDimitry Andric}
1384*0b57cec5SDimitry Andric
1385*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
1386*0b57cec5SDimitry Andrictemplate <class _ToDuration, class _Clock, class _Duration>
1387*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1388*0b57cec5SDimitry Andrictypename enable_if
1389*0b57cec5SDimitry Andric<
1390*0b57cec5SDimitry Andric    __is_duration<_ToDuration>::value,
1391*0b57cec5SDimitry Andric    time_point<_Clock, _ToDuration>
1392*0b57cec5SDimitry Andric>::type
1393*0b57cec5SDimitry Andricfloor(const time_point<_Clock, _Duration>& __t)
1394*0b57cec5SDimitry Andric{
1395*0b57cec5SDimitry Andric    return time_point<_Clock, _ToDuration>{floor<_ToDuration>(__t.time_since_epoch())};
1396*0b57cec5SDimitry Andric}
1397*0b57cec5SDimitry Andric
1398*0b57cec5SDimitry Andrictemplate <class _ToDuration, class _Clock, class _Duration>
1399*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1400*0b57cec5SDimitry Andrictypename enable_if
1401*0b57cec5SDimitry Andric<
1402*0b57cec5SDimitry Andric    __is_duration<_ToDuration>::value,
1403*0b57cec5SDimitry Andric    time_point<_Clock, _ToDuration>
1404*0b57cec5SDimitry Andric>::type
1405*0b57cec5SDimitry Andricceil(const time_point<_Clock, _Duration>& __t)
1406*0b57cec5SDimitry Andric{
1407*0b57cec5SDimitry Andric    return time_point<_Clock, _ToDuration>{ceil<_ToDuration>(__t.time_since_epoch())};
1408*0b57cec5SDimitry Andric}
1409*0b57cec5SDimitry Andric
1410*0b57cec5SDimitry Andrictemplate <class _ToDuration, class _Clock, class _Duration>
1411*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1412*0b57cec5SDimitry Andrictypename enable_if
1413*0b57cec5SDimitry Andric<
1414*0b57cec5SDimitry Andric    __is_duration<_ToDuration>::value,
1415*0b57cec5SDimitry Andric    time_point<_Clock, _ToDuration>
1416*0b57cec5SDimitry Andric>::type
1417*0b57cec5SDimitry Andricround(const time_point<_Clock, _Duration>& __t)
1418*0b57cec5SDimitry Andric{
1419*0b57cec5SDimitry Andric    return time_point<_Clock, _ToDuration>{round<_ToDuration>(__t.time_since_epoch())};
1420*0b57cec5SDimitry Andric}
1421*0b57cec5SDimitry Andric
1422*0b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
1423*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1424*0b57cec5SDimitry Andrictypename enable_if
1425*0b57cec5SDimitry Andric<
1426*0b57cec5SDimitry Andric    numeric_limits<_Rep>::is_signed,
1427*0b57cec5SDimitry Andric    duration<_Rep, _Period>
1428*0b57cec5SDimitry Andric>::type
1429*0b57cec5SDimitry Andricabs(duration<_Rep, _Period> __d)
1430*0b57cec5SDimitry Andric{
1431*0b57cec5SDimitry Andric    return __d >= __d.zero() ? __d : -__d;
1432*0b57cec5SDimitry Andric}
1433*0b57cec5SDimitry Andric#endif
1434*0b57cec5SDimitry Andric
1435*0b57cec5SDimitry Andric// time_point ==
1436*0b57cec5SDimitry Andric
1437*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration1, class _Duration2>
1438*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1439*0b57cec5SDimitry Andricbool
1440*0b57cec5SDimitry Andricoperator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1441*0b57cec5SDimitry Andric{
1442*0b57cec5SDimitry Andric    return __lhs.time_since_epoch() == __rhs.time_since_epoch();
1443*0b57cec5SDimitry Andric}
1444*0b57cec5SDimitry Andric
1445*0b57cec5SDimitry Andric// time_point !=
1446*0b57cec5SDimitry Andric
1447*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration1, class _Duration2>
1448*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1449*0b57cec5SDimitry Andricbool
1450*0b57cec5SDimitry Andricoperator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1451*0b57cec5SDimitry Andric{
1452*0b57cec5SDimitry Andric    return !(__lhs == __rhs);
1453*0b57cec5SDimitry Andric}
1454*0b57cec5SDimitry Andric
1455*0b57cec5SDimitry Andric// time_point <
1456*0b57cec5SDimitry Andric
1457*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration1, class _Duration2>
1458*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1459*0b57cec5SDimitry Andricbool
1460*0b57cec5SDimitry Andricoperator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1461*0b57cec5SDimitry Andric{
1462*0b57cec5SDimitry Andric    return __lhs.time_since_epoch() < __rhs.time_since_epoch();
1463*0b57cec5SDimitry Andric}
1464*0b57cec5SDimitry Andric
1465*0b57cec5SDimitry Andric// time_point >
1466*0b57cec5SDimitry Andric
1467*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration1, class _Duration2>
1468*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1469*0b57cec5SDimitry Andricbool
1470*0b57cec5SDimitry Andricoperator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1471*0b57cec5SDimitry Andric{
1472*0b57cec5SDimitry Andric    return __rhs < __lhs;
1473*0b57cec5SDimitry Andric}
1474*0b57cec5SDimitry Andric
1475*0b57cec5SDimitry Andric// time_point <=
1476*0b57cec5SDimitry Andric
1477*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration1, class _Duration2>
1478*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1479*0b57cec5SDimitry Andricbool
1480*0b57cec5SDimitry Andricoperator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1481*0b57cec5SDimitry Andric{
1482*0b57cec5SDimitry Andric    return !(__rhs < __lhs);
1483*0b57cec5SDimitry Andric}
1484*0b57cec5SDimitry Andric
1485*0b57cec5SDimitry Andric// time_point >=
1486*0b57cec5SDimitry Andric
1487*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration1, class _Duration2>
1488*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1489*0b57cec5SDimitry Andricbool
1490*0b57cec5SDimitry Andricoperator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1491*0b57cec5SDimitry Andric{
1492*0b57cec5SDimitry Andric    return !(__lhs < __rhs);
1493*0b57cec5SDimitry Andric}
1494*0b57cec5SDimitry Andric
1495*0b57cec5SDimitry Andric// time_point operator+(time_point x, duration y);
1496*0b57cec5SDimitry Andric
1497*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration1, class _Rep2, class _Period2>
1498*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1499*0b57cec5SDimitry Andrictime_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
1500*0b57cec5SDimitry Andricoperator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1501*0b57cec5SDimitry Andric{
1502*0b57cec5SDimitry Andric    typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
1503*0b57cec5SDimitry Andric    return _Tr (__lhs.time_since_epoch() + __rhs);
1504*0b57cec5SDimitry Andric}
1505*0b57cec5SDimitry Andric
1506*0b57cec5SDimitry Andric// time_point operator+(duration x, time_point y);
1507*0b57cec5SDimitry Andric
1508*0b57cec5SDimitry Andrictemplate <class _Rep1, class _Period1, class _Clock, class _Duration2>
1509*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1510*0b57cec5SDimitry Andrictime_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
1511*0b57cec5SDimitry Andricoperator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1512*0b57cec5SDimitry Andric{
1513*0b57cec5SDimitry Andric    return __rhs + __lhs;
1514*0b57cec5SDimitry Andric}
1515*0b57cec5SDimitry Andric
1516*0b57cec5SDimitry Andric// time_point operator-(time_point x, duration y);
1517*0b57cec5SDimitry Andric
1518*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration1, class _Rep2, class _Period2>
1519*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1520*0b57cec5SDimitry Andrictime_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
1521*0b57cec5SDimitry Andricoperator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
1522*0b57cec5SDimitry Andric{
1523*0b57cec5SDimitry Andric    typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret;
1524*0b57cec5SDimitry Andric    return _Ret(__lhs.time_since_epoch() -__rhs);
1525*0b57cec5SDimitry Andric}
1526*0b57cec5SDimitry Andric
1527*0b57cec5SDimitry Andric// duration operator-(time_point x, time_point y);
1528*0b57cec5SDimitry Andric
1529*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration1, class _Duration2>
1530*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1531*0b57cec5SDimitry Andrictypename common_type<_Duration1, _Duration2>::type
1532*0b57cec5SDimitry Andricoperator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
1533*0b57cec5SDimitry Andric{
1534*0b57cec5SDimitry Andric    return __lhs.time_since_epoch() - __rhs.time_since_epoch();
1535*0b57cec5SDimitry Andric}
1536*0b57cec5SDimitry Andric
1537*0b57cec5SDimitry Andric//////////////////////////////////////////////////////////
1538*0b57cec5SDimitry Andric/////////////////////// clocks ///////////////////////////
1539*0b57cec5SDimitry Andric//////////////////////////////////////////////////////////
1540*0b57cec5SDimitry Andric
1541*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS system_clock
1542*0b57cec5SDimitry Andric{
1543*0b57cec5SDimitry Andricpublic:
1544*0b57cec5SDimitry Andric    typedef microseconds                     duration;
1545*0b57cec5SDimitry Andric    typedef duration::rep                    rep;
1546*0b57cec5SDimitry Andric    typedef duration::period                 period;
1547*0b57cec5SDimitry Andric    typedef chrono::time_point<system_clock> time_point;
1548*0b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
1549*0b57cec5SDimitry Andric
1550*0b57cec5SDimitry Andric    static time_point now() _NOEXCEPT;
1551*0b57cec5SDimitry Andric    static time_t     to_time_t  (const time_point& __t) _NOEXCEPT;
1552*0b57cec5SDimitry Andric    static time_point from_time_t(time_t __t) _NOEXCEPT;
1553*0b57cec5SDimitry Andric};
1554*0b57cec5SDimitry Andric
1555*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
1556*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS steady_clock
1557*0b57cec5SDimitry Andric{
1558*0b57cec5SDimitry Andricpublic:
1559*0b57cec5SDimitry Andric    typedef nanoseconds                                   duration;
1560*0b57cec5SDimitry Andric    typedef duration::rep                                 rep;
1561*0b57cec5SDimitry Andric    typedef duration::period                              period;
1562*0b57cec5SDimitry Andric    typedef chrono::time_point<steady_clock, duration>    time_point;
1563*0b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true;
1564*0b57cec5SDimitry Andric
1565*0b57cec5SDimitry Andric    static time_point now() _NOEXCEPT;
1566*0b57cec5SDimitry Andric};
1567*0b57cec5SDimitry Andric
1568*0b57cec5SDimitry Andrictypedef steady_clock high_resolution_clock;
1569*0b57cec5SDimitry Andric#else
1570*0b57cec5SDimitry Andrictypedef system_clock high_resolution_clock;
1571*0b57cec5SDimitry Andric#endif
1572*0b57cec5SDimitry Andric
1573*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17
1574*0b57cec5SDimitry Andric// [time.clock.file], type file_clock
1575*0b57cec5SDimitry Andricusing file_clock = _VSTD_FS::_FilesystemClock;
1576*0b57cec5SDimitry Andric
1577*0b57cec5SDimitry Andrictemplate<class _Duration>
1578*0b57cec5SDimitry Andricusing file_time = time_point<file_clock, _Duration>;
1579*0b57cec5SDimitry Andric
1580*0b57cec5SDimitry Andric
1581*0b57cec5SDimitry Andrictemplate <class _Duration>
1582*0b57cec5SDimitry Andricusing sys_time    = time_point<system_clock, _Duration>;
1583*0b57cec5SDimitry Andricusing sys_seconds = sys_time<seconds>;
1584*0b57cec5SDimitry Andricusing sys_days    = sys_time<days>;
1585*0b57cec5SDimitry Andric
1586*0b57cec5SDimitry Andricstruct local_t {};
1587*0b57cec5SDimitry Andrictemplate<class Duration>
1588*0b57cec5SDimitry Andricusing local_time  = time_point<local_t, Duration>;
1589*0b57cec5SDimitry Andricusing local_seconds = local_time<seconds>;
1590*0b57cec5SDimitry Andricusing local_days    = local_time<days>;
1591*0b57cec5SDimitry Andric
1592*0b57cec5SDimitry Andric
1593*0b57cec5SDimitry Andricstruct last_spec { explicit last_spec() = default; };
1594*0b57cec5SDimitry Andric
1595*0b57cec5SDimitry Andricclass day {
1596*0b57cec5SDimitry Andricprivate:
1597*0b57cec5SDimitry Andric    unsigned char __d;
1598*0b57cec5SDimitry Andricpublic:
1599*0b57cec5SDimitry Andric    day() = default;
1600*0b57cec5SDimitry Andric    explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {}
1601*0b57cec5SDimitry Andric    inline constexpr day& operator++()    noexcept { ++__d; return *this; }
1602*0b57cec5SDimitry Andric    inline constexpr day  operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; }
1603*0b57cec5SDimitry Andric    inline constexpr day& operator--()    noexcept { --__d; return *this; }
1604*0b57cec5SDimitry Andric    inline constexpr day  operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; }
1605*0b57cec5SDimitry Andric           constexpr day& operator+=(const days& __dd) noexcept;
1606*0b57cec5SDimitry Andric           constexpr day& operator-=(const days& __dd) noexcept;
1607*0b57cec5SDimitry Andric    explicit inline constexpr operator unsigned() const noexcept { return __d; }
1608*0b57cec5SDimitry Andric    inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; }
1609*0b57cec5SDimitry Andric  };
1610*0b57cec5SDimitry Andric
1611*0b57cec5SDimitry Andric
1612*0b57cec5SDimitry Andricinline constexpr
1613*0b57cec5SDimitry Andricbool operator==(const day& __lhs, const day& __rhs) noexcept
1614*0b57cec5SDimitry Andric{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
1615*0b57cec5SDimitry Andric
1616*0b57cec5SDimitry Andricinline constexpr
1617*0b57cec5SDimitry Andricbool operator!=(const day& __lhs, const day& __rhs) noexcept
1618*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
1619*0b57cec5SDimitry Andric
1620*0b57cec5SDimitry Andricinline constexpr
1621*0b57cec5SDimitry Andricbool operator< (const day& __lhs, const day& __rhs) noexcept
1622*0b57cec5SDimitry Andric{ return static_cast<unsigned>(__lhs) <  static_cast<unsigned>(__rhs); }
1623*0b57cec5SDimitry Andric
1624*0b57cec5SDimitry Andricinline constexpr
1625*0b57cec5SDimitry Andricbool operator> (const day& __lhs, const day& __rhs) noexcept
1626*0b57cec5SDimitry Andric{ return __rhs < __lhs; }
1627*0b57cec5SDimitry Andric
1628*0b57cec5SDimitry Andricinline constexpr
1629*0b57cec5SDimitry Andricbool operator<=(const day& __lhs, const day& __rhs) noexcept
1630*0b57cec5SDimitry Andric{ return !(__rhs < __lhs);}
1631*0b57cec5SDimitry Andric
1632*0b57cec5SDimitry Andricinline constexpr
1633*0b57cec5SDimitry Andricbool operator>=(const day& __lhs, const day& __rhs) noexcept
1634*0b57cec5SDimitry Andric{ return !(__lhs < __rhs); }
1635*0b57cec5SDimitry Andric
1636*0b57cec5SDimitry Andricinline constexpr
1637*0b57cec5SDimitry Andricday operator+ (const day& __lhs, const days& __rhs) noexcept
1638*0b57cec5SDimitry Andric{ return day(static_cast<unsigned>(__lhs) + __rhs.count()); }
1639*0b57cec5SDimitry Andric
1640*0b57cec5SDimitry Andricinline constexpr
1641*0b57cec5SDimitry Andricday operator+ (const days& __lhs, const day& __rhs) noexcept
1642*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
1643*0b57cec5SDimitry Andric
1644*0b57cec5SDimitry Andricinline constexpr
1645*0b57cec5SDimitry Andricday operator- (const day& __lhs, const days& __rhs) noexcept
1646*0b57cec5SDimitry Andric{ return __lhs + -__rhs; }
1647*0b57cec5SDimitry Andric
1648*0b57cec5SDimitry Andricinline constexpr
1649*0b57cec5SDimitry Andricdays operator-(const day& __lhs, const day& __rhs) noexcept
1650*0b57cec5SDimitry Andric{ return days(static_cast<int>(static_cast<unsigned>(__lhs)) -
1651*0b57cec5SDimitry Andric              static_cast<int>(static_cast<unsigned>(__rhs))); }
1652*0b57cec5SDimitry Andric
1653*0b57cec5SDimitry Andricinline constexpr day& day::operator+=(const days& __dd) noexcept
1654*0b57cec5SDimitry Andric{ *this = *this + __dd; return *this; }
1655*0b57cec5SDimitry Andric
1656*0b57cec5SDimitry Andricinline constexpr day& day::operator-=(const days& __dd) noexcept
1657*0b57cec5SDimitry Andric{ *this = *this - __dd; return *this; }
1658*0b57cec5SDimitry Andric
1659*0b57cec5SDimitry Andric
1660*0b57cec5SDimitry Andricclass month {
1661*0b57cec5SDimitry Andricprivate:
1662*0b57cec5SDimitry Andric    unsigned char __m;
1663*0b57cec5SDimitry Andricpublic:
1664*0b57cec5SDimitry Andric    month() = default;
1665*0b57cec5SDimitry Andric    explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {}
1666*0b57cec5SDimitry Andric    inline constexpr month& operator++()    noexcept { ++__m; return *this; }
1667*0b57cec5SDimitry Andric    inline constexpr month  operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; }
1668*0b57cec5SDimitry Andric    inline constexpr month& operator--()    noexcept { --__m; return *this; }
1669*0b57cec5SDimitry Andric    inline constexpr month  operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; }
1670*0b57cec5SDimitry Andric           constexpr month& operator+=(const months& __m1) noexcept;
1671*0b57cec5SDimitry Andric           constexpr month& operator-=(const months& __m1) noexcept;
1672*0b57cec5SDimitry Andric    explicit inline constexpr operator unsigned() const noexcept { return __m; }
1673*0b57cec5SDimitry Andric    inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; }
1674*0b57cec5SDimitry Andric};
1675*0b57cec5SDimitry Andric
1676*0b57cec5SDimitry Andric
1677*0b57cec5SDimitry Andricinline constexpr
1678*0b57cec5SDimitry Andricbool operator==(const month& __lhs, const month& __rhs) noexcept
1679*0b57cec5SDimitry Andric{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
1680*0b57cec5SDimitry Andric
1681*0b57cec5SDimitry Andricinline constexpr
1682*0b57cec5SDimitry Andricbool operator!=(const month& __lhs, const month& __rhs) noexcept
1683*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
1684*0b57cec5SDimitry Andric
1685*0b57cec5SDimitry Andricinline constexpr
1686*0b57cec5SDimitry Andricbool operator< (const month& __lhs, const month& __rhs) noexcept
1687*0b57cec5SDimitry Andric{ return static_cast<unsigned>(__lhs)  < static_cast<unsigned>(__rhs); }
1688*0b57cec5SDimitry Andric
1689*0b57cec5SDimitry Andricinline constexpr
1690*0b57cec5SDimitry Andricbool operator> (const month& __lhs, const month& __rhs) noexcept
1691*0b57cec5SDimitry Andric{ return __rhs < __lhs; }
1692*0b57cec5SDimitry Andric
1693*0b57cec5SDimitry Andricinline constexpr
1694*0b57cec5SDimitry Andricbool operator<=(const month& __lhs, const month& __rhs) noexcept
1695*0b57cec5SDimitry Andric{ return !(__rhs < __lhs); }
1696*0b57cec5SDimitry Andric
1697*0b57cec5SDimitry Andricinline constexpr
1698*0b57cec5SDimitry Andricbool operator>=(const month& __lhs, const month& __rhs) noexcept
1699*0b57cec5SDimitry Andric{ return !(__lhs < __rhs); }
1700*0b57cec5SDimitry Andric
1701*0b57cec5SDimitry Andricinline constexpr
1702*0b57cec5SDimitry Andricmonth operator+ (const month& __lhs, const months& __rhs) noexcept
1703*0b57cec5SDimitry Andric{
1704*0b57cec5SDimitry Andric    auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1);
1705*0b57cec5SDimitry Andric    auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12;
1706*0b57cec5SDimitry Andric    return month{static_cast<unsigned>(__mu - __yr * 12 + 1)};
1707*0b57cec5SDimitry Andric}
1708*0b57cec5SDimitry Andric
1709*0b57cec5SDimitry Andricinline constexpr
1710*0b57cec5SDimitry Andricmonth operator+ (const months& __lhs, const month& __rhs) noexcept
1711*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
1712*0b57cec5SDimitry Andric
1713*0b57cec5SDimitry Andricinline constexpr
1714*0b57cec5SDimitry Andricmonth operator- (const month& __lhs, const months& __rhs) noexcept
1715*0b57cec5SDimitry Andric{ return __lhs + -__rhs; }
1716*0b57cec5SDimitry Andric
1717*0b57cec5SDimitry Andricinline constexpr
1718*0b57cec5SDimitry Andricmonths operator-(const month& __lhs, const month& __rhs) noexcept
1719*0b57cec5SDimitry Andric{
1720*0b57cec5SDimitry Andric    auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs);
1721*0b57cec5SDimitry Andric    return months(__dm <= 11 ? __dm : __dm + 12);
1722*0b57cec5SDimitry Andric}
1723*0b57cec5SDimitry Andric
1724*0b57cec5SDimitry Andricinline constexpr month& month::operator+=(const months& __dm) noexcept
1725*0b57cec5SDimitry Andric{ *this = *this + __dm; return *this; }
1726*0b57cec5SDimitry Andric
1727*0b57cec5SDimitry Andricinline constexpr month& month::operator-=(const months& __dm) noexcept
1728*0b57cec5SDimitry Andric{ *this = *this - __dm; return *this; }
1729*0b57cec5SDimitry Andric
1730*0b57cec5SDimitry Andric
1731*0b57cec5SDimitry Andricclass year {
1732*0b57cec5SDimitry Andricprivate:
1733*0b57cec5SDimitry Andric    short __y;
1734*0b57cec5SDimitry Andricpublic:
1735*0b57cec5SDimitry Andric    year() = default;
1736*0b57cec5SDimitry Andric    explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {}
1737*0b57cec5SDimitry Andric
1738*0b57cec5SDimitry Andric    inline constexpr year& operator++()    noexcept { ++__y; return *this; }
1739*0b57cec5SDimitry Andric    inline constexpr year  operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; }
1740*0b57cec5SDimitry Andric    inline constexpr year& operator--()    noexcept { --__y; return *this; }
1741*0b57cec5SDimitry Andric    inline constexpr year  operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; }
1742*0b57cec5SDimitry Andric           constexpr year& operator+=(const years& __dy) noexcept;
1743*0b57cec5SDimitry Andric           constexpr year& operator-=(const years& __dy) noexcept;
1744*0b57cec5SDimitry Andric    inline constexpr year operator+() const noexcept { return *this; }
1745*0b57cec5SDimitry Andric    inline constexpr year operator-() const noexcept { return year{-__y}; }
1746*0b57cec5SDimitry Andric
1747*0b57cec5SDimitry Andric    inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); }
1748*0b57cec5SDimitry Andric    explicit inline constexpr operator int() const noexcept { return __y; }
1749*0b57cec5SDimitry Andric           constexpr bool ok() const noexcept;
1750*0b57cec5SDimitry Andric    static inline constexpr year min() noexcept { return year{-32767}; }
1751*0b57cec5SDimitry Andric    static inline constexpr year max() noexcept { return year{ 32767}; }
1752*0b57cec5SDimitry Andric};
1753*0b57cec5SDimitry Andric
1754*0b57cec5SDimitry Andric
1755*0b57cec5SDimitry Andricinline constexpr
1756*0b57cec5SDimitry Andricbool operator==(const year& __lhs, const year& __rhs) noexcept
1757*0b57cec5SDimitry Andric{ return static_cast<int>(__lhs) == static_cast<int>(__rhs); }
1758*0b57cec5SDimitry Andric
1759*0b57cec5SDimitry Andricinline constexpr
1760*0b57cec5SDimitry Andricbool operator!=(const year& __lhs, const year& __rhs) noexcept
1761*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
1762*0b57cec5SDimitry Andric
1763*0b57cec5SDimitry Andricinline constexpr
1764*0b57cec5SDimitry Andricbool operator< (const year& __lhs, const year& __rhs) noexcept
1765*0b57cec5SDimitry Andric{ return static_cast<int>(__lhs)  < static_cast<int>(__rhs); }
1766*0b57cec5SDimitry Andric
1767*0b57cec5SDimitry Andricinline constexpr
1768*0b57cec5SDimitry Andricbool operator> (const year& __lhs, const year& __rhs) noexcept
1769*0b57cec5SDimitry Andric{ return __rhs < __lhs; }
1770*0b57cec5SDimitry Andric
1771*0b57cec5SDimitry Andricinline constexpr
1772*0b57cec5SDimitry Andricbool operator<=(const year& __lhs, const year& __rhs) noexcept
1773*0b57cec5SDimitry Andric{ return !(__rhs < __lhs); }
1774*0b57cec5SDimitry Andric
1775*0b57cec5SDimitry Andricinline constexpr
1776*0b57cec5SDimitry Andricbool operator>=(const year& __lhs, const year& __rhs) noexcept
1777*0b57cec5SDimitry Andric{ return !(__lhs < __rhs); }
1778*0b57cec5SDimitry Andric
1779*0b57cec5SDimitry Andricinline constexpr
1780*0b57cec5SDimitry Andricyear operator+ (const year& __lhs, const years& __rhs) noexcept
1781*0b57cec5SDimitry Andric{ return year(static_cast<int>(__lhs) + __rhs.count()); }
1782*0b57cec5SDimitry Andric
1783*0b57cec5SDimitry Andricinline constexpr
1784*0b57cec5SDimitry Andricyear operator+ (const years& __lhs, const year& __rhs) noexcept
1785*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
1786*0b57cec5SDimitry Andric
1787*0b57cec5SDimitry Andricinline constexpr
1788*0b57cec5SDimitry Andricyear operator- (const year& __lhs, const years& __rhs) noexcept
1789*0b57cec5SDimitry Andric{ return __lhs + -__rhs; }
1790*0b57cec5SDimitry Andric
1791*0b57cec5SDimitry Andricinline constexpr
1792*0b57cec5SDimitry Andricyears operator-(const year& __lhs, const year& __rhs) noexcept
1793*0b57cec5SDimitry Andric{ return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; }
1794*0b57cec5SDimitry Andric
1795*0b57cec5SDimitry Andric
1796*0b57cec5SDimitry Andricinline constexpr year& year::operator+=(const years& __dy) noexcept
1797*0b57cec5SDimitry Andric{ *this = *this + __dy; return *this; }
1798*0b57cec5SDimitry Andric
1799*0b57cec5SDimitry Andricinline constexpr year& year::operator-=(const years& __dy) noexcept
1800*0b57cec5SDimitry Andric{ *this = *this - __dy; return *this; }
1801*0b57cec5SDimitry Andric
1802*0b57cec5SDimitry Andricinline constexpr bool year::ok() const noexcept
1803*0b57cec5SDimitry Andric{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); }
1804*0b57cec5SDimitry Andric
1805*0b57cec5SDimitry Andricclass weekday_indexed;
1806*0b57cec5SDimitry Andricclass weekday_last;
1807*0b57cec5SDimitry Andric
1808*0b57cec5SDimitry Andricclass weekday {
1809*0b57cec5SDimitry Andricprivate:
1810*0b57cec5SDimitry Andric    unsigned char __wd;
1811*0b57cec5SDimitry Andricpublic:
1812*0b57cec5SDimitry Andric  weekday() = default;
1813*0b57cec5SDimitry Andric  inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val)) {}
1814*0b57cec5SDimitry Andric  inline constexpr          weekday(const sys_days& __sysd) noexcept
1815*0b57cec5SDimitry Andric          : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {}
1816*0b57cec5SDimitry Andric  inline explicit constexpr weekday(const local_days& __locd) noexcept
1817*0b57cec5SDimitry Andric          : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {}
1818*0b57cec5SDimitry Andric
1819*0b57cec5SDimitry Andric  inline constexpr weekday& operator++()    noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; }
1820*0b57cec5SDimitry Andric  inline constexpr weekday  operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; }
1821*0b57cec5SDimitry Andric  inline constexpr weekday& operator--()    noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; }
1822*0b57cec5SDimitry Andric  inline constexpr weekday  operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; }
1823*0b57cec5SDimitry Andric         constexpr weekday& operator+=(const days& __dd) noexcept;
1824*0b57cec5SDimitry Andric         constexpr weekday& operator-=(const days& __dd) noexcept;
1825*0b57cec5SDimitry Andric  inline explicit constexpr operator unsigned() const noexcept { return __wd; }
1826*0b57cec5SDimitry Andric  inline constexpr bool ok() const noexcept { return __wd <= 6; }
1827*0b57cec5SDimitry Andric         constexpr weekday_indexed operator[](unsigned __index) const noexcept;
1828*0b57cec5SDimitry Andric         constexpr weekday_last    operator[](last_spec) const noexcept;
1829*0b57cec5SDimitry Andric
1830*0b57cec5SDimitry Andric  static constexpr unsigned char __weekday_from_days(int __days) noexcept;
1831*0b57cec5SDimitry Andric};
1832*0b57cec5SDimitry Andric
1833*0b57cec5SDimitry Andric
1834*0b57cec5SDimitry Andric// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days
1835*0b57cec5SDimitry Andricinline constexpr
1836*0b57cec5SDimitry Andricunsigned char weekday::__weekday_from_days(int __days) noexcept
1837*0b57cec5SDimitry Andric{
1838*0b57cec5SDimitry Andric    return static_cast<unsigned char>(
1839*0b57cec5SDimitry Andric              static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6)
1840*0b57cec5SDimitry Andric           );
1841*0b57cec5SDimitry Andric}
1842*0b57cec5SDimitry Andric
1843*0b57cec5SDimitry Andricinline constexpr
1844*0b57cec5SDimitry Andricbool operator==(const weekday& __lhs, const weekday& __rhs) noexcept
1845*0b57cec5SDimitry Andric{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
1846*0b57cec5SDimitry Andric
1847*0b57cec5SDimitry Andricinline constexpr
1848*0b57cec5SDimitry Andricbool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept
1849*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
1850*0b57cec5SDimitry Andric
1851*0b57cec5SDimitry Andricinline constexpr
1852*0b57cec5SDimitry Andricbool operator< (const weekday& __lhs, const weekday& __rhs) noexcept
1853*0b57cec5SDimitry Andric{ return static_cast<unsigned>(__lhs) <  static_cast<unsigned>(__rhs); }
1854*0b57cec5SDimitry Andric
1855*0b57cec5SDimitry Andricinline constexpr
1856*0b57cec5SDimitry Andricbool operator> (const weekday& __lhs, const weekday& __rhs) noexcept
1857*0b57cec5SDimitry Andric{ return __rhs < __lhs; }
1858*0b57cec5SDimitry Andric
1859*0b57cec5SDimitry Andricinline constexpr
1860*0b57cec5SDimitry Andricbool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept
1861*0b57cec5SDimitry Andric{ return !(__rhs < __lhs);}
1862*0b57cec5SDimitry Andric
1863*0b57cec5SDimitry Andricinline constexpr
1864*0b57cec5SDimitry Andricbool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept
1865*0b57cec5SDimitry Andric{ return !(__lhs < __rhs); }
1866*0b57cec5SDimitry Andric
1867*0b57cec5SDimitry Andricconstexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept
1868*0b57cec5SDimitry Andric{
1869*0b57cec5SDimitry Andric    auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + __rhs.count();
1870*0b57cec5SDimitry Andric    auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7;
1871*0b57cec5SDimitry Andric    return weekday{static_cast<unsigned>(__mu - __yr * 7)};
1872*0b57cec5SDimitry Andric}
1873*0b57cec5SDimitry Andric
1874*0b57cec5SDimitry Andricconstexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept
1875*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
1876*0b57cec5SDimitry Andric
1877*0b57cec5SDimitry Andricconstexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept
1878*0b57cec5SDimitry Andric{ return __lhs + -__rhs; }
1879*0b57cec5SDimitry Andric
1880*0b57cec5SDimitry Andricconstexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept
1881*0b57cec5SDimitry Andric{
1882*0b57cec5SDimitry Andric    const int __wdu = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs);
1883*0b57cec5SDimitry Andric    const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7;
1884*0b57cec5SDimitry Andric    return days{__wdu - __wk * 7};
1885*0b57cec5SDimitry Andric}
1886*0b57cec5SDimitry Andric
1887*0b57cec5SDimitry Andricinline constexpr weekday& weekday::operator+=(const days& __dd) noexcept
1888*0b57cec5SDimitry Andric{ *this = *this + __dd; return *this; }
1889*0b57cec5SDimitry Andric
1890*0b57cec5SDimitry Andricinline constexpr weekday& weekday::operator-=(const days& __dd) noexcept
1891*0b57cec5SDimitry Andric{ *this = *this - __dd; return *this; }
1892*0b57cec5SDimitry Andric
1893*0b57cec5SDimitry Andric
1894*0b57cec5SDimitry Andricclass weekday_indexed {
1895*0b57cec5SDimitry Andricprivate:
1896*0b57cec5SDimitry Andric    _VSTD::chrono::weekday __wd;
1897*0b57cec5SDimitry Andric    unsigned char          __idx;
1898*0b57cec5SDimitry Andricpublic:
1899*0b57cec5SDimitry Andric    weekday_indexed() = default;
1900*0b57cec5SDimitry Andric    inline constexpr weekday_indexed(const _VSTD::chrono::weekday& __wdval, unsigned __idxval) noexcept
1901*0b57cec5SDimitry Andric        : __wd{__wdval}, __idx(__idxval) {}
1902*0b57cec5SDimitry Andric    inline constexpr _VSTD::chrono::weekday weekday() const noexcept { return __wd; }
1903*0b57cec5SDimitry Andric    inline constexpr unsigned                 index() const noexcept { return __idx; }
1904*0b57cec5SDimitry Andric    inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; }
1905*0b57cec5SDimitry Andric};
1906*0b57cec5SDimitry Andric
1907*0b57cec5SDimitry Andricinline constexpr
1908*0b57cec5SDimitry Andricbool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
1909*0b57cec5SDimitry Andric{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); }
1910*0b57cec5SDimitry Andric
1911*0b57cec5SDimitry Andricinline constexpr
1912*0b57cec5SDimitry Andricbool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept
1913*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
1914*0b57cec5SDimitry Andric
1915*0b57cec5SDimitry Andric
1916*0b57cec5SDimitry Andricclass weekday_last {
1917*0b57cec5SDimitry Andricprivate:
1918*0b57cec5SDimitry Andric    _VSTD::chrono::weekday __wd;
1919*0b57cec5SDimitry Andricpublic:
1920*0b57cec5SDimitry Andric    explicit constexpr weekday_last(const _VSTD::chrono::weekday& __val) noexcept
1921*0b57cec5SDimitry Andric        : __wd{__val} {}
1922*0b57cec5SDimitry Andric    constexpr _VSTD::chrono::weekday weekday() const noexcept { return __wd; }
1923*0b57cec5SDimitry Andric    constexpr bool ok() const noexcept { return __wd.ok(); }
1924*0b57cec5SDimitry Andric};
1925*0b57cec5SDimitry Andric
1926*0b57cec5SDimitry Andricinline constexpr
1927*0b57cec5SDimitry Andricbool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
1928*0b57cec5SDimitry Andric{ return __lhs.weekday() == __rhs.weekday(); }
1929*0b57cec5SDimitry Andric
1930*0b57cec5SDimitry Andricinline constexpr
1931*0b57cec5SDimitry Andricbool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept
1932*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
1933*0b57cec5SDimitry Andric
1934*0b57cec5SDimitry Andricinline constexpr
1935*0b57cec5SDimitry Andricweekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; }
1936*0b57cec5SDimitry Andric
1937*0b57cec5SDimitry Andricinline constexpr
1938*0b57cec5SDimitry Andricweekday_last    weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; }
1939*0b57cec5SDimitry Andric
1940*0b57cec5SDimitry Andric
1941*0b57cec5SDimitry Andricinline constexpr last_spec last{};
1942*0b57cec5SDimitry Andricinline constexpr weekday   Sunday{0};
1943*0b57cec5SDimitry Andricinline constexpr weekday   Monday{1};
1944*0b57cec5SDimitry Andricinline constexpr weekday   Tuesday{2};
1945*0b57cec5SDimitry Andricinline constexpr weekday   Wednesday{3};
1946*0b57cec5SDimitry Andricinline constexpr weekday   Thursday{4};
1947*0b57cec5SDimitry Andricinline constexpr weekday   Friday{5};
1948*0b57cec5SDimitry Andricinline constexpr weekday   Saturday{6};
1949*0b57cec5SDimitry Andric
1950*0b57cec5SDimitry Andricinline constexpr month January{1};
1951*0b57cec5SDimitry Andricinline constexpr month February{2};
1952*0b57cec5SDimitry Andricinline constexpr month March{3};
1953*0b57cec5SDimitry Andricinline constexpr month April{4};
1954*0b57cec5SDimitry Andricinline constexpr month May{5};
1955*0b57cec5SDimitry Andricinline constexpr month June{6};
1956*0b57cec5SDimitry Andricinline constexpr month July{7};
1957*0b57cec5SDimitry Andricinline constexpr month August{8};
1958*0b57cec5SDimitry Andricinline constexpr month September{9};
1959*0b57cec5SDimitry Andricinline constexpr month October{10};
1960*0b57cec5SDimitry Andricinline constexpr month November{11};
1961*0b57cec5SDimitry Andricinline constexpr month December{12};
1962*0b57cec5SDimitry Andric
1963*0b57cec5SDimitry Andric
1964*0b57cec5SDimitry Andricclass month_day {
1965*0b57cec5SDimitry Andricprivate:
1966*0b57cec5SDimitry Andric   chrono::month __m;
1967*0b57cec5SDimitry Andric   chrono::day   __d;
1968*0b57cec5SDimitry Andricpublic:
1969*0b57cec5SDimitry Andric    month_day() = default;
1970*0b57cec5SDimitry Andric    constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept
1971*0b57cec5SDimitry Andric        : __m{__mval}, __d{__dval} {}
1972*0b57cec5SDimitry Andric    inline constexpr chrono::month month() const noexcept { return __m; }
1973*0b57cec5SDimitry Andric    inline constexpr chrono::day   day()   const noexcept { return __d; }
1974*0b57cec5SDimitry Andric    constexpr bool ok() const noexcept;
1975*0b57cec5SDimitry Andric};
1976*0b57cec5SDimitry Andric
1977*0b57cec5SDimitry Andricinline constexpr
1978*0b57cec5SDimitry Andricbool month_day::ok() const noexcept
1979*0b57cec5SDimitry Andric{
1980*0b57cec5SDimitry Andric    if (!__m.ok()) return false;
1981*0b57cec5SDimitry Andric    const unsigned __dval = static_cast<unsigned>(__d);
1982*0b57cec5SDimitry Andric    if (__dval < 1 || __dval > 31) return false;
1983*0b57cec5SDimitry Andric    if (__dval <= 29) return true;
1984*0b57cec5SDimitry Andric//  Now we've got either 30 or 31
1985*0b57cec5SDimitry Andric    const unsigned __mval = static_cast<unsigned>(__m);
1986*0b57cec5SDimitry Andric    if (__mval == 2) return false;
1987*0b57cec5SDimitry Andric    if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11)
1988*0b57cec5SDimitry Andric        return __dval == 30;
1989*0b57cec5SDimitry Andric    return true;
1990*0b57cec5SDimitry Andric}
1991*0b57cec5SDimitry Andric
1992*0b57cec5SDimitry Andricinline constexpr
1993*0b57cec5SDimitry Andricbool operator==(const month_day& __lhs, const month_day& __rhs) noexcept
1994*0b57cec5SDimitry Andric{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
1995*0b57cec5SDimitry Andric
1996*0b57cec5SDimitry Andricinline constexpr
1997*0b57cec5SDimitry Andricbool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept
1998*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
1999*0b57cec5SDimitry Andric
2000*0b57cec5SDimitry Andricinline constexpr
2001*0b57cec5SDimitry Andricmonth_day operator/(const month& __lhs, const day& __rhs) noexcept
2002*0b57cec5SDimitry Andric{ return month_day{__lhs, __rhs}; }
2003*0b57cec5SDimitry Andric
2004*0b57cec5SDimitry Andricconstexpr
2005*0b57cec5SDimitry Andricmonth_day operator/(const day& __lhs, const month& __rhs) noexcept
2006*0b57cec5SDimitry Andric{ return __rhs / __lhs; }
2007*0b57cec5SDimitry Andric
2008*0b57cec5SDimitry Andricinline constexpr
2009*0b57cec5SDimitry Andricmonth_day operator/(const month& __lhs, int __rhs) noexcept
2010*0b57cec5SDimitry Andric{ return __lhs / day(__rhs); }
2011*0b57cec5SDimitry Andric
2012*0b57cec5SDimitry Andricconstexpr
2013*0b57cec5SDimitry Andricmonth_day operator/(int __lhs, const day& __rhs) noexcept
2014*0b57cec5SDimitry Andric{ return month(__lhs) / __rhs; }
2015*0b57cec5SDimitry Andric
2016*0b57cec5SDimitry Andricconstexpr
2017*0b57cec5SDimitry Andricmonth_day operator/(const day& __lhs, int __rhs) noexcept
2018*0b57cec5SDimitry Andric{ return month(__rhs) / __lhs; }
2019*0b57cec5SDimitry Andric
2020*0b57cec5SDimitry Andric
2021*0b57cec5SDimitry Andricinline constexpr
2022*0b57cec5SDimitry Andricbool operator< (const month_day& __lhs, const month_day& __rhs) noexcept
2023*0b57cec5SDimitry Andric{ return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); }
2024*0b57cec5SDimitry Andric
2025*0b57cec5SDimitry Andricinline constexpr
2026*0b57cec5SDimitry Andricbool operator> (const month_day& __lhs, const month_day& __rhs) noexcept
2027*0b57cec5SDimitry Andric{ return __rhs < __lhs; }
2028*0b57cec5SDimitry Andric
2029*0b57cec5SDimitry Andricinline constexpr
2030*0b57cec5SDimitry Andricbool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept
2031*0b57cec5SDimitry Andric{ return !(__rhs < __lhs);}
2032*0b57cec5SDimitry Andric
2033*0b57cec5SDimitry Andricinline constexpr
2034*0b57cec5SDimitry Andricbool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept
2035*0b57cec5SDimitry Andric{ return !(__lhs < __rhs); }
2036*0b57cec5SDimitry Andric
2037*0b57cec5SDimitry Andric
2038*0b57cec5SDimitry Andric
2039*0b57cec5SDimitry Andricclass month_day_last {
2040*0b57cec5SDimitry Andricprivate:
2041*0b57cec5SDimitry Andric    chrono::month __m;
2042*0b57cec5SDimitry Andricpublic:
2043*0b57cec5SDimitry Andric    explicit constexpr month_day_last(const chrono::month& __val) noexcept
2044*0b57cec5SDimitry Andric        : __m{__val} {}
2045*0b57cec5SDimitry Andric    inline constexpr chrono::month month() const noexcept { return __m; }
2046*0b57cec5SDimitry Andric    inline constexpr bool ok() const noexcept { return __m.ok(); }
2047*0b57cec5SDimitry Andric};
2048*0b57cec5SDimitry Andric
2049*0b57cec5SDimitry Andricinline constexpr
2050*0b57cec5SDimitry Andricbool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
2051*0b57cec5SDimitry Andric{ return __lhs.month() == __rhs.month(); }
2052*0b57cec5SDimitry Andric
2053*0b57cec5SDimitry Andricinline constexpr
2054*0b57cec5SDimitry Andricbool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
2055*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
2056*0b57cec5SDimitry Andric
2057*0b57cec5SDimitry Andricinline constexpr
2058*0b57cec5SDimitry Andricbool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept
2059*0b57cec5SDimitry Andric{ return __lhs.month() < __rhs.month(); }
2060*0b57cec5SDimitry Andric
2061*0b57cec5SDimitry Andricinline constexpr
2062*0b57cec5SDimitry Andricbool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept
2063*0b57cec5SDimitry Andric{ return __rhs < __lhs; }
2064*0b57cec5SDimitry Andric
2065*0b57cec5SDimitry Andricinline constexpr
2066*0b57cec5SDimitry Andricbool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
2067*0b57cec5SDimitry Andric{ return !(__rhs < __lhs);}
2068*0b57cec5SDimitry Andric
2069*0b57cec5SDimitry Andricinline constexpr
2070*0b57cec5SDimitry Andricbool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept
2071*0b57cec5SDimitry Andric{ return !(__lhs < __rhs); }
2072*0b57cec5SDimitry Andric
2073*0b57cec5SDimitry Andricinline constexpr
2074*0b57cec5SDimitry Andricmonth_day_last operator/(const month& __lhs, last_spec) noexcept
2075*0b57cec5SDimitry Andric{ return month_day_last{__lhs}; }
2076*0b57cec5SDimitry Andric
2077*0b57cec5SDimitry Andricinline constexpr
2078*0b57cec5SDimitry Andricmonth_day_last operator/(last_spec, const month& __rhs) noexcept
2079*0b57cec5SDimitry Andric{ return month_day_last{__rhs}; }
2080*0b57cec5SDimitry Andric
2081*0b57cec5SDimitry Andricinline constexpr
2082*0b57cec5SDimitry Andricmonth_day_last operator/(int __lhs, last_spec) noexcept
2083*0b57cec5SDimitry Andric{ return month_day_last{month(__lhs)}; }
2084*0b57cec5SDimitry Andric
2085*0b57cec5SDimitry Andricinline constexpr
2086*0b57cec5SDimitry Andricmonth_day_last operator/(last_spec, int __rhs) noexcept
2087*0b57cec5SDimitry Andric{ return month_day_last{month(__rhs)}; }
2088*0b57cec5SDimitry Andric
2089*0b57cec5SDimitry Andric
2090*0b57cec5SDimitry Andricclass month_weekday {
2091*0b57cec5SDimitry Andricprivate:
2092*0b57cec5SDimitry Andric    chrono::month __m;
2093*0b57cec5SDimitry Andric    chrono::weekday_indexed __wdi;
2094*0b57cec5SDimitry Andricpublic:
2095*0b57cec5SDimitry Andric    month_weekday() = default;
2096*0b57cec5SDimitry Andric    constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept
2097*0b57cec5SDimitry Andric        : __m{__mval}, __wdi{__wdival} {}
2098*0b57cec5SDimitry Andric    inline constexpr chrono::month                     month() const noexcept { return __m; }
2099*0b57cec5SDimitry Andric    inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
2100*0b57cec5SDimitry Andric    inline constexpr bool                                 ok() const noexcept { return __m.ok() && __wdi.ok(); }
2101*0b57cec5SDimitry Andric};
2102*0b57cec5SDimitry Andric
2103*0b57cec5SDimitry Andricinline constexpr
2104*0b57cec5SDimitry Andricbool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
2105*0b57cec5SDimitry Andric{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
2106*0b57cec5SDimitry Andric
2107*0b57cec5SDimitry Andricinline constexpr
2108*0b57cec5SDimitry Andricbool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept
2109*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
2110*0b57cec5SDimitry Andric
2111*0b57cec5SDimitry Andricinline constexpr
2112*0b57cec5SDimitry Andricmonth_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept
2113*0b57cec5SDimitry Andric{ return month_weekday{__lhs, __rhs}; }
2114*0b57cec5SDimitry Andric
2115*0b57cec5SDimitry Andricinline constexpr
2116*0b57cec5SDimitry Andricmonth_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept
2117*0b57cec5SDimitry Andric{ return month_weekday{month(__lhs), __rhs}; }
2118*0b57cec5SDimitry Andric
2119*0b57cec5SDimitry Andricinline constexpr
2120*0b57cec5SDimitry Andricmonth_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept
2121*0b57cec5SDimitry Andric{ return month_weekday{__rhs, __lhs}; }
2122*0b57cec5SDimitry Andric
2123*0b57cec5SDimitry Andricinline constexpr
2124*0b57cec5SDimitry Andricmonth_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept
2125*0b57cec5SDimitry Andric{ return month_weekday{month(__rhs), __lhs}; }
2126*0b57cec5SDimitry Andric
2127*0b57cec5SDimitry Andric
2128*0b57cec5SDimitry Andricclass month_weekday_last {
2129*0b57cec5SDimitry Andric    chrono::month        __m;
2130*0b57cec5SDimitry Andric    chrono::weekday_last __wdl;
2131*0b57cec5SDimitry Andric  public:
2132*0b57cec5SDimitry Andric    constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept
2133*0b57cec5SDimitry Andric        : __m{__mval}, __wdl{__wdlval} {}
2134*0b57cec5SDimitry Andric    inline constexpr chrono::month               month() const noexcept { return __m; }
2135*0b57cec5SDimitry Andric    inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; }
2136*0b57cec5SDimitry Andric    inline constexpr bool                           ok() const noexcept { return __m.ok() && __wdl.ok(); }
2137*0b57cec5SDimitry Andric};
2138*0b57cec5SDimitry Andric
2139*0b57cec5SDimitry Andricinline constexpr
2140*0b57cec5SDimitry Andricbool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
2141*0b57cec5SDimitry Andric{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
2142*0b57cec5SDimitry Andric
2143*0b57cec5SDimitry Andricinline constexpr
2144*0b57cec5SDimitry Andricbool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept
2145*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
2146*0b57cec5SDimitry Andric
2147*0b57cec5SDimitry Andric
2148*0b57cec5SDimitry Andricinline constexpr
2149*0b57cec5SDimitry Andricmonth_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept
2150*0b57cec5SDimitry Andric{ return month_weekday_last{__lhs, __rhs}; }
2151*0b57cec5SDimitry Andric
2152*0b57cec5SDimitry Andricinline constexpr
2153*0b57cec5SDimitry Andricmonth_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept
2154*0b57cec5SDimitry Andric{ return month_weekday_last{month(__lhs), __rhs}; }
2155*0b57cec5SDimitry Andric
2156*0b57cec5SDimitry Andricinline constexpr
2157*0b57cec5SDimitry Andricmonth_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept
2158*0b57cec5SDimitry Andric{ return month_weekday_last{__rhs, __lhs}; }
2159*0b57cec5SDimitry Andric
2160*0b57cec5SDimitry Andricinline constexpr
2161*0b57cec5SDimitry Andricmonth_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept
2162*0b57cec5SDimitry Andric{ return month_weekday_last{month(__rhs), __lhs}; }
2163*0b57cec5SDimitry Andric
2164*0b57cec5SDimitry Andric
2165*0b57cec5SDimitry Andricclass year_month {
2166*0b57cec5SDimitry Andric    chrono::year  __y;
2167*0b57cec5SDimitry Andric    chrono::month __m;
2168*0b57cec5SDimitry Andricpublic:
2169*0b57cec5SDimitry Andric    year_month() = default;
2170*0b57cec5SDimitry Andric    constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept
2171*0b57cec5SDimitry Andric        : __y{__yval}, __m{__mval} {}
2172*0b57cec5SDimitry Andric    inline constexpr chrono::year  year()  const noexcept { return __y; }
2173*0b57cec5SDimitry Andric    inline constexpr chrono::month month() const noexcept { return __m; }
2174*0b57cec5SDimitry Andric    inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; }
2175*0b57cec5SDimitry Andric    inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; }
2176*0b57cec5SDimitry Andric    inline constexpr year_month& operator+=(const years& __dy)  noexcept { this->__y += __dy; return *this; }
2177*0b57cec5SDimitry Andric    inline constexpr year_month& operator-=(const years& __dy)  noexcept { this->__y -= __dy; return *this; }
2178*0b57cec5SDimitry Andric    inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); }
2179*0b57cec5SDimitry Andric};
2180*0b57cec5SDimitry Andric
2181*0b57cec5SDimitry Andricinline constexpr
2182*0b57cec5SDimitry Andricyear_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; }
2183*0b57cec5SDimitry Andric
2184*0b57cec5SDimitry Andricinline constexpr
2185*0b57cec5SDimitry Andricyear_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; }
2186*0b57cec5SDimitry Andric
2187*0b57cec5SDimitry Andricinline constexpr
2188*0b57cec5SDimitry Andricbool operator==(const year_month& __lhs, const year_month& __rhs) noexcept
2189*0b57cec5SDimitry Andric{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); }
2190*0b57cec5SDimitry Andric
2191*0b57cec5SDimitry Andricinline constexpr
2192*0b57cec5SDimitry Andricbool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept
2193*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
2194*0b57cec5SDimitry Andric
2195*0b57cec5SDimitry Andricinline constexpr
2196*0b57cec5SDimitry Andricbool operator< (const year_month& __lhs, const year_month& __rhs) noexcept
2197*0b57cec5SDimitry Andric{ return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); }
2198*0b57cec5SDimitry Andric
2199*0b57cec5SDimitry Andricinline constexpr
2200*0b57cec5SDimitry Andricbool operator> (const year_month& __lhs, const year_month& __rhs) noexcept
2201*0b57cec5SDimitry Andric{ return __rhs < __lhs; }
2202*0b57cec5SDimitry Andric
2203*0b57cec5SDimitry Andricinline constexpr
2204*0b57cec5SDimitry Andricbool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept
2205*0b57cec5SDimitry Andric{ return !(__rhs < __lhs);}
2206*0b57cec5SDimitry Andric
2207*0b57cec5SDimitry Andricinline constexpr
2208*0b57cec5SDimitry Andricbool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept
2209*0b57cec5SDimitry Andric{ return !(__lhs < __rhs); }
2210*0b57cec5SDimitry Andric
2211*0b57cec5SDimitry Andricconstexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept
2212*0b57cec5SDimitry Andric{
2213*0b57cec5SDimitry Andric    int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count();
2214*0b57cec5SDimitry Andric    const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12;
2215*0b57cec5SDimitry Andric    __dmi = __dmi - __dy * 12 + 1;
2216*0b57cec5SDimitry Andric    return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi));
2217*0b57cec5SDimitry Andric}
2218*0b57cec5SDimitry Andric
2219*0b57cec5SDimitry Andricconstexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept
2220*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
2221*0b57cec5SDimitry Andric
2222*0b57cec5SDimitry Andricconstexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept
2223*0b57cec5SDimitry Andric{ return (__lhs.year() + __rhs) / __lhs.month(); }
2224*0b57cec5SDimitry Andric
2225*0b57cec5SDimitry Andricconstexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept
2226*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
2227*0b57cec5SDimitry Andric
2228*0b57cec5SDimitry Andricconstexpr months     operator-(const year_month& __lhs, const year_month& __rhs) noexcept
2229*0b57cec5SDimitry Andric{ return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); }
2230*0b57cec5SDimitry Andric
2231*0b57cec5SDimitry Andricconstexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept
2232*0b57cec5SDimitry Andric{ return __lhs + -__rhs; }
2233*0b57cec5SDimitry Andric
2234*0b57cec5SDimitry Andricconstexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept
2235*0b57cec5SDimitry Andric{ return __lhs + -__rhs; }
2236*0b57cec5SDimitry Andric
2237*0b57cec5SDimitry Andricclass year_month_day_last;
2238*0b57cec5SDimitry Andric
2239*0b57cec5SDimitry Andricclass year_month_day {
2240*0b57cec5SDimitry Andricprivate:
2241*0b57cec5SDimitry Andric    chrono::year  __y;
2242*0b57cec5SDimitry Andric    chrono::month __m;
2243*0b57cec5SDimitry Andric    chrono::day   __d;
2244*0b57cec5SDimitry Andricpublic:
2245*0b57cec5SDimitry Andric     year_month_day() = default;
2246*0b57cec5SDimitry Andric     inline constexpr year_month_day(
2247*0b57cec5SDimitry Andric            const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept
2248*0b57cec5SDimitry Andric            : __y{__yval}, __m{__mval}, __d{__dval} {}
2249*0b57cec5SDimitry Andric            constexpr year_month_day(const year_month_day_last& __ymdl) noexcept;
2250*0b57cec5SDimitry Andric     inline constexpr year_month_day(const sys_days& __sysd) noexcept
2251*0b57cec5SDimitry Andric            : year_month_day(__from_days(__sysd.time_since_epoch())) {}
2252*0b57cec5SDimitry Andric     inline explicit constexpr year_month_day(const local_days& __locd) noexcept
2253*0b57cec5SDimitry Andric            : year_month_day(__from_days(__locd.time_since_epoch())) {}
2254*0b57cec5SDimitry Andric
2255*0b57cec5SDimitry Andric            constexpr year_month_day& operator+=(const months& __dm) noexcept;
2256*0b57cec5SDimitry Andric            constexpr year_month_day& operator-=(const months& __dm) noexcept;
2257*0b57cec5SDimitry Andric            constexpr year_month_day& operator+=(const years& __dy)  noexcept;
2258*0b57cec5SDimitry Andric            constexpr year_month_day& operator-=(const years& __dy)  noexcept;
2259*0b57cec5SDimitry Andric
2260*0b57cec5SDimitry Andric     inline constexpr chrono::year   year() const noexcept { return __y; }
2261*0b57cec5SDimitry Andric     inline constexpr chrono::month month() const noexcept { return __m; }
2262*0b57cec5SDimitry Andric     inline constexpr chrono::day     day() const noexcept { return __d; }
2263*0b57cec5SDimitry Andric     inline constexpr operator   sys_days() const noexcept          { return   sys_days{__to_days()}; }
2264*0b57cec5SDimitry Andric     inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
2265*0b57cec5SDimitry Andric
2266*0b57cec5SDimitry Andric            constexpr bool             ok() const noexcept;
2267*0b57cec5SDimitry Andric
2268*0b57cec5SDimitry Andric     static constexpr year_month_day __from_days(days __d) noexcept;
2269*0b57cec5SDimitry Andric     constexpr days __to_days() const noexcept;
2270*0b57cec5SDimitry Andric};
2271*0b57cec5SDimitry Andric
2272*0b57cec5SDimitry Andric
2273*0b57cec5SDimitry Andric// https://howardhinnant.github.io/date_algorithms.html#civil_from_days
2274*0b57cec5SDimitry Andricinline constexpr
2275*0b57cec5SDimitry Andricyear_month_day
2276*0b57cec5SDimitry Andricyear_month_day::__from_days(days __d) noexcept
2277*0b57cec5SDimitry Andric{
2278*0b57cec5SDimitry Andric    static_assert(std::numeric_limits<unsigned>::digits >= 18, "");
2279*0b57cec5SDimitry Andric    static_assert(std::numeric_limits<int>::digits >= 20     , "");
2280*0b57cec5SDimitry Andric    const int      __z = __d.count() + 719468;
2281*0b57cec5SDimitry Andric    const int      __era = (__z >= 0 ? __z : __z - 146096) / 146097;
2282*0b57cec5SDimitry Andric    const unsigned __doe = static_cast<unsigned>(__z - __era * 146097);              // [0, 146096]
2283*0b57cec5SDimitry Andric    const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365;  // [0, 399]
2284*0b57cec5SDimitry Andric    const int      __yr = static_cast<int>(__yoe) + __era * 400;
2285*0b57cec5SDimitry Andric    const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100);              // [0, 365]
2286*0b57cec5SDimitry Andric    const unsigned __mp = (5 * __doy + 2)/153;                                       // [0, 11]
2287*0b57cec5SDimitry Andric    const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1;                            // [1, 31]
2288*0b57cec5SDimitry Andric    const unsigned __mth = __mp + (__mp < 10 ? 3 : -9);                              // [1, 12]
2289*0b57cec5SDimitry Andric    return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}};
2290*0b57cec5SDimitry Andric}
2291*0b57cec5SDimitry Andric
2292*0b57cec5SDimitry Andric// https://howardhinnant.github.io/date_algorithms.html#days_from_civil
2293*0b57cec5SDimitry Andricinline constexpr days year_month_day::__to_days() const noexcept
2294*0b57cec5SDimitry Andric{
2295*0b57cec5SDimitry Andric    static_assert(std::numeric_limits<unsigned>::digits >= 18, "");
2296*0b57cec5SDimitry Andric    static_assert(std::numeric_limits<int>::digits >= 20     , "");
2297*0b57cec5SDimitry Andric
2298*0b57cec5SDimitry Andric    const int      __yr  = static_cast<int>(__y) - (__m <= February);
2299*0b57cec5SDimitry Andric    const unsigned __mth = static_cast<unsigned>(__m);
2300*0b57cec5SDimitry Andric    const unsigned __dy  = static_cast<unsigned>(__d);
2301*0b57cec5SDimitry Andric
2302*0b57cec5SDimitry Andric    const int      __era = (__yr >= 0 ? __yr : __yr - 399) / 400;
2303*0b57cec5SDimitry Andric    const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400);                // [0, 399]
2304*0b57cec5SDimitry Andric    const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1;  // [0, 365]
2305*0b57cec5SDimitry Andric    const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy;                // [0, 146096]
2306*0b57cec5SDimitry Andric    return days{__era * 146097 + static_cast<int>(__doe) - 719468};
2307*0b57cec5SDimitry Andric}
2308*0b57cec5SDimitry Andric
2309*0b57cec5SDimitry Andricinline constexpr
2310*0b57cec5SDimitry Andricbool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2311*0b57cec5SDimitry Andric{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
2312*0b57cec5SDimitry Andric
2313*0b57cec5SDimitry Andricinline constexpr
2314*0b57cec5SDimitry Andricbool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2315*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
2316*0b57cec5SDimitry Andric
2317*0b57cec5SDimitry Andricinline constexpr
2318*0b57cec5SDimitry Andricbool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2319*0b57cec5SDimitry Andric{
2320*0b57cec5SDimitry Andric    if (__lhs.year() < __rhs.year()) return true;
2321*0b57cec5SDimitry Andric    if (__lhs.year() > __rhs.year()) return false;
2322*0b57cec5SDimitry Andric    if (__lhs.month() < __rhs.month()) return true;
2323*0b57cec5SDimitry Andric    if (__lhs.month() > __rhs.month()) return false;
2324*0b57cec5SDimitry Andric    return __lhs.day() < __rhs.day();
2325*0b57cec5SDimitry Andric}
2326*0b57cec5SDimitry Andric
2327*0b57cec5SDimitry Andricinline constexpr
2328*0b57cec5SDimitry Andricbool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2329*0b57cec5SDimitry Andric{ return __rhs < __lhs; }
2330*0b57cec5SDimitry Andric
2331*0b57cec5SDimitry Andricinline constexpr
2332*0b57cec5SDimitry Andricbool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2333*0b57cec5SDimitry Andric{ return !(__rhs < __lhs);}
2334*0b57cec5SDimitry Andric
2335*0b57cec5SDimitry Andricinline constexpr
2336*0b57cec5SDimitry Andricbool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
2337*0b57cec5SDimitry Andric{ return !(__lhs < __rhs); }
2338*0b57cec5SDimitry Andric
2339*0b57cec5SDimitry Andricinline constexpr
2340*0b57cec5SDimitry Andricyear_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept
2341*0b57cec5SDimitry Andric{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; }
2342*0b57cec5SDimitry Andric
2343*0b57cec5SDimitry Andricinline constexpr
2344*0b57cec5SDimitry Andricyear_month_day operator/(const year_month& __lhs, int __rhs) noexcept
2345*0b57cec5SDimitry Andric{ return __lhs / day(__rhs); }
2346*0b57cec5SDimitry Andric
2347*0b57cec5SDimitry Andricinline constexpr
2348*0b57cec5SDimitry Andricyear_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept
2349*0b57cec5SDimitry Andric{ return __lhs / __rhs.month() / __rhs.day(); }
2350*0b57cec5SDimitry Andric
2351*0b57cec5SDimitry Andricinline constexpr
2352*0b57cec5SDimitry Andricyear_month_day operator/(int __lhs, const month_day& __rhs) noexcept
2353*0b57cec5SDimitry Andric{ return year(__lhs) / __rhs; }
2354*0b57cec5SDimitry Andric
2355*0b57cec5SDimitry Andricinline constexpr
2356*0b57cec5SDimitry Andricyear_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept
2357*0b57cec5SDimitry Andric{ return __rhs / __lhs; }
2358*0b57cec5SDimitry Andric
2359*0b57cec5SDimitry Andricinline constexpr
2360*0b57cec5SDimitry Andricyear_month_day operator/(const month_day& __lhs, int __rhs) noexcept
2361*0b57cec5SDimitry Andric{ return year(__rhs) / __lhs; }
2362*0b57cec5SDimitry Andric
2363*0b57cec5SDimitry Andric
2364*0b57cec5SDimitry Andricinline constexpr
2365*0b57cec5SDimitry Andricyear_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept
2366*0b57cec5SDimitry Andric{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); }
2367*0b57cec5SDimitry Andric
2368*0b57cec5SDimitry Andricinline constexpr
2369*0b57cec5SDimitry Andricyear_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept
2370*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
2371*0b57cec5SDimitry Andric
2372*0b57cec5SDimitry Andricinline constexpr
2373*0b57cec5SDimitry Andricyear_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept
2374*0b57cec5SDimitry Andric{ return __lhs + -__rhs; }
2375*0b57cec5SDimitry Andric
2376*0b57cec5SDimitry Andricinline constexpr
2377*0b57cec5SDimitry Andricyear_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept
2378*0b57cec5SDimitry Andric{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); }
2379*0b57cec5SDimitry Andric
2380*0b57cec5SDimitry Andricinline constexpr
2381*0b57cec5SDimitry Andricyear_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept
2382*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
2383*0b57cec5SDimitry Andric
2384*0b57cec5SDimitry Andricinline constexpr
2385*0b57cec5SDimitry Andricyear_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept
2386*0b57cec5SDimitry Andric{ return __lhs + -__rhs; }
2387*0b57cec5SDimitry Andric
2388*0b57cec5SDimitry Andricinline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
2389*0b57cec5SDimitry Andricinline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
2390*0b57cec5SDimitry Andricinline constexpr year_month_day& year_month_day::operator+=(const years& __dy)  noexcept { *this = *this + __dy; return *this; }
2391*0b57cec5SDimitry Andricinline constexpr year_month_day& year_month_day::operator-=(const years& __dy)  noexcept { *this = *this - __dy; return *this; }
2392*0b57cec5SDimitry Andric
2393*0b57cec5SDimitry Andricclass year_month_day_last {
2394*0b57cec5SDimitry Andricprivate:
2395*0b57cec5SDimitry Andric    chrono::year           __y;
2396*0b57cec5SDimitry Andric    chrono::month_day_last __mdl;
2397*0b57cec5SDimitry Andricpublic:
2398*0b57cec5SDimitry Andric     constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept
2399*0b57cec5SDimitry Andric        : __y{__yval}, __mdl{__mdlval} {}
2400*0b57cec5SDimitry Andric
2401*0b57cec5SDimitry Andric     constexpr year_month_day_last& operator+=(const months& __m) noexcept;
2402*0b57cec5SDimitry Andric     constexpr year_month_day_last& operator-=(const months& __m) noexcept;
2403*0b57cec5SDimitry Andric     constexpr year_month_day_last& operator+=(const years& __y)  noexcept;
2404*0b57cec5SDimitry Andric     constexpr year_month_day_last& operator-=(const years& __y)  noexcept;
2405*0b57cec5SDimitry Andric
2406*0b57cec5SDimitry Andric     inline constexpr chrono::year                     year() const noexcept { return __y; }
2407*0b57cec5SDimitry Andric     inline constexpr chrono::month                   month() const noexcept { return __mdl.month(); }
2408*0b57cec5SDimitry Andric     inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; }
2409*0b57cec5SDimitry Andric            constexpr chrono::day                       day() const noexcept;
2410*0b57cec5SDimitry Andric     inline constexpr operator                     sys_days() const noexcept { return   sys_days{year()/month()/day()}; }
2411*0b57cec5SDimitry Andric     inline explicit constexpr operator          local_days() const noexcept { return local_days{year()/month()/day()}; }
2412*0b57cec5SDimitry Andric     inline constexpr bool                               ok() const noexcept { return __y.ok() && __mdl.ok(); }
2413*0b57cec5SDimitry Andric};
2414*0b57cec5SDimitry Andric
2415*0b57cec5SDimitry Andricinline constexpr
2416*0b57cec5SDimitry Andricchrono::day year_month_day_last::day() const noexcept
2417*0b57cec5SDimitry Andric{
2418*0b57cec5SDimitry Andric    constexpr chrono::day __d[] =
2419*0b57cec5SDimitry Andric    {
2420*0b57cec5SDimitry Andric        chrono::day(31), chrono::day(28), chrono::day(31),
2421*0b57cec5SDimitry Andric        chrono::day(30), chrono::day(31), chrono::day(30),
2422*0b57cec5SDimitry Andric        chrono::day(31), chrono::day(31), chrono::day(30),
2423*0b57cec5SDimitry Andric        chrono::day(31), chrono::day(30), chrono::day(31)
2424*0b57cec5SDimitry Andric    };
2425*0b57cec5SDimitry Andric    return month() != February || !__y.is_leap() ?
2426*0b57cec5SDimitry Andric        __d[static_cast<unsigned>(month()) - 1] : chrono::day{29};
2427*0b57cec5SDimitry Andric}
2428*0b57cec5SDimitry Andric
2429*0b57cec5SDimitry Andricinline constexpr
2430*0b57cec5SDimitry Andricbool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2431*0b57cec5SDimitry Andric{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); }
2432*0b57cec5SDimitry Andric
2433*0b57cec5SDimitry Andricinline constexpr
2434*0b57cec5SDimitry Andricbool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2435*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
2436*0b57cec5SDimitry Andric
2437*0b57cec5SDimitry Andricinline constexpr
2438*0b57cec5SDimitry Andricbool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2439*0b57cec5SDimitry Andric{
2440*0b57cec5SDimitry Andric    if (__lhs.year() < __rhs.year()) return true;
2441*0b57cec5SDimitry Andric    if (__lhs.year() > __rhs.year()) return false;
2442*0b57cec5SDimitry Andric    return __lhs.month_day_last() < __rhs.month_day_last();
2443*0b57cec5SDimitry Andric}
2444*0b57cec5SDimitry Andric
2445*0b57cec5SDimitry Andricinline constexpr
2446*0b57cec5SDimitry Andricbool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2447*0b57cec5SDimitry Andric{ return __rhs < __lhs; }
2448*0b57cec5SDimitry Andric
2449*0b57cec5SDimitry Andricinline constexpr
2450*0b57cec5SDimitry Andricbool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2451*0b57cec5SDimitry Andric{ return !(__rhs < __lhs);}
2452*0b57cec5SDimitry Andric
2453*0b57cec5SDimitry Andricinline constexpr
2454*0b57cec5SDimitry Andricbool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
2455*0b57cec5SDimitry Andric{ return !(__lhs < __rhs); }
2456*0b57cec5SDimitry Andric
2457*0b57cec5SDimitry Andricinline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept
2458*0b57cec5SDimitry Andric{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; }
2459*0b57cec5SDimitry Andric
2460*0b57cec5SDimitry Andricinline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept
2461*0b57cec5SDimitry Andric{ return year_month_day_last{__lhs, __rhs}; }
2462*0b57cec5SDimitry Andric
2463*0b57cec5SDimitry Andricinline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept
2464*0b57cec5SDimitry Andric{ return year_month_day_last{year{__lhs}, __rhs}; }
2465*0b57cec5SDimitry Andric
2466*0b57cec5SDimitry Andricinline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept
2467*0b57cec5SDimitry Andric{ return __rhs / __lhs; }
2468*0b57cec5SDimitry Andric
2469*0b57cec5SDimitry Andricinline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept
2470*0b57cec5SDimitry Andric{ return year{__rhs} / __lhs; }
2471*0b57cec5SDimitry Andric
2472*0b57cec5SDimitry Andric
2473*0b57cec5SDimitry Andricinline constexpr
2474*0b57cec5SDimitry Andricyear_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept
2475*0b57cec5SDimitry Andric{ return (__lhs.year() / __lhs.month() + __rhs) / last; }
2476*0b57cec5SDimitry Andric
2477*0b57cec5SDimitry Andricinline constexpr
2478*0b57cec5SDimitry Andricyear_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept
2479*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
2480*0b57cec5SDimitry Andric
2481*0b57cec5SDimitry Andricinline constexpr
2482*0b57cec5SDimitry Andricyear_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept
2483*0b57cec5SDimitry Andric{ return __lhs + (-__rhs); }
2484*0b57cec5SDimitry Andric
2485*0b57cec5SDimitry Andricinline constexpr
2486*0b57cec5SDimitry Andricyear_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept
2487*0b57cec5SDimitry Andric{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; }
2488*0b57cec5SDimitry Andric
2489*0b57cec5SDimitry Andricinline constexpr
2490*0b57cec5SDimitry Andricyear_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept
2491*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
2492*0b57cec5SDimitry Andric
2493*0b57cec5SDimitry Andricinline constexpr
2494*0b57cec5SDimitry Andricyear_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept
2495*0b57cec5SDimitry Andric{ return __lhs + (-__rhs); }
2496*0b57cec5SDimitry Andric
2497*0b57cec5SDimitry Andricinline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
2498*0b57cec5SDimitry Andricinline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
2499*0b57cec5SDimitry Andricinline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy)  noexcept { *this = *this + __dy; return *this; }
2500*0b57cec5SDimitry Andricinline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy)  noexcept { *this = *this - __dy; return *this; }
2501*0b57cec5SDimitry Andric
2502*0b57cec5SDimitry Andricinline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
2503*0b57cec5SDimitry Andric    : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {}
2504*0b57cec5SDimitry Andric
2505*0b57cec5SDimitry Andricinline constexpr bool year_month_day::ok() const noexcept
2506*0b57cec5SDimitry Andric{
2507*0b57cec5SDimitry Andric    if (!__y.ok() || !__m.ok()) return false;
2508*0b57cec5SDimitry Andric    return chrono::day{1} <= __d && __d <= (__y / __m / last).day();
2509*0b57cec5SDimitry Andric}
2510*0b57cec5SDimitry Andric
2511*0b57cec5SDimitry Andricclass year_month_weekday {
2512*0b57cec5SDimitry Andric    chrono::year            __y;
2513*0b57cec5SDimitry Andric    chrono::month           __m;
2514*0b57cec5SDimitry Andric    chrono::weekday_indexed __wdi;
2515*0b57cec5SDimitry Andricpublic:
2516*0b57cec5SDimitry Andric    year_month_weekday() = default;
2517*0b57cec5SDimitry Andric    constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval,
2518*0b57cec5SDimitry Andric                               const chrono::weekday_indexed& __wdival) noexcept
2519*0b57cec5SDimitry Andric        : __y{__yval}, __m{__mval}, __wdi{__wdival} {}
2520*0b57cec5SDimitry Andric    constexpr year_month_weekday(const sys_days& __sysd) noexcept
2521*0b57cec5SDimitry Andric            : year_month_weekday(__from_days(__sysd.time_since_epoch())) {}
2522*0b57cec5SDimitry Andric    inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept
2523*0b57cec5SDimitry Andric            : year_month_weekday(__from_days(__locd.time_since_epoch())) {}
2524*0b57cec5SDimitry Andric    constexpr year_month_weekday& operator+=(const months& m) noexcept;
2525*0b57cec5SDimitry Andric    constexpr year_month_weekday& operator-=(const months& m) noexcept;
2526*0b57cec5SDimitry Andric    constexpr year_month_weekday& operator+=(const years& y)  noexcept;
2527*0b57cec5SDimitry Andric    constexpr year_month_weekday& operator-=(const years& y)  noexcept;
2528*0b57cec5SDimitry Andric
2529*0b57cec5SDimitry Andric    inline constexpr chrono::year                       year() const noexcept { return __y; }
2530*0b57cec5SDimitry Andric    inline constexpr chrono::month                     month() const noexcept { return __m; }
2531*0b57cec5SDimitry Andric    inline constexpr chrono::weekday                 weekday() const noexcept { return __wdi.weekday(); }
2532*0b57cec5SDimitry Andric    inline constexpr unsigned                          index() const noexcept { return __wdi.index(); }
2533*0b57cec5SDimitry Andric    inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
2534*0b57cec5SDimitry Andric
2535*0b57cec5SDimitry Andric    inline constexpr                       operator sys_days() const noexcept { return   sys_days{__to_days()}; }
2536*0b57cec5SDimitry Andric    inline explicit constexpr operator            local_days() const noexcept { return local_days{__to_days()}; }
2537*0b57cec5SDimitry Andric    inline constexpr bool ok() const noexcept
2538*0b57cec5SDimitry Andric    {
2539*0b57cec5SDimitry Andric        if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false;
2540*0b57cec5SDimitry Andric    //  TODO: make sure it's a valid date
2541*0b57cec5SDimitry Andric        return true;
2542*0b57cec5SDimitry Andric    }
2543*0b57cec5SDimitry Andric
2544*0b57cec5SDimitry Andric    static constexpr year_month_weekday __from_days(days __d) noexcept;
2545*0b57cec5SDimitry Andric    constexpr days __to_days() const noexcept;
2546*0b57cec5SDimitry Andric};
2547*0b57cec5SDimitry Andric
2548*0b57cec5SDimitry Andricinline constexpr
2549*0b57cec5SDimitry Andricyear_month_weekday year_month_weekday::__from_days(days __d) noexcept
2550*0b57cec5SDimitry Andric{
2551*0b57cec5SDimitry Andric    const sys_days      __sysd{__d};
2552*0b57cec5SDimitry Andric    const chrono::weekday __wd = chrono::weekday(__sysd);
2553*0b57cec5SDimitry Andric    const year_month_day __ymd = year_month_day(__sysd);
2554*0b57cec5SDimitry Andric    return year_month_weekday{__ymd.year(), __ymd.month(),
2555*0b57cec5SDimitry Andric                              __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]};
2556*0b57cec5SDimitry Andric}
2557*0b57cec5SDimitry Andric
2558*0b57cec5SDimitry Andricinline constexpr
2559*0b57cec5SDimitry Andricdays year_month_weekday::__to_days() const noexcept
2560*0b57cec5SDimitry Andric{
2561*0b57cec5SDimitry Andric    const sys_days __sysd = sys_days(__y/__m/1);
2562*0b57cec5SDimitry Andric    return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7}))
2563*0b57cec5SDimitry Andric                .time_since_epoch();
2564*0b57cec5SDimitry Andric}
2565*0b57cec5SDimitry Andric
2566*0b57cec5SDimitry Andricinline constexpr
2567*0b57cec5SDimitry Andricbool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
2568*0b57cec5SDimitry Andric{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
2569*0b57cec5SDimitry Andric
2570*0b57cec5SDimitry Andricinline constexpr
2571*0b57cec5SDimitry Andricbool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
2572*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
2573*0b57cec5SDimitry Andric
2574*0b57cec5SDimitry Andricinline constexpr
2575*0b57cec5SDimitry Andricyear_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept
2576*0b57cec5SDimitry Andric{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; }
2577*0b57cec5SDimitry Andric
2578*0b57cec5SDimitry Andricinline constexpr
2579*0b57cec5SDimitry Andricyear_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept
2580*0b57cec5SDimitry Andric{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; }
2581*0b57cec5SDimitry Andric
2582*0b57cec5SDimitry Andricinline constexpr
2583*0b57cec5SDimitry Andricyear_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept
2584*0b57cec5SDimitry Andric{ return year(__lhs) / __rhs; }
2585*0b57cec5SDimitry Andric
2586*0b57cec5SDimitry Andricinline constexpr
2587*0b57cec5SDimitry Andricyear_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept
2588*0b57cec5SDimitry Andric{ return __rhs / __lhs; }
2589*0b57cec5SDimitry Andric
2590*0b57cec5SDimitry Andricinline constexpr
2591*0b57cec5SDimitry Andricyear_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept
2592*0b57cec5SDimitry Andric{ return year(__rhs) / __lhs; }
2593*0b57cec5SDimitry Andric
2594*0b57cec5SDimitry Andric
2595*0b57cec5SDimitry Andricinline constexpr
2596*0b57cec5SDimitry Andricyear_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept
2597*0b57cec5SDimitry Andric{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); }
2598*0b57cec5SDimitry Andric
2599*0b57cec5SDimitry Andricinline constexpr
2600*0b57cec5SDimitry Andricyear_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept
2601*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
2602*0b57cec5SDimitry Andric
2603*0b57cec5SDimitry Andricinline constexpr
2604*0b57cec5SDimitry Andricyear_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept
2605*0b57cec5SDimitry Andric{ return __lhs + (-__rhs); }
2606*0b57cec5SDimitry Andric
2607*0b57cec5SDimitry Andricinline constexpr
2608*0b57cec5SDimitry Andricyear_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept
2609*0b57cec5SDimitry Andric{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; }
2610*0b57cec5SDimitry Andric
2611*0b57cec5SDimitry Andricinline constexpr
2612*0b57cec5SDimitry Andricyear_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept
2613*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
2614*0b57cec5SDimitry Andric
2615*0b57cec5SDimitry Andricinline constexpr
2616*0b57cec5SDimitry Andricyear_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept
2617*0b57cec5SDimitry Andric{ return __lhs + (-__rhs); }
2618*0b57cec5SDimitry Andric
2619*0b57cec5SDimitry Andric
2620*0b57cec5SDimitry Andricinline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
2621*0b57cec5SDimitry Andricinline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
2622*0b57cec5SDimitry Andricinline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy)  noexcept { *this = *this + __dy; return *this; }
2623*0b57cec5SDimitry Andricinline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy)  noexcept { *this = *this - __dy; return *this; }
2624*0b57cec5SDimitry Andric
2625*0b57cec5SDimitry Andricclass year_month_weekday_last {
2626*0b57cec5SDimitry Andricprivate:
2627*0b57cec5SDimitry Andric    chrono::year         __y;
2628*0b57cec5SDimitry Andric    chrono::month        __m;
2629*0b57cec5SDimitry Andric    chrono::weekday_last __wdl;
2630*0b57cec5SDimitry Andricpublic:
2631*0b57cec5SDimitry Andric    constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval,
2632*0b57cec5SDimitry Andric                                      const chrono::weekday_last& __wdlval) noexcept
2633*0b57cec5SDimitry Andric                : __y{__yval}, __m{__mval}, __wdl{__wdlval} {}
2634*0b57cec5SDimitry Andric    constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept;
2635*0b57cec5SDimitry Andric    constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept;
2636*0b57cec5SDimitry Andric    constexpr year_month_weekday_last& operator+=(const years& __dy)  noexcept;
2637*0b57cec5SDimitry Andric    constexpr year_month_weekday_last& operator-=(const years& __dy)  noexcept;
2638*0b57cec5SDimitry Andric
2639*0b57cec5SDimitry Andric    inline constexpr chrono::year                 year() const noexcept { return __y; }
2640*0b57cec5SDimitry Andric    inline constexpr chrono::month               month() const noexcept { return __m; }
2641*0b57cec5SDimitry Andric    inline constexpr chrono::weekday           weekday() const noexcept { return __wdl.weekday(); }
2642*0b57cec5SDimitry Andric    inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; }
2643*0b57cec5SDimitry Andric    inline constexpr operator                 sys_days() const noexcept { return   sys_days{__to_days()}; }
2644*0b57cec5SDimitry Andric    inline explicit constexpr operator      local_days() const noexcept { return local_days{__to_days()}; }
2645*0b57cec5SDimitry Andric    inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); }
2646*0b57cec5SDimitry Andric
2647*0b57cec5SDimitry Andric    constexpr days __to_days() const noexcept;
2648*0b57cec5SDimitry Andric
2649*0b57cec5SDimitry Andric};
2650*0b57cec5SDimitry Andric
2651*0b57cec5SDimitry Andricinline constexpr
2652*0b57cec5SDimitry Andricdays year_month_weekday_last::__to_days() const noexcept
2653*0b57cec5SDimitry Andric{
2654*0b57cec5SDimitry Andric    const sys_days __last = sys_days{__y/__m/last};
2655*0b57cec5SDimitry Andric    return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch();
2656*0b57cec5SDimitry Andric
2657*0b57cec5SDimitry Andric}
2658*0b57cec5SDimitry Andric
2659*0b57cec5SDimitry Andricinline constexpr
2660*0b57cec5SDimitry Andricbool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
2661*0b57cec5SDimitry Andric{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
2662*0b57cec5SDimitry Andric
2663*0b57cec5SDimitry Andricinline constexpr
2664*0b57cec5SDimitry Andricbool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
2665*0b57cec5SDimitry Andric{ return !(__lhs == __rhs); }
2666*0b57cec5SDimitry Andric
2667*0b57cec5SDimitry Andric
2668*0b57cec5SDimitry Andricinline constexpr
2669*0b57cec5SDimitry Andricyear_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept
2670*0b57cec5SDimitry Andric{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; }
2671*0b57cec5SDimitry Andric
2672*0b57cec5SDimitry Andricinline constexpr
2673*0b57cec5SDimitry Andricyear_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept
2674*0b57cec5SDimitry Andric{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; }
2675*0b57cec5SDimitry Andric
2676*0b57cec5SDimitry Andricinline constexpr
2677*0b57cec5SDimitry Andricyear_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept
2678*0b57cec5SDimitry Andric{ return year(__lhs) / __rhs; }
2679*0b57cec5SDimitry Andric
2680*0b57cec5SDimitry Andricinline constexpr
2681*0b57cec5SDimitry Andricyear_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept
2682*0b57cec5SDimitry Andric{ return __rhs / __lhs; }
2683*0b57cec5SDimitry Andric
2684*0b57cec5SDimitry Andricinline constexpr
2685*0b57cec5SDimitry Andricyear_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept
2686*0b57cec5SDimitry Andric{ return year(__rhs) / __lhs; }
2687*0b57cec5SDimitry Andric
2688*0b57cec5SDimitry Andric
2689*0b57cec5SDimitry Andricinline constexpr
2690*0b57cec5SDimitry Andricyear_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
2691*0b57cec5SDimitry Andric{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); }
2692*0b57cec5SDimitry Andric
2693*0b57cec5SDimitry Andricinline constexpr
2694*0b57cec5SDimitry Andricyear_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept
2695*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
2696*0b57cec5SDimitry Andric
2697*0b57cec5SDimitry Andricinline constexpr
2698*0b57cec5SDimitry Andricyear_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
2699*0b57cec5SDimitry Andric{ return __lhs + (-__rhs); }
2700*0b57cec5SDimitry Andric
2701*0b57cec5SDimitry Andricinline constexpr
2702*0b57cec5SDimitry Andricyear_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
2703*0b57cec5SDimitry Andric{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; }
2704*0b57cec5SDimitry Andric
2705*0b57cec5SDimitry Andricinline constexpr
2706*0b57cec5SDimitry Andricyear_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept
2707*0b57cec5SDimitry Andric{ return __rhs + __lhs; }
2708*0b57cec5SDimitry Andric
2709*0b57cec5SDimitry Andricinline constexpr
2710*0b57cec5SDimitry Andricyear_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
2711*0b57cec5SDimitry Andric{ return __lhs + (-__rhs); }
2712*0b57cec5SDimitry Andric
2713*0b57cec5SDimitry Andricinline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
2714*0b57cec5SDimitry Andricinline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
2715*0b57cec5SDimitry Andricinline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy)  noexcept { *this = *this + __dy; return *this; }
2716*0b57cec5SDimitry Andricinline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy)  noexcept { *this = *this - __dy; return *this; }
2717*0b57cec5SDimitry Andric
2718*0b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 17
2719*0b57cec5SDimitry Andric} // chrono
2720*0b57cec5SDimitry Andric
2721*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
2722*0b57cec5SDimitry Andric// Suffixes for duration literals [time.duration.literals]
2723*0b57cec5SDimitry Andricinline namespace literals
2724*0b57cec5SDimitry Andric{
2725*0b57cec5SDimitry Andric  inline namespace chrono_literals
2726*0b57cec5SDimitry Andric  {
2727*0b57cec5SDimitry Andric
2728*0b57cec5SDimitry Andric    constexpr chrono::hours operator""h(unsigned long long __h)
2729*0b57cec5SDimitry Andric    {
2730*0b57cec5SDimitry Andric        return chrono::hours(static_cast<chrono::hours::rep>(__h));
2731*0b57cec5SDimitry Andric    }
2732*0b57cec5SDimitry Andric
2733*0b57cec5SDimitry Andric    constexpr chrono::duration<long double, ratio<3600,1>> operator""h(long double __h)
2734*0b57cec5SDimitry Andric    {
2735*0b57cec5SDimitry Andric        return chrono::duration<long double, ratio<3600,1>>(__h);
2736*0b57cec5SDimitry Andric    }
2737*0b57cec5SDimitry Andric
2738*0b57cec5SDimitry Andric
2739*0b57cec5SDimitry Andric    constexpr chrono::minutes operator""min(unsigned long long __m)
2740*0b57cec5SDimitry Andric    {
2741*0b57cec5SDimitry Andric        return chrono::minutes(static_cast<chrono::minutes::rep>(__m));
2742*0b57cec5SDimitry Andric    }
2743*0b57cec5SDimitry Andric
2744*0b57cec5SDimitry Andric    constexpr chrono::duration<long double, ratio<60,1>> operator""min(long double __m)
2745*0b57cec5SDimitry Andric    {
2746*0b57cec5SDimitry Andric        return chrono::duration<long double, ratio<60,1>> (__m);
2747*0b57cec5SDimitry Andric    }
2748*0b57cec5SDimitry Andric
2749*0b57cec5SDimitry Andric
2750*0b57cec5SDimitry Andric    constexpr chrono::seconds operator""s(unsigned long long __s)
2751*0b57cec5SDimitry Andric    {
2752*0b57cec5SDimitry Andric        return chrono::seconds(static_cast<chrono::seconds::rep>(__s));
2753*0b57cec5SDimitry Andric    }
2754*0b57cec5SDimitry Andric
2755*0b57cec5SDimitry Andric    constexpr chrono::duration<long double> operator""s(long double __s)
2756*0b57cec5SDimitry Andric    {
2757*0b57cec5SDimitry Andric        return chrono::duration<long double> (__s);
2758*0b57cec5SDimitry Andric    }
2759*0b57cec5SDimitry Andric
2760*0b57cec5SDimitry Andric
2761*0b57cec5SDimitry Andric    constexpr chrono::milliseconds operator""ms(unsigned long long __ms)
2762*0b57cec5SDimitry Andric    {
2763*0b57cec5SDimitry Andric        return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms));
2764*0b57cec5SDimitry Andric    }
2765*0b57cec5SDimitry Andric
2766*0b57cec5SDimitry Andric    constexpr chrono::duration<long double, milli> operator""ms(long double __ms)
2767*0b57cec5SDimitry Andric    {
2768*0b57cec5SDimitry Andric        return chrono::duration<long double, milli>(__ms);
2769*0b57cec5SDimitry Andric    }
2770*0b57cec5SDimitry Andric
2771*0b57cec5SDimitry Andric
2772*0b57cec5SDimitry Andric    constexpr chrono::microseconds operator""us(unsigned long long __us)
2773*0b57cec5SDimitry Andric    {
2774*0b57cec5SDimitry Andric        return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us));
2775*0b57cec5SDimitry Andric    }
2776*0b57cec5SDimitry Andric
2777*0b57cec5SDimitry Andric    constexpr chrono::duration<long double, micro> operator""us(long double __us)
2778*0b57cec5SDimitry Andric    {
2779*0b57cec5SDimitry Andric        return chrono::duration<long double, micro> (__us);
2780*0b57cec5SDimitry Andric    }
2781*0b57cec5SDimitry Andric
2782*0b57cec5SDimitry Andric
2783*0b57cec5SDimitry Andric    constexpr chrono::nanoseconds operator""ns(unsigned long long __ns)
2784*0b57cec5SDimitry Andric    {
2785*0b57cec5SDimitry Andric        return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns));
2786*0b57cec5SDimitry Andric    }
2787*0b57cec5SDimitry Andric
2788*0b57cec5SDimitry Andric    constexpr chrono::duration<long double, nano> operator""ns(long double __ns)
2789*0b57cec5SDimitry Andric    {
2790*0b57cec5SDimitry Andric        return chrono::duration<long double, nano> (__ns);
2791*0b57cec5SDimitry Andric    }
2792*0b57cec5SDimitry Andric
2793*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS)
2794*0b57cec5SDimitry Andric    constexpr chrono::day operator ""d(unsigned long long __d) noexcept
2795*0b57cec5SDimitry Andric    {
2796*0b57cec5SDimitry Andric        return chrono::day(static_cast<unsigned>(__d));
2797*0b57cec5SDimitry Andric    }
2798*0b57cec5SDimitry Andric
2799*0b57cec5SDimitry Andric    constexpr chrono::year operator ""y(unsigned long long __y) noexcept
2800*0b57cec5SDimitry Andric    {
2801*0b57cec5SDimitry Andric        return chrono::year(static_cast<int>(__y));
2802*0b57cec5SDimitry Andric    }
2803*0b57cec5SDimitry Andric#endif
2804*0b57cec5SDimitry Andric}}
2805*0b57cec5SDimitry Andric
2806*0b57cec5SDimitry Andricnamespace chrono { // hoist the literals into namespace std::chrono
2807*0b57cec5SDimitry Andric   using namespace literals::chrono_literals;
2808*0b57cec5SDimitry Andric}
2809*0b57cec5SDimitry Andric
2810*0b57cec5SDimitry Andric#endif
2811*0b57cec5SDimitry Andric
2812*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
2813*0b57cec5SDimitry Andric
2814*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2815*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2816*0b57cec5SDimitry Andricstruct _FilesystemClock {
2817*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_INT128)
2818*0b57cec5SDimitry Andric  typedef __int128_t rep;
2819*0b57cec5SDimitry Andric  typedef nano period;
2820*0b57cec5SDimitry Andric#else
2821*0b57cec5SDimitry Andric  typedef long long rep;
2822*0b57cec5SDimitry Andric  typedef nano period;
2823*0b57cec5SDimitry Andric#endif
2824*0b57cec5SDimitry Andric
2825*0b57cec5SDimitry Andric  typedef chrono::duration<rep, period> duration;
2826*0b57cec5SDimitry Andric  typedef chrono::time_point<_FilesystemClock> time_point;
2827*0b57cec5SDimitry Andric
2828*0b57cec5SDimitry Andric  static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
2829*0b57cec5SDimitry Andric
2830*0b57cec5SDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept;
2831*0b57cec5SDimitry Andric
2832*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2833*0b57cec5SDimitry Andric  static time_t to_time_t(const time_point& __t) noexcept {
2834*0b57cec5SDimitry Andric      typedef chrono::duration<rep> __secs;
2835*0b57cec5SDimitry Andric      return time_t(
2836*0b57cec5SDimitry Andric          chrono::duration_cast<__secs>(__t.time_since_epoch()).count());
2837*0b57cec5SDimitry Andric  }
2838*0b57cec5SDimitry Andric
2839*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2840*0b57cec5SDimitry Andric  static time_point from_time_t(time_t __t) noexcept {
2841*0b57cec5SDimitry Andric      typedef chrono::duration<rep> __secs;
2842*0b57cec5SDimitry Andric      return time_point(__secs(__t));
2843*0b57cec5SDimitry Andric  }
2844*0b57cec5SDimitry Andric};
2845*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_FILESYSTEM
2846*0b57cec5SDimitry Andric#endif // !_LIBCPP_CXX03_LANG
2847*0b57cec5SDimitry Andric
2848*0b57cec5SDimitry Andric_LIBCPP_POP_MACROS
2849*0b57cec5SDimitry Andric
2850*0b57cec5SDimitry Andric#endif  // _LIBCPP_CHRONO
2851