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′) ))
128132end
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-
134134length_val (a:: T ) where {T <: StaticArrayLike } = length_val (Size (T))
135135length_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
143146end
0 commit comments