aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/libcxx/include/__chrono/weekday.h
blob: 5a7dedc6e3a16859252eda4776b3a6a704ddca24 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___CHRONO_WEEKDAY_H
#define _LIBCPP___CHRONO_WEEKDAY_H

#include <__chrono/calendar.h>
#include <__chrono/duration.h>
#include <__chrono/system_clock.h>
#include <__chrono/time_point.h>
#include <__config>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

#if _LIBCPP_STD_VER >= 20

_LIBCPP_BEGIN_NAMESPACE_STD

namespace chrono {

class weekday_indexed;
class weekday_last;

class weekday {
private:
  unsigned char __wd_;
  _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept;

public:
  weekday() = default;
  _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept
      : __wd_(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {}
  _LIBCPP_HIDE_FROM_ABI inline constexpr weekday(const sys_days& __sysd) noexcept
      : __wd_(__weekday_from_days(__sysd.time_since_epoch().count())) {}
  _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(const local_days& __locd) noexcept
      : __wd_(__weekday_from_days(__locd.time_since_epoch().count())) {}

  _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator++() noexcept {
    __wd_ = (__wd_ == 6 ? 0 : __wd_ + 1);
    return *this;
  }
  _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator++(int) noexcept {
    weekday __tmp = *this;
    ++(*this);
    return __tmp;
  }
  _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator--() noexcept {
    __wd_ = (__wd_ == 0 ? 6 : __wd_ - 1);
    return *this;
  }
  _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator--(int) noexcept {
    weekday __tmp = *this;
    --(*this);
    return __tmp;
  }
  _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator+=(const days& __dd) noexcept;
  _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator-=(const days& __dd) noexcept;
  _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned c_encoding() const noexcept { return __wd_; }
  _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned iso_encoding() const noexcept { return __wd_ == 0u ? 7 : __wd_; }
  _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_ <= 6; }
  _LIBCPP_HIDE_FROM_ABI constexpr weekday_indexed operator[](unsigned __index) const noexcept;
  _LIBCPP_HIDE_FROM_ABI constexpr weekday_last operator[](last_spec) const noexcept;
};

// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days
_LIBCPP_HIDE_FROM_ABI inline constexpr unsigned char weekday::__weekday_from_days(int __days) noexcept {
  return static_cast<unsigned char>(static_cast<unsigned>(__days >= -4 ? (__days + 4) % 7 : (__days + 5) % 7 + 6));
}

_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept {
  return __lhs.c_encoding() == __rhs.c_encoding();
}

_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator<(const weekday& __lhs, const weekday& __rhs) noexcept {
  return __lhs.c_encoding() < __rhs.c_encoding();
}

_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator>(const weekday& __lhs, const weekday& __rhs) noexcept {
  return __rhs < __lhs;
}

_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept {
  return !(__rhs < __lhs);
}

_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept {
  return !(__lhs < __rhs);
}

_LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept {
  auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count();
  auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7;
  return weekday{static_cast<unsigned>(__mu - __yr * 7)};
}

_LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept {
  return __rhs + __lhs;
}

_LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept {
  return __lhs + -__rhs;
}

_LIBCPP_HIDE_FROM_ABI inline constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept {
  const int __wdu = __lhs.c_encoding() - __rhs.c_encoding();
  const int __wk  = (__wdu >= 0 ? __wdu : __wdu - 6) / 7;
  return days{__wdu - __wk * 7};
}

_LIBCPP_HIDE_FROM_ABI inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept {
  *this = *this + __dd;
  return *this;
}

_LIBCPP_HIDE_FROM_ABI inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept {
  *this = *this - __dd;
  return *this;
}

class weekday_indexed {
private:
  chrono::weekday __wd_;
  unsigned char __idx_;

public:
  weekday_indexed() = default;
  _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept
      : __wd_{__wdval}, __idx_(__idxval) {}
  _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd_; }
  _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __idx_; }
  _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_.ok() && __idx_ >= 1 && __idx_ <= 5; }
};

_LIBCPP_HIDE_FROM_ABI inline constexpr bool
operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept {
  return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index();
}

class weekday_last {
private:
  chrono::weekday __wd_;

public:
  _LIBCPP_HIDE_FROM_ABI explicit constexpr weekday_last(const chrono::weekday& __val) noexcept : __wd_{__val} {}
  _LIBCPP_HIDE_FROM_ABI constexpr chrono::weekday weekday() const noexcept { return __wd_; }
  _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept { return __wd_.ok(); }
};

_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept {
  return __lhs.weekday() == __rhs.weekday();
}

_LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed weekday::operator[](unsigned __index) const noexcept {
  return weekday_indexed{*this, __index};
}

_LIBCPP_HIDE_FROM_ABI inline constexpr weekday_last weekday::operator[](last_spec) const noexcept {
  return weekday_last{*this};
}

inline constexpr weekday Sunday{0};
inline constexpr weekday Monday{1};
inline constexpr weekday Tuesday{2};
inline constexpr weekday Wednesday{3};
inline constexpr weekday Thursday{4};
inline constexpr weekday Friday{5};
inline constexpr weekday Saturday{6};

} // namespace chrono

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_STD_VER >= 20

#endif // _LIBCPP___CHRONO_WEEKDAY_H