@@ -74,15 +74,32 @@ collect_with_eltype(::Type{T}, vec::Vector{T}) where {T} = vec
7474collect_with_eltype (:: Type{T} , vec:: AbstractVector{T} ) where {T} = collect (vec)
7575
7676function collect_with_eltype (:: Type{T} , iter) where {T}
77- # TODO we could be super smart about allocating the right length
78- # but its kinda annoying, since e.g. T == Triangle and first(iter) isa Quad
79- # will need double the length etc - but could all be figured out ;)
80- result = T[]
77+ # We need to get `eltype` information from `iter`, it seems to be `Any`
78+ # most of the time so the eltype checks here don't actually work
79+ l = if Base. IteratorSize (iter) isa Union{Base. HasShape,Base. HasLength}
80+ if Base. IteratorEltype (iter) isa Base. HasEltype && isconcretetype (eltype (iter))
81+ # Work out the exact length
82+ length (convert_simplex (T, first (iter))) * length (iter)
83+ else
84+ # We know it is at least the length of iter,
85+ # after that we will `push!` if we have to
86+ length (iter)
87+ end
88+ else
89+ 0
90+ end
91+ n = 0
92+ result = Vector {T} (undef, l)
8193 for element in iter
8294 # convert_simplex always returns a tuple,
8395 # so that e.g. convert(Triangle, quad) can return 2 elements
8496 for telement in convert_simplex (T, element)
85- push! (result, telement)
97+ n += 1
98+ if n > l
99+ push! (result, telement)
100+ else
101+ result[n] = telement
102+ end
86103 end
87104 end
88105 return result
0 commit comments