Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
perrutquist committed Jan 1, 2020
1 parent 45507d7 commit d1cb0e1
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ version = "0.2.0"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"

[compat]
julia = "0.7, 1"
Requires = "1.0, 1"
julia = "0.7, 1"

[extras]
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Expand Down
48 changes: 19 additions & 29 deletions src/StaticNumbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,36 +84,24 @@ Base.@pure Base.Val(::Static{X}) where X = Val(X)
const StaticOrInt = Union{StaticInteger, Int}

# Promotion
Base.promote_rule(::Type{<:Static{X}}, ::Type{<:Static{X}}) where {X} =
typeof(X)
Base.promote_rule(::Type{<:AbstractIrrational}, ::Type{<:Static{X}}) where {X} =
promote_type(Float64, typeof(X))
# We need to override promote and promote_typeof because they don't even call
# promote_rule for all-same types.
Base.promote(::ST, ys::ST...) where {ST <: Static{X}} where {X} = ntuple(i->X, 1+length(ys))
Base.promote_type(::Type{ST}, ::Type{ST}) where {ST <: Static{X}} where {X} = typeof(X)
Base.promote_typeof(::ST, ::ST...) where {ST <: Static{X}} where {X} = typeof(X)

# To avoid infinite recursion, we need this:
Base.promote_type(::Type{<:Static{X}}, T::Type...) where {X} = promote_type(typeof(X), promote_type(T...))

# Loop over all three types specifically, instead of dispatching on the Union.
for ST in (StaticInteger, StaticReal, StaticNumber)
# We need to override promote and promote_typeof because they don't even call
# promote_rule for all-same types.
Base.promote(::ST{X}, ys::ST{X}...) where {X} = ntuple(i->X, 1+length(ys))
Base.promote_type(::Type{ST{X}}, ::Type{ST{X}}) where {X} = typeof(X)
Base.promote_typeof(::ST{X}, ::ST{X}...) where {X} = typeof(X)
# To avoid infinite recursion, we need this:
Base.promote_type(::Type{ST{X}}, T::Type...) where {X} = promote_type(typeof(X), promote_type(T...))

Base.promote_rule(::Type{<:ST{X}}, ::Type{T}) where {X,T<:Number} = promote_type(typeof(X), T)
Base.promote_rule(::Type{ST{X}}, ::Type{T}) where {X,T<:Number} = promote_type(typeof(X), T)

# Constructors
(::Type{Complex{T}})(::ST{X}) where {T<:Real, X} = Complex{T}(X)
(::Type{Rational{T}})(::ST{X}) where {T<:Integer, X} = Rational{T}(X)
end

Base.promote_rule(::Type{<:Static{X}}, ::Type{<:Static{Y}}) where {X,Y} =
promote_type(typeof(X),typeof(Y))

# Bool has a special rule that we need to override?
#Base.promote_rule(::Type{Bool}, ::Type{StaticInteger{X}}) where {X} = promote_type(Bool, typeof(X))

#Base.BigInt(::Static{X}) where {X} = BigInt(X)

"ofstatictype(x,y) - like oftype(x,y), but return a `Static` `x` is a `Static`."
ofstatictype(::Static{X}, y) where {X} = static(oftype(X, y))
ofstatictype(x, y) = oftype(x, y)
Expand All @@ -137,7 +125,7 @@ end
for fun in (:-, :zero, :one, :oneunit, :trailing_zeros, :widen, :decompose)
@eval Base.$fun(::Static{X}) where X = Base.$fun(X)
end
for fun in (:trunc, :floor, :ceil, :round)
for fun in (:trunc, :floor, :ceil, :round, :isnan)
@eval Base.$fun(::Union{StaticReal{X}, StaticNumber{X}}) where {X} = Base.$fun(X)
end
for fun in (:zero, :one, :oneunit)
Expand Down Expand Up @@ -187,17 +175,19 @@ for f in (:+, :-, :*, :/, :^)
@eval Base.$f(::Static{X}, ::Static{X}) where {X} = $f(X,X)
end
# ...where simplifications are possible:
# Note: We allow creation of specific static numbers, like 1 and 0 (as an exception)
# since this cannot lead to the set of static numbers growing uncontrollably.
Base.:&(::StaticInteger{X}, ::StaticInteger{X}) where {X} = X
Base.:|(::StaticInteger{X}, ::StaticInteger{X}) where {X} = X
Base.xor(::StaticInteger{X}, ::StaticInteger{X}) where {X} = zero(X)
Base.:<(::Static{X}, ::Static{X}) where {X} = false
Base.:<=(::Static{X}, ::Static{X}) where {X} = true
Base.rem(::Static{X}, ::Static{X}) where {X} = (X==0 || isinf(X)) ? X isa AbstractFloat ? oftype(X, NaN) : throw(DivideError()) : zero(X)
Base.mod(::Static{X}, ::Static{X}) where {X} = (X==0 || isinf(X)) ? X isa AbstractFloat ? oftype(X, NaN) : throw(DivideError()) : zero(X)
Base.div(::Static{X}, ::Static{X}) where {X} = static(one(X)) # Needed for Julia > 1.3
Base.xor(::StaticInteger{X}, ::StaticInteger{X}) where {X} = static(zero(X))
Base.:<(::ST, ::ST) where {ST<:Static{X}} where {X} = false
Base.:<=(::ST, ::ST) where {ST<:Static{X}} where {X} = true
Base.rem(::ST, ::ST) where {ST<:Static{X}} where {X} = (X==0 || isinf(X)) ? X isa AbstractFloat ? static(oftype(X, NaN)) : throw(DivideError()) : static(zero(X))
Base.mod(::ST, ::ST) where {ST<:Static{X}} where {X} = (X==0 || isinf(X)) ? X isa AbstractFloat ? static(oftype(X, NaN)) : throw(DivideError()) : static(zero(X))
Base.div(::ST, ::ST) where {ST<:Static{X}} where {X} = static(one(X)) # Needed for Julia > 1.3

# Three-argument function that gives no_op_err
fma(x::Static{X}, y::Static{X}, z::Static{X}) where {X} = fma(X,X,X)
fma(x::ST, y::ST, z::ST) where {ST<:Static{X}} where {X} = fma(X,X,X)

# Static powers using Base.literal_pow.
# This avoids DomainError in some cases?
Expand Down
9 changes: 9 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ using Test

@test zero(static(1)) === 0
@test zero(static(1.0)) === 0.0
@test zero(typeof(static(1))) === 0
@test zero(typeof(static(1.0))) === 0.0

@test static(true) == true
@test static(false) == false
Expand Down Expand Up @@ -122,6 +124,13 @@ end
@test Base.promote_typeof(static(1), static(1)) === Int

@test static(1):static(2):5 isa LengthStepRange{Int64,StaticInteger{-1},StaticInteger{2},Int64}

@test Rational{Int}(static(3//2)) === 3//2

@test Base.promote_rule(StaticInteger{3}, StaticReal{3.14}) === Float64

@test widemul(static(1), true) === widemul(1, true)
@test widemul(static(1.0), false) === widemul(1.0, false)
end

@testset "show" begin
Expand Down

0 comments on commit d1cb0e1

Please sign in to comment.