year_month_weekday.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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. {
  30. class year_month_weekday {
  31. chrono::year __y_;
  32. chrono::month __m_;
  33. chrono::weekday_indexed __wdi_;
  34. public:
  35. year_month_weekday() = default;
  36. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval,
  37. const chrono::weekday_indexed& __wdival) noexcept
  38. : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {}
  39. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const sys_days& __sysd) noexcept
  40. : year_month_weekday(__from_days(__sysd.time_since_epoch())) {}
  41. _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept
  42. : year_month_weekday(__from_days(__locd.time_since_epoch())) {}
  43. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months&) noexcept;
  44. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months&) noexcept;
  45. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years&) noexcept;
  46. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years&) noexcept;
  47. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; }
  48. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; }
  49. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdi_.weekday(); }
  50. _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __wdi_.index(); }
  51. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; }
  52. _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
  53. _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
  54. _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept
  55. {
  56. if (!__y_.ok() || !__m_.ok() || !__wdi_.ok()) return false;
  57. if (__wdi_.index() <= 4) return true;
  58. auto __nth_weekday_day =
  59. __wdi_.weekday() -
  60. chrono::weekday{static_cast<sys_days>(__y_ / __m_ / 1)} +
  61. days{(__wdi_.index() - 1) * 7 + 1};
  62. return static_cast<unsigned>(__nth_weekday_day.count()) <=
  63. static_cast<unsigned>((__y_ / __m_ / last).day());
  64. }
  65. _LIBCPP_HIDE_FROM_ABI static constexpr year_month_weekday __from_days(days __d) noexcept;
  66. _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept;
  67. };
  68. _LIBCPP_HIDE_FROM_ABI inline constexpr
  69. year_month_weekday year_month_weekday::__from_days(days __d) noexcept
  70. {
  71. const sys_days __sysd{__d};
  72. const chrono::weekday __wd = chrono::weekday(__sysd);
  73. const year_month_day __ymd = year_month_day(__sysd);
  74. return year_month_weekday{__ymd.year(), __ymd.month(),
  75. __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]};
  76. }
  77. _LIBCPP_HIDE_FROM_ABI inline constexpr
  78. days year_month_weekday::__to_days() const noexcept
  79. {
  80. const sys_days __sysd = sys_days(__y_/__m_/1);
  81. return (__sysd + (__wdi_.weekday() - chrono::weekday(__sysd) + days{(__wdi_.index()-1)*7}))
  82. .time_since_epoch();
  83. }
  84. _LIBCPP_HIDE_FROM_ABI inline constexpr
  85. bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
  86. { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
  87. _LIBCPP_HIDE_FROM_ABI inline constexpr
  88. year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept
  89. { return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; }
  90. _LIBCPP_HIDE_FROM_ABI inline constexpr
  91. year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept
  92. { return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; }
  93. _LIBCPP_HIDE_FROM_ABI inline constexpr
  94. year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept
  95. { return year(__lhs) / __rhs; }
  96. _LIBCPP_HIDE_FROM_ABI inline constexpr
  97. year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept
  98. { return __rhs / __lhs; }
  99. _LIBCPP_HIDE_FROM_ABI inline constexpr
  100. year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept
  101. { return year(__rhs) / __lhs; }
  102. _LIBCPP_HIDE_FROM_ABI inline constexpr
  103. year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept
  104. { return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); }
  105. _LIBCPP_HIDE_FROM_ABI inline constexpr
  106. year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept
  107. { return __rhs + __lhs; }
  108. _LIBCPP_HIDE_FROM_ABI inline constexpr
  109. year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept
  110. { return __lhs + (-__rhs); }
  111. _LIBCPP_HIDE_FROM_ABI inline constexpr
  112. year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept
  113. { return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; }
  114. _LIBCPP_HIDE_FROM_ABI inline constexpr
  115. year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept
  116. { return __rhs + __lhs; }
  117. _LIBCPP_HIDE_FROM_ABI inline constexpr
  118. year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept
  119. { return __lhs + (-__rhs); }
  120. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
  121. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
  122. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
  123. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
  124. class year_month_weekday_last {
  125. private:
  126. chrono::year __y_;
  127. chrono::month __m_;
  128. chrono::weekday_last __wdl_;
  129. public:
  130. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval,
  131. const chrono::weekday_last& __wdlval) noexcept
  132. : __y_{__yval}, __m_{__mval}, __wdl_{__wdlval} {}
  133. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept;
  134. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept;
  135. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept;
  136. _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept;
  137. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; }
  138. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; }
  139. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdl_.weekday(); }
  140. _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; }
  141. _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }
  142. _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; }
  143. _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok() && __wdl_.ok(); }
  144. _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept;
  145. };
  146. _LIBCPP_HIDE_FROM_ABI inline constexpr
  147. days year_month_weekday_last::__to_days() const noexcept
  148. {
  149. const sys_days __last = sys_days{__y_/__m_/last};
  150. return (__last - (chrono::weekday{__last} - __wdl_.weekday())).time_since_epoch();
  151. }
  152. _LIBCPP_HIDE_FROM_ABI inline constexpr
  153. bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept
  154. { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); }
  155. _LIBCPP_HIDE_FROM_ABI inline constexpr
  156. year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept
  157. { return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; }
  158. _LIBCPP_HIDE_FROM_ABI inline constexpr
  159. year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept
  160. { return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; }
  161. _LIBCPP_HIDE_FROM_ABI inline constexpr
  162. year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept
  163. { return year(__lhs) / __rhs; }
  164. _LIBCPP_HIDE_FROM_ABI inline constexpr
  165. year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept
  166. { return __rhs / __lhs; }
  167. _LIBCPP_HIDE_FROM_ABI inline constexpr
  168. year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept
  169. { return year(__rhs) / __lhs; }
  170. _LIBCPP_HIDE_FROM_ABI inline constexpr
  171. year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
  172. { return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); }
  173. _LIBCPP_HIDE_FROM_ABI inline constexpr
  174. year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept
  175. { return __rhs + __lhs; }
  176. _LIBCPP_HIDE_FROM_ABI inline constexpr
  177. year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept
  178. { return __lhs + (-__rhs); }
  179. _LIBCPP_HIDE_FROM_ABI inline constexpr
  180. year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
  181. { return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; }
  182. _LIBCPP_HIDE_FROM_ABI inline constexpr
  183. year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept
  184. { return __rhs + __lhs; }
  185. _LIBCPP_HIDE_FROM_ABI inline constexpr
  186. year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept
  187. { return __lhs + (-__rhs); }
  188. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
  189. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
  190. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
  191. _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
  192. } // namespace chrono
  193. _LIBCPP_END_NAMESPACE_STD
  194. #endif // _LIBCPP_STD_VER >= 20
  195. #endif // _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H