@@ -357,13 +357,17 @@ module IteratorsMD
357
357
@propagate_inbounds function Base. getindex (iter:: CartesianIndices{0,R} ) where {R}
358
358
CartesianIndex ()
359
359
end
360
- @propagate_inbounds function Base. getindex (iter:: CartesianIndices{N,R} , I:: Vararg{Int, N} ) where {N,R}
361
- CartesianIndex (_get_cartesianindex .(iter. indices, I))
360
+ @inline function Base. getindex (iter:: CartesianIndices{N,R} , I:: Vararg{Int, N} ) where {N,R}
361
+ # Eagerly do boundscheck before calculating each item of the CartesianIndex,
362
+ # this generates inlined codes for `_get_cartesianindex` and furthermore enables SIMD
363
+ @boundscheck checkbounds (iter. indices, I)
364
+ @inbounds CartesianIndex (_get_cartesianindex (iter. indices, I))
362
365
end
363
- # specialize to gives better hint to compiler to enable SIMD (#42115)
364
- @inline _get_cartesianindex (:: OneTo , i:: Int ) = i
365
- @inline _get_cartesianindex (:: Base.IdentityUnitRange , i:: Int ) = i
366
- @inline _get_cartesianindex (r, i) = getindex (r, i)
366
+ @propagate_inbounds _get_cartesianindex (indices, I) = _get_cartesianindex (getindex (first (indices), first (I)), tail (indices), tail (I))
367
+ @propagate_inbounds function _get_cartesianindex (out, indices, I)
368
+ _get_cartesianindex ((out... , getindex (first (indices), first (I))), tail (indices), tail (I))
369
+ end
370
+ @inline _get_cartesianindex (out, :: Tuple{} , :: Tuple{} ) = out
367
371
368
372
# CartesianIndices act as a multidimensional range, so cartesian indexing of CartesianIndices
369
373
# with compatible dimensions may be seen as indexing into the component ranges.
0 commit comments