diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 45aecd26a2d25..2fe9735c6a56a 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -137,13 +137,12 @@ end Expr(:block, Expr(:meta, :inline), ex) end -_checkbounds(sz, i::Integer) = 1 <= i <= sz -_checkbounds(sz, i::Real) = 1 <= to_index(i) <= sz -_checkbounds(sz, I::AbstractVector{Bool}) = length(I) == sz -_checkbounds(sz, r::Range{Int}) = (@_inline_meta; isempty(r) || (minimum(r) >= 1 && maximum(r) <= sz)) -_checkbounds{T<:Real}(sz, r::Range{T}) = (@_inline_meta; _checkbounds(sz, to_index(r))) +_checkbounds(sz, i) = throw(ArgumentError("unable to check bounds for indices of type $(typeof(i))")) +_checkbounds(sz, i::Real) = 1 <= i <= sz _checkbounds(sz, ::Colon) = true -function _checkbounds{T <: Real}(sz, I::AbstractArray{T}) +_checkbounds(sz, r::Range) = (@_inline_meta; isempty(r) || (_checkbounds(sz, minimum(r)) && _checkbounds(sz,maximum(r)))) +_checkbounds(sz, I::AbstractVector{Bool}) = length(I) == sz +function _checkbounds(sz, I::AbstractArray) @_inline_meta b = true for i in I @@ -487,8 +486,9 @@ _getindex(::LinearFast, A::AbstractArray, I::Int) = error("indexing not defined function _getindex(::LinearFast, A::AbstractArray, I::Real...) @_inline_meta # We must check bounds for sub2ind; so we can then call unsafe_getindex - checkbounds(A, I...) - unsafe_getindex(A, sub2ind(size(A), to_indexes(I...)...)) + J = to_indexes(I...) + checkbounds(A, J...) + unsafe_getindex(A, sub2ind(size(A), J...)) end _unsafe_getindex(::LinearFast, A::AbstractArray, I::Int) = (@_inline_meta; getindex(A, I)) function _unsafe_getindex(::LinearFast, A::AbstractArray, I::Real...) @@ -512,19 +512,20 @@ end end else # Expand the last index into the appropriate number of indices - Isplat = Expr[:(to_index(I[$d])) for d = 1:N-1] + Jsplat = Expr[:(J[$d]) for d = 1:N-1] i = 0 for d=N:AN - push!(Isplat, :(s[$(i+=1)])) + push!(Jsplat, :(s[$(i+=1)])) end sz = Expr(:tuple) sz.args = Expr[:(size(A, $d)) for d=N:AN] quote $(Expr(:meta, :inline)) # ind2sub requires all dimensions to be nonzero, so checkbounds first - checkbounds(A, I...) - s = ind2sub($sz, to_index(I[$N])) - unsafe_getindex(A, $(Isplat...)) + J = to_indexes(I...) + checkbounds(A, J...) + s = ind2sub($sz, J[$N]) + unsafe_getindex(A, $(Jsplat...)) end end end @@ -583,8 +584,9 @@ _setindex!(::LinearFast, A::AbstractArray, v, I::Int) = error("indexed assignmen function _setindex!(::LinearFast, A::AbstractArray, v, I::Real...) @_inline_meta # We must check bounds for sub2ind; so we can then call unsafe_setindex! - checkbounds(A, I...) - unsafe_setindex!(A, v, sub2ind(size(A), to_indexes(I...)...)) + J = to_indexes(I...) + checkbounds(A, J...) + unsafe_setindex!(A, v, sub2ind(size(A), J...)) end _unsafe_setindex!(::LinearFast, A::AbstractArray, v, I::Int) = (@_inline_meta; setindex!(A, v, I)) function _unsafe_setindex!(::LinearFast, A::AbstractArray, v, I::Real...) @@ -608,18 +610,19 @@ end end else # Expand the last index into the appropriate number of indices - Isplat = Expr[:(to_index(I[$d])) for d = 1:N-1] + Jsplat = Expr[:(J[$d]) for d = 1:N-1] i = 0 for d=N:AN - push!(Isplat, :(s[$(i+=1)])) + push!(Jsplat, :(s[$(i+=1)])) end sz = Expr(:tuple) sz.args = Expr[:(size(A, $d)) for d=N:AN] quote $(Expr(:meta, :inline)) - checkbounds(A, I...) + J = to_indexes(I...) + checkbounds(A, J...) s = ind2sub($sz, to_index(I[$N])) - unsafe_setindex!(A, v, $(Isplat...)) + unsafe_setindex!(A, v, $(Jsplat...)) end end end diff --git a/base/deprecated.jl b/base/deprecated.jl index dad7aac7da3f9..522033020f820 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -417,16 +417,7 @@ function to_index(i::Real) to_index_nodep(i) end -function to_index{T<:Real}(r::UnitRange{T}) - depwarn("indexing with non Integer UnitRanges is deprecated", :to_index) - to_index_nodep(first(r)):to_index_nodep(last(r)) -end - -function to_index{T<:Real}(r::StepRange{T}) - depwarn("indexing with non Integer StepRanges is deprecated", :to_index) - to_index_nodep(first(r)):to_index_nodep(step(r)):to_index_nodep(last(r)) -end - +to_index{T<:Integer}(A::AbstractArray{T}) = A function to_index{T<:Real}(A::AbstractArray{T}) depwarn("indexing with non Integer AbstractArrays is deprecated", :to_index) Int[to_index_nodep(x) for x in A] diff --git a/base/operators.jl b/base/operators.jl index 961e32c640539..50dd4b9e409cb 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -303,20 +303,15 @@ function setindex_shape_check{T}(X::AbstractArray{T,2}, i::Int, j::Int) end setindex_shape_check(X, I::Int...) = nothing # Non-arrays broadcast to all idxs -# convert to integer index +# convert to a supported index type (Array, Colon, or Int) to_index(i::Int) = i to_index(i::Integer) = convert(Int,i)::Int -to_index(r::UnitRange{Int}) = r -to_index(r::Range{Int}) = r -to_index(I::UnitRange{Bool}) = find(I) -to_index(I::Range{Bool}) = find(I) -to_index{T<:Integer}(r::UnitRange{T}) = to_index(first(r)):to_index(last(r)) -to_index{T<:Integer}(r::StepRange{T}) = to_index(first(r)):to_index(step(r)):to_index(last(r)) to_index(c::Colon) = c to_index(I::AbstractArray{Bool}) = find(I) -to_index(A::AbstractArray{Int}) = A -to_index{T<:Integer}(A::AbstractArray{T}) = [to_index(x) for x in A] -to_index(i) = error("invalid index: $i") +to_index(A::AbstractArray) = A +to_index{T<:AbstractArray}(A::AbstractArray{T}) = throw(ArgumentError("invalid index: $A")) +to_index(A::AbstractArray{Colon}) = throw(ArgumentError("invalid index: $A")) +to_index(i) = throw(ArgumentError("invalid index: $i")) to_indexes() = () to_indexes(i1) = (to_index(i1),) diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 8b808de58cbb6..af13bdaaf2434 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -193,6 +193,9 @@ function test_vector_indexing{T}(::Type{T}, shape, ::Type{TestAbstractArray}) @test B[1:end] == A[1:end] == collect(1:N) @test B[:,:] == A[:,:] == reshape(1:N, shape[1], prod(shape[2:end])) @test B[1:end,1:end] == A[1:end,1:end] == reshape(1:N, shape[1], prod(shape[2:end])) + # Test with containers that aren't Int[] + @test B[[]] == A[[]] == [] + @test B[convert(Array{Any}, idxs)] == A[convert(Array{Any}, idxs)] == idxs end function test_primitives{T}(::Type{T}, shape, ::Type{TestAbstractArray})