Bug 1874684 - Part 10: Replace BigInt with Int128 in RoundNumberToIncrement. r=mgaudet
[gecko.git] / js / src / builtin / temporal / Duration.h
blob9111d512aebe847bdd7a3984bc4a1b0a4a95b38d
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_Duration_h
8 #define builtin_temporal_Duration_h
10 #include <stdint.h>
12 #include "builtin/temporal/TemporalTypes.h"
13 #include "builtin/temporal/Wrapped.h"
14 #include "js/RootingAPI.h"
15 #include "js/TypeDecls.h"
16 #include "js/Value.h"
17 #include "vm/NativeObject.h"
19 namespace js {
20 struct ClassSpec;
23 namespace js::temporal {
25 class DurationObject : public NativeObject {
26 public:
27 static const JSClass class_;
28 static const JSClass& protoClass_;
30 static constexpr uint32_t YEARS_SLOT = 0;
31 static constexpr uint32_t MONTHS_SLOT = 1;
32 static constexpr uint32_t WEEKS_SLOT = 2;
33 static constexpr uint32_t DAYS_SLOT = 3;
34 static constexpr uint32_t HOURS_SLOT = 4;
35 static constexpr uint32_t MINUTES_SLOT = 5;
36 static constexpr uint32_t SECONDS_SLOT = 6;
37 static constexpr uint32_t MILLISECONDS_SLOT = 7;
38 static constexpr uint32_t MICROSECONDS_SLOT = 8;
39 static constexpr uint32_t NANOSECONDS_SLOT = 9;
40 static constexpr uint32_t SLOT_COUNT = 10;
42 double years() const { return getFixedSlot(YEARS_SLOT).toNumber(); }
43 double months() const { return getFixedSlot(MONTHS_SLOT).toNumber(); }
44 double weeks() const { return getFixedSlot(WEEKS_SLOT).toNumber(); }
45 double days() const { return getFixedSlot(DAYS_SLOT).toNumber(); }
46 double hours() const { return getFixedSlot(HOURS_SLOT).toNumber(); }
47 double minutes() const { return getFixedSlot(MINUTES_SLOT).toNumber(); }
48 double seconds() const { return getFixedSlot(SECONDS_SLOT).toNumber(); }
49 double milliseconds() const {
50 return getFixedSlot(MILLISECONDS_SLOT).toNumber();
52 double microseconds() const {
53 return getFixedSlot(MICROSECONDS_SLOT).toNumber();
55 double nanoseconds() const {
56 return getFixedSlot(NANOSECONDS_SLOT).toNumber();
59 private:
60 static const ClassSpec classSpec_;
63 /**
64 * Extract the duration fields from the Duration object.
66 inline Duration ToDuration(const DurationObject* duration) {
67 return {
68 duration->years(), duration->months(),
69 duration->weeks(), duration->days(),
70 duration->hours(), duration->minutes(),
71 duration->seconds(), duration->milliseconds(),
72 duration->microseconds(), duration->nanoseconds(),
76 class Increment;
77 class CalendarRecord;
78 class PlainDateObject;
79 class TimeZoneRecord;
80 class ZonedDateTime;
81 class ZonedDateTimeObject;
82 enum class TemporalRoundingMode;
83 enum class TemporalUnit;
85 /**
86 * DurationSign ( years, months, weeks, days, hours, minutes, seconds,
87 * milliseconds, microseconds, nanoseconds )
89 int32_t DurationSign(const Duration& duration);
91 /**
92 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
93 * milliseconds, microseconds, nanoseconds )
95 bool IsValidDuration(const Duration& duration);
97 #ifdef DEBUG
98 /**
99 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
100 * milliseconds, microseconds, nanoseconds )
102 bool IsValidDuration(const NormalizedDuration& duration);
103 #endif
106 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
107 * milliseconds, microseconds, nanoseconds )
109 bool ThrowIfInvalidDuration(JSContext* cx, const Duration& duration);
112 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
113 * milliseconds, microseconds, nanoseconds )
115 inline bool IsValidNormalizedTimeDuration(
116 const NormalizedTimeDuration& duration) {
117 MOZ_ASSERT(0 <= duration.nanoseconds && duration.nanoseconds <= 999'999'999);
119 // Step 4.
121 // The absolute value of the seconds part of normalized time duration must be
122 // less-or-equal to `2**53 - 1` and the nanoseconds part must be less or equal
123 // to `999'999'999`.
124 return NormalizedTimeDuration::min() <= duration &&
125 duration <= NormalizedTimeDuration::max();
129 * NormalizeTimeDuration ( hours, minutes, seconds, milliseconds, microseconds,
130 * nanoseconds )
132 NormalizedTimeDuration NormalizeTimeDuration(int32_t hours, int32_t minutes,
133 int32_t seconds,
134 int32_t milliseconds,
135 int32_t microseconds,
136 int32_t nanoseconds);
139 * NormalizeTimeDuration ( hours, minutes, seconds, milliseconds, microseconds,
140 * nanoseconds )
142 NormalizedTimeDuration NormalizeTimeDuration(const Duration& duration);
145 * CompareNormalizedTimeDuration ( one, two )
147 inline int32_t CompareNormalizedTimeDuration(
148 const NormalizedTimeDuration& one, const NormalizedTimeDuration& two) {
149 MOZ_ASSERT(IsValidNormalizedTimeDuration(one));
150 MOZ_ASSERT(IsValidNormalizedTimeDuration(two));
152 // Step 1.
153 if (one > two) {
154 return 1;
157 // Step 2.
158 if (one < two) {
159 return -1;
162 // Step 3.
163 return 0;
167 * NormalizedTimeDurationSign ( d )
169 inline int32_t NormalizedTimeDurationSign(const NormalizedTimeDuration& d) {
170 MOZ_ASSERT(IsValidNormalizedTimeDuration(d));
172 // Steps 1-3.
173 return CompareNormalizedTimeDuration(d, NormalizedTimeDuration{});
177 * Add24HourDaysToNormalizedTimeDuration ( d, days )
179 bool Add24HourDaysToNormalizedTimeDuration(JSContext* cx,
180 const NormalizedTimeDuration& d,
181 double days,
182 NormalizedTimeDuration* result);
185 * CreateNormalizedDurationRecord ( years, months, weeks, days, norm )
187 inline NormalizedDuration CreateNormalizedDurationRecord(
188 const DateDuration& date, const NormalizedTimeDuration& time) {
189 MOZ_ASSERT(IsValidDuration(date.toDuration()));
190 MOZ_ASSERT(IsValidNormalizedTimeDuration(time));
191 #ifdef DEBUG
192 int64_t dateValues = date.years | date.months | date.weeks | date.days;
193 int32_t dateSign = dateValues ? dateValues < 0 ? -1 : 1 : 0;
194 int32_t timeSign = NormalizedTimeDurationSign(time);
195 MOZ_ASSERT((dateSign * timeSign) >= 0);
196 #endif
198 return {date, time};
202 * CreateNormalizedDurationRecord ( years, months, weeks, days, norm )
204 inline NormalizedDuration CreateNormalizedDurationRecord(
205 const Duration& duration) {
206 return CreateNormalizedDurationRecord(duration.toDateDuration(),
207 NormalizeTimeDuration(duration));
211 * CombineDateAndNormalizedTimeDuration ( dateDurationRecord, norm )
213 bool CombineDateAndNormalizedTimeDuration(JSContext* cx,
214 const DateDuration& date,
215 const NormalizedTimeDuration& time,
216 NormalizedDuration* result);
219 * CreateNormalizedDurationRecord ( years, months, weeks, days, norm )
221 inline bool CreateNormalizedDurationRecord(JSContext* cx,
222 const DateDuration& date,
223 const NormalizedTimeDuration& time,
224 NormalizedDuration* result) {
225 return CombineDateAndNormalizedTimeDuration(cx, date, time, result);
229 * NormalizedTimeDurationFromEpochNanosecondsDifference ( one, two )
231 NormalizedTimeDuration NormalizedTimeDurationFromEpochNanosecondsDifference(
232 const Instant& one, const Instant& two);
235 * CreateTemporalDuration ( years, months, weeks, days, hours, minutes, seconds,
236 * milliseconds, microseconds, nanoseconds [ , newTarget ] )
238 DurationObject* CreateTemporalDuration(JSContext* cx, const Duration& duration);
241 * ToTemporalDuration ( item )
243 Wrapped<DurationObject*> ToTemporalDuration(JSContext* cx,
244 JS::Handle<JS::Value> item);
247 * ToTemporalDuration ( item )
249 bool ToTemporalDuration(JSContext* cx, JS::Handle<JS::Value> item,
250 Duration* result);
253 * ToTemporalDurationRecord ( temporalDurationLike )
255 bool ToTemporalDurationRecord(JSContext* cx,
256 JS::Handle<JS::Value> temporalDurationLike,
257 Duration* result);
260 * BalanceTimeDuration ( norm, largestUnit )
262 TimeDuration BalanceTimeDuration(const NormalizedTimeDuration& duration,
263 TemporalUnit largestUnit);
266 * BalanceDateDurationRelative ( years, months, weeks, days, largestUnit,
267 * smallestUnit, plainRelativeTo, calendarRec )
269 bool BalanceDateDurationRelative(
270 JSContext* cx, const DateDuration& duration, TemporalUnit largestUnit,
271 TemporalUnit smallestUnit,
272 JS::Handle<Wrapped<PlainDateObject*>> plainRelativeTo,
273 JS::Handle<CalendarRecord> calendar, DateDuration* result);
276 * AdjustRoundedDurationDays ( years, months, weeks, days, norm, increment,
277 * unit, roundingMode, zonedRelativeTo, calendarRec, timeZoneRec,
278 * precalculatedPlainDateTime )
280 bool AdjustRoundedDurationDays(JSContext* cx,
281 const NormalizedDuration& duration,
282 Increment increment, TemporalUnit unit,
283 TemporalRoundingMode roundingMode,
284 JS::Handle<ZonedDateTime> relativeTo,
285 JS::Handle<CalendarRecord> calendar,
286 JS::Handle<TimeZoneRecord> timeZone,
287 const PlainDateTime& precalculatedPlainDateTime,
288 NormalizedDuration* result);
291 * RoundDuration ( years, months, weeks, days, norm, increment, unit,
292 * roundingMode [ , plainRelativeTo [ , calendarRec [ , zonedRelativeTo [ ,
293 * timeZoneRec [ , precalculatedPlainDateTime ] ] ] ] ] )
295 NormalizedTimeDuration RoundDuration(const NormalizedTimeDuration& duration,
296 Increment increment, TemporalUnit unit,
297 TemporalRoundingMode roundingMode);
300 * RoundDuration ( years, months, weeks, days, norm, increment, unit,
301 * roundingMode [ , plainRelativeTo [ , calendarRec [ , zonedRelativeTo [ ,
302 * timeZoneRec [ , precalculatedPlainDateTime ] ] ] ] ] )
304 bool RoundDuration(JSContext* cx, const NormalizedDuration& duration,
305 Increment increment, TemporalUnit unit,
306 TemporalRoundingMode roundingMode,
307 JS::Handle<Wrapped<PlainDateObject*>> plainRelativeTo,
308 JS::Handle<CalendarRecord> calendar,
309 NormalizedDuration* result);
312 * RoundDuration ( years, months, weeks, days, norm, increment, unit,
313 * roundingMode [ , plainRelativeTo [ , calendarRec [ , zonedRelativeTo [ ,
314 * timeZoneRec [ , precalculatedPlainDateTime ] ] ] ] ] )
316 bool RoundDuration(JSContext* cx, const NormalizedDuration& duration,
317 Increment increment, TemporalUnit unit,
318 TemporalRoundingMode roundingMode,
319 JS::Handle<PlainDateObject*> plainRelativeTo,
320 JS::Handle<CalendarRecord> calendar,
321 JS::Handle<ZonedDateTime> zonedRelativeTo,
322 JS::Handle<TimeZoneRecord> timeZone,
323 const PlainDateTime& precalculatedPlainDateTime,
324 NormalizedDuration* result);
327 * DaysUntil ( earlier, later )
329 int32_t DaysUntil(const PlainDate& earlier, const PlainDate& later);
331 } /* namespace js::temporal */
333 #endif /* builtin_temporal_Duration_h */