Skip to content

Commit

Permalink
Define promotion and conversion for CartesianIndices and LinearIndices (
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy authored and mbauman committed Jul 13, 2018
1 parent a5a4e99 commit 47e496f
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 1 deletion.
11 changes: 11 additions & 0 deletions base/indices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 7 additions & 1 deletion base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand Down
8 changes: 8 additions & 0 deletions test/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 47e496f

Please sign in to comment.