@@ -74,15 +74,32 @@ collect_with_eltype(::Type{T}, vec::Vector{T}) where {T} = vec
74
74
collect_with_eltype (:: Type{T} , vec:: AbstractVector{T} ) where {T} = collect (vec)
75
75
76
76
function 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)
81
93
for element in iter
82
94
# convert_simplex always returns a tuple,
83
95
# so that e.g. convert(Triangle, quad) can return 2 elements
84
96
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
86
103
end
87
104
end
88
105
return result
0 commit comments