|
2 | 2 |
|
3 | 3 | ### Multidimensional iterators
|
4 | 4 | module IteratorsMD
|
5 |
| - import .Base: eltype, length, size, first, last, in, getindex, |
6 |
| - setindex!, IndexStyle, min, max, zero, oneunit, isless, eachindex, |
7 |
| - ndims, IteratorSize, convert, show, iterate, promote_rule, to_indices |
| 5 | + import .Base: eltype, length, size, first, last, in, getindex, setindex!, IndexStyle, |
| 6 | + min, max, zero, oneunit, isless, eachindex, ndims, IteratorSize, |
| 7 | + convert, show, iterate, promote_rule, to_indices, to_index |
8 | 8 |
|
9 | 9 | import .Base: +, -, *, (:)
|
10 | 10 | import .Base: simd_outer_range, simd_inner_length, simd_index, setindex
|
@@ -465,8 +465,10 @@ module IteratorsMD
|
465 | 465 | last(iter::CartesianIndices) = CartesianIndex(map(last, iter.indices))
|
466 | 466 |
|
467 | 467 | # When used as indices themselves, CartesianIndices can simply become its tuple of ranges
|
468 |
| - @inline to_indices(A, inds, I::Tuple{CartesianIndices, Vararg{Any}}) = |
469 |
| - to_indices(A, inds, (I[1].indices..., tail(I)...)) |
| 468 | + @inline function to_indices(A, inds, I::Tuple{CartesianIndices{N}, Vararg{Any}}) where N |
| 469 | + _, indstail = split(inds, Val(N)) |
| 470 | + (map(i -> to_index(A, i), I[1].indices)..., to_indices(A, indstail, tail(I))...) |
| 471 | + end |
470 | 472 | # but preserve CartesianIndices{0} as they consume a dimension.
|
471 | 473 | @inline to_indices(A, inds, I::Tuple{CartesianIndices{0},Vararg{Any}}) =
|
472 | 474 | (first(I), to_indices(A, inds, tail(I))...)
|
@@ -835,10 +837,12 @@ ensure_indexable(I::Tuple{}) = ()
|
835 | 837 | # until Julia gets smart enough to elide the call on its own:
|
836 | 838 | @inline to_indices(A, I::Tuple{Vararg{Union{Integer, CartesianIndex}}}) = to_indices(A, (), I)
|
837 | 839 | # But some index types require more context spanning multiple indices
|
838 |
| -# CartesianIndexes are simple; they just splat out |
839 |
| -@inline to_indices(A, inds, I::Tuple{CartesianIndex, Vararg{Any}}) = |
840 |
| - to_indices(A, inds, (I[1].I..., tail(I)...)) |
841 |
| -# But for arrays of CartesianIndex, we just skip the appropriate number of inds |
| 840 | +# CartesianIndex is unfolded outside the inner to_indices for better inference |
| 841 | +@inline function to_indices(A, inds, I::Tuple{CartesianIndex{N}, Vararg{Any}}) where N |
| 842 | + _, indstail = IteratorsMD.split(inds, Val(N)) |
| 843 | + (map(i -> to_index(A, i), I[1].I)..., to_indices(A, indstail, tail(I))...) |
| 844 | +end |
| 845 | +# For arrays of CartesianIndex, we just skip the appropriate number of inds |
842 | 846 | @inline function to_indices(A, inds, I::Tuple{AbstractArray{CartesianIndex{N}}, Vararg{Any}}) where N
|
843 | 847 | _, indstail = IteratorsMD.split(inds, Val(N))
|
844 | 848 | (to_index(A, I[1]), to_indices(A, indstail, tail(I))...)
|
|
0 commit comments