Bug 1874684 - Part 10: Replace BigInt with Int128 in RoundNumberToIncrement. r=mgaudet
[gecko.git] / js / src / builtin / temporal / PlainDate.h
blob37df8d63580b6052d80947df18452b4fe9b3292b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef builtin_temporal_PlainDate_h
8 #define builtin_temporal_PlainDate_h
10 #include "mozilla/Assertions.h"
12 #include <initializer_list>
13 #include <stdint.h>
15 #include "builtin/temporal/Calendar.h"
16 #include "builtin/temporal/PlainDateTime.h"
17 #include "builtin/temporal/TemporalTypes.h"
18 #include "builtin/temporal/Wrapped.h"
19 #include "js/RootingAPI.h"
20 #include "js/TypeDecls.h"
21 #include "js/Value.h"
22 #include "vm/NativeObject.h"
24 class JS_PUBLIC_API JSTracer;
26 namespace js {
27 struct ClassSpec;
28 class PlainObject;
29 } // namespace js
31 namespace js::temporal {
33 class PlainDateObject : public NativeObject {
34 public:
35 static const JSClass class_;
36 static const JSClass& protoClass_;
38 // TODO: Consider compacting fields to reduce object size.
40 // ceil(log2(271821)) + ceil(log2(12)) + ceil(log2(31)) = 28 bits are
41 // needed to store a date value in a single int32.
43 static constexpr uint32_t ISO_YEAR_SLOT = 0;
44 static constexpr uint32_t ISO_MONTH_SLOT = 1;
45 static constexpr uint32_t ISO_DAY_SLOT = 2;
46 static constexpr uint32_t CALENDAR_SLOT = 3;
47 static constexpr uint32_t SLOT_COUNT = 4;
49 int32_t isoYear() const { return getFixedSlot(ISO_YEAR_SLOT).toInt32(); }
51 int32_t isoMonth() const { return getFixedSlot(ISO_MONTH_SLOT).toInt32(); }
53 int32_t isoDay() const { return getFixedSlot(ISO_DAY_SLOT).toInt32(); }
55 CalendarValue calendar() const {
56 return CalendarValue(getFixedSlot(CALENDAR_SLOT));
59 private:
60 static const ClassSpec classSpec_;
63 class PlainDateWithCalendar {
64 PlainDate date_;
65 CalendarValue calendar_;
67 public:
68 PlainDateWithCalendar() = default;
70 PlainDateWithCalendar(const PlainDate& date, const CalendarValue& calendar)
71 : date_(date), calendar_(calendar) {
72 MOZ_ASSERT(ISODateTimeWithinLimits(date));
75 const auto& date() const { return date_; }
76 const auto& calendar() const { return calendar_; }
78 // Allow implicit conversion to a calendar-less PlainDate.
79 operator const PlainDate&() const { return date(); }
81 void trace(JSTracer* trc) { calendar_.trace(trc); }
83 const auto* calendarDoNotUse() const { return &calendar_; }
86 /**
87 * Extract the date fields from the PlainDate object.
89 inline PlainDate ToPlainDate(const PlainDateObject* date) {
90 return {date->isoYear(), date->isoMonth(), date->isoDay()};
93 enum class TemporalOverflow;
94 enum class TemporalUnit;
95 class DurationObject;
96 class ZonedDateTimeObject;
98 #ifdef DEBUG
99 /**
100 * IsValidISODate ( year, month, day )
102 bool IsValidISODate(const PlainDate& date);
105 * IsValidISODate ( year, month, day )
107 bool IsValidISODate(double year, double month, double day);
108 #endif
111 * IsValidISODate ( year, month, day )
113 bool ThrowIfInvalidISODate(JSContext* cx, const PlainDate& date);
116 * IsValidISODate ( year, month, day )
118 bool ThrowIfInvalidISODate(JSContext* cx, double year, double month,
119 double day);
122 * ToTemporalDate ( item [ , options ] )
124 bool ToTemporalDate(JSContext* cx, JS::Handle<JS::Value> item,
125 PlainDate* result);
128 * ToTemporalDate ( item [ , options ] )
130 bool ToTemporalDate(JSContext* cx, JS::Handle<JS::Value> item,
131 JS::MutableHandle<PlainDateWithCalendar> result);
134 * CreateTemporalDate ( isoYear, isoMonth, isoDay, calendar [ , newTarget ] )
136 PlainDateObject* CreateTemporalDate(JSContext* cx, const PlainDate& date,
137 JS::Handle<CalendarValue> calendar);
140 * CreateTemporalDate ( isoYear, isoMonth, isoDay, calendar [ , newTarget ] )
142 bool CreateTemporalDate(JSContext* cx, const PlainDate& date,
143 JS::Handle<CalendarValue> calendar,
144 JS::MutableHandle<PlainDateWithCalendar> result);
147 * RegulateISODate ( year, month, day, overflow )
149 bool RegulateISODate(JSContext* cx, const PlainDate& date,
150 TemporalOverflow overflow, PlainDate* result);
152 struct RegulatedISODate final {
153 double year;
154 int32_t month;
155 int32_t day;
159 * RegulateISODate ( year, month, day, overflow )
161 bool RegulateISODate(JSContext* cx, double year, double month, double day,
162 TemporalOverflow overflow, RegulatedISODate* result);
165 * AddISODate ( year, month, day, years, months, weeks, days, overflow )
167 bool AddISODate(JSContext* cx, const PlainDate& date,
168 const DateDuration& duration, TemporalOverflow overflow,
169 PlainDate* result);
172 * AddDate ( calendarRec, plainDate, duration [ , options ] )
174 Wrapped<PlainDateObject*> AddDate(JSContext* cx,
175 JS::Handle<CalendarRecord> calendar,
176 JS::Handle<Wrapped<PlainDateObject*>> date,
177 const Duration& duration,
178 JS::Handle<JSObject*> options);
181 * AddDate ( calendarRec, plainDate, duration [ , options ] )
183 Wrapped<PlainDateObject*> AddDate(JSContext* cx,
184 JS::Handle<CalendarRecord> calendar,
185 JS::Handle<Wrapped<PlainDateObject*>> date,
186 const Duration& duration);
189 * AddDate ( calendarRec, plainDate, duration [ , options ] )
191 Wrapped<PlainDateObject*> AddDate(
192 JSContext* cx, JS::Handle<CalendarRecord> calendar,
193 JS::Handle<Wrapped<PlainDateObject*>> date,
194 JS::Handle<Wrapped<DurationObject*>> durationObj,
195 JS::Handle<JSObject*> options);
198 * AddDate ( calendarRec, plainDate, duration [ , options ] )
200 Wrapped<PlainDateObject*> AddDate(
201 JSContext* cx, JS::Handle<CalendarRecord> calendar,
202 JS::Handle<Wrapped<PlainDateObject*>> date,
203 JS::Handle<Wrapped<DurationObject*>> durationObj);
206 * AddDate ( calendarRec, plainDate, duration [ , options ] )
208 bool AddDate(JSContext* cx, JS::Handle<CalendarRecord> calendar,
209 const PlainDate& date, const Duration& duration,
210 JS::Handle<JSObject*> options, PlainDate* result);
213 * AddDate ( calendarRec, plainDate, duration [ , options ] )
215 bool AddDate(JSContext* cx, JS::Handle<CalendarRecord> calendar,
216 JS::Handle<Wrapped<PlainDateObject*>> date,
217 const Duration& duration, PlainDate* result);
220 * DifferenceISODate ( y1, m1, d1, y2, m2, d2, largestUnit )
222 DateDuration DifferenceISODate(const PlainDate& start, const PlainDate& end,
223 TemporalUnit largestUnit);
226 * DifferenceDate ( calendarRec, one, two, options )
228 bool DifferenceDate(JSContext* cx, JS::Handle<CalendarRecord> calendar,
229 JS::Handle<Wrapped<PlainDateObject*>> one,
230 JS::Handle<Wrapped<PlainDateObject*>> two,
231 JS::Handle<PlainObject*> options, Duration* result);
234 * DifferenceDate ( calendarRec, one, two, options )
236 bool DifferenceDate(JSContext* cx, JS::Handle<CalendarRecord> calendar,
237 JS::Handle<Wrapped<PlainDateObject*>> one,
238 JS::Handle<Wrapped<PlainDateObject*>> two,
239 TemporalUnit largestUnit, Duration* result);
242 * CompareISODate ( y1, m1, d1, y2, m2, d2 )
244 int32_t CompareISODate(const PlainDate& one, const PlainDate& two);
247 * BalanceISODate ( year, month, day )
249 bool BalanceISODate(JSContext* cx, int32_t year, int32_t month, int64_t day,
250 PlainDate* result);
253 * BalanceISODate ( year, month, day )
255 PlainDate BalanceISODate(int32_t year, int32_t month, int32_t day);
258 * BalanceISODate ( year, month, day )
260 PlainDate BalanceISODateNew(int32_t year, int32_t month, int32_t day);
263 * Return true when accessing the calendar fields |fieldNames| can be optimized.
264 * Otherwise returns false.
266 bool IsBuiltinAccess(JSContext* cx, JS::Handle<PlainDateObject*> date,
267 std::initializer_list<CalendarField> fieldNames);
269 } /* namespace js::temporal */
271 namespace js {
273 template <typename Wrapper>
274 class WrappedPtrOperations<temporal::PlainDateWithCalendar, Wrapper> {
275 const auto& container() const {
276 return static_cast<const Wrapper*>(this)->get();
279 public:
280 const auto& date() const { return container().date(); }
282 JS::Handle<temporal::CalendarValue> calendar() const {
283 return JS::Handle<temporal::CalendarValue>::fromMarkedLocation(
284 container().calendarDoNotUse());
287 // Allow implicit conversion to a calendar-less PlainDate.
288 operator const temporal::PlainDate&() const { return date(); }
291 } // namespace js
293 #endif /* builtin_temporal_PlainDate_h */