1 | // -*- C++ -*- |
2 | //===----------------------------------------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H |
11 | #define _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H |
12 | |
13 | #include <__chrono/calendar.h> |
14 | #include <__chrono/day.h> |
15 | #include <__chrono/duration.h> |
16 | #include <__chrono/month.h> |
17 | #include <__chrono/month_weekday.h> |
18 | #include <__chrono/system_clock.h> |
19 | #include <__chrono/time_point.h> |
20 | #include <__chrono/weekday.h> |
21 | #include <__chrono/year.h> |
22 | #include <__chrono/year_month.h> |
23 | #include <__chrono/year_month_day.h> |
24 | #include <__config> |
25 | |
26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
27 | # pragma GCC system_header |
28 | #endif |
29 | |
30 | #if _LIBCPP_STD_VER >= 20 |
31 | |
32 | _LIBCPP_BEGIN_NAMESPACE_STD |
33 | |
34 | namespace chrono { |
35 | |
36 | class year_month_weekday { |
37 | chrono::year __y_; |
38 | chrono::month __m_; |
39 | chrono::weekday_indexed __wdi_; |
40 | |
41 | public: |
42 | year_month_weekday() = default; |
43 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday( |
44 | const chrono::year& __yval, const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept |
45 | : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {} |
46 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const sys_days& __sysd) noexcept |
47 | : year_month_weekday(__from_days(d: __sysd.time_since_epoch())) {} |
48 | _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept |
49 | : year_month_weekday(__from_days(d: __locd.time_since_epoch())) {} |
50 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months&) noexcept; |
51 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months&) noexcept; |
52 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years&) noexcept; |
53 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years&) noexcept; |
54 | |
55 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } |
56 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } |
57 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdi_.weekday(); } |
58 | _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __wdi_.index(); } |
59 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } |
60 | |
61 | _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } |
62 | _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { |
63 | return local_days{__to_days()}; |
64 | } |
65 | _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { |
66 | if (!__y_.ok() || !__m_.ok() || !__wdi_.ok()) |
67 | return false; |
68 | if (__wdi_.index() <= 4) |
69 | return true; |
70 | auto __nth_weekday_day = |
71 | __wdi_.weekday() - chrono::weekday{static_cast<sys_days>(__y_ / __m_ / 1)} + days{(__wdi_.index() - 1) * 7 + 1}; |
72 | return static_cast<unsigned>(__nth_weekday_day.count()) <= static_cast<unsigned>((__y_ / __m_ / last).day()); |
73 | } |
74 | |
75 | _LIBCPP_HIDE_FROM_ABI static constexpr year_month_weekday __from_days(days __d) noexcept; |
76 | _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; |
77 | }; |
78 | |
79 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday year_month_weekday::__from_days(days __d) noexcept { |
80 | const sys_days __sysd{__d}; |
81 | const chrono::weekday __wd = chrono::weekday(__sysd); |
82 | const year_month_day __ymd = year_month_day(__sysd); |
83 | return year_month_weekday{__ymd.year(), __ymd.month(), __wd[(static_cast<unsigned>(__ymd.day()) - 1) / 7 + 1]}; |
84 | } |
85 | |
86 | _LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_weekday::__to_days() const noexcept { |
87 | const sys_days __sysd = sys_days(__y_ / __m_ / 1); |
88 | return (__sysd + (__wdi_.weekday() - chrono::weekday(__sysd) + days{(__wdi_.index() - 1) * 7})).time_since_epoch(); |
89 | } |
90 | |
91 | _LIBCPP_HIDE_FROM_ABI inline constexpr bool |
92 | operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept { |
93 | return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && |
94 | __lhs.weekday_indexed() == __rhs.weekday_indexed(); |
95 | } |
96 | |
97 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday |
98 | operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept { |
99 | return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; |
100 | } |
101 | |
102 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday |
103 | operator/(const year& __lhs, const month_weekday& __rhs) noexcept { |
104 | return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; |
105 | } |
106 | |
107 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept { |
108 | return year(__lhs) / __rhs; |
109 | } |
110 | |
111 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday |
112 | operator/(const month_weekday& __lhs, const year& __rhs) noexcept { |
113 | return __rhs / __lhs; |
114 | } |
115 | |
116 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept { |
117 | return year(__rhs) / __lhs; |
118 | } |
119 | |
120 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday |
121 | operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept { |
122 | return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); |
123 | } |
124 | |
125 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday |
126 | operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept { |
127 | return __rhs + __lhs; |
128 | } |
129 | |
130 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday |
131 | operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept { |
132 | return __lhs + (-__rhs); |
133 | } |
134 | |
135 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday |
136 | operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept { |
137 | return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; |
138 | } |
139 | |
140 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday |
141 | operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept { |
142 | return __rhs + __lhs; |
143 | } |
144 | |
145 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday |
146 | operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept { |
147 | return __lhs + (-__rhs); |
148 | } |
149 | |
150 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { |
151 | *this = *this + __dm; |
152 | return *this; |
153 | } |
154 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { |
155 | *this = *this - __dm; |
156 | return *this; |
157 | } |
158 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { |
159 | *this = *this + __dy; |
160 | return *this; |
161 | } |
162 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { |
163 | *this = *this - __dy; |
164 | return *this; |
165 | } |
166 | |
167 | class year_month_weekday_last { |
168 | private: |
169 | chrono::year __y_; |
170 | chrono::month __m_; |
171 | chrono::weekday_last __wdl_; |
172 | |
173 | public: |
174 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last( |
175 | const chrono::year& __yval, const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept |
176 | : __y_{__yval}, __m_{__mval}, __wdl_{__wdlval} {} |
177 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; |
178 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; |
179 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; |
180 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; |
181 | |
182 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } |
183 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } |
184 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdl_.weekday(); } |
185 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } |
186 | _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } |
187 | _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { |
188 | return local_days{__to_days()}; |
189 | } |
190 | _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok() && __wdl_.ok(); } |
191 | |
192 | _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; |
193 | }; |
194 | |
195 | _LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_weekday_last::__to_days() const noexcept { |
196 | const sys_days __last = sys_days{__y_ / __m_ / last}; |
197 | return (__last - (chrono::weekday{__last} - __wdl_.weekday())).time_since_epoch(); |
198 | } |
199 | |
200 | _LIBCPP_HIDE_FROM_ABI inline constexpr bool |
201 | operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept { |
202 | return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); |
203 | } |
204 | |
205 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
206 | operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept { |
207 | return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; |
208 | } |
209 | |
210 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
211 | operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept { |
212 | return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; |
213 | } |
214 | |
215 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
216 | operator/(int __lhs, const month_weekday_last& __rhs) noexcept { |
217 | return year(__lhs) / __rhs; |
218 | } |
219 | |
220 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
221 | operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept { |
222 | return __rhs / __lhs; |
223 | } |
224 | |
225 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
226 | operator/(const month_weekday_last& __lhs, int __rhs) noexcept { |
227 | return year(__rhs) / __lhs; |
228 | } |
229 | |
230 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
231 | operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept { |
232 | return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); |
233 | } |
234 | |
235 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
236 | operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept { |
237 | return __rhs + __lhs; |
238 | } |
239 | |
240 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
241 | operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept { |
242 | return __lhs + (-__rhs); |
243 | } |
244 | |
245 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
246 | operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept { |
247 | return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; |
248 | } |
249 | |
250 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
251 | operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept { |
252 | return __rhs + __lhs; |
253 | } |
254 | |
255 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last |
256 | operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept { |
257 | return __lhs + (-__rhs); |
258 | } |
259 | |
260 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& |
261 | year_month_weekday_last::operator+=(const months& __dm) noexcept { |
262 | *this = *this + __dm; |
263 | return *this; |
264 | } |
265 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& |
266 | year_month_weekday_last::operator-=(const months& __dm) noexcept { |
267 | *this = *this - __dm; |
268 | return *this; |
269 | } |
270 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& |
271 | year_month_weekday_last::operator+=(const years& __dy) noexcept { |
272 | *this = *this + __dy; |
273 | return *this; |
274 | } |
275 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& |
276 | year_month_weekday_last::operator-=(const years& __dy) noexcept { |
277 | *this = *this - __dy; |
278 | return *this; |
279 | } |
280 | |
281 | } // namespace chrono |
282 | |
283 | _LIBCPP_END_NAMESPACE_STD |
284 | |
285 | #endif // _LIBCPP_STD_VER >= 20 |
286 | |
287 | #endif // _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H |
288 | |