year_month_weekday.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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. #ifndef _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H
  10. #define _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H
  11. #include <__chrono/calendar.h>
  12. #include <__chrono/day.h>
  13. #include <__chrono/duration.h>
  14. #include <__chrono/month.h>
  15. #include <__chrono/month_weekday.h>
  16. #include <__chrono/system_clock.h>
  17. #include <__chrono/time_point.h>
  18. #include <__chrono/weekday.h>
  19. #include <__chrono/year.h>
  20. #include <__chrono/year_month.h>
  21. #include <__chrono/year_month_day.h>
  22. #include <__config>
  23. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  24. # pragma GCC system_header
  25. #endif
  26. #if _LIBCPP_STD_VER >= 20
  27. _LIBCPP_BEGIN_NAMESPACE_STD
  28. namespace chrono {
  29. class year_month_weekday {
  30. chrono::year __y_;
  31. chrono::month __m_;
  32. chrono::weekday_indexed __wdi_;
  33. public:
  34. year_month_weekday() = default;
  35. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(
  36. const chrono::year& __yval, const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept
  37. : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {}
  38. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const sys_days& __sysd) noexcept
  39. : year_month_weekday(__from_days(__sysd.time_since_epoch())) {}
  40. _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept
  41. : year_month_weekday(__from_days(__locd.time_since_epoch())) {}
  42. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months&) noexcept;
  43. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months&) noexcept;
  44. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years&) noexcept;
  45. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years&) noexcept;
  46. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; }
  47. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; }
  48. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdi_.weekday(); }
  49. _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __wdi_.index(); }
  50. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; }
  51. _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
  52. _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept {
  53. return local_days{__to_days()};
  54. }
  55. _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept {
  56. if (!__y_.ok() || !__m_.ok() || !__wdi_.ok())
  57. return false;
  58. if (__wdi_.index() <= 4)
  59. return true;
  60. auto __nth_weekday_day =
  61. __wdi_.weekday() - chrono::weekday{static_cast<sys_days>(__y_ / __m_ / 1)} + days{(__wdi_.index() - 1) * 7 + 1};
  62. return static_cast<unsigned>(__nth_weekday_day.count()) <= static_cast<unsigned>((__y_ / __m_ / last).day());
  63. }
  64. _LIBCPP_HIDE_FROM_ABI static constexpr year_month_weekday __from_days(days __d) noexcept;
  65. _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept;
  66. };
  67. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday year_month_weekday::__from_days(days __d) noexcept {
  68. const sys_days __sysd{__d};
  69. const chrono::weekday __wd = chrono::weekday(__sysd);
  70. const year_month_day __ymd = year_month_day(__sysd);
  71. return year_month_weekday{__ymd.year(), __ymd.month(), __wd[(static_cast<unsigned>(__ymd.day()) - 1) / 7 + 1]};
  72. }
  73. _LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_weekday::__to_days() const noexcept {
  74. const sys_days __sysd = sys_days(__y_ / __m_ / 1);
  75. return (__sysd + (__wdi_.weekday() - chrono::weekday(__sysd) + days{(__wdi_.index() - 1) * 7})).time_since_epoch();
  76. }
  77. _LIBCPP_HIDE_FROM_ABI inline constexpr bool
  78. operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept {
  79. return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() &&
  80. __lhs.weekday_indexed() == __rhs.weekday_indexed();
  81. }
  82. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday
  83. operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept {
  84. return year_month_weekday{__lhs.year(), __lhs.month(), __rhs};
  85. }
  86. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday
  87. operator/(const year& __lhs, const month_weekday& __rhs) noexcept {
  88. return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()};
  89. }
  90. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept {
  91. return year(__lhs) / __rhs;
  92. }
  93. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday
  94. operator/(const month_weekday& __lhs, const year& __rhs) noexcept {
  95. return __rhs / __lhs;
  96. }
  97. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept {
  98. return year(__rhs) / __lhs;
  99. }
  100. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday
  101. operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept {
  102. return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed();
  103. }
  104. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday
  105. operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept {
  106. return __rhs + __lhs;
  107. }
  108. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday
  109. operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept {
  110. return __lhs + (-__rhs);
  111. }
  112. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday
  113. operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept {
  114. return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()};
  115. }
  116. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday
  117. operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept {
  118. return __rhs + __lhs;
  119. }
  120. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday
  121. operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept {
  122. return __lhs + (-__rhs);
  123. }
  124. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept {
  125. *this = *this + __dm;
  126. return *this;
  127. }
  128. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept {
  129. *this = *this - __dm;
  130. return *this;
  131. }
  132. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept {
  133. *this = *this + __dy;
  134. return *this;
  135. }
  136. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept {
  137. *this = *this - __dy;
  138. return *this;
  139. }
  140. class year_month_weekday_last {
  141. private:
  142. chrono::year __y_;
  143. chrono::month __m_;
  144. chrono::weekday_last __wdl_;
  145. public:
  146. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last(
  147. const chrono::year& __yval, const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept
  148. : __y_{__yval}, __m_{__mval}, __wdl_{__wdlval} {}
  149. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept;
  150. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept;
  151. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept;
  152. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept;
  153. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; }
  154. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; }
  155. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdl_.weekday(); }
  156. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; }
  157. _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
  158. _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept {
  159. return local_days{__to_days()};
  160. }
  161. _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok() && __wdl_.ok(); }
  162. _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept;
  163. };
  164. _LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_weekday_last::__to_days() const noexcept {
  165. const sys_days __last = sys_days{__y_ / __m_ / last};
  166. return (__last - (chrono::weekday{__last} - __wdl_.weekday())).time_since_epoch();
  167. }
  168. _LIBCPP_HIDE_FROM_ABI inline constexpr bool
  169. operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept {
  170. return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last();
  171. }
  172. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  173. operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept {
  174. return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs};
  175. }
  176. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  177. operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept {
  178. return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()};
  179. }
  180. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  181. operator/(int __lhs, const month_weekday_last& __rhs) noexcept {
  182. return year(__lhs) / __rhs;
  183. }
  184. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  185. operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept {
  186. return __rhs / __lhs;
  187. }
  188. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  189. operator/(const month_weekday_last& __lhs, int __rhs) noexcept {
  190. return year(__rhs) / __lhs;
  191. }
  192. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  193. operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept {
  194. return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last();
  195. }
  196. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  197. operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept {
  198. return __rhs + __lhs;
  199. }
  200. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  201. operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept {
  202. return __lhs + (-__rhs);
  203. }
  204. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  205. operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept {
  206. return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()};
  207. }
  208. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  209. operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept {
  210. return __rhs + __lhs;
  211. }
  212. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last
  213. operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept {
  214. return __lhs + (-__rhs);
  215. }
  216. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last&
  217. year_month_weekday_last::operator+=(const months& __dm) noexcept {
  218. *this = *this + __dm;
  219. return *this;
  220. }
  221. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last&
  222. year_month_weekday_last::operator-=(const months& __dm) noexcept {
  223. *this = *this - __dm;
  224. return *this;
  225. }
  226. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last&
  227. year_month_weekday_last::operator+=(const years& __dy) noexcept {
  228. *this = *this + __dy;
  229. return *this;
  230. }
  231. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last&
  232. year_month_weekday_last::operator-=(const years& __dy) noexcept {
  233. *this = *this - __dy;
  234. return *this;
  235. }
  236. } // namespace chrono
  237. _LIBCPP_END_NAMESPACE_STD
  238. #endif // _LIBCPP_STD_VER >= 20
  239. #endif // _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H