From 9c209b80793b7717ba5a3973722e0b5941696cfd Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Tue, 21 Dec 2021 21:22:38 +0100 Subject: [PATCH] LibJS: Support modulo(x, y) with different types It's a bit annoying having to add '.0' to y given that it's an integral number in most cases. This turns the single template parameter T into T and U to permit that. --- .../Libraries/LibJS/Runtime/AbstractOperations.h | 9 +++++---- Userland/Libraries/LibJS/Runtime/Date.cpp | 2 +- .../Libraries/LibJS/Runtime/Temporal/PlainTime.cpp | 12 ++++++------ .../LibJS/Runtime/Temporal/PlainYearMonth.cpp | 2 +- .../Libraries/LibJS/Runtime/Temporal/TimeZone.cpp | 4 ++-- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h index 2084868045b..e9e6a7595d8 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h @@ -77,13 +77,14 @@ ThrowCompletionOr ordinary_create_from_constructor(GlobalObject& global_obje } // x modulo y, https://tc39.es/ecma262/#eqn-modulo -template -T modulo(T x, T y) +template +auto modulo(T x, U y) requires(IsArithmetic, IsArithmetic) { // The notation “x modulo y” (y must be finite and non-zero) computes a value k of the same sign as y (or zero) such that abs(k) < abs(y) and x - k = q × y for some integer q. VERIFY(y != 0); - if constexpr (IsFloatingPoint) { - VERIFY(isfinite(y)); + if constexpr (IsFloatingPoint || IsFloatingPoint) { + if constexpr (IsFloatingPoint) + VERIFY(isfinite(y)); return fmod(fmod(x, y) + y, y); } else { return ((x % y) + y) % y; diff --git a/Userland/Libraries/LibJS/Runtime/Date.cpp b/Userland/Libraries/LibJS/Runtime/Date.cpp index 95770459f8e..f68f27f3074 100644 --- a/Userland/Libraries/LibJS/Runtime/Date.cpp +++ b/Userland/Libraries/LibJS/Runtime/Date.cpp @@ -311,7 +311,7 @@ u16 ms_from_time(double t) u8 week_day(double t) { // 𝔽(ℝ(Day(t) + 4𝔽) modulo 7) - return static_cast(modulo(day(t) + 4, 7.0)); + return static_cast(modulo(day(t) + 4, 7)); } // 21.4.1.11 MakeTime ( hour, min, sec, ms ), https://tc39.es/ecma262/#sec-maketime diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp index 7224392ebce..932e531afdb 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainTime.cpp @@ -281,37 +281,37 @@ DaysAndTime balance_time(double hour, double minute, double second, double milli microsecond += floor(nanosecond / 1000); // 3. Set nanosecond to nanosecond modulo 1000. - nanosecond = modulo(nanosecond, 1000.0); + nanosecond = modulo(nanosecond, 1000); // 4. Set millisecond to millisecond + floor(microsecond / 1000). millisecond += floor(microsecond / 1000); // 5. Set microsecond to microsecond modulo 1000. - microsecond = modulo(microsecond, 1000.0); + microsecond = modulo(microsecond, 1000); // 6. Set second to second + floor(millisecond / 1000). second += floor(millisecond / 1000); // 7. Set millisecond to millisecond modulo 1000. - millisecond = modulo(millisecond, 1000.0); + millisecond = modulo(millisecond, 1000); // 8. Set minute to minute + floor(second / 60). minute += floor(second / 60); // 9. Set second to second modulo 60. - second = modulo(second, 60.0); + second = modulo(second, 60); // 10. Set hour to hour + floor(minute / 60). hour += floor(minute / 60); // 11. Set minute to minute modulo 60. - minute = modulo(minute, 60.0); + minute = modulo(minute, 60); // 12. Let days be floor(hour / 24). auto days = floor(hour / 24); // 13. Set hour to hour modulo 24. - hour = modulo(hour, 24.0); + hour = modulo(hour, 24); // 14. Return the Record { [[Days]]: days, [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond }. return DaysAndTime { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp index a32ec83ae9e..d428bd490bc 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp @@ -180,7 +180,7 @@ ISOYearMonth balance_iso_year_month(double year, double month) year += floor((month - 1) / 12); // 3. Set month to (month − 1) modulo 12 + 1. - month = modulo(month - 1, 12.0) + 1; + month = modulo(month - 1, 12) + 1; // 4. Return the Record { [[Year]]: year, [[Month]]: month }. return ISOYearMonth { .year = static_cast(year), .month = static_cast(month), .reference_iso_day = 0 }; diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index 4ec26758377..6a36fe25ad4 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -150,10 +150,10 @@ ISODateTime get_iso_parts_from_epoch(BigInt const& epoch_nanoseconds) auto millisecond = ms_from_time(epoch_milliseconds); // 11. Let microsecond be floor(remainderNs / 1000) modulo 1000. - auto microsecond = modulo(floor(remainder_ns / 1000), 1000.0); + auto microsecond = modulo(floor(remainder_ns / 1000), 1000); // 12. Let nanosecond be remainderNs modulo 1000. - auto nanosecond = modulo(remainder_ns, 1000.0); + auto nanosecond = modulo(remainder_ns, 1000); // 13. Return the Record { [[Year]]: year, [[Month]]: month, [[Day]]: day, [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond }. return { .year = year, .month = month, .day = day, .hour = hour, .minute = minute, .second = second, .millisecond = millisecond, .microsecond = static_cast(microsecond), .nanosecond = static_cast(nanosecond) };