Skip to content

Commit

Permalink
Eagerly do boundscheck when indexing CartesianIndices with CartesianI…
Browse files Browse the repository at this point in the history
…ndices
  • Loading branch information
johnnychen94 authored and N5N3 committed Dec 1, 2021
1 parent 5a3e95d commit d112903
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
11 changes: 8 additions & 3 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,19 @@ module IteratorsMD
# CartesianIndices act as a multidimensional range, so cartesian indexing of CartesianIndices
# with compatible dimensions may be seen as indexing into the component ranges.
# This may use the special indexing behavior implemented for ranges to return another CartesianIndices
@propagate_inbounds function Base.getindex(iter::CartesianIndices{N,R},
@inline function Base.getindex(iter::CartesianIndices{N,R},
I::Vararg{Union{OrdinalRange{<:Integer, <:Integer}, Colon}, N}) where {N,R}
CartesianIndices(getindex.(iter.indices, I))
@boundscheck checkbounds(iter, I...)
indices = map(iter.indices, I) do r, i
@inbounds getindex(r, i)
end
CartesianIndices(indices)
end
@propagate_inbounds function Base.getindex(iter::CartesianIndices{N},
C::CartesianIndices{N}) where {N}
CartesianIndices(getindex.(iter.indices, C.indices))
getindex(iter, C.indices...)
end
@inline Base.getindex(iter::CartesianIndices{0}, ::CartesianIndices{0}) = iter

# If dimensions permit, we may index into a CartesianIndices directly instead of constructing a SubArray wrapper
@propagate_inbounds function Base.view(c::CartesianIndices{N}, r::Vararg{Union{OrdinalRange{<:Integer, <:Integer}, Colon},N}) where {N}
Expand Down
9 changes: 9 additions & 0 deletions test/boundscheck_exec.jl
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ if bc_opt == bc_default || bc_opt == bc_off
end

@testset "pass inbounds meta to getindex on CartesianIndices (#42115)" begin
@inline getindex_42115(r, i) = @inbounds getindex(r, i)
@inline getindex_42115(r, i, j) = @inbounds getindex(r, i, j)

R = CartesianIndices((5, 5))
Expand All @@ -270,6 +271,14 @@ end
@test getindex_42115(R, -1, -1) == CartesianIndex(-1, -1)
@test getindex_42115(R, 1, -1) == CartesianIndex(1, -1)
end

if bc_opt == bc_on
@test_throws BoundsError getindex_42115(R, CartesianIndices((6, 6)))
@test_throws BoundsError getindex_42115(R, -1:3, :)
else
@test getindex_42115(R, CartesianIndices((6, 6))) == CartesianIndices((6, 6))
@test getindex_42115(R, -1:3, :) == CartesianIndices((-1:3, 1:5))
end
end

end

0 comments on commit d112903

Please sign in to comment.