Skip to content

Commit a06bba8

Browse files
authored
Merge pull request #71 from SymbolicML/reduce-invalidations-2
Reduce the number of method invalidations
2 parents 13998ee + b6c707e commit a06bba8

File tree

2 files changed

+23
-13
lines changed

2 files changed

+23
-13
lines changed

src/fixed_rational.jl

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,21 @@ end
5555
Base.iszero(x::FixedRational) = iszero(x.num)
5656
Base.isone(x::F) where {F<:FixedRational} = x.num == denom(F)
5757
Base.isinteger(x::F) where {F<:FixedRational} = iszero(x.num % denom(F))
58-
Base.convert(::Type{F}, x::Integer) where {F<:FixedRational} = unsafe_fixed_rational(x * denom(F), eltype(F), val_denom(F))
59-
Base.convert(::Type{F}, x::Rational) where {F<:FixedRational} = F(x)
60-
Base.convert(::Type{Rational{R}}, x::F) where {R,F<:FixedRational} = Rational{R}(x.num, denom(F))
61-
Base.convert(::Type{Rational}, x::F) where {F<:FixedRational} = Rational{eltype(F)}(x.num, denom(F))
62-
Base.convert(::Type{AF}, x::F) where {AF<:AbstractFloat,F<:FixedRational} = convert(AF, x.num) / convert(AF, denom(F))
63-
Base.convert(::Type{I}, x::F) where {I<:Integer,F<:FixedRational} =
58+
59+
Rational{R}(x::F) where {R,F<:FixedRational} = Rational{R}(x.num, denom(F))
60+
Rational(x::F) where {F<:FixedRational} = Rational{eltype(F)}(x)
61+
(::Type{AF})(x::F) where {AF<:AbstractFloat,F<:FixedRational} = convert(AF, x.num) / convert(AF, denom(F))
62+
(::Type{I})(x::F) where {I<:Integer,F<:FixedRational} =
6463
let
6564
isinteger(x) || throw(InexactError(:convert, I, x))
6665
convert(I, div(x.num, denom(F)))
6766
end
67+
(::Type{Bool})(x::F) where {F<:FixedRational} =
68+
let
69+
iszero(x) || isone(x) || throw(InexactError(:convert, Bool, x))
70+
return x.num == denom(F)
71+
end
72+
6873
Base.round(::Type{T}, x::F, r::RoundingMode=RoundNearest) where {T,F<:FixedRational} = div(convert(T, x.num), convert(T, denom(F)), r)
6974
Base.decompose(x::F) where {T,F<:FixedRational{T}} = (x.num, zero(T), denom(F))
7075

@@ -78,13 +83,13 @@ end
7883
function Base.promote_rule(::Type{<:FixedRational{T1}}, ::Type{Rational{T2}}) where {T1,T2}
7984
return Rational{promote_type(T1,T2)}
8085
end
81-
function Base.promote_rule(::Type{<:FixedRational{T1}}, ::Type{T2}) where {T1,T2}
86+
function Base.promote_rule(::Type{<:FixedRational{T1}}, ::Type{T2}) where {T1,T2<:Real}
8287
return promote_type(Rational{T1}, T2)
8388
end
84-
85-
# Want to consume integers:
86-
Base.promote(x::Integer, y::F) where {F<:FixedRational} = (F(x), y)
87-
Base.promote(x::F, y::Integer) where {F<:FixedRational} = reverse(promote(y, x))
89+
function Base.promote_rule(::Type{F}, ::Type{<:Integer}) where {F<:FixedRational}
90+
# Want to consume integers:
91+
return F
92+
end
8893

8994
Base.string(x::FixedRational) =
9095
let
@@ -93,7 +98,6 @@ Base.string(x::FixedRational) =
9398
return string(div(x.num, g)) * "//" * string(div(denom(x), g))
9499
end
95100
Base.show(io::IO, x::FixedRational) = print(io, string(x))
96-
Base.zero(::Type{F}) where {F<:FixedRational} = unsafe_fixed_rational(0, eltype(F), val_denom(F))
97101

98102
tryrationalize(::Type{F}, x::F) where {F<:FixedRational} = x
99103
tryrationalize(::Type{F}, x::Union{Rational,Integer}) where {F<:FixedRational} = convert(F, x)

test/unittests.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,11 @@ end
407407
@testset "Additional tests of FixedRational" begin
408408
@test convert(Int64, FixedRational{Int64,1000}(2 // 1)) == 2
409409
@test convert(Int32, FixedRational{Int64,1000}(3 // 1)) == 3
410+
@test convert(Bool, FixedRational{Int8,6}(1//1)) === true
411+
@test convert(Bool, FixedRational{Int8,6}(0//1)) === false
412+
413+
@test_throws InexactError convert(Int32, FixedRational{Int8,6}(2//3))
414+
@test_throws InexactError convert(Bool, FixedRational{Int8,6}(2//1))
410415

411416
VERSION >= v"1.8" && @test_throws "Refusing to" promote(FixedRational{Int,10}(2), FixedRational{Int,4}(2))
412417

@@ -415,6 +420,7 @@ end
415420
@test promote(f64, f8) == (2, 2)
416421
@test typeof(promote(f64, f8)) == typeof((f64, f64))
417422
@test typeof(promote(FixedRational{Int8,10}(2), FixedRational{Int8,10}(2))) == typeof((f8, f8))
423+
@test promote_type(Float64, typeof(f64)) == Float64
418424

419425
# Required to hit integer branch (otherwise will go to `literal_pow`)
420426
f(i::Int) = Dimensions(length=1, mass=-1)^i
@@ -438,7 +444,7 @@ end
438444
# Promotion rules
439445
@test promote_type(FixedRational{Int64,10},FixedRational{BigInt,10}) == FixedRational{BigInt,10}
440446
@test promote_type(Rational{Int8}, FixedRational{Int,12345}) == Rational{Int}
441-
@test promote_type(Int8, FixedRational{Int,12345}) == promote_type(Int8, Rational{Int})
447+
@test promote_type(Int8, FixedRational{Int,12345}) == FixedRational{Int,12345}
442448
end
443449

444450
@testset "Quantity promotion" begin

0 commit comments

Comments
 (0)