Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide constructors from generators #792

Merged
merged 11 commits into from
May 23, 2020
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
julia = "1"

[extras]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"

[targets]
test = ["InteractiveUtils", "Test", "BenchmarkTools"]
28 changes: 28 additions & 0 deletions src/SArray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,34 @@ end
end
end

@generated function (::Type{SArray{S, T}})(gen::Base.Generator) where {S <: Tuple, T}
eschnett marked this conversation as resolved.
Show resolved Hide resolved
stmts = [:(Base.@_inline_meta)]
args = []
iter = :(iterate(gen))
for i in CartesianIndices(size_to_tuple(S))
el = Symbol(:el, i)
push!(stmts, :(($el,st) = $iter))
eschnett marked this conversation as resolved.
Show resolved Hide resolved
push!(args, el)
iter = :(iterate(gen,st))
end
push!(stmts, :(SArray{S, T}($(args...))))
eschnett marked this conversation as resolved.
Show resolved Hide resolved
Expr(:block, stmts...)
end

@generated function (::Type{SArray{S}})(gen::Base.Generator) where {S <: Tuple}
stmts = [:(Base.@_inline_meta)]
args = []
iter = :(iterate(gen))
for i in CartesianIndices(size_to_tuple(S))
el = Symbol(:el, i)
push!(stmts, :(($el,st) = $iter))
push!(args, el)
iter = :(iterate(gen,st))
end
push!(stmts, :(SArray{S}($(args...))))
Expr(:block, stmts...)
end

@inline SArray(a::StaticArray) = SArray{size_tuple(Size(a))}(Tuple(a))

####################
Expand Down
28 changes: 28 additions & 0 deletions src/SMatrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,34 @@ end
end
end

@generated function SMatrix{M, N, T}(gen::Base.Generator) where {M, N, T}
eschnett marked this conversation as resolved.
Show resolved Hide resolved
stmts = [:(Base.@_inline_meta)]
args = []
iter = :(iterate(gen))
for j in 1:N, i in 1:M
el = Symbol(:el, i, :x, j)
push!(stmts, :(($el,st) = $iter))
push!(args, el)
iter = :(iterate(gen,st))
end
push!(stmts, :(SMatrix{M, N, T}($(args...))))
Expr(:block, stmts...)
end

@generated function SMatrix{M, N}(gen::Base.Generator) where {M, N}
stmts = [:(Base.@_inline_meta)]
args = []
iter = :(iterate(gen))
for j in 1:N, i in 1:M
el = Symbol(:el, i, :x, j)
push!(stmts, :(($el,st) = $iter))
push!(args, el)
iter = :(iterate(gen,st))
end
push!(stmts, :(SMatrix{M, N}($(args...))))
Expr(:block, stmts...)
end

@inline convert(::Type{SMatrix{S1,S2}}, a::StaticArray{<:Tuple, T}) where {S1,S2,T} = SMatrix{S1,S2,T}(Tuple(a))
@inline SMatrix(a::StaticMatrix{S1, S2}) where {S1, S2} = SMatrix{S1, S2}(Tuple(a))

Expand Down
28 changes: 28 additions & 0 deletions src/SVector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,34 @@ const SVector{S, T} = SArray{Tuple{S}, T, 1, S}
@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)

@generated function SVector{N, T}(gen::Base.Generator) where {N, T}
stmts = [:(Base.@_inline_meta)]
args = []
iter = :(iterate(gen))
for i in 1:N
el = Symbol(:el, i)
push!(stmts, :(($el,st) = $iter))
push!(args, el)
iter = :(iterate(gen,st))
end
push!(stmts, :(SVector{N,T}($(args...))))
Expr(:block, stmts...)
end

@generated function SVector{N}(gen::Base.Generator) where {N}
stmts = [:(Base.@_inline_meta)]
args = []
iter = :(iterate(gen))
for i in 1:N
el = Symbol(:el, i)
push!(stmts, :(($el,st) = $iter))
push!(args, el)
iter = :(iterate(gen,st))
end
push!(stmts, :(SVector{N}($(args...))))
Expr(:block, stmts...)
end

# conversion from AbstractVector / AbstractArray (better inference than default)
#@inline convert{S,T}(::Type{SVector{S}}, a::AbstractArray{T}) = SVector{S,T}((a...))

Expand Down
5 changes: 5 additions & 0 deletions test/SArray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@

@test SArray(SArray{Tuple{2}}(1,2)) === SArray{Tuple{2}}(1,2)

@test SArray{Tuple{}}(i for i in 1:1).data === (1,)
@test SArray{Tuple{3}}(i for i in 1:3).data === (1,2,3)
@test SArray{Tuple{3}}(float(i) for i in 1:3).data === (1.0,2.0,3.0)
@test SArray{Tuple{2,3}}(i+10j for i in 1:2, j in 1:3).data === (11,12,21,22,31,32)

@test ((@SArray [1])::SArray{Tuple{1}}).data === (1,)
@test ((@SArray [1,2])::SArray{Tuple{2}}).data === (1,2)
@test ((@SArray Float64[1,2,3])::SArray{Tuple{3}}).data === (1.0, 2.0, 3.0)
Expand Down
12 changes: 12 additions & 0 deletions test/SMatrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@
@test SMatrix{2}((1,2,3,4)).data === (1,2,3,4)
@test_throws DimensionMismatch SMatrix{2}((1,2,3,4,5))

@test (SMatrix{2,3}(i+10j for i in 1:2, j in 1:3)::SMatrix{2,3}).data ===
(11,12,21,22,31,32)
@test (SMatrix{2,3}(float(i+10j) for i in 1:2, j in 1:3)::SMatrix{2,3}).data ===
(11.0,12.0,21.0,22.0,31.0,32.0)
@test (SMatrix{0,0,Int}()::SMatrix{0,0}).data === ()
@test (SMatrix{0,3,Int}()::SMatrix{0,3}).data === ()
@test (SMatrix{2,0,Int}()::SMatrix{2,0}).data === ()
@test (SMatrix{2,3,Int}(i+10j for i in 1:2, j in 1:3)::SMatrix{2,3}).data ===
(11,12,21,22,31,32)
@test (SMatrix{2,3,Float64}(i+10j for i in 1:2, j in 1:3)::SMatrix{2,3}).data ===
(11.0,12.0,21.0,22.0,31.0,32.0)

@test ((@SMatrix [1.0])::SMatrix{1,1}).data === (1.0,)
@test ((@SMatrix [1 2])::SMatrix{1,2}).data === (1, 2)
@test ((@SMatrix [1 ; 2])::SMatrix{2,1}).data === (1, 2)
Expand Down
6 changes: 6 additions & 0 deletions test/SVector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
@test SVector((1,)).data === (1,)
@test SVector((1.0,)).data === (1.0,)

@test SVector{3}(i for i in 1:3).data === (1,2,3)
@test SVector{3}(float(i) for i in 1:3).data === (1.0,2.0,3.0)
@test SVector{0,Int}().data === ()
@test SVector{3,Int}(i for i in 1:3).data === (1,2,3)
@test SVector{3,Float64}(i for i in 1:3).data === (1.0,2.0,3.0)

@test SVector(1).data === (1,)
@test SVector(1,1.0).data === (1.0,1.0)

Expand Down