diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 8df892a1e3fe4a..15a40748275adc 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -185,7 +185,7 @@ module IteratorsMD CartesianIndex(2, 2, 2) ``` """ - struct CartesianRange{N,R<:NTuple{N,AbstractUnitRange{Int}}} + struct CartesianRange{N,R<:NTuple{N,AbstractUnitRange{Int}}} <: AbstractArray{CartesianIndex{N},N} indices::R end @@ -222,6 +222,10 @@ module IteratorsMD convert(::Type{Tuple{Vararg{UnitRange}}}, R::CartesianRange) = convert(Tuple{Vararg{UnitRange{Int}}}, R) + # AbstractArray implementation + Base.IndexStyle(::Type{CartesianRange{N,R}}) where {N,R} = IndexCartesian() + @inline Base.getindex(iter::CartesianRange{N,R}, I::Vararg{Int, N}) where {N,R} = CartesianIndex(first.(iter.indices) .- 1) + CartesianIndex(I) + ndims(R::CartesianRange) = ndims(typeof(R)) ndims(::Type{CartesianRange{N}}) where {N} = N ndims(::Type{CartesianRange{N,TT}}) where {N,TT} = N diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 6e852a90c5b225..cf834b5ff9e03d 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -877,3 +877,21 @@ end Z = Array{Int}(); Z[] = 17 @test Z == collect(Z) == copy(Z) end + +@testset "CartesianRange" begin + xrng = 2:4 + yrng = 1:5 + CR = CartesianRange((xrng,yrng)) + + for (i,i_idx) in enumerate(xrng) + for (j,j_idx) in enumerate(yrng) + @test CR[i,j] == CartesianIndex(i_idx,j_idx) + end + end + + for i_lin in linearindices(CR) + i = (i_lin-1) % length(xrng) + 1 + j = (i_lin-i) รท length(xrng) + 1 + @test CR[i_lin] == CartesianIndex(xrng[i],yrng[j]) + end +end