Skip to content

Commit

Permalink
Merge pull request #30076 from bramtayl/patch-1
Browse files Browse the repository at this point in the history
Slight refactor to collection widening
  • Loading branch information
andyferris authored Dec 1, 2018
2 parents d54f40d + cd447cf commit 5b827f5
Showing 1 changed file with 23 additions and 12 deletions.
35 changes: 23 additions & 12 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,14 @@ function collect_to_with_first!(dest, v1, itr, st)
return grow_to!(dest, itr, st)
end

function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
@_inline_meta
new = similar(dest, promote_typejoin(T, typeof(el)))
copyto!(new, firstindex(new), dest, firstindex(dest), i-1)
@inbounds new[i] = el
return new
end

function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
# collect to dest array, checking the type of each result. if a result does not
# match, widen the result type and re-dispatch.
Expand All @@ -644,10 +652,7 @@ function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
@inbounds dest[i] = el::T
i += 1
else
R = promote_typejoin(T, typeof(el))
new = similar(dest, R)
copyto!(new,1, dest,1, i-1)
@inbounds new[i] = el
new = setindex_widen_up_to(dest, el, i)
return collect_to!(new, itr, i+1, st)
end
end
Expand All @@ -662,6 +667,19 @@ function grow_to!(dest, itr)
grow_to!(dest2, itr, y[2])
end

function push_widen(dest, el)
@_inline_meta
new = sizehint!(empty(dest, promote_typejoin(eltype(dest), typeof(el))), length(dest))
if new isa AbstractSet
# TODO: merge back these two branches when copy! is re-enabled for sets/vectors
union!(new, dest)
else
append!(new, dest)
end
push!(new, el)
return new
end

function grow_to!(dest, itr, st)
T = eltype(dest)
y = iterate(itr, st)
Expand All @@ -671,14 +689,7 @@ function grow_to!(dest, itr, st)
if S === T || S <: T
push!(dest, el::T)
else
new = sizehint!(empty(dest, promote_typejoin(T, S)), length(dest))
if new isa AbstractSet
# TODO: merge back these two branches when copy! is re-enabled for sets/vectors
union!(new, dest)
else
append!(new, dest)
end
push!(new, el)
new = push_widen(dest, el)
return grow_to!(new, itr, st)
end
y = iterate(itr, st)
Expand Down

0 comments on commit 5b827f5

Please sign in to comment.