Skip to content

Commit

Permalink
Use Base.promote instead of promote_tuple_eltype to fik promotion
Browse files Browse the repository at this point in the history
issue for element types defined after StaticArrays.
  • Loading branch information
andreasnoack committed Oct 14, 2019
1 parent 4cfeb58 commit ec0edb8
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 40 deletions.
12 changes: 6 additions & 6 deletions src/MArray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ end
end
end

@generated function (::Type{MArray{S}})(x::T) where {S, T <: Tuple}
return quote
$(Expr(:meta, :inline))
MArray{S,promote_tuple_eltype(T),$(tuple_length(S)),$(tuple_prod(S))}(x)
end
end
# Promote to common element type
@inline (::Type{MArray{S}})(x::Tuple) where {S <: Tuple} = MArray{S}(promote(x...))
# ...once all elements are the same, call the constructor with all parameters determined
@inline (::Type{MArray{S}})(x::NTuple{N,T}) where {S <: Tuple, T, N} = MArray{S, T, tuple_length(S), N}(x)
# ...the empty case requires special casing since T isn't defined in the above definition in the empty case
@inline (::Type{MArray{S}})(x::Tuple{}) where {S <: Tuple} = MArray{S, Union{}, tuple_length(S), 0}(x)

@generated function (::Type{MArray{S,T,N}})(::UndefInitializer) where {S,T,N}
return quote
Expand Down
2 changes: 1 addition & 1 deletion src/MVector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const MVector{S, T} = MArray{Tuple{S}, T, 1, S}

@inline MVector(x::NTuple{S,Any}) where {S} = MVector{S}(x)
@inline MVector{S}(x::NTuple{S,T}) where {S, T} = MVector{S, T}(x)
@inline MVector{S}(x::NTuple{S,Any}) where {S} = MVector{S, promote_tuple_eltype(typeof(x))}(x)
@inline MVector{S}(x::Tuple) where {S} = MVector{S}(promote(x...))

# Simplified show for the type
#show(io::IO, ::Type{MVector{N, T}}) where {N, T} = print(io, "MVector{$N,$T}")
Expand Down
13 changes: 6 additions & 7 deletions src/SArray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,12 @@ end
end
end

@generated function (::Type{SArray{S}})(x::T) where {S <: Tuple, T <: Tuple}
return quote
@_inline_meta
SArray{S, $(promote_tuple_eltype(T)), $(tuple_length(S)), $(tuple_prod(S))}(x)
end
end

# Promote to common element type
@inline (::Type{SArray{S}})(x::Tuple) where {S <: Tuple} = SArray{S}(promote(x...))
# ...once all elements are the same, call the constructor with all parameters determined
@inline (::Type{SArray{S}})(x::NTuple{N,T}) where {S <: Tuple, N, T} = SArray{S, T, tuple_length(S), N}(x)
# ...the empty case requires special casing since T isn't defined in the above definition in the empty case
@inline (::Type{SArray{S}})(x::Tuple{}) where {S <: Tuple} = SArray{S, Union{}, tuple_length(S), 0}(x)
@inline SArray(a::StaticArray) = SArray{size_tuple(Size(a))}(Tuple(a))

# Simplified show for the type
Expand Down
2 changes: 1 addition & 1 deletion src/SHermitianCompact.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ end
SHermitianCompact{N, T, L}(a)
end

@inline (::Type{SHermitianCompact{N}})(a::Tuple) where {N} = SHermitianCompact{N, promote_tuple_eltype(a)}(a)
@inline (::Type{SHermitianCompact{N}})(a::Tuple) where {N} = SHermitianCompact{N}(promote(a...))
@inline (::Type{SHermitianCompact{N}})(a::NTuple{M, T}) where {N, T, M} = SHermitianCompact{N, T}(a)
@inline SHermitianCompact(a::StaticMatrix{N, N, T}) where {N, T} = SHermitianCompact{N, T}(a)

Expand Down
14 changes: 8 additions & 6 deletions src/SMatrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,36 @@ unknown to the compiler (the element type may optionally also be specified).
"""
const SMatrix{S1, S2, T, L} = SArray{Tuple{S1, S2}, T, 2, L}

@generated function (::Type{SMatrix{S1}})(x::NTuple{L,Any}) where {S1,L}
@generated function (::Type{SMatrix{S1}})(x::NTuple{L,T}) where {S1,L,T}
S2 = div(L, S1)
if S1*S2 != L
throw(DimensionMismatch("Incorrect matrix sizes. $S1 does not divide $L elements"))
end

return quote
$(Expr(:meta, :inline))
T = promote_tuple_eltype(typeof(x))
SMatrix{S1, $S2, T, L}(x)
end
end
@inline (::Type{SMatrix{S1}})(x::Tuple) where {S1} = SMatrix{S1}(promote(x...))

@generated function (::Type{SMatrix{S1,S2}})(x::NTuple{L,Any}) where {S1,S2,L}
@generated function (::Type{SMatrix{S1,S2}})(x::NTuple{L,T}) where {S1,S2,L,T}
return quote
$(Expr(:meta, :inline))
T = promote_tuple_eltype(typeof(x))
SMatrix{S1, S2, T, L}(x)
end
end
(::Type{SMatrix{S1,S2}})(x::Tuple{}) where {S1,S2} = SMatrix{S1, S2, Union{}, 0}(x)
@inline (::Type{SMatrix{S1,S2}})(x::Tuple) where {S1,S2} = SMatrix{S1,S2}(promote(x...))

SMatrixNoType{S1, S2, L, T} = SMatrix{S1, S2, T, L}
@generated function (::Type{SMatrixNoType{S1, S2, L}})(x::NTuple{L,Any}) where {S1,S2,L}
@generated function (::Type{SMatrixNoType{S1, S2, L}})(x::NTuple{L,T}) where {S1,S2,L,T}
return quote
$(Expr(:meta, :inline))
T = promote_tuple_eltype(typeof(x))
SMatrix{S1, S2, T, L}(x)
end
end
@inline (::Type{SMatrixNoType{S1,S2,L}})(x::NTuple{L,Any}) where {S1,S2,L} = SMatrixNoType{S1,S2,L}(promote(x...))

@generated function (::Type{SMatrix{S1,S2,T}})(x::NTuple{L,Any}) where {S1,S2,T,L}
return quote
Expand Down
2 changes: 1 addition & 1 deletion src/SVector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const SVector{S, T} = SArray{Tuple{S}, T, 1, S}

@inline SVector(x::NTuple{S,Any}) where {S} = SVector{S}(x)
@inline SVector{S}(x::NTuple{S,T}) where {S, T} = SVector{S,T}(x)
@inline SVector{S}(x::T) where {S, T <: Tuple} = SVector{S,promote_tuple_eltype(T)}(x)
@inline SVector{S}(x::Tuple) where {S} = SVector{S}(promote(x...))

# conversion from AbstractVector / AbstractArray (better inference than default)
#@inline convert{S,T}(::Type{SVector{S}}, a::AbstractArray{T}) = SVector{S,T}((a...))
Expand Down
16 changes: 0 additions & 16 deletions src/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,6 @@ TupleN{T,N} = NTuple{N,T}
end
end

# Base gives up on tuples for promote_eltype... (TODO can we improve Base?)
@generated function promote_tuple_eltype(::Union{T,Type{T}}) where T <: Tuple
t = Union{}
for i = 1:length(T.parameters)
tmp = T.parameters[i]
if tmp <: Vararg
tmp = tmp.parameters[1]
end
t = :(promote_type($t, $tmp))
end
return quote
@_inline_meta
$t
end
end

# The ::Tuple variants exist to make sure that anything that calls with a tuple
# instead of a Tuple gets through to the constructor, so the user gets a nice
# error message
Expand Down
4 changes: 2 additions & 2 deletions test/SHermitianCompact.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,13 @@ fill3(x) = fill(3, x)
@testset "transpose/adjoint" begin
a = Hermitian([[rand(Complex{Int}) for i = 1 : 2, j = 1 : 2] for row = 1 : 3, col = 1 : 3])
if VERSION < v"1.2.0-"
@test transpose(SHermitianCompact{3}(a)) == transpose(a)
@test_broken transpose(SHermitianCompact{3}(a)) == transpose(a)
else
# FIXME: This `transpose(a)` crashes in v1.2.0-rc1.
# See https://github.com/JuliaLang/julia/issues/32222
@test_skip transpose(SHermitianCompact{3}(a)) == transpose(a)
end
@test adjoint(SHermitianCompact{3}(a)) == adjoint(a)
@test_broken adjoint(SHermitianCompact{3}(a)) == adjoint(a)

b = Hermitian([rand(Complex{Int}) for i = 1 : 3, j = 1 : 3])
@test adjoint(SHermitianCompact{3}(b)) == adjoint(b)
Expand Down

0 comments on commit ec0edb8

Please sign in to comment.