@@ -583,23 +583,38 @@ julia> collect(Float64, 1:2:5)
583
583
"""
584
584
collect (:: Type{T} , itr) where {T} = _collect (T, itr, IteratorSize (itr))
585
585
586
- _collect (:: Type{T} , itr, isz:: HasLength ) where {T} = copyto! ( Vector {T} (undef, Int ( length (itr) :: Integer )), itr)
587
- _collect ( :: Type{T} , itr, isz :: HasShape ) where {T} = copyto! (similar (Array{T}, axes (itr)), itr)
586
+ _collect (:: Type{T} , itr, isz:: Union{ HasLength,HasShape} ) where {T} =
587
+ copyto! (_array_for (T, isz, _similar_shape (itr, isz )), itr)
588
588
function _collect (:: Type{T} , itr, isz:: SizeUnknown ) where T
589
589
a = Vector {T} ()
590
590
for x in itr
591
- push! (a,x)
591
+ push! (a, x)
592
592
end
593
593
return a
594
594
end
595
595
596
596
# make a collection similar to `c` and appropriate for collecting `itr`
597
- _similar_for (c:: AbstractArray , :: Type{T} , itr, :: SizeUnknown ) where {T} = similar (c, T, 0 )
598
- _similar_for (c:: AbstractArray , :: Type{T} , itr, :: HasLength ) where {T} =
599
- similar (c, T, Int (length (itr):: Integer ))
600
- _similar_for (c:: AbstractArray , :: Type{T} , itr, :: HasShape ) where {T} =
601
- similar (c, T, axes (itr))
602
- _similar_for (c, :: Type{T} , itr, isz) where {T} = similar (c, T)
597
+ _similar_for (c, :: Type{T} , itr, isz, shp) where {T} = similar (c, T)
598
+
599
+ _similar_shape (itr, :: SizeUnknown ) = nothing
600
+ _similar_shape (itr, :: HasLength ) = length (itr):: Integer
601
+ _similar_shape (itr, :: HasShape ) = axes (itr)
602
+
603
+ _similar_for (c:: AbstractArray , :: Type{T} , itr, :: SizeUnknown , :: Nothing ) where {T} =
604
+ similar (c, T, 0 )
605
+ _similar_for (c:: AbstractArray , :: Type{T} , itr, :: HasLength , len:: Integer ) where {T} =
606
+ similar (c, T, len)
607
+ _similar_for (c:: AbstractArray , :: Type{T} , itr, :: HasShape , axs) where {T} =
608
+ similar (c, T, axs)
609
+
610
+ # make a collection appropriate for collecting `itr::Generator`
611
+ _array_for (:: Type{T} , :: SizeUnknown , :: Nothing ) where {T} = Vector {T} (undef, 0 )
612
+ _array_for (:: Type{T} , :: HasLength , len:: Integer ) where {T} = Vector {T} (undef, Int (len))
613
+ _array_for (:: Type{T} , :: HasShape{N} , axs) where {T,N} = similar (Array{T,N}, axs)
614
+
615
+ # used by syntax lowering for simple typed comprehensions
616
+ _array_for (:: Type{T} , itr, isz) where {T} = _array_for (T, isz, _similar_shape (itr, isz))
617
+
603
618
604
619
"""
605
620
collect(collection)
@@ -638,10 +653,10 @@ collect(A::AbstractArray) = _collect_indices(axes(A), A)
638
653
collect_similar (cont, itr) = _collect (cont, itr, IteratorEltype (itr), IteratorSize (itr))
639
654
640
655
_collect (cont, itr, :: HasEltype , isz:: Union{HasLength,HasShape} ) =
641
- copyto! (_similar_for (cont, eltype (itr), itr, isz), itr)
656
+ copyto! (_similar_for (cont, eltype (itr), itr, isz, _similar_shape (itr, isz) ), itr)
642
657
643
658
function _collect (cont, itr, :: HasEltype , isz:: SizeUnknown )
644
- a = _similar_for (cont, eltype (itr), itr, isz)
659
+ a = _similar_for (cont, eltype (itr), itr, isz, nothing )
645
660
for x in itr
646
661
push! (a,x)
647
662
end
@@ -699,24 +714,19 @@ else
699
714
end
700
715
end
701
716
702
- _array_for (:: Type{T} , itr, isz:: HasLength ) where {T} = _array_for (T, itr, isz, length (itr))
703
- _array_for (:: Type{T} , itr, isz:: HasShape{N} ) where {T,N} = _array_for (T, itr, isz, axes (itr))
704
- _array_for (:: Type{T} , itr, :: HasLength , len) where {T} = Vector {T} (undef, len)
705
- _array_for (:: Type{T} , itr, :: HasShape{N} , axs) where {T,N} = similar (Array{T,N}, axs)
706
-
707
717
function collect (itr:: Generator )
708
718
isz = IteratorSize (itr. iter)
709
719
et = @default_eltype (itr)
710
720
if isa (isz, SizeUnknown)
711
721
return grow_to! (Vector {et} (), itr)
712
722
else
713
- shape = isz isa HasLength ? length (itr) : axes (itr )
723
+ shp = _similar_shape (itr, isz )
714
724
y = iterate (itr)
715
725
if y === nothing
716
- return _array_for (et, itr . iter, isz )
726
+ return _array_for (et, isz, shp )
717
727
end
718
728
v1, st = y
719
- dest = _array_for (typeof (v1), itr . iter, isz, shape )
729
+ dest = _array_for (typeof (v1), isz, shp )
720
730
# The typeassert gives inference a helping hand on the element type and dimensionality
721
731
# (work-around for #28382)
722
732
et′ = et <: Type ? Type : et
@@ -726,15 +736,22 @@ function collect(itr::Generator)
726
736
end
727
737
728
738
_collect (c, itr, :: EltypeUnknown , isz:: SizeUnknown ) =
729
- grow_to! (_similar_for (c, @default_eltype (itr), itr, isz), itr)
739
+ grow_to! (_similar_for (c, @default_eltype (itr), itr, isz, nothing ), itr)
730
740
731
741
function _collect (c, itr, :: EltypeUnknown , isz:: Union{HasLength,HasShape} )
742
+ et = @default_eltype (itr)
743
+ shp = _similar_shape (itr, isz)
732
744
y = iterate (itr)
733
745
if y === nothing
734
- return _similar_for (c, @default_eltype (itr) , itr, isz)
746
+ return _similar_for (c, et , itr, isz, shp )
735
747
end
736
748
v1, st = y
737
- collect_to_with_first! (_similar_for (c, typeof (v1), itr, isz), v1, itr, st)
749
+ dest = _similar_for (c, typeof (v1), itr, isz, shp)
750
+ # The typeassert gives inference a helping hand on the element type and dimensionality
751
+ # (work-around for #28382)
752
+ et′ = et <: Type ? Type : et
753
+ RT = dest isa AbstractArray ? AbstractArray{<: et′ , ndims (dest)} : Any
754
+ collect_to_with_first! (dest, v1, itr, st):: RT
738
755
end
739
756
740
757
function collect_to_with_first! (dest:: AbstractArray , v1, itr, st)
0 commit comments