MT Core (C++)
Core library for replacing C++ standard in project usage
Loading...
Searching...
No Matches
fixed.hpp
Go to the documentation of this file.
1/*
2
3Copyright 2025 Matthew Tolman
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16
17*/
18
19#ifndef MTCORE_CALENDARS_FIXED_HPP
20#define MTCORE_CALENDARS_FIXED_HPP
21
22#include "mtcore.hpp"
26#include <string_view>
27
32
36namespace mtcore::calendars {
42 struct Fixed {
43 static constexpr auto EPOCH = FIXED_EPOCH;
44 static constexpr std::string_view name = "FIXED";
46
51 [[nodiscard]] constexpr auto operator<=>(const Fixed &o) const { return day <=> o.day; }
52 [[nodiscard]] constexpr auto operator==(const Fixed &o) const -> bool {
53 auto cmp = *this <=> o;
54 return cmp == decltype(cmp)::equivalent;
55 }
56 [[nodiscard]] constexpr auto operator!=(const Fixed &o) const -> bool {
57 auto cmp = *this <=> o;
58 return cmp != decltype(cmp)::equivalent;
59 }
60 [[nodiscard]] constexpr auto operator<=(const Fixed &o) const -> bool {
61 auto cmp = *this <=> o;
62 return cmp == decltype(cmp)::equivalent || cmp == decltype(cmp)::less;
63 }
64 [[nodiscard]] constexpr auto operator>=(const Fixed &o) const -> bool {
65 auto cmp = *this <=> o;
66 return cmp == decltype(cmp)::equivalent || cmp == decltype(cmp)::greater;
67 }
68 [[nodiscard]] constexpr auto operator<(const Fixed &o) const -> bool {
69 auto cmp = *this <=> o;
70 return cmp == decltype(cmp)::less;
71 }
72 [[nodiscard]] constexpr auto operator>(const Fixed &o) const -> bool {
73 auto cmp = *this <=> o;
74 return cmp == decltype(cmp)::greater;
75 }
76
78 [[nodiscard]] static constexpr Fixed from_fixed(const Fixed &o) { return o; }
80 [[nodiscard]] constexpr Fixed to_fixed() const { return *this; }
81
83 [[nodiscard]] constexpr DayOfWeek day_of_week() const {
84 const i32 d = day - FIXED_EPOCH - static_cast<i32>(DayOfWeek::Sunday);
85 const auto dow = math::mod(d, 7);
86 ensure(dow >= 0 && dow < 7);
87 return static_cast<DayOfWeek>(dow);
88 }
89
91 [[nodiscard]] constexpr Fixed add_days(const i32 days) const { return {day + days}; }
92
94 [[nodiscard]] constexpr Fixed sub_days(const i32 days) const { return {day - days}; }
95
97 [[nodiscard]] constexpr i32 day_difference(const Fixed &other) const { return day - other.day; }
98
100 [[nodiscard]] constexpr Fixed nth_week_day(const i32 n, const DayOfWeek k) const {
101 if (n > 0) {
102 return day_of_week_before(k).add_days(7 * n);
103 }
104 else if (n < 0) {
105 return day_of_week_after(k).add_days(7 * n);
106 }
107 else {
108 return *this;
109 }
110 }
111
113 [[nodiscard]] constexpr Fixed day_of_week_before(const DayOfWeek k) const {
115 }
116
118 [[nodiscard]] constexpr Fixed day_of_week_after(const DayOfWeek k) const {
120 }
121
123 [[nodiscard]] constexpr Fixed day_of_week_nearest(const DayOfWeek k) const {
125 }
126
128 [[nodiscard]] constexpr Fixed day_of_week_on_or_before(const DayOfWeek k) const {
129 const auto dayOfWeekPrev = (Fixed{
130 .day = day - static_cast<i32>(k),
131 })
132 .day_of_week();
133 return Fixed{.day = day - static_cast<i32>(dayOfWeekPrev)};
134 }
135
137 [[nodiscard]] constexpr Fixed day_of_week_on_or_after(const DayOfWeek k) const {
139 }
140
142 [[nodiscard]] constexpr Fixed first_week_day(const DayOfWeek k) const { return nth_week_day(1, k); }
143
145 [[nodiscard]] constexpr Fixed last_week_day(const DayOfWeek k) const { return nth_week_day(-1, k); }
146
161 [[nodiscard]] auto positions_in_range(Allocator &alloc, const Fixed &end, i32 pthMoment, i32 cDayCycle,
163 auto capacity =
164 std::max<size_t>(1, static_cast<size_t>(count_positions_in_range(end, pthMoment, cDayCycle, delta)));
166 if (const auto r = res.init(alloc, capacity); r.is_error()) {
167 return r.error();
168 }
169 auto start = this->day;
170 while (true) {
171 auto curDate = math::mod_range<i32>(pthMoment - delta, start, start + cDayCycle);
172 if (curDate >= end.day) {
173 return success(res);
174 }
175 ensure(res.push({curDate}).is_success());
176 start += cDayCycle;
177 }
178 }
179
185 [[nodiscard]] constexpr i32 day_of_m_cycle(i32 m, i32 offset) const { return math::mod(day - offset, m); }
186
194 [[nodiscard]] constexpr auto kth_day_of_m_cycle_on_or_before(i32 k, i32 m, i32 offset) const noexcept -> Fixed {
195 const auto mCycleDay = sub_days(k).day_of_m_cycle(m, offset);
196 return sub_days(mCycleDay);
197 }
198
206 [[nodiscard]] constexpr auto kth_day_of_m_cycle_before(i32 k, i32 m, i32 offset) const noexcept -> Fixed {
207 return sub_days(1).kth_day_of_m_cycle_on_or_before(k, m, offset);
208 }
209
217 [[nodiscard]] constexpr auto kth_day_of_m_cycle_on_or_after(i32 k, i32 m, i32 offset) const noexcept -> Fixed {
218 return add_days(m - 1).kth_day_of_m_cycle_on_or_before(k, m, offset);
219 }
220
228 [[nodiscard]] constexpr auto kth_day_of_m_cycle_after(i32 k, i32 m, i32 offset) const noexcept -> Fixed {
229 return add_days(m).kth_day_of_m_cycle_on_or_before(k, m, offset);
230 }
231
239 [[nodiscard]] constexpr auto kth_day_of_m_cycle_nearest(i32 k, i32 m, i32 offset) const noexcept -> Fixed {
240 return add_days(m / 2).kth_day_of_m_cycle_on_or_before(k, m, offset);
241 }
242
243 private:
244 [[nodiscard]] constexpr auto count_positions_in_range(const Fixed &end, i32 pthMoment, i32 cDayCycle,
245 i32 delta) const -> size_t {
246 size_t res = 0;
247 auto start = this->day;
248 while (true) {
249 auto curDate = math::mod_range<int64_t>(pthMoment - delta, start, start + cDayCycle);
250 if (curDate >= end.day) {
251 return res;
252 }
253 ++res;
254 start += cDayCycle;
255 }
256 }
257 };
258
264 struct Moment {
265 static constexpr auto EPOCH = FIXED_EPOCH;
266 static constexpr std::string_view name = "MOMENT";
268
270 [[nodiscard]] constexpr bool is_valid() const { return std::isfinite(dayAndTime); }
271
273 [[nodiscard]] constexpr Moment to_moment() const { return *this; }
275 [[nodiscard]] constexpr static Moment from_moment(Moment m) { return m; }
276
278 [[nodiscard]] constexpr auto operator<=>(const Moment &o) const { return dayAndTime <=> o.dayAndTime; }
279
281 [[nodiscard]] constexpr static Fixed moment_to_fixed(const Moment &m) {
283 }
284
286 [[nodiscard]] constexpr static Moment reconstruct(const Fixed &f, const Moment &m) {
287 const auto mt = m.dayAndTime - math::floor<f64, i32>(m.dayAndTime);
288 return {static_cast<f64>(f.day) + mt};
289 }
290
292 [[nodiscard]] constexpr Moment add_days(const i32 days) const { return {dayAndTime + days}; }
293
295 [[nodiscard]] constexpr Moment sub_days(const i32 days) const { return {dayAndTime - days}; }
296
298 [[nodiscard]] constexpr i32 day_difference(const Moment &other) const {
300 }
301 };
302} // namespace mtcore::calendars
303
304#endif // MTCORE_CALENDARS_FIXED_HPP
DayOfWeek
Enum class for the day of week.
AllocationError
Error indicating failed allocation.
#define ensure(check,...)
Ensures that a check holds true, aborts the program if not true Will print error if the condition is ...
constexpr R floor(T num) noexcept
Floors a number with support for constexpr and fast runtime compilation.
constexpr Res mod(L left, R right) noexcept
Calculates the mathematical mod of two numbers.
constexpr auto mod_range(T x, i64 a, i64 b) noexcept -> T
x mod [a..b)
Success< void > success()
Creates a successful void Result object.
Definition result.hpp:398
int32_t i32
Alias for 32-bit ints.
double f64
Alias for 64-bit floats.
Namespace for calendaring systems.
constexpr i32 FIXED_EPOCH
Definition epochs.hpp:25
Represents a memory allocator Exact behavior depends on the underlying VTable used Should use the a_*...
Array list is a growable, dynamic array with elements inside Elements are stored in an array,...
Result< void, AllocationError > init(Allocator &alloc, size_t initCapacity=10) noexcept
Initializes an empty ArrayList with an initial capacity.
Result< void, AllocationError > push(Allocator &alloc, const Slice< std::add_const_t< T > > &elems) noexcept
Pushes a list of items onto an array list.
Represents a Result that may have an error (error code) or a success value A type of "void" means the...
Definition result.hpp:170
Base calendar system tracking the number of days since its epoch.
Definition fixed.hpp:42
auto positions_in_range(Allocator &alloc, const Fixed &end, i32 pthMoment, i32 cDayCycle, i32 delta) const -> Result< mtcore::ArrayList< Fixed >, AllocationError >
Return the cyclic positions in the range of the current date to the end date (exclusive) Used to coll...
Definition fixed.hpp:161
constexpr i32 day_of_m_cycle(i32 m, i32 offset) const
Gets which day the current date occurs in an m-length ("month") cycle.
Definition fixed.hpp:185
constexpr Fixed last_week_day(const DayOfWeek k) const
Gets the last week day in a month (assuming current date is the end of the month)
Definition fixed.hpp:145
constexpr auto operator>=(const Fixed &o) const -> bool
Definition fixed.hpp:64
constexpr auto kth_day_of_m_cycle_on_or_before(i32 k, i32 m, i32 offset) const noexcept -> Fixed
Finds the kth day of the m-cycle that occurs on or before the current date.
Definition fixed.hpp:194
constexpr auto operator<=(const Fixed &o) const -> bool
Definition fixed.hpp:60
constexpr auto kth_day_of_m_cycle_nearest(i32 k, i32 m, i32 offset) const noexcept -> Fixed
Finds the kth day of the m-cycle that occurs nearest the current date.
Definition fixed.hpp:239
static constexpr auto EPOCH
Definition fixed.hpp:43
constexpr Fixed day_of_week_on_or_before(const DayOfWeek k) const
Gets the day of week on or before the current date.
Definition fixed.hpp:128
constexpr Fixed nth_week_day(const i32 n, const DayOfWeek k) const
Gets the nth day of week.
Definition fixed.hpp:100
constexpr Fixed day_of_week_on_or_after(const DayOfWeek k) const
Gets the day of week on or after the current date.
Definition fixed.hpp:137
static constexpr std::string_view name
Definition fixed.hpp:44
constexpr Fixed first_week_day(const DayOfWeek k) const
Gets the first week day in a month (assuming current date is the start of the month)
Definition fixed.hpp:142
constexpr Fixed day_of_week_before(const DayOfWeek k) const
Gets the day of week before current date.
Definition fixed.hpp:113
constexpr auto operator!=(const Fixed &o) const -> bool
Definition fixed.hpp:56
constexpr auto kth_day_of_m_cycle_before(i32 k, i32 m, i32 offset) const noexcept -> Fixed
Finds the kth day of the m-cycle that occurs before the current date.
Definition fixed.hpp:206
constexpr auto operator<(const Fixed &o) const -> bool
Definition fixed.hpp:68
constexpr Fixed add_days(const i32 days) const
Adds n days to a date.
Definition fixed.hpp:91
constexpr auto operator>(const Fixed &o) const -> bool
Definition fixed.hpp:72
constexpr auto operator==(const Fixed &o) const -> bool
Definition fixed.hpp:52
constexpr auto kth_day_of_m_cycle_on_or_after(i32 k, i32 m, i32 offset) const noexcept -> Fixed
Finds the kth day of the m-cycle that occurs on or after the current date.
Definition fixed.hpp:217
constexpr Fixed day_of_week_after(const DayOfWeek k) const
Gets the day of week after the current date.
Definition fixed.hpp:118
constexpr auto kth_day_of_m_cycle_after(i32 k, i32 m, i32 offset) const noexcept -> Fixed
Finds the kth day of the m-cycle that occurs after the current date.
Definition fixed.hpp:228
constexpr Fixed to_fixed() const
Day Calendar System contract.
Definition fixed.hpp:80
constexpr DayOfWeek day_of_week() const
Gets the day of week for a date.
Definition fixed.hpp:83
constexpr auto operator<=>(const Fixed &o) const
Comparison method.
Definition fixed.hpp:51
static constexpr Fixed from_fixed(const Fixed &o)
Day Calendar System contract.
Definition fixed.hpp:78
constexpr Fixed day_of_week_nearest(const DayOfWeek k) const
Gets the day of week nearest to the current date.
Definition fixed.hpp:123
constexpr Fixed sub_days(const i32 days) const
Subtracts n days from a date.
Definition fixed.hpp:94
constexpr i32 day_difference(const Fixed &other) const
Difference between two dates in days.
Definition fixed.hpp:97
Base calendar system tracking the number of days (and fraction of days) since its epoch.
Definition fixed.hpp:264
static constexpr Moment from_moment(Moment m)
Time Calendar System contract.
Definition fixed.hpp:275
constexpr auto operator<=>(const Moment &o) const
Time Calendar System contract.
Definition fixed.hpp:278
constexpr bool is_valid() const
Checks that a moment is valid.
Definition fixed.hpp:270
constexpr i32 day_difference(const Moment &other) const
Get the difference in days between two moments.
Definition fixed.hpp:298
static constexpr Moment reconstruct(const Fixed &f, const Moment &m)
Reconstructs a moment from a fixed date and the time portion of a moment.
Definition fixed.hpp:286
constexpr Moment add_days(const i32 days) const
Adds n days to a moment.
Definition fixed.hpp:292
static constexpr Fixed moment_to_fixed(const Moment &m)
Converts a moment to fixed date (drops time)
Definition fixed.hpp:281
constexpr Moment to_moment() const
Time Calendar System contract.
Definition fixed.hpp:273
static constexpr std::string_view name
Definition fixed.hpp:266
constexpr Moment sub_days(const i32 days) const
Subtracts n days from a moment.
Definition fixed.hpp:295
static constexpr auto EPOCH
Definition fixed.hpp:265