Repository: JuliaLang/julia
File: base/abstractarray.jl (Julia)

Code before:
        I[i, i] = unit
    end
    I
end

one(x::AbstractMatrix{T}) where {T} = _one(one(T), x)
oneunit(x::AbstractMatrix{T}) where {T} = _one(oneunit(T), x)

## iteration support for arrays by iterating over `eachindex` in the array ##
# Allows fast iteration by default for both IndexLinear and IndexCartesian arrays

# While the definitions for IndexLinear are all simple enough to inline on their
# own, IndexCartesian's CartesianIndices is more complicated and requires explicit
# inlining.
iterate_starting_state(A) = iterate_starting_state(A, IndexStyle(A))
iterate_starting_state(A, ::IndexLinear) = firstindex(A)
iterate_starting_state(A, ::IndexStyle) = (eachindex(A),)
@inline iterate(A::AbstractArray, state = iterate_starting_state(A)) = _iterate(A, state)
function _iterate(A::AbstractArray, state::Tuple)
    y = iterate(state...)
    y === nothing && return nothing
    A[y[1]], (state[1], tail(y)...)
end
function _iterate(A::AbstractArray, state::Integer)
    checkbounds(Bool, A, state) || return nothing
    A[state], state + one(state)
end

isempty(a::AbstractArray) = (length(a) == 0)


## range conversions ##

map(::Type{T}, r::StepRange) where {T<:Real} = T(r.start):T(r.step):T(last(r))
map(::Type{T}, r::UnitRange) where {T<:Real} = T(r.start):T(last(r))
map(::Type{T}, r::StepRangeLen) where {T<:AbstractFloat} = convert(StepRangeLen{T}, r)
function map(::Type{T}, r::LinRange) where T<:AbstractFloat
    LinRange(T(r.start), T(r.stop), length(r))
end

## unsafe/pointer conversions ##

# note: the following type definitions don't mean any AbstractArray is convertible to
# a data Ref. they just map the array element type to the pointer type for
# convenience in cases that work.
pointer(x::AbstractArray{T}) where {T} = unsafe_convert(Ptr{T}, cconvert(Ptr{T}, x))
function pointer(x::AbstractArray{T}, i::Integer) where T
    @inline
    pointer(x) + Int(_memory_offset(x, i))::Int
end


Review comment (performance):
Does removing the `@inbounds` impact performance here? I had added it originally because iterating over a view of an `Array` with a non-unit stride was slow without it

Code after:
    end
    I
end

one(x::AbstractMatrix{T}) where {T} = _one(one(T), x)
oneunit(x::AbstractMatrix{T}) where {T} = _one(oneunit(T), x)

## iteration support for arrays by iterating over `eachindex` in the array ##
# Allows fast iteration by default for both IndexLinear and IndexCartesian arrays

# While the definitions for IndexLinear are all simple enough to inline on their
# own, IndexCartesian's CartesianIndices is more complicated and requires explicit
# inlining.
iterate_starting_state(A) = iterate_starting_state(A, IndexStyle(A))
iterate_starting_state(A, ::IndexLinear) = firstindex(A)
iterate_starting_state(A, ::IndexStyle) = (eachindex(A),)
iterate(A::AbstractArray, state = iterate_starting_state(A)) = _iterate(A, state)
function _iterate(A::AbstractArray, state::Tuple)
    y = iterate(state...)
    y === nothing && return nothing
    A[y[1]], (state[1], tail(y)...)
end
function _iterate(A::AbstractArray, state::Integer)
    checkbounds(Bool, A, state) || return nothing
    @inbounds(A[state]), state + one(state)
end

isempty(a::AbstractArray) = (length(a) == 0)


## range conversions ##

map(::Type{T}, r::StepRange) where {T<:Real} = T(r.start):T(r.step):T(last(r))
map(::Type{T}, r::UnitRange) where {T<:Real} = T(r.start):T(last(r))
map(::Type{T}, r::StepRangeLen) where {T<:AbstractFloat} = convert(StepRangeLen{T}, r)
function map(::Type{T}, r::LinRange) where T<:AbstractFloat
    LinRange(T(r.start), T(r.stop), length(r))
end

## unsafe/pointer conversions ##

# note: the following type definitions don't mean any AbstractArray is convertible to
# a data Ref. they just map the array element type to the pointer type for
# convenience in cases that work.
pointer(x::AbstractArray{T}) where {T} = unsafe_convert(Ptr{T}, cconvert(Ptr{T}, x))
function pointer(x::AbstractArray{T}, i::Integer) where T
    @inline
    pointer(x) + Int(_memory_offset(x, i))::Int
end

# The distance from pointer(x) to the element at x[I...] in bytes