@@ -64,7 +64,7 @@ _collect_structarray!(dest, itr, st, ::Nothing) =
6464
6565function collect_to_structarray! (dest:: AbstractArray , itr, offs, st)
6666 # collect to dest array, checking the type of each result. if a result does not
67- # match, widen the result type and re-dispatch.
67+ # match, widen_from_instance the result type and re-dispatch.
6868 i = offs
6969 while true
7070 elem = iterate (itr, st)
@@ -74,7 +74,7 @@ function collect_to_structarray!(dest::AbstractArray, itr, offs, st)
7474 @inbounds dest[i] = el
7575 i += 1
7676 else
77- new = widen (dest, i, el)
77+ new = widen_from_instance (dest, i, el)
7878 @inbounds new[i] = el
7979 return collect_to_structarray! (new, itr, i+ 1 , st)
8080 end
8484
8585function grow_to_structarray! (dest:: AbstractArray , itr, elem = iterate (itr))
8686 # collect to dest array, checking the type of each result. if a result does not
87- # match, widen the result type and re-dispatch.
87+ # match, widen_from_instance the result type and re-dispatch.
8888 i = length (dest)+ 1
8989 while elem != = nothing
9090 el, st = elem
@@ -93,7 +93,7 @@ function grow_to_structarray!(dest::AbstractArray, itr, elem = iterate(itr))
9393 elem = iterate (itr, st)
9494 i += 1
9595 else
96- new = widen (dest, i, el)
96+ new = widen_from_instance (dest, i, el)
9797 push! (new, el)
9898 return grow_to_structarray! (new, itr, iterate (itr, st))
9999 end
@@ -102,7 +102,12 @@ function grow_to_structarray!(dest::AbstractArray, itr, elem = iterate(itr))
102102end
103103
104104# Widen `dest` to contain `el` and copy until index `i-1`
105- widen (dest:: AbstractArray{S} , i, el:: T ) where {S, T} = _widenstructarray (dest, i, _promote_typejoin (S, T))
105+ widen_from_instance (dest:: AbstractArray , i, el:: T ) where {T} = widen_from_type (dest, i, T)
106+ # Widen `dest` to contain elements of type `T` and copy until index `i-1`
107+ function widen_from_type (dest:: AbstractArray{S} , i, :: Type{T} ) where {S, T}
108+ U = _promote_typejoin (S, T)
109+ return _widenstructarray (dest, i, U)
110+ end
106111
107112function _widenstructarray (dest:: StructArray , i, :: Type{T} ) where {T}
108113 sch = hasfields (T) ? staticschema (T) : nothing
@@ -145,11 +150,20 @@ function _append!!(dest::AbstractVector, itr, ::Union{Base.HasShape, Base.HasLen
145150 fr === nothing && return dest
146151 el, st = fr
147152 i = lastindex (dest) + 1
148- new = iscompatible (el, dest) ? dest : widen (dest, i, el)
153+ new = iscompatible (el, dest) ? dest : widen_from_instance (dest, i, el)
149154 resize! (new, length (dest) + n)
150155 @inbounds new[i] = el
151156 return collect_to_structarray! (new, itr, i + 1 , st)
152157end
153158
154159_append!! (dest:: AbstractVector , itr, :: Base.SizeUnknown ) =
155160 grow_to_structarray! (dest, itr)
161+
162+ # Optimized version when element collection is an `AbstractVector`
163+ # This only works for julia 1.3 or greater, which has `append!` for `AbstractVector`
164+ @static if VERSION ≥ v " 1.3.0"
165+ function append!! (dest:: V , v:: AbstractVector{T} ) where {V<: AbstractVector , T}
166+ new = iscompatible (T, V) ? dest : widen_from_type (dest, length (dest) + 1 , T)
167+ return append! (new, v)
168+ end
169+ end
0 commit comments