@@ -95,6 +95,9 @@ module IteratorsMD
95
95
# access to index tuple
96
96
Tuple (index:: CartesianIndex ) = index. I
97
97
98
+ # equality
99
+ Base.:(== )(a:: CartesianIndex{N} , b:: CartesianIndex{N} ) where N = a. I == b. I
100
+
98
101
# zeros and ones
99
102
zero (:: CartesianIndex{N} ) where {N} = zero (CartesianIndex{N})
100
103
zero (:: Type{CartesianIndex{N}} ) where {N} = CartesianIndex (ntuple (x -> 0 , Val (N)))
@@ -142,11 +145,15 @@ module IteratorsMD
142
145
# nextind and prevind with CartesianIndex
143
146
function Base. nextind (a:: AbstractArray{<:Any,N} , i:: CartesianIndex{N} ) where {N}
144
147
iter = CartesianIndices (axes (a))
145
- return CartesianIndex (inc (i. I, first (iter). I, last (iter). I))
148
+ # might overflow
149
+ I = inc (i. I, first (iter). I, last (iter). I)
150
+ return I
146
151
end
147
152
function Base. prevind (a:: AbstractArray{<:Any,N} , i:: CartesianIndex{N} ) where {N}
148
153
iter = CartesianIndices (axes (a))
149
- return CartesianIndex (dec (i. I, last (iter). I, first (iter). I))
154
+ # might underflow
155
+ I = dec (i. I, last (iter). I, first (iter). I)
156
+ return I
150
157
end
151
158
152
159
# Iteration over the elements of CartesianIndex cannot be supported until its length can be inferred,
@@ -334,20 +341,30 @@ module IteratorsMD
334
341
iterfirst, iterfirst
335
342
end
336
343
@inline function iterate (iter:: CartesianIndices , state)
337
- nextstate = CartesianIndex ( inc ( state. I, first (iter). I, last (iter). I) )
338
- nextstate . I[ end ] > last (iter . indices[ end ]) && return nothing
339
- nextstate, nextstate
344
+ valid, I = __inc ( state. I, first (iter). I, last (iter). I)
345
+ valid || return nothing
346
+ return CartesianIndex (I ... ), CartesianIndex (I ... )
340
347
end
341
348
342
349
# increment & carry
343
- @inline inc (:: Tuple{} , :: Tuple{} , :: Tuple{} ) = ()
344
- @inline inc (state:: Tuple{Int} , start:: Tuple{Int} , stop:: Tuple{Int} ) = (state[1 ]+ 1 ,)
345
350
@inline function inc (state, start, stop)
351
+ _, I = __inc (state, start, stop)
352
+ return CartesianIndex (I... )
353
+ end
354
+
355
+ # increment post check to avoid integer overflow
356
+ @inline __inc (:: Tuple{} , :: Tuple{} , :: Tuple{} ) = false , ()
357
+ @inline function __inc (state:: Tuple{Int} , start:: Tuple{Int} , stop:: Tuple{Int} )
358
+ valid = state[1 ] < stop[1 ]
359
+ return valid, (state[1 ]+ 1 ,)
360
+ end
361
+
362
+ @inline function __inc (state, start, stop)
346
363
if state[1 ] < stop[1 ]
347
- return (state[1 ]+ 1 ,tail (state)... )
364
+ return true , (state[1 ]+ 1 , tail (state)... )
348
365
end
349
- newtail = inc (tail (state), tail (start), tail (stop))
350
- (start[1 ], newtail ... )
366
+ valid, I = __inc (tail (state), tail (start), tail (stop))
367
+ return valid, (start[1 ], I ... )
351
368
end
352
369
353
370
# 0-d cartesian ranges are special-cased to iterate once and only once
@@ -414,21 +431,32 @@ module IteratorsMD
414
431
iterfirst, iterfirst
415
432
end
416
433
@inline function iterate (r:: Reverse{<:CartesianIndices} , state)
417
- nextstate = CartesianIndex ( dec ( state. I, last (r. itr). I, first (r. itr). I) )
418
- nextstate . I[ end ] < first (r . itr . indices[ end ]) && return nothing
419
- nextstate, nextstate
434
+ valid, I = __dec ( state. I, last (r. itr). I, first (r. itr). I)
435
+ valid || return nothing
436
+ return CartesianIndex (I ... ), CartesianIndex (I ... )
420
437
end
421
438
422
439
# decrement & carry
423
- @inline dec (:: Tuple{} , :: Tuple{} , :: Tuple{} ) = ()
424
- @inline dec (state:: Tuple{Int} , start:: Tuple{Int} , stop:: Tuple{Int} ) = (state[1 ]- 1 ,)
425
440
@inline function dec (state, start, stop)
441
+ _, I = __dec (state, start, stop)
442
+ return CartesianIndex (I... )
443
+ end
444
+
445
+ # decrement post check to avoid integer overflow
446
+ @inline __dec (:: Tuple{} , :: Tuple{} , :: Tuple{} ) = false , ()
447
+ @inline function __dec (state:: Tuple{Int} , start:: Tuple{Int} , stop:: Tuple{Int} )
448
+ valid = state[1 ] > stop[1 ]
449
+ return valid, (state[1 ]- 1 ,)
450
+ end
451
+
452
+ @inline function __dec (state, start, stop)
426
453
if state[1 ] > stop[1 ]
427
- return (state[1 ]- 1 ,tail (state)... )
454
+ return true , (state[1 ]- 1 , tail (state)... )
428
455
end
429
- newtail = dec (tail (state), tail (start), tail (stop))
430
- (start[1 ], newtail ... )
456
+ valid, I = __dec (tail (state), tail (start), tail (stop))
457
+ return valid, (start[1 ], I ... )
431
458
end
459
+
432
460
# 0-d cartesian ranges are special-cased to iterate once and only once
433
461
iterate (iter:: Reverse{<:CartesianIndices{0}} , state= false ) = state ? nothing : (CartesianIndex (), true )
434
462
0 commit comments