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

Code before:
    end
    return Integer(a)
end

length(r::OneTo) = Integer(r.stop - zero(r.stop))
length(r::StepRangeLen) = r.len
length(r::LinRange) = r.len

let bigints = Union{Int, UInt, Int64, UInt64, Int128, UInt128},
    smallints = (Int === Int64 ?
                Union{Int8, UInt8, Int16, UInt16, Int32, UInt32} :
                Union{Int8, UInt8, Int16, UInt16}),
    bitints = Union{bigints, smallints}
    global length, checked_length, firstindex
    # compile optimization for which promote_type(T, Int) == T
    length(r::OneTo{T}) where {T<:bigints} = r.stop
    # slightly more accurate length and checked_length in extreme cases
    # (near typemax) for types with known `unsigned` functions
    function length(r::OrdinalRange{T}) where T<:bigints
        s = step(r)
        diff = last(r) - first(r)
        isempty(r) && return zero(diff)
        # compute `(diff ÷ s) + 1` in a manner robust to overflow
        # by using the absolute values as unsigneds for non-empty ranges
        a = div(unsigned(flipsign(diff, s)), unsigned(abs(s))) % typeof(diff)
        return max(a + oneunit(a), zero(a))
    end
    function checked_length(r::OrdinalRange{T}) where T<:bigints
        s = step(r)
        stop, start = last(r), first(r)
        ET = promote_type(typeof(stop), typeof(start))
        isempty(r) && return zero(ET)
        # n.b. !(s isa T)
        if s > 1
            diff = stop - start
            a = convert(ET, div(unsigned(diff), s))
        elseif s < -1
            diff = start - stop
            a = convert(ET, div(unsigned(diff), -s))
        elseif s > 0
            a = convert(ET, div(checked_sub(stop, start), s))
        else
            a = convert(ET, div(checked_sub(start, stop), -s))
        end
        return checked_add(a, oneunit(a))
    end
    firstindex(r::StepRange{<:bigints,<:bitints}) = one(last(r)-first(r))

    # some special cases to favor default Int type
    function length(r::OrdinalRange{<:smallints})
        s = step(r)

Review comment (suggestion):
```suggestion
        return a + oneunit(a)
```

Oops, this was leftover from me trying to remove the isempty branch, but that doesn't work.

Code after:
    end
    return Integer(a)
end

length(r::OneTo) = Integer(r.stop - zero(r.stop))
length(r::StepRangeLen) = r.len
length(r::LinRange) = r.len

let bigints = Union{Int, UInt, Int64, UInt64, Int128, UInt128},
    smallints = (Int === Int64 ?
                Union{Int8, UInt8, Int16, UInt16, Int32, UInt32} :
                Union{Int8, UInt8, Int16, UInt16}),
    bitints = Union{bigints, smallints}
    global length, checked_length, firstindex
    # compile optimization for which promote_type(T, Int) == T
    length(r::OneTo{T}) where {T<:bigints} = r.stop
    # slightly more accurate length and checked_length in extreme cases
    # (near typemax) for types with known `unsigned` functions
    function length(r::OrdinalRange{T}) where T<:bigints
        s = step(r)
        diff = last(r) - first(r)
        isempty(r) && return zero(diff)
        # Compute `(diff ÷ s) + 1` in a manner robust to signed overflow
        # by using the absolute values as unsigneds for non-empty ranges.
        # Note that `s` may be a different type from T and diff; it may not
        # even be a BitInteger that supports `unsigned`. Handle with care.
        a = div(unsigned(flipsign(diff, s)), s) % typeof(diff)
        return flipsign(a, s) + oneunit(a)
    end
    function checked_length(r::OrdinalRange{T}) where T<:bigints
        s = step(r)
        stop, start = last(r), first(r)
        ET = promote_type(typeof(stop), typeof(start))
        isempty(r) && return zero(ET)
        # n.b. !(s isa T)
        if s > 1
            diff = stop - start
            a = convert(ET, div(unsigned(diff), s))
        elseif s < -1
            diff = start - stop
            a = convert(ET, div(unsigned(diff), -s))
        elseif s > 0
            a = convert(ET, div(checked_sub(stop, start), s))
        else
            a = convert(ET, div(checked_sub(start, stop), -s))
        end
        return checked_add(a, oneunit(a))
    end
    firstindex(r::StepRange{<:bigints,<:bitints}) = one(last(r)-first(r))

    # some special cases to favor default Int type