Skip to content

Commit 24ecff6

Browse files
committed
Update multidimensional.jl
1. improve CartesianIndices 2. retain to_index Update multidimensional.jl Update abstractarray.jl add test
1 parent 1256ff4 commit 24ecff6

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

base/multidimensional.jl

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
### Multidimensional iterators
44
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
88

99
import .Base: +, -, *, (:)
1010
import .Base: simd_outer_range, simd_inner_length, simd_index, setindex
@@ -465,8 +465,10 @@ module IteratorsMD
465465
last(iter::CartesianIndices) = CartesianIndex(map(last, iter.indices))
466466

467467
# 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
470472
# but preserve CartesianIndices{0} as they consume a dimension.
471473
@inline to_indices(A, inds, I::Tuple{CartesianIndices{0},Vararg{Any}}) =
472474
(first(I), to_indices(A, inds, tail(I))...)
@@ -835,10 +837,12 @@ ensure_indexable(I::Tuple{}) = ()
835837
# until Julia gets smart enough to elide the call on its own:
836838
@inline to_indices(A, I::Tuple{Vararg{Union{Integer, CartesianIndex}}}) = to_indices(A, (), I)
837839
# 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
842846
@inline function to_indices(A, inds, I::Tuple{AbstractArray{CartesianIndex{N}}, Vararg{Any}}) where N
843847
_, indstail = IteratorsMD.split(inds, Val(N))
844848
(to_index(A, I[1]), to_indices(A, indstail, tail(I))...)

test/abstractarray.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,3 +1577,9 @@ end
15771577

15781578
@test haskey([1, 2, 3], 1)
15791579
@test !haskey([1, 2, 3], 4)
1580+
1581+
@testset "to_indices inference #42001" begin
1582+
@test only(Base.return_types(to_indices,(Array{Any,0}, NTuple{32,CartesianIndex{1}}))) == NTuple{32,Int}
1583+
@test only(Base.return_types(to_indices,(Array{Any,0}, NTuple{32,CartesianIndices{1,Tuple{Base.OneTo{Int}}}}))) == NTuple{32, Base.OneTo{Int}}
1584+
@test only(Base.return_types(to_indices,(Array{Any,0}, Tuple{CartesianIndex{0},Int,CartesianIndex{3}}))) == NTuple{4,Int}
1585+
end

0 commit comments

Comments
 (0)