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

Code before:
    (rows, cols) = axes(mat)
    (length(rows) == length(cols)) ||
      throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
    zer = zero(unit)::T
    require_one_based_indexing(mat)
    I = similar(mat, T)
    fill!(I, zer)
    for i ∈ rows
        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

Review comment (suggestion):
I'm not entirely sure about adding this `@inline`, but it was used in `Array` and `Memory` methods already.

Code after:
    (length(rows) == length(cols)) ||
      throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
    zer = zero(unit)::T
    require_one_based_indexing(mat)
    I = similar(mat, T)
    fill!(I, zer)
    for i ∈ rows
        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),)
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