Skip to content

Commit 5b2b067

Browse files
committed
Split up rem/mod definitions
1 parent 88ea317 commit 5b2b067

File tree

1 file changed

+50
-29
lines changed

1 file changed

+50
-29
lines changed

src/math.jl

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES
2-
div_base_type = type === AbstractGenericQuantity ? Number : base_type
2+
# For div, we don't want to go more generic than `Number`
3+
div_base_type = base_type <: Number ? base_type : Number
34
@eval begin
45
function Base.:*(l::$type, r::$type)
56
l, r = promote_except_value(l, r)
@@ -206,34 +207,54 @@ for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES, f in (:copysign, :flipsign,
206207
end
207208
end
208209
end
209-
for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES, f in (:rem, :mod)
210-
# Need to define all rounding modes to avoid ambiguities
211-
rounding_modes = f == :rem ? (RoundingMode, typeof.((RoundToZero, RoundDown, RoundUp, RoundFromZero))...) : (nothing,)
212-
for rounding_mode in rounding_modes
213-
param, extra_f_args = if rounding_mode == RoundingMode
214-
# Add default:
215-
((), (:RoundToZero,))
216-
elseif f == :rem
217-
((:(::$rounding_mode),), (:($rounding_mode()),))
218-
else # :mod
219-
((), ())
220-
end
221-
for (type2, _, _) in ABSTRACT_QUANTITY_TYPES
222-
@eval function Base.$f(x::$type, y::$type2, $(param...))
223-
x, y = promote_except_value(x, y)
224-
dimension(x) == dimension(y) || throw(DimensionError(x, y))
225-
return new_quantity(typeof(x), $f(ustrip(x), ustrip(y), $(extra_f_args...)), dimension(x))
226-
end
227-
end
228-
@eval begin
229-
function Base.$f(x::$type, y::$base_type, $(param...))
230-
iszero(dimension(x)) || throw(DimensionError(x))
231-
return new_quantity(typeof(x), $f(ustrip(x), y, $(extra_f_args...)), dimension(x))
232-
end
233-
function Base.$f(x::$base_type, y::$type, $(param...))
234-
iszero(dimension(y)) || throw(DimensionError(y))
235-
return new_quantity(typeof(y), $f(x, ustrip(y), $(extra_f_args...)), dimension(y))
236-
end
210+
# Define :rem
211+
for (type, _base_type, _) in ABSTRACT_QUANTITY_TYPES, rounding_mode in (RoundingMode, RoundingMode{:ToZero}, RoundingMode{:Down}, RoundingMode{:Up}, RoundingMode{:FromZero})
212+
213+
# We don't want to go more generic than `Number` for mod and rem
214+
base_type = _base_type <: Number ? _base_type : Number
215+
# Add extra args:
216+
param = rounding_mode === RoundingMode ? (()) : (:(::$rounding_mode),)
217+
extra_f_args = rounding_mode === RoundingMode ? (:RoundToZero,) : (:($rounding_mode()),)
218+
219+
for (type2, _, _) in ABSTRACT_QUANTITY_TYPES
220+
@eval function Base.rem(x::$type, y::$type2, $(param...))
221+
x, y = promote_except_value(x, y)
222+
dimension(x) == dimension(y) || throw(DimensionError(x, y))
223+
return new_quantity(typeof(x), rem(ustrip(x), ustrip(y), $(extra_f_args...)), dimension(x))
224+
end
225+
end
226+
@eval begin
227+
function Base.rem(x::$type, y::$base_type, $(param...))
228+
iszero(dimension(x)) || throw(DimensionError(x))
229+
return new_quantity(typeof(x), rem(ustrip(x), y, $(extra_f_args...)), dimension(x))
230+
end
231+
function Base.rem(x::$base_type, y::$type, $(param...))
232+
iszero(dimension(y)) || throw(DimensionError(y))
233+
return new_quantity(typeof(y), rem(x, ustrip(y), $(extra_f_args...)), dimension(y))
234+
end
235+
end
236+
end
237+
# Define :mod
238+
for (type, _base_type, _) in ABSTRACT_QUANTITY_TYPES
239+
240+
# We don't want to go more generic than `Number` for mod and rem
241+
base_type = _base_type <: Number ? _base_type : Number
242+
243+
for (type2, _, _) in ABSTRACT_QUANTITY_TYPES
244+
@eval function Base.mod(x::$type, y::$type2)
245+
x, y = promote_except_value(x, y)
246+
dimension(x) == dimension(y) || throw(DimensionError(x, y))
247+
return new_quantity(typeof(x), mod(ustrip(x), ustrip(y)), dimension(x))
248+
end
249+
end
250+
@eval begin
251+
function Base.mod(x::$type, y::$base_type)
252+
iszero(dimension(x)) || throw(DimensionError(x))
253+
return new_quantity(typeof(x), mod(ustrip(x), y), dimension(x))
254+
end
255+
function Base.mod(x::$base_type, y::$type)
256+
iszero(dimension(y)) || throw(DimensionError(y))
257+
return new_quantity(typeof(y), mod(x, ustrip(y)), dimension(y))
237258
end
238259
end
239260
end

0 commit comments

Comments
 (0)