From 47e496f8bdae00fac236f53bf7cc2090954b9f3d Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Fri, 13 Jul 2018 12:35:10 -0500 Subject: [PATCH] Define promotion and conversion for CartesianIndices and LinearIndices (#28084) --- base/indices.jl | 11 +++++++++++ base/multidimensional.jl | 8 +++++++- test/abstractarray.jl | 8 ++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/base/indices.jl b/base/indices.jl index 5e1c858d87781..84830137db5c8 100644 --- a/base/indices.jl +++ b/base/indices.jl @@ -357,6 +357,17 @@ LinearIndices(inds::NTuple{N,Union{<:Integer,AbstractUnitRange{<:Integer}}}) whe LinearIndices(map(i->first(i):last(i), inds)) LinearIndices(A::Union{AbstractArray,SimpleVector}) = LinearIndices(axes(A)) +promote_rule(::Type{LinearIndices{N,R1}}, ::Type{LinearIndices{N,R2}}) where {N,R1,R2} = + LinearIndices{N,indices_promote_type(R1,R2)} + +function indices_promote_type(::Type{Tuple{R1,Vararg{R1,N}}}, ::Type{Tuple{R2,Vararg{R2,N}}}) where {R1,R2,N} + R = promote_type(R1, R2) + Tuple{R,Vararg{R,N}} +end + +convert(::Type{LinearIndices{N,R}}, inds::LinearIndices{N}) where {N,R} = + LinearIndices(convert(R, inds.indices)) + # AbstractArray implementation IndexStyle(::Type{<:LinearIndices}) = IndexLinear() axes(iter::LinearIndices) = map(axes1, iter.indices) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index fd8e8024e8b59..5fe078a47ca41 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -4,7 +4,7 @@ module IteratorsMD import .Base: eltype, length, size, first, last, in, getindex, setindex!, IndexStyle, min, max, zero, one, isless, eachindex, - ndims, IteratorSize, convert, show, iterate + ndims, IteratorSize, convert, show, iterate, promote_rule import .Base: +, -, * import .Base: simd_outer_range, simd_inner_length, simd_index @@ -228,6 +228,9 @@ module IteratorsMD CartesianIndices(A::AbstractArray) = CartesianIndices(axes(A)) + promote_rule(::Type{CartesianIndices{N,R1}}, ::Type{CartesianIndices{N,R2}}) where {N,R1,R2} = + CartesianIndices{N,Base.indices_promote_type(R1,R2)} + convert(::Type{Tuple{}}, R::CartesianIndices{0}) = () convert(::Type{NTuple{N,AbstractUnitRange{Int}}}, R::CartesianIndices{N}) where {N} = R.indices @@ -246,6 +249,9 @@ module IteratorsMD convert(::Type{Tuple{Vararg{UnitRange}}}, R::CartesianIndices) = convert(Tuple{Vararg{UnitRange{Int}}}, R) + convert(::Type{CartesianIndices{N,R}}, inds::CartesianIndices{N}) where {N,R} = + CartesianIndices(convert(R, inds.indices)) + # AbstractArray implementation Base.axes(iter::CartesianIndices{N,R}) where {N,R} = map(Base.axes1, iter.indices) Base.IndexStyle(::Type{CartesianIndices{N,R}}) where {N,R} = IndexCartesian() diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 36cfc8704ad1c..aff3e78e718ed 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -887,6 +887,14 @@ end @test CartesianIndices(fill(1., 2, 3)) == CartesianIndices((2,3)) @test LinearIndices((2,3)) == [1 3 5; 2 4 6] + + for IType in (CartesianIndices, LinearIndices) + I1 = IType((Base.OneTo(3),)) + I2 = IType((1:3,)) + @test !(I1 === I2) + J1, J2 = @inferred(promote(I1, I2)) + @test J1 === J2 + end end @testset "issue #25770" begin