@@ -315,32 +315,52 @@ IteratorEltype(::Type{Zip{I,Z}}) where {I,Z} = and_iteratoreltype(IteratorEltype
315315reverse (it:: ZipHead ) = ZipHead (reverse (it. a))
316316reverse (it:: Zip ) = Zip (reverse (it. a), reverse (it. z))
317317
318- # Iteration
319- @inline function iterate (it:: ZipHead , state... )
320- isdone (it. a) === true && return nothing
321- a = iterate (it. a, state... )
322- a === nothing && return nothing
323- ((a[1 ],), a[2 ])
318+ # the states are either Tuple{} or Tuple{Any}
319+ @inline function zip_iterate (a, z, sta, stz)
320+ da, dz = isdone (a), isdone (z)
321+
322+ # Note that stateless iterators vectorize provided there's no early return.
323+ # In the case of stateless iterators: all branches are removed compile-time
324+ # In the case of stateful iterators: the first condition is almost always true
325+ if da === dz === missing || da === dz === false
326+ ya, yz = iterate (a, sta... ), iterate (z, stz... )
327+ ya === nothing && return nothing
328+ yz === nothing && return nothing
329+ elseif da === true || dz === true
330+ return nothing
331+ elseif da === missing
332+ # Iterate a only if z is not done and vice versa
333+ ya = iterate (a, sta... )
334+ ya === nothing && return nothing
335+ yz = iterate (z, stz... )
336+ yz === nothing && return nothing
337+ else
338+ yz = iterate (z, stz... )
339+ yz === nothing && return nothing
340+ ya = iterate (a, sta... )
341+ ya === nothing && return nothing
342+ end
343+
344+ return ya, yz
324345end
325346
326347@inline function iterate (it:: Zip )
327- isdone (it. a) === true && return nothing
328- isdone (it. z) === true && return nothing
329- a = iterate (it. a)
330- z = iterate (it. z)
331- a === nothing && return nothing
332- z === nothing && return nothing
333- ((a[1 ], z[1 ]. .. ), (a[2 ], z[2 ]))
348+ y = zip_iterate (it. a, it. z, (), ())
349+ y === nothing && return nothing
350+ (val_a, state_a), (val_z, state_z) = y
351+ return (val_a, val_z... ), (state_a, state_z)
334352end
335-
336- @inline function iterate (it:: Zip , state:: Tuple{Any, Any} )
353+ @inline function iterate (it:: Zip , s:: Tuple{Any, Any} )
354+ y = zip_iterate (it. a, it. z, (s[1 ],), (s[2 ],))
355+ y === nothing && return nothing
356+ (val_a, state_a), (val_z, state_z) = y
357+ return (val_a, val_z... ), (state_a, state_z)
358+ end
359+ @inline function iterate (it:: ZipHead , state... )
337360 isdone (it. a) === true && return nothing
338- isdone (it. z) === true && return nothing
339- a = iterate (it. a, state[1 ])
340- z = iterate (it. z, state[2 ])
361+ a = iterate (it. a, state... )
341362 a === nothing && return nothing
342- z === nothing && return nothing
343- ((a[1 ], z[1 ]. .. ), (a[2 ], z[2 ]))
363+ ((a[1 ],), a[2 ])
344364end
345365
346366# filter
0 commit comments