Skip to content

Commit cd339b6

Browse files
committed
Reduce invalidations
1 parent 5b2b067 commit cd339b6

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

src/math.jl

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES
5050
new_quantity(typeof(r), inv(ustrip(r)), l / dimension(r))
5151
end
5252
end
53+
# Comparison with exact value type, in case we had to artificially limit it to Number
54+
!(base_type <: Number) && @eval begin
55+
function Base.div(x::$type{T}, y::T, r::RoundingMode=RoundToZero) where {T<:$base_type}
56+
new_quantity(typeof(x), div(ustrip(x), y, r), dimension(x))
57+
end
58+
function Base.div(x::T, y::$type{T}, r::RoundingMode=RoundToZero) where {T<:$base_type}
59+
new_quantity(typeof(y), div(x, ustrip(y), r), inv(dimension(y)))
60+
end
61+
end
5362
end
5463

5564
Base.:*(l::AbstractDimensions, r::AbstractDimensions) = map_dimensions(+, l, r)
@@ -208,10 +217,10 @@ for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES, f in (:copysign, :flipsign,
208217
end
209218
end
210219
# Define :rem
211-
for (type, _base_type, _) in ABSTRACT_QUANTITY_TYPES, rounding_mode in (RoundingMode, RoundingMode{:ToZero}, RoundingMode{:Down}, RoundingMode{:Up}, RoundingMode{:FromZero})
220+
for (type, true_base_type, _) in ABSTRACT_QUANTITY_TYPES, rounding_mode in (RoundingMode, RoundingMode{:ToZero}, RoundingMode{:Down}, RoundingMode{:Up}, RoundingMode{:FromZero})
212221

213222
# We don't want to go more generic than `Number` for mod and rem
214-
base_type = _base_type <: Number ? _base_type : Number
223+
base_type = true_base_type <: Number ? true_base_type : Number
215224
# Add extra args:
216225
param = rounding_mode === RoundingMode ? (()) : (:(::$rounding_mode),)
217226
extra_f_args = rounding_mode === RoundingMode ? (:RoundToZero,) : (:($rounding_mode()),)
@@ -235,10 +244,10 @@ for (type, _base_type, _) in ABSTRACT_QUANTITY_TYPES, rounding_mode in (Rounding
235244
end
236245
end
237246
# Define :mod
238-
for (type, _base_type, _) in ABSTRACT_QUANTITY_TYPES
247+
for (type, true_base_type, _) in ABSTRACT_QUANTITY_TYPES
239248

240249
# We don't want to go more generic than `Number` for mod and rem
241-
base_type = _base_type <: Number ? _base_type : Number
250+
base_type = true_base_type <: Number ? true_base_type : Number
242251

243252
for (type2, _, _) in ABSTRACT_QUANTITY_TYPES
244253
@eval function Base.mod(x::$type, y::$type2)

src/utils.jl

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ Base.keys(q::UnionAbstractQuantity) = keys(ustrip(q))
167167

168168

169169
# Numeric checks
170-
for op in (:(<=), :(<), :(>=), :(>), :isless),
171-
(type, base_type, _) in ABSTRACT_QUANTITY_TYPES
172-
170+
for op in (:(<=), :(<), :(>=), :(>), :isless), (type, true_base_type, _) in ABSTRACT_QUANTITY_TYPES
171+
# Avoid creating overly generic operations on these:
172+
base_type = true_base_type <: Number ? true_base_type : Number
173173
@eval begin
174174
function Base.$(op)(l::$type, r::$type)
175175
l, r = promote_except_value(l, r)
@@ -186,7 +186,9 @@ for op in (:(<=), :(<), :(>=), :(>), :isless),
186186
end
187187
end
188188
end
189-
for op in (:isequal, :(==)), (type, base_type, _) in ABSTRACT_QUANTITY_TYPES
189+
for op in (:isequal, :(==)), (type, true_base_type, _) in ABSTRACT_QUANTITY_TYPES
190+
# Avoid creating overly generic operations on these:
191+
base_type = true_base_type <: Number ? true_base_type : Number
190192
@eval begin
191193
function Base.$(op)(l::$type, r::$type)
192194
l, r = promote_except_value(l, r)
@@ -211,7 +213,9 @@ for op in (:(<=), :(<), :(>=), :(>), :isless, :isgreater, :isequal, :(==)),
211213
end
212214
end
213215
# Define isapprox:
214-
for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES
216+
for (type, true_base_type, _) in ABSTRACT_QUANTITY_TYPES
217+
# Avoid creating overly generic operations on these:
218+
base_type = true_base_type <: Number ? true_base_type : Number
215219
@eval begin
216220
function Base.isapprox(l::$type, r::$type; kws...)
217221
dimension(l) == dimension(r) || throw(DimensionError(l, r))
@@ -306,11 +310,11 @@ tryrationalize(::Type{R}, x) where {R} = isinteger(x) ? convert(R, round(Int, x)
306310
Base.showerror(io::IO, e::DimensionError) = print(io, "DimensionError: ", e.q1, " and ", e.q2, " have incompatible dimensions")
307311
Base.showerror(io::IO, e::DimensionError{<:Any,Nothing}) = print(io, "DimensionError: ", e.q1, " is not dimensionless")
308312

309-
for (type, _, _) in ABSTRACT_QUANTITY_TYPES
313+
for (type, _, _) in ABSTRACT_QUANTITY_TYPES, (type2, _, _) in ABSTRACT_QUANTITY_TYPES
310314
@eval begin
311-
Base.convert(::Type{Q}, q::$type) where {Q<:UnionAbstractQuantity} = q
312-
Base.convert(::Type{Q}, q::$type) where {T,Q<:UnionAbstractQuantity{T}} = new_quantity(Q, convert(T, ustrip(q)), dimension(q))
313-
Base.convert(::Type{Q}, q::$type) where {T,D,Q<:UnionAbstractQuantity{T,D}} = new_quantity(Q, convert(T, ustrip(q)), convert(D, dimension(q)))
315+
Base.convert(::Type{Q}, q::$type) where {Q<:$type2} = q
316+
Base.convert(::Type{Q}, q::$type) where {T,Q<:$type2{T}} = new_quantity(Q, convert(T, ustrip(q)), dimension(q))
317+
Base.convert(::Type{Q}, q::$type) where {T,D,Q<:$type2{T,D}} = new_quantity(Q, convert(T, ustrip(q)), convert(D, dimension(q)))
314318
end
315319
end
316320

0 commit comments

Comments
 (0)