Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename endof->lastindex and introduce firstindex. Fixes #23354 #25458

Merged
merged 2 commits into from
Jan 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ Library improvements
has been changed to `KeySet{K, <:Associative{K}} <: AbstractSet{K}` ([#24580]).

* New function `ncodeunits(s::AbstractString)` gives the number of code units in a string.
The generic definition is constant time but calls `endof(s)` which may be inefficient.
The generic definition is constant time but calls `lastindex(s)` which may be inefficient.
Therefore custom string types may want to define direct `ncodeunits` methods.

* `reverseind(s::AbstractString, i::Integer)` now has an efficient generic fallback, so
Expand Down Expand Up @@ -993,6 +993,8 @@ Deprecated or removed

* `scale!` has been deprecated in favor of `mul!`, `mul1!`, and `mul2!` ([#25701]).

* `endof(a)` has been renamed to `lastindex(a)` ([#23554]).

* `DateTime()`, `Date()`, and `Time()` have been deprecated, instead use `DateTime(1)`, `Date(1)`
and `Time(0)` respectively ([#23724]).

Expand Down Expand Up @@ -1152,6 +1154,7 @@ Command-line option changes
[#23323]: https://github.com/JuliaLang/julia/issues/23323
[#23341]: https://github.com/JuliaLang/julia/issues/23341
[#23342]: https://github.com/JuliaLang/julia/issues/23342
[#23354]: https://github.com/JuliaLang/julia/issues/23354
[#23366]: https://github.com/JuliaLang/julia/issues/23366
[#23373]: https://github.com/JuliaLang/julia/issues/23373
[#23404]: https://github.com/JuliaLang/julia/issues/23404
Expand Down
23 changes: 18 additions & 5 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ ndims(::Type{T}) where {T<:AbstractArray} = ndims(supertype(T))

Return the number of elements in the collection.

Use [`endof`](@ref) to get the last valid index of an indexable collection.
Use [`lastindex`](@ref) to get the last valid index of an indexable collection.

# Examples
```jldoctest
Expand All @@ -165,17 +165,30 @@ _length(A::AbstractArray) = (@_inline_meta; prod(map(unsafe_length, axes(A)))) #
_length(A) = (@_inline_meta; length(A))

"""
endof(collection) -> Integer
lastindex(collection) -> Integer

Return the last index of the collection.

# Examples
```jldoctest
julia> endof([1,2,4])
julia> lastindex([1,2,4])
3
```
"""
endof(a::AbstractArray) = (@_inline_meta; last(linearindices(a)))
lastindex(a::AbstractArray) = (@_inline_meta; last(linearindices(a)))

"""
firstindex(collection) -> Integer

Return the first index of the collection.

# Examples
```jldoctest
julia> firstindex([1,2,4])
1
```
"""
firstindex(a::AbstractArray) = (@_inline_meta; first(linearindices(a)))

first(a::AbstractArray) = a[first(eachindex(a))]

Expand Down Expand Up @@ -204,7 +217,7 @@ end
last(coll)

Get the last element of an ordered collection, if it can be computed in O(1) time. This is
accomplished by calling [`endof`](@ref) to get the last index. Return the end
accomplished by calling [`lastindex`](@ref) to get the last index. Return the end
point of an `AbstractRange` even if it is empty.

# Examples
Expand Down
3 changes: 2 additions & 1 deletion base/char.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ size(c::Char,d) = convert(Int, d) < 1 ? throw(BoundsError()) : 1
ndims(c::Char) = 0
ndims(::Type{Char}) = 0
length(c::Char) = 1
endof(c::Char) = 1
firstindex(c::Char) = 1
lastindex(c::Char) = 1
getindex(c::Char) = c
getindex(c::Char, i::Integer) = i == 1 ? c : throw(BoundsError())
getindex(c::Char, I::Integer...) = all(x -> x == 1, I) ? c : throw(BoundsError())
Expand Down
13 changes: 10 additions & 3 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1298,9 +1298,9 @@ end
@deprecate rsearch(s::AbstractString, r::Regex) findlast(r, s)
@deprecate rsearch(s::AbstractString, c::Char, i::Integer) findprev(equalto(c), s, i)
@deprecate rsearch(s::AbstractString, c::Char) findlast(equalto(c), s)
@deprecate rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = endof(a)) findprev(equalto(b), a, i)
@deprecate rsearch(a::String, b::Union{Int8,UInt8}, i::Integer = endof(a)) findprev(equalto(Char(b)), a, i)
@deprecate rsearch(a::ByteArray, b::Char, i::Integer = endof(a)) findprev(equalto(UInt8(b)), a, i)
@deprecate rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) findprev(equalto(b), a, i)
@deprecate rsearch(a::String, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) findprev(equalto(Char(b)), a, i)
@deprecate rsearch(a::ByteArray, b::Char, i::Integer = lastindex(a)) findprev(equalto(UInt8(b)), a, i)

@deprecate searchindex(s::AbstractString, t::AbstractString) first(findfirst(t, s))
@deprecate searchindex(s::AbstractString, t::AbstractString, i::Integer) first(findnext(t, s, i))
Expand Down Expand Up @@ -1385,6 +1385,13 @@ export readandwrite
@deprecate methodswith(typ, supertypes) methodswith(typ, supertypes = supertypes)
@deprecate code_lowered(f, types, generated) code_lowered(f, types, generated = generated)

# PR 25458
@deprecate endof(a) lastindex(a)
function firstindex(a)
depwarn("if appropriate you should implement `firstindex` for type $(typeof(a)), which might just return 1", :beginof)
1
end

@deprecate Timer(timeout, repeat) Timer(timeout, interval = repeat)
@deprecate Timer(callback, delay, repeat) Time(callback, delay, interval = repeat)
@deprecate names(m, all) names(m, all = all)
Expand Down
2 changes: 1 addition & 1 deletion base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function _truncate_at_width_or_chars(str, width, chars="", truncmark="…")

lastidx != 0 && str[lastidx] in chars && (lastidx = prevind(str, lastidx))
truncidx == 0 && (truncidx = lastidx)
if lastidx < endof(str)
if lastidx < lastindex(str)
return String(SubString(str, 1, truncidx) * truncmark)
else
return String(str)
Expand Down
3 changes: 2 additions & 1 deletion base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,8 @@ function length(v::SimpleVector)
@_gc_preserve_end t
return l
end
endof(v::SimpleVector) = length(v)
firstindex(v::SimpleVector) = 1
lastindex(v::SimpleVector) = length(v)
start(v::SimpleVector) = 1
next(v::SimpleVector,i) = (v[i],i+1)
done(v::SimpleVector,i) = (length(v) < i)
Expand Down
3 changes: 2 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -505,14 +505,15 @@ export
allunique,
any!,
any,
firstindex,
collect,
count,
delete!,
deleteat!,
eltype,
empty!,
empty,
endof,
lastindex,
filter!,
filter,
foldl,
Expand Down
4 changes: 2 additions & 2 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@ hastypemax(::Type{BigInt}) = false

function tryparse_internal(::Type{BigInt}, s::AbstractString, startpos::Int, endpos::Int, base_::Integer, raise::Bool)
# don't make a copy in the common case where we are parsing a whole String
bstr = startpos == start(s) && endpos == endof(s) ? String(s) : String(SubString(s,startpos,endpos))
bstr = startpos == start(s) && endpos == lastindex(s) ? String(s) : String(SubString(s,startpos,endpos))

sgn, base, i = Base.parseint_preamble(true,Int(base_),bstr,start(bstr),endof(bstr))
sgn, base, i = Base.parseint_preamble(true,Int(base_),bstr,start(bstr),lastindex(bstr))
if !(2 <= base <= 62)
raise && throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base"))
return nothing
Expand Down
4 changes: 2 additions & 2 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -539,9 +539,9 @@ end
macro big_str(s)
if '_' in s
# remove _ in s[2:end-1]
bf = IOBuffer(endof(s))
bf = IOBuffer(lastindex(s))
print(bf, s[1])
for c in SubString(s, 2, endof(s)-1)
for c in SubString(s, 2, lastindex(s)-1)
c != '_' && print(bf, c)
end
print(bf, s[end])
Expand Down
10 changes: 4 additions & 6 deletions base/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -661,15 +661,13 @@ function readuntil(s::IO, delim::T; keep::Bool=false) where T
return out
end

# requires that indices for target are small ordered integers bounded by start and endof
# requires that indices for target are small ordered integers bounded by firstindex and lastindex
# returns whether the delimiter was matched
function readuntil_indexable(io::IO, target#=::Indexable{T}=#, out)
T = eltype(target)
first = start(target)
if done(target, first)
return true
end
len = endof(target)
isempty(target) && return true
first = firstindex(target)
len = lastindex(target)
local cache # will be lazy initialized when needed
second = next(target, first)[2]
max_pos = second
Expand Down
3 changes: 2 additions & 1 deletion base/markdown/parse/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ config(md::MD) = md.meta[:config]::Config
Base.push!(md::MD, x) = push!(md.content, x)
Base.getindex(md::MD, args...) = md.content[args...]
Base.setindex!(md::MD, args...) = setindex!(md.content, args...)
Base.endof(md::MD) = endof(md.content)
Base.lastindex(md::MD) = lastindex(md.content)
Base.firstindex(md::MD) = firstindex(md.content)
Base.length(md::MD) = length(md.content)
Base.isempty(md::MD) = isempty(md.content)
Base.copy(md::MD) = MD(copy(md.content), copy(md.meta))
Expand Down
3 changes: 2 additions & 1 deletion base/namedtuple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ length(t::NamedTuple) = nfields(t)
start(t::NamedTuple) = 1
done(t::NamedTuple, iter) = iter > nfields(t)
next(t::NamedTuple, iter) = (getfield(t, iter), iter + 1)
endof(t::NamedTuple) = nfields(t)
firstindex(t::NamedTuple) = 1
lastindex(t::NamedTuple) = nfields(t)
getindex(t::NamedTuple, i::Int) = getfield(t, i)
getindex(t::NamedTuple, i::Symbol) = getfield(t, i)
indexed_next(t::NamedTuple, i::Int, state) = (getfield(t, i), i+1)
Expand Down
3 changes: 2 additions & 1 deletion base/number.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ eltype(::Type{T}) where {T<:Number} = T
ndims(x::Number) = 0
ndims(::Type{<:Number}) = 0
length(x::Number) = 1
endof(x::Number) = 1
firstindex(x::Number) = 1
lastindex(x::Number) = 1
IteratorSize(::Type{<:Number}) = HasShape{0}()
keys(::Number) = OneTo(1)

Expand Down
3 changes: 2 additions & 1 deletion base/pair.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ getindex(p::Pair,i::Int) = getfield(p,i)
getindex(p::Pair,i::Real) = getfield(p, convert(Int, i))
reverse(p::Pair{A,B}) where {A,B} = Pair{B,A}(p.second, p.first)

endof(p::Pair) = 2
firstindex(p::Pair) = 1
lastindex(p::Pair) = 2
length(p::Pair) = 2
first(p::Pair) = p.first
last(p::Pair) = p.second
Expand Down
8 changes: 4 additions & 4 deletions base/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,11 @@ or [`nothing`](@ref) if the string does not contain a valid number.
"""
function tryparse(::Type{T}, s::AbstractString; base::Union{Nothing,Integer} = nothing) where {T<:Integer}
# Zero base means, "figure it out"
tryparse_internal(T, s, start(s), endof(s), base===nothing ? 0 : check_valid_base(base), false)
tryparse_internal(T, s, start(s), lastindex(s), base===nothing ? 0 : check_valid_base(base), false)
end

function parse(::Type{T}, s::AbstractString; base::Union{Nothing,Integer} = nothing) where {T<:Integer}
tryparse_internal(T, s, start(s), endof(s), base===nothing ? 0 : check_valid_base(base), true)
tryparse_internal(T, s, start(s), lastindex(s), base===nothing ? 0 : check_valid_base(base), true)
end

## string to float functions ##
Expand Down Expand Up @@ -327,7 +327,7 @@ tryparse_internal(T::Type{<:Complex}, s::AbstractString, i::Int, e::Int, raise::

# fallback methods for tryparse_internal
tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::Int) where T<:Real =
startpos == start(s) && endpos == endof(s) ? tryparse(T, s) : tryparse(T, SubString(s, startpos, endpos))
startpos == start(s) && endpos == lastindex(s) ? tryparse(T, s) : tryparse(T, SubString(s, startpos, endpos))
function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::Int, raise::Bool) where T<:Real
result = tryparse_internal(T, s, startpos, endpos)
if raise && result === nothing
Expand All @@ -339,4 +339,4 @@ tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::Int, rais
tryparse_internal(T, s, startpos, endpos, 10, raise)

parse(::Type{T}, s::AbstractString) where T<:Union{Real,Complex} =
tryparse_internal(T, s, start(s), endof(s), true)
tryparse_internal(T, s, start(s), lastindex(s), true)
8 changes: 4 additions & 4 deletions base/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -545,11 +545,11 @@ precompile(Tuple{Type{BoundsError}, Array{Expr, 1}, Base.UnitRange{Int64}})
precompile(Tuple{getfield(Base.Cartesian, Symbol("#@ncall")), Int64, Symbol, Symbol})
precompile(Tuple{typeof(Base.getindex), Tuple{Symbol}, Base.UnitRange{Int64}})
precompile(Tuple{getfield(Base.Cartesian, Symbol("#@ncall")), Int64, Symbol, Symbol, Expr})
precompile(Tuple{typeof(Base.endof), Tuple{Symbol, Expr}})
precompile(Tuple{typeof(Base.lastindex), Tuple{Symbol, Expr}})
precompile(Tuple{typeof(Base.getindex), Tuple{Symbol, Expr}, Base.UnitRange{Int64}})
precompile(Tuple{getfield(Base.Cartesian, Symbol("#@nloops")), Int64, Symbol, Expr, Expr})
precompile(Tuple{typeof(Base.endof), Tuple{Expr}})
precompile(Tuple{typeof(Base.endof), Tuple{Symbol, Symbol, Symbol}})
precompile(Tuple{typeof(Base.lastindex), Tuple{Expr}})
precompile(Tuple{typeof(Base.lastindex), Tuple{Symbol, Symbol, Symbol}})
precompile(Tuple{typeof(Base.getindex), Tuple{Symbol, Symbol, Symbol}, Base.UnitRange{Int64}})
precompile(Tuple{Type{Expr}, Symbol, Symbol, Symbol, Symbol, Symbol, Symbol})
precompile(Tuple{typeof(Base.join), Base.GenericIOBuffer{Array{UInt8, 1}}, Tuple{String, String}, Char})
Expand Down Expand Up @@ -752,7 +752,7 @@ precompile(Tuple{typeof(Base.Markdown.terminline), Base.GenericIOBuffer{Array{UI
precompile(Tuple{typeof(Base._search), Base.SubString{String}, String, Int64})
precompile(Tuple{typeof(Base._split), Base.SubString{String}, String, Int64, Bool, Array{Base.SubString{String}, 1}})
precompile(Tuple{getfield(Base.Markdown, Symbol("#kw##wrapped_lines")), Array{Any, 1}, typeof(Base.Markdown.wrapped_lines), Base.SubString{String}})
precompile(Tuple{typeof(Base.endof), Array{AbstractString, 1}})
precompile(Tuple{typeof(Base.lastindex), Array{AbstractString, 1}})
precompile(Tuple{typeof(Base.getindex), Array{AbstractString, 1}, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Base.throw_boundserror), Array{AbstractString, 1}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Base.unsafe_copyto!), Array{AbstractString, 1}, Int64, Array{AbstractString, 1}, Int64, Int64})
Expand Down
2 changes: 1 addition & 1 deletion base/printf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function parse(s::AbstractString)
j1 = j
j = k
end
i > endof(s) || push!(list, s[i:end])
i > lastindex(s) || push!(list, s[i:end])
# coalesce adjacent strings
i = 1
while i < length(list)
Expand Down
2 changes: 1 addition & 1 deletion base/process.jl
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ wait(x::ProcessChain) = for p in x.processes; wait(p); end
show(io::IO, p::Process) = print(io, "Process(", p.cmd, ", ", process_status(p), ")")

# allow the elements of the Cmd to be accessed as an array or iterator
for f in (:length, :endof, :start, :keys, :first, :last)
for f in (:length, :firstindex, :lastindex, :start, :keys, :first, :last)
@eval $f(cmd::Cmd) = $f(cmd.exec)
end
eltype(::Type{Cmd}) = eltype(fieldtype(Cmd, :exec))
Expand Down
4 changes: 2 additions & 2 deletions base/reduce.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ end
Like [`mapreduce`](@ref), but with guaranteed right associativity, as in [`foldr`](@ref).
`v0` will be used exactly once.
"""
mapfoldr(f, op, v0, itr) = mapfoldr_impl(f, op, v0, itr, endof(itr))
mapfoldr(f, op, v0, itr) = mapfoldr_impl(f, op, v0, itr, lastindex(itr))

"""
mapfoldr(f, op, itr)
Expand All @@ -137,7 +137,7 @@ Specifically, `mapfoldr(f, op, itr)` produces the same result as
In general, this cannot be used with empty collections (see [`reduce(op, itr)`](@ref)).
"""
function mapfoldr(f, op, itr)
i = endof(itr)
i = lastindex(itr)
if isempty(itr)
return Base.mapreduce_empty_iter(f, op, itr, IteratorEltype(itr))
end
Expand Down
6 changes: 3 additions & 3 deletions base/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ matchall(re::Regex, str::SubString; overlap::Bool = false) =

# TODO: return only start index and update deprecation
function findnext(re::Regex, str::Union{String,SubString}, idx::Integer)
if idx > nextind(str,endof(str))
if idx > nextind(str,lastindex(str))
throw(BoundsError())
end
opts = re.match_options
Expand Down Expand Up @@ -315,7 +315,7 @@ function _replace(io, repl_s::SubstitutionString, str, r, re)
RBRACKET = '>'
repl = repl_s.string
i = start(repl)
e = endof(repl)
e = lastindex(repl)
while i <= e
if repl[i] == SUB_CHAR
next_i = nextind(repl, i)
Expand Down Expand Up @@ -393,7 +393,7 @@ function next(itr::RegexMatchIterator, prev_match)
offset = prev_match.offset
end
else
offset = prev_match.offset + endof(prev_match.match)
offset = prev_match.offset + lastindex(prev_match.match)
end

opts_nonempty = UInt32(PCRE.ANCHORED | PCRE.NOTEMPTY_ATSTART)
Expand Down
Loading