@@ -64,7 +64,7 @@ _collect_structarray!(dest, itr, st, ::Nothing) =
64
64
65
65
function collect_to_structarray! (dest:: AbstractArray , itr, offs, st)
66
66
# 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.
68
68
i = offs
69
69
while true
70
70
elem = iterate (itr, st)
@@ -74,7 +74,7 @@ function collect_to_structarray!(dest::AbstractArray, itr, offs, st)
74
74
@inbounds dest[i] = el
75
75
i += 1
76
76
else
77
- new = widen (dest, i, el)
77
+ new = widen_from_instance (dest, i, el)
78
78
@inbounds new[i] = el
79
79
return collect_to_structarray! (new, itr, i+ 1 , st)
80
80
end
84
84
85
85
function grow_to_structarray! (dest:: AbstractArray , itr, elem = iterate (itr))
86
86
# 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.
88
88
i = length (dest)+ 1
89
89
while elem != = nothing
90
90
el, st = elem
@@ -93,7 +93,7 @@ function grow_to_structarray!(dest::AbstractArray, itr, elem = iterate(itr))
93
93
elem = iterate (itr, st)
94
94
i += 1
95
95
else
96
- new = widen (dest, i, el)
96
+ new = widen_from_instance (dest, i, el)
97
97
push! (new, el)
98
98
return grow_to_structarray! (new, itr, iterate (itr, st))
99
99
end
@@ -102,7 +102,12 @@ function grow_to_structarray!(dest::AbstractArray, itr, elem = iterate(itr))
102
102
end
103
103
104
104
# 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
106
111
107
112
function _widenstructarray (dest:: StructArray , i, :: Type{T} ) where {T}
108
113
sch = hasfields (T) ? staticschema (T) : nothing
@@ -145,11 +150,20 @@ function _append!!(dest::AbstractVector, itr, ::Union{Base.HasShape, Base.HasLen
145
150
fr === nothing && return dest
146
151
el, st = fr
147
152
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)
149
154
resize! (new, length (dest) + n)
150
155
@inbounds new[i] = el
151
156
return collect_to_structarray! (new, itr, i + 1 , st)
152
157
end
153
158
154
159
_append!! (dest:: AbstractVector , itr, :: Base.SizeUnknown ) =
155
160
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