Skip to content

Commit 5d106c5

Browse files
jishnubKristofferC
authored andcommitted
Define in for CartesianIndex ranges (#58616)
Currently, this hits a fallback method that assumes that division is defined for the elements of the range. After this, the following works: ```julia julia> r = StepRangeLen(CartesianIndex(1), CartesianIndex(1), 3); julia> r[1] in r true julia> CartesianIndex(0) in r false ``` (cherry picked from commit 24b3273)
1 parent f388837 commit 5d106c5

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

base/multidimensional.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,24 @@ module IteratorsMD
183183
step(r), ", ", length(r), ")")
184184
end
185185

186+
Base.in(x::CartesianIndex, r::AbstractRange{<:CartesianIndex}) = false
187+
function Base.in(x::CartesianIndex{N}, r::AbstractRange{CartesianIndex{N}}) where {N}
188+
isempty(r) && return false
189+
f, st, l = first(r), step(r), last(r)
190+
# The n-th element of the range is a CartesianIndex
191+
# whose elements are the n-th along each dimension
192+
# Find the first dimension along which the index is changing,
193+
# so that n may be uniquely determined
194+
for i in 1:N
195+
iszero(st[i]) && continue
196+
n = findfirst(==(x[i]), f[i]:st[i]:l[i])
197+
isnothing(n) && return false
198+
return r[n] == x
199+
end
200+
# if the step is zero, the elements are identical, so compare with the first
201+
return x == f
202+
end
203+
186204
# Iteration
187205
const OrdinalRangeInt = OrdinalRange{Int, Int}
188206
"""

test/cartesian.jl

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,3 +573,57 @@ end
573573
end
574574
@test t3 == (1, 2, 0)
575575
end
576+
577+
@testset "CartesianIndex show" begin
578+
c = CartesianIndex()
579+
@test sprint(show, c) == "CartesianIndex()"
580+
c = CartesianIndex(3)
581+
@test sprint(show, c) == "CartesianIndex(3)"
582+
c = CartesianIndex(3, 3)
583+
@test sprint(show, c) == "CartesianIndex(3, 3)"
584+
end
585+
586+
@testset "CartesianIndex indexing with begin/end" begin
587+
I = CartesianIndex(3,4)
588+
@test I[begin] == I[1]
589+
@test I[end] == I[2]
590+
end
591+
592+
@testset "in for a CartesianIndex StepRangeLen" begin
593+
@testset for l in [0, 1, 4], r in Any[
594+
StepRangeLen(CartesianIndex(), CartesianIndex(), l),
595+
StepRangeLen(CartesianIndex(1), CartesianIndex(0), l),
596+
StepRangeLen(CartesianIndex(1), CartesianIndex(1), l),
597+
StepRangeLen(CartesianIndex(1), CartesianIndex(4), l),
598+
StepRangeLen(CartesianIndex(1), CartesianIndex(-4), l),
599+
StepRangeLen(CartesianIndex(-1, 2), CartesianIndex(0, 0), l),
600+
StepRangeLen(CartesianIndex(-1, 2), CartesianIndex(0, 4), l),
601+
StepRangeLen(CartesianIndex(-1, 2), CartesianIndex(0, -4), l),
602+
StepRangeLen(CartesianIndex(-1, 2), CartesianIndex(4, 0), l),
603+
StepRangeLen(CartesianIndex(-1, 2), CartesianIndex(-4, 0), l),
604+
StepRangeLen(CartesianIndex(-1, 2), CartesianIndex(4, 2), l),
605+
StepRangeLen(CartesianIndex(-1, 2), CartesianIndex(-4, 2), l),
606+
StepRangeLen(CartesianIndex(-1, 2), CartesianIndex(4, -2), l),
607+
StepRangeLen(CartesianIndex(-1, 2), CartesianIndex(-4, -2), l),
608+
StepRangeLen(CartesianIndex(-1, 2, 0), CartesianIndex(0, 0, 0), l),
609+
StepRangeLen(CartesianIndex(-1, 2, 0), CartesianIndex(0, 0, -2), l),
610+
]
611+
612+
if length(r) == 0
613+
@test !(first(r) in r)
614+
@test !(last(r) in r)
615+
end
616+
for x in r
617+
@test x in r
618+
if step(r) != oneunit(x)
619+
@test !((x + oneunit(x)) in r)
620+
end
621+
end
622+
@test !(CartesianIndex(ntuple(x->0, ndims(r))) in r)
623+
@test !(CartesianIndex(ntuple(x->typemax(Int), ndims(r))) in r)
624+
@test !(CartesianIndex(ntuple(x->typemin(Int), ndims(r))) in r)
625+
if ndims(r) > 1
626+
@test !(CartesianIndex(ntuple(x->0, ndims(r)-1)...) in r)
627+
end
628+
end
629+
end

0 commit comments

Comments
 (0)