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

Code before:
function getindex(v::AbstractRange{T}, i::Integer) where T
    @inline
    i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
    @boundscheck checkbounds(v, i)
    convert(T, first(v) + (i - oneunit(i))*step_hp(v))
end

let BitInteger64 = Union{Int8,Int16,Int32,Int64,UInt8,UInt16,UInt32,UInt64} # for bootstrapping
    function checkbounds(::Type{Bool}, v::StepRange{<:BitInteger64, <:BitInteger64}, i::BitInteger64)
        @inline
        res = widemul(step(v), i-oneunit(i)) + first(v)
        (0 < i) & ifelse(0 < step(v), res <= last(v), res >= last(v))
    end
end

function getindex(r::Union{StepRangeLen,LinRange}, i::Integer)
    @inline
    i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
    @boundscheck checkbounds(r, i)
    unsafe_getindex(r, i)
end

# This is separate to make it useful even when running with --check-bounds=yes
function unsafe_getindex(r::StepRangeLen{T}, i::Integer) where T
    i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
    if i < r.offset # 1 <= offset <= len && 1 <= i <= len
        u = r.offset - i
        return T(r.ref - u*r.step)
    else
        u = i - r.offset
        return T(r.ref + u*r.step)
    end
end

function _getindex_hiprec(r::StepRangeLen, i::Integer)  # without rounding by T
    i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
    if i < r.offset # 1 <= offset <= len && 1 <= i <= len
        u = r.offset - i
        return r.ref - u*r.step
    else
        u = i - r.offset
        return r.ref + u*r.step
    end
end

function unsafe_getindex(r::LinRange, i::Integer)
    i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
    lerpi(i-oneunit(i), r.lendiv, r.start, r.stop)
end

function lerpi(j::Integer, d::Integer, a::T, b::T) where T

Review comment (suggestion):
I wonder if a better fix would be
```julia
    u = oftype(r.offset, i) - r.offset
```
since if the number wasn't representable as the type of the offset, then it was out of bounds anyways. and this cast should typically be free.

Code after:
function getindex(v::AbstractRange{T}, i::Integer) where T
    @inline
    i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
    @boundscheck checkbounds(v, i)
    convert(T, first(v) + (i - oneunit(i))*step_hp(v))
end

let BitInteger64 = Union{Int8,Int16,Int32,Int64,UInt8,UInt16,UInt32,UInt64} # for bootstrapping
    function checkbounds(::Type{Bool}, v::StepRange{<:BitInteger64, <:BitInteger64}, i::BitInteger64)
        @inline
        res = widemul(step(v), i-oneunit(i)) + first(v)
        (0 < i) & ifelse(0 < step(v), res <= last(v), res >= last(v))
    end
end

function getindex(r::Union{StepRangeLen,LinRange}, i::Integer)
    @inline
    i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
    @boundscheck checkbounds(r, i)
    unsafe_getindex(r, i)
end

# This is separate to make it useful even when running with --check-bounds=yes
function unsafe_getindex(r::StepRangeLen{T}, i::Integer) where T
    i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
    u = oftype(r.offset, i) - r.offset
    T(r.ref + u*r.step)
end

function _getindex_hiprec(r::StepRangeLen, i::Integer)  # without rounding by T
    i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
    u = oftype(r.offset, i) - r.offset
    r.ref + u*r.step
end

function unsafe_getindex(r::LinRange, i::Integer)
    i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
    lerpi(i-oneunit(i), r.lendiv, r.start, r.stop)
end

function lerpi(j::Integer, d::Integer, a::T, b::T) where T
    @inline
    t = j/d # ∈ [0,1]
    # compute approximately fma(t, b, -fma(t, a, a))
    return T((1-t)*a + t*b)
end

getindex(r::AbstractRange, ::Colon) = copy(r)

function getindex(r::AbstractUnitRange, s::AbstractUnitRange{T}) where {T<:Integer}
    @inline