Skip to content

Commit 2d1c974

Browse files
committed
Define general convert with construct_type.
And fix for input with non-1 based axes.
1 parent d2a5aa7 commit 2d1c974

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

src/convert.jl

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,12 @@ end
101101
@propagate_inbounds (::Type{SA})(a::AbstractArray) where {SA <: StaticArray} = convert(SA, a)
102102

103103
# this covers most conversions and "statically-sized reshapes"
104-
@inline convert(::Type{SA}, sa::StaticArray) where {SA<:StaticArray} = SA(Tuple(sa))
105-
@inline convert(::Type{SA}, sa::StaticArray) where {SA<:Scalar} = SA((sa[],)) # disambiguation
104+
@inline function convert(::Type{SA}, sa::StaticArray{S}) where {SA<:StaticArray,S<:Tuple}
105+
SA′ = construct_type(SA, sa)
106+
# `SA′((sa,))` is not valid. As we want `SA′(sa...)`
107+
sa isa eltype(SA′) && throw_convert(SA, S)
108+
return SA′(Tuple(sa))
109+
end
106110
@inline convert(::Type{SA}, sa::SA) where {SA<:StaticArray} = sa
107111
@inline convert(::Type{SA}, x::Tuple) where {SA<:StaticArray} = SA(x) # convert -> constructor. Hopefully no loops...
108112

@@ -123,21 +127,20 @@ end
123127
@boundscheck if length(a) != length(SA)
124128
dimension_mismatch_fail(SA, a)
125129
end
126-
127-
return _convert(SA, a, Length(SA))
130+
SA′ = construct_type(SA, a)
131+
return SA′(unroll_tuple(a, Length(SA′)))
128132
end
129133

130-
@inline _convert(SA, a, l::Length) = SA(unroll_tuple(a, l))
131-
@inline _convert(SA::Type{<:StaticArray{<:Tuple,T}}, a, ::Length{0}) where T = similar_type(SA, T)(())
132-
@inline _convert(SA, a, ::Length{0}) = similar_type(SA, eltype(a))(())
133-
134134
length_val(a::T) where {T <: StaticArrayLike} = length_val(Size(T))
135135
length_val(a::Type{T}) where {T<:StaticArrayLike} = length_val(Size(T))
136136

137+
unroll_tuple(a::AbstractArray, ::Length{0}) = ()
138+
unroll_tuple(a::AbstractArray, ::Length{1}) = @inbounds (a[],)
137139
@generated function unroll_tuple(a::AbstractArray, ::Length{L}) where {L}
138-
exprs = [:(a[$j]) for j = 1:L]
140+
exprs = (:(a[$j+Δj]) for j = 0:L-1)
139141
quote
140142
@_inline_meta
143+
Δj = firstindex(a)
141144
@inbounds return $(Expr(:tuple, exprs...))
142145
end
143146
end

0 commit comments

Comments
 (0)