From 8deab5151c6df460d1dab874e006638b2b89babf Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Tue, 9 Jan 2018 10:52:57 -0600 Subject: [PATCH] Change sentinel in find(first|next|prev|last) to `nothing` --- base/array.jl | 56 +++++++++-------- base/bitarray.jl | 34 +++++------ base/bitset.jl | 6 +- base/client.jl | 2 +- base/combinatorics.jl | 4 +- base/event.jl | 2 +- base/file.jl | 2 +- base/filesystem.jl | 1 + base/inference.jl | 4 +- base/iobuffer.jl | 6 +- base/libgit2/types.jl | 5 +- base/methodshow.jl | 4 +- base/parse.jl | 8 +-- base/path.jl | 4 +- base/permuteddimsarray.jl | 2 +- base/pkg/query.jl | 4 +- base/pkg/types.jl | 2 +- base/repl/LineEdit.jl | 27 ++++---- base/repl/REPL.jl | 4 +- base/repl/REPLCompletions.jl | 13 ++-- base/sparse/abstractsparse.jl | 8 +-- base/sparse/sparsematrix.jl | 12 ++-- base/sparse/sparsevector.jl | 6 +- base/stacktraces.jl | 5 +- base/stream.jl | 6 +- base/strings/search.jl | 44 ++++++------- base/strings/util.jl | 12 ++-- base/threadcall.jl | 2 +- doc/src/manual/strings.md | 2 - stdlib/DelimitedFiles/src/DelimitedFiles.jl | 2 +- stdlib/SharedArrays/test/runtests.jl | 2 +- stdlib/SuiteSparse/src/cholmod.jl | 2 +- stdlib/Test/src/Test.jl | 4 +- test/arrayops.jl | 14 ++--- test/bitarray.jl | 54 ++++++++-------- test/strings/search.jl | 68 ++++++++++----------- test/strings/types.jl | 2 +- 37 files changed, 220 insertions(+), 215 deletions(-) diff --git a/base/array.jl b/base/array.jl index c94511aaf8304..263230286fc86 100644 --- a/base/array.jl +++ b/base/array.jl @@ -1495,7 +1495,7 @@ cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(x->1, n-1)..., length(x """ findnext(A, i::Integer) -Find the next linear index >= `i` of a `true` element of `A`, or `0` if not found. +Find the next linear index >= `i` of a `true` element of `A`, or `nothing` if not found. # Examples ```jldoctest @@ -1508,7 +1508,6 @@ julia> findnext(A, 1) 2 julia> findnext(A, 3) -0 ``` """ function findnext(A, start::Integer) @@ -1526,14 +1525,14 @@ function findnext(A, start::Integer) end i = nextind(A, i) end - return 0 + return nothing end """ findfirst(A) Return the linear index of the first `true` value in `A`. -Return `0` if no such value is found. +Return `nothing` if no such value is found. To search for other kinds of values, pass a predicate as the first argument. # Examples @@ -1546,8 +1545,8 @@ julia> A = [false false; true false] julia> findfirst(A) 2 -julia> findfirst(falses(3)) -0 +julia> findfirst(falses(3)) == nothing +true ``` """ findfirst(A) = findnext(A, 1) @@ -1555,7 +1554,8 @@ findfirst(A) = findnext(A, 1) """ findnext(predicate::Function, A, i::Integer) -Find the next linear index >= `i` of an element of `A` for which `predicate` returns `true`, or `0` if not found. +Find the next linear index >= `i` of an element of `A` for which `predicate` returns `true`, +or `nothing` if not found. # Examples ```jldoctest @@ -1567,8 +1567,8 @@ julia> A = [1 4; 2 2] julia> findnext(isodd, A, 1) 1 -julia> findnext(isodd, A, 2) -0 +julia> findnext(isodd, A, 2) == nothing +true ``` """ function findnext(testf::Function, A, start::Integer) @@ -1580,14 +1580,14 @@ function findnext(testf::Function, A, start::Integer) end i = nextind(A, i) end - return 0 + return nothing end """ findfirst(predicate::Function, A) Return the linear index of the first element of `A` for which `predicate` returns `true`. -Return `0` if there is no such element. +Return `nothing` if there is no such element. # Examples ```jldoctest @@ -1599,8 +1599,8 @@ julia> A = [1 4; 2 2] julia> findfirst(iseven, A) 2 -julia> findfirst(x -> x>10, A) -0 +julia> findfirst(x -> x>10, A) == nothing +true julia> findfirst(equalto(4), A) 3 @@ -1611,7 +1611,7 @@ findfirst(testf::Function, A) = findnext(testf, A, 1) """ findprev(A, i::Integer) -Find the previous linear index <= `i` of a `true` element of `A`, or `0` if not found. +Find the previous linear index <= `i` of a `true` element of `A`, or `nothing` if not found. # Examples ```jldoctest @@ -1623,8 +1623,8 @@ julia> A = [false false; true true] julia> findprev(A,2) 2 -julia> findprev(A,1) -0 +julia> findprev(A,1) == nothing +true ``` """ function findprev(A, start::Integer) @@ -1639,14 +1639,14 @@ function findprev(A, start::Integer) a != 0 && return i i = prevind(A, i) end - return 0 + return nothing end """ findlast(A) Return the linear index of the last `true` value in `A`. -Return `0` if there is no `true` value in `A`. +Return `nothing` if there is no `true` value in `A`. # Examples ```jldoctest @@ -1660,8 +1660,8 @@ julia> findlast(A) julia> A = falses(2,2); -julia> findlast(A) -0 +julia> findlast(A) == nothing +true ``` """ findlast(A) = findprev(A, endof(A)) @@ -1670,7 +1670,7 @@ findlast(A) = findprev(A, endof(A)) findprev(predicate::Function, A, i::Integer) Find the previous linear index <= `i` of an element of `A` for which `predicate` returns `true`, or -`0` if not found. +`nothing` if not found. # Examples ```jldoctest @@ -1679,8 +1679,8 @@ julia> A = [4 6; 1 2] 4 6 1 2 -julia> findprev(isodd, A, 1) -0 +julia> findprev(isodd, A, 1) == nothing +true julia> findprev(isodd, A, 3) 2 @@ -1692,14 +1692,14 @@ function findprev(testf::Function, A, start::Integer) testf(A[i]) && return i i = prevind(A, i) end - return 0 + return nothing end """ findlast(predicate::Function, A) Return the linear index of the last element of `A` for which `predicate` returns `true`. -Return `0` if there is no such element. +Return `nothing` if there is no such element. # Examples ```jldoctest @@ -1711,12 +1711,14 @@ julia> A = [1 2; 3 4] julia> findlast(isodd, A) 2 -julia> findlast(x -> x > 5, A) -0 +julia> findlast(x -> x > 5, A) == nothing +true ``` """ findlast(testf::Function, A) = findprev(testf, A, endof(A)) +nothing_sentinel(i) = i == 0 ? nothing : i + """ find(f::Function, A) diff --git a/base/bitarray.jl b/base/bitarray.jl index 5fecd2e0f06ca..fc001f530f221 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -1459,13 +1459,13 @@ function unsafe_bitfindnext(Bc::Vector{UInt64}, start::Integer) end end end - return 0 + return nothing end -# returns the index of the next non-zero element, or 0 if all zeros +# returns the index of the next true element, or nothing if all false function findnext(B::BitArray, start::Integer) start > 0 || throw(BoundsError(B, start)) - start > length(B) && return 0 + start > length(B) && return nothing unsafe_bitfindnext(B.chunks, start) end @@ -1474,11 +1474,11 @@ end # aux function: same as findnext(~B, start), but performed without temporaries function findnextnot(B::BitArray, start::Integer) start > 0 || throw(BoundsError(B, start)) - start > length(B) && return 0 + start > length(B) && return nothing Bc = B.chunks l = length(Bc) - l == 0 && return 0 + l == 0 && return nothing chunk_start = _div64(start-1)+1 within_chunk_start = _mod64(start-1) @@ -1499,7 +1499,7 @@ function findnextnot(B::BitArray, start::Integer) elseif Bc[l] | mask != _msk_end(B) return (l-1) << 6 + trailing_ones(Bc[l] | mask) + 1 end - return 0 + return nothing end findfirstnot(B::BitArray) = findnextnot(B,1) @@ -1508,7 +1508,7 @@ function findnext(pred::EqualTo, B::BitArray, start::Integer) v = pred.x v == false && return findnextnot(B, start) v == true && return findnext(B, start) - return 0 + return nothing end #findfirst(B::BitArray, v) = findnext(B, 1, v) ## defined in array.jl @@ -1520,9 +1520,9 @@ function findnext(testf::Function, B::BitArray, start::Integer) f0 && !f1 && return findnextnot(B, start) start > 0 || throw(BoundsError(B, start)) - start > length(B) && return 0 + start > length(B) && return nothing f0 && f1 && return Int(start) - return 0 # last case: !f0 && !f1 + return nothing # last case: !f0 && !f1 end #findfirst(testf::Function, B::BitArray) = findnext(testf, B, 1) ## defined in array.jl @@ -1541,18 +1541,18 @@ function unsafe_bitfindprev(Bc::Vector{UInt64}, start::Integer) end end end - return 0 + return nothing end -# returns the index of the previous non-zero element, or 0 if all zeros +# returns the index of the previous true element, or nothing if all false function findprev(B::BitArray, start::Integer) - start > 0 || return 0 + start > 0 || return nothing start > length(B) && throw(BoundsError(B, start)) unsafe_bitfindprev(B.chunks, start) end function findprevnot(B::BitArray, start::Integer) - start > 0 || return 0 + start > 0 || return nothing start > length(B) && throw(BoundsError(B, start)) Bc = B.chunks @@ -1571,7 +1571,7 @@ function findprevnot(B::BitArray, start::Integer) end end end - return 0 + return nothing end findlastnot(B::BitArray) = findprevnot(B, length(B)) @@ -1580,7 +1580,7 @@ function findprev(pred::EqualTo, B::BitArray, start::Integer) v = pred.x v == false && return findprevnot(B, start) v == true && return findprev(B, start) - return 0 + return nothing end #findlast(B::BitArray, v) = findprev(B, 1, v) ## defined in array.jl @@ -1591,10 +1591,10 @@ function findprev(testf::Function, B::BitArray, start::Integer) !f0 && f1 && return findprev(B, start) f0 && !f1 && return findprevnot(B, start) - start > 0 || return 0 + start > 0 || return nothing start > length(B) && throw(BoundsError(B, start)) f0 && f1 && return Int(start) - return 0 # last case: !f0 && !f1 + return nothing # last case: !f0 && !f1 end #findlast(testf::Function, B::BitArray) = findprev(testf, B, 1) ## defined in array.jl diff --git a/base/bitset.jl b/base/bitset.jl index 9304fc3051ab5..98320788a862d 100644 --- a/base/bitset.jl +++ b/base/bitset.jl @@ -68,14 +68,16 @@ function _bits_findnext(b::Bits, start::Int) # start is 0-based # @assert start >= 0 _div64(start) + 1 > length(b) && return -1 - unsafe_bitfindnext(b, start+1) - 1 + ind = unsafe_bitfindnext(b, start+1) + ind === nothing ? -1 : ind - 1 end function _bits_findprev(b::Bits, start::Int) # start is 0-based # @assert start <= 64 * length(b) - 1 start >= 0 || return -1 - unsafe_bitfindprev(b, start+1) - 1 + ind = unsafe_bitfindprev(b, start+1) + ind === nothing ? -1 : ind - 1 end # An internal function for setting the inclusion bit for a given integer diff --git a/base/client.jl b/base/client.jl index c1487d8563aba..a0ab18b5f41ad 100644 --- a/base/client.jl +++ b/base/client.jl @@ -149,7 +149,7 @@ function display_error(io::IO, er, bt) print_with_color(Base.error_color(), io, "ERROR: "; bold = true) # remove REPL-related frames from interactive printing eval_ind = findlast(addr->Base.REPL.ip_matches_func(addr, :eval), bt) - if eval_ind != 0 + if eval_ind !== nothing bt = bt[1:eval_ind-1] end showerror(IOContext(io, :limit => true), er, bt) diff --git a/base/combinatorics.jl b/base/combinatorics.jl index a90084b4ff4e0..f08465be40e62 100644 --- a/base/combinatorics.jl +++ b/base/combinatorics.jl @@ -75,7 +75,7 @@ function permute!!(a, p::AbstractVector{<:Integer}) count = 0 start = 0 while count < length(a) - ptr = start = findnext(!iszero, p, start+1) + ptr = start = findnext(!iszero, p, start+1)::Int temp = a[start] next = p[start] count += 1 @@ -125,7 +125,7 @@ function invpermute!!(a, p::AbstractVector{<:Integer}) count = 0 start = 0 while count < length(a) - start = findnext(!iszero, p, start+1) + start = findnext(!iszero, p, start+1)::Int temp = a[start] next = p[start] count += 1 diff --git a/base/event.jl b/base/event.jl index 6f7cc45866a62..92ae58248ebbb 100644 --- a/base/event.jl +++ b/base/event.jl @@ -231,7 +231,7 @@ function ensure_rescheduled(othertask::Task) # also need to return it to the runnable state # before throwing an error i = findfirst(t->t===ct, Workqueue) - i == 0 || deleteat!(Workqueue, i) + i === nothing || deleteat!(Workqueue, i) ct.state = :runnable end nothing diff --git a/base/file.jl b/base/file.jl index 846da9b8eddae..122c35f485a13 100644 --- a/base/file.jl +++ b/base/file.jl @@ -271,7 +271,7 @@ function tempname(temppath::AbstractString,uunique::UInt32) tempp = cwstring(temppath) tname = Vector{UInt16}(uninitialized, 32767) uunique = ccall(:GetTempFileNameW,stdcall,UInt32,(Ptr{UInt16},Ptr{UInt16},UInt32,Ptr{UInt16}), tempp,temp_prefix,uunique,tname) - lentname = findfirst(iszero,tname)-1 + lentname = coalesce(findfirst(iszero,tname), 0)-1 if uunique == 0 || lentname <= 0 error("GetTempFileName failed: $(Libc.FormatMessage())") end diff --git a/base/filesystem.jl b/base/filesystem.jl index 001a8fcb210bb..9f29ee127783d 100644 --- a/base/filesystem.jl +++ b/base/filesystem.jl @@ -43,6 +43,7 @@ import Base: nb_available, position, read, read!, readavailable, seek, seekend, show, skip, stat, unsafe_read, unsafe_write, transcode, uv_error, uvhandle, uvtype, write +using Base: coalesce if Sys.iswindows() import Base: cwstring diff --git a/base/inference.jl b/base/inference.jl index ab3b0bcff5424..804c2d4a3f494 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -1794,7 +1794,7 @@ function builtin_tfunction(@nospecialize(f), argtypes::Array{Any,1}, tf = t_ifunc[iidx] else fidx = findfirst(x->x===f, t_ffunc_key) - if fidx == 0 + if fidx === nothing # unknown/unhandled builtin function return Any end @@ -5118,7 +5118,7 @@ function statement_cost(ex::Expr, line::Int, src::CodeInfo, mod::Module, params: return plus_saturate(argcost, isknowntype(ex.typ) ? 4 : params.inline_nonleaf_penalty) end fidx = findfirst(x->x===f, t_ffunc_key) - if fidx == 0 + if fidx === nothing # unknown/unhandled builtin or anonymous function # Use the generic cost of a direct function call return plus_saturate(argcost, 20) diff --git a/base/iobuffer.jl b/base/iobuffer.jl index e91e8c30cd213..fea9cabea2a7f 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -429,8 +429,8 @@ read(io::GenericIOBuffer, nb::Integer) = read!(io,StringVector(min(nb, nb_availa function findfirst(delim::EqualTo{UInt8}, buf::IOBuffer) p = pointer(buf.data, buf.ptr) q = @gc_preserve buf ccall(:memchr,Ptr{UInt8},(Ptr{UInt8},Int32,Csize_t),p,delim.x,nb_available(buf)) - nb::Int = (q == C_NULL ? 0 : q-p+1) - return nb + q == C_NULL && return nothing + return Int(q-p+1) end function findfirst(delim::EqualTo{UInt8}, buf::GenericIOBuffer) @@ -441,7 +441,7 @@ function findfirst(delim::EqualTo{UInt8}, buf::GenericIOBuffer) return i - buf.ptr + 1 end end - return 0 + return nothing end function readuntil(io::GenericIOBuffer, delim::UInt8) diff --git a/base/libgit2/types.jl b/base/libgit2/types.jl index 7cd6c36f15917..45981a7d5801d 100644 --- a/base/libgit2/types.jl +++ b/base/libgit2/types.jl @@ -1,5 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Base: coalesce import Base.@kwdef import .Consts: GIT_SUBMODULE_IGNORE, GIT_MERGE_FILE_FAVOR, GIT_MERGE_FILE, GIT_CONFIG @@ -894,8 +895,8 @@ function Base.split(ce::ConfigEntry) key = unsafe_string(ce.name) # Determine the positions of the delimiters - subsection_delim = findfirst(equalto('.'), key) - name_delim = findlast(equalto('.'), key) + subsection_delim = coalesce(findfirst(equalto('.'), key), 0) + name_delim = coalesce(findlast(equalto('.'), key), 0) section = SubString(key, 1, subsection_delim - 1) subsection = SubString(key, subsection_delim + 1, name_delim - 1) diff --git a/base/methodshow.jl b/base/methodshow.jl index 7afa482d69f8a..ea9d78d6bf061 100644 --- a/base/methodshow.jl +++ b/base/methodshow.jl @@ -12,7 +12,7 @@ function argtype_decl(env, n, sig::DataType, i::Int, nargs, isva::Bool) # -> (ar end s = string(n) i = findfirst(equalto('#'), s) - if i > 0 + if i !== nothing s = s[1:i-1] end if t === Any && !isempty(s) @@ -84,7 +84,7 @@ function kwarg_decl(m::Method, kwtype::DataType) # ensure the kwarg... is always printed last. The order of the arguments are not # necessarily the same as defined in the function i = findfirst(x -> endswith(string(x), "..."), kws) - i == 0 && return kws + i === nothing && return kws push!(kws, kws[i]) return deleteat!(kws, i) end diff --git a/base/parse.jl b/base/parse.jl index e0da3ea303058..0d51a66408af1 100644 --- a/base/parse.jl +++ b/base/parse.jl @@ -281,16 +281,16 @@ function tryparse_internal(::Type{Complex{T}}, s::Union{String,SubString{String} end # find index of ± separating real/imaginary parts (if any) - i₊ = findnext(occursin(('+','-')), s, i) + i₊ = coalesce(findnext(occursin(('+','-')), s, i), 0) if i₊ == i # leading ± sign - i₊ = findnext(occursin(('+','-')), s, i₊+1) + i₊ = coalesce(findnext(occursin(('+','-')), s, i₊+1), 0) end if i₊ != 0 && s[i₊-1] in ('e','E') # exponent sign - i₊ = findnext(occursin(('+','-')), s, i₊+1) + i₊ = coalesce(findnext(occursin(('+','-')), s, i₊+1), 0) end # find trailing im/i/j - iᵢ = findprev(occursin(('m','i','j')), s, e) + iᵢ = coalesce(findprev(occursin(('m','i','j')), s, e), 0) if iᵢ > 0 && s[iᵢ] == 'm' # im iᵢ -= 1 if s[iᵢ] != 'i' diff --git a/base/path.jl b/base/path.jl index c602e409d7009..d2448a083a315 100644 --- a/base/path.jl +++ b/base/path.jl @@ -380,8 +380,8 @@ function relpath(path::String, startpath::String = ".") break end end - pathpart = join(path_arr[i+1:findlast(x -> !isempty(x), path_arr)], path_separator) - prefix_num = findlast(x -> !isempty(x), start_arr) - i - 1 + pathpart = join(path_arr[i+1:coalesce(findlast(x -> !isempty(x), path_arr), 0)], path_separator) + prefix_num = coalesce(findlast(x -> !isempty(x), start_arr), 0) - i - 1 if prefix_num >= 0 prefix = pardir * path_separator relpath_ = isempty(pathpart) ? diff --git a/base/permuteddimsarray.jl b/base/permuteddimsarray.jl index bf7c73f25071d..3991e3e70c93c 100644 --- a/base/permuteddimsarray.jl +++ b/base/permuteddimsarray.jl @@ -214,7 +214,7 @@ function _copy!(P::PermutedDimsArray{T,N,perm}, src) where {T,N,perm} copyto!(parent(P), src) # it's not permuted else R1 = CartesianIndices(axes(src)[1:d]) - d1 = findfirst(equalto(d+1), perm) # first permuted dim of dest + d1 = findfirst(equalto(d+1), perm)::Int # first permuted dim of dest R2 = CartesianIndices(axes(src)[d+2:d1-1]) R3 = CartesianIndices(axes(src)[d1+1:end]) _permutedims!(P, src, R1, R2, R3, d+1, d1) diff --git a/base/pkg/query.jl b/base/pkg/query.jl index a4ca902dd7ea4..bf51e3e8b0726 100644 --- a/base/pkg/query.jl +++ b/base/pkg/query.jl @@ -406,7 +406,7 @@ function prune_versions(reqs::Requires, deps::Dict{String,Dict{VersionNumber,Ava end for (vn,a) in fdepsp vmind = findfirst(equalto(a.requires), uniqdepssets) - @assert vmind > 0 + @assert vmind !== nothing vm = vmaskp[vn] vm[vmind] = true end @@ -435,7 +435,7 @@ function prune_versions(reqs::Requires, deps::Dict{String,Dict{VersionNumber,Ava nc = length(vmask0_uniq) classes = [VersionNumber[] for c0 = 1:nc] for (vn,vm) in vmaskp - c0 = findfirst(equalto(vm), vmask0_uniq) + c0 = findfirst(equalto(vm), vmask0_uniq)::Int push!(classes[c0], vn) end map(sort!, classes) diff --git a/base/pkg/types.jl b/base/pkg/types.jl index 0e5df375892d3..9918a1aa8f153 100644 --- a/base/pkg/types.jl +++ b/base/pkg/types.jl @@ -102,7 +102,7 @@ function union!(A::VersionSet, B::VersionSet) for intB in B.intervals lB, uB = intB.lower, intB.upper k0 = findfirst(i->(i.upper > lB), ivals) - if k0 == 0 + if k0 === nothing push!(ivals, intB) continue end diff --git a/base/repl/LineEdit.jl b/base/repl/LineEdit.jl index 7f92d6d047b4d..b29049de02886 100644 --- a/base/repl/LineEdit.jl +++ b/base/repl/LineEdit.jl @@ -8,6 +8,7 @@ import ..Terminals: raw!, width, height, cmove, getX, getY, clear_line, beep import Base: ensureroom, peek, show, AnyDict, position +using Base: coalesce using Base.Unicode: lowercase, uppercase, ucfirst, textwidth, isspace @@ -581,10 +582,10 @@ end function edit_move_up(buf::IOBuffer) npos = findprev(equalto(UInt8('\n')), buf.data, position(buf)) - npos == 0 && return false # we're in the first line + npos === nothing && return false # we're in the first line # We're interested in character count, not byte count offset = length(content(buf, npos => position(buf))) - npos2 = findprev(equalto(UInt8('\n')), buf.data, npos-1) + npos2 = coalesce(findprev(equalto(UInt8('\n')), buf.data, npos-1), 0) seek(buf, npos2) for _ = 1:offset pos = position(buf) @@ -603,11 +604,11 @@ function edit_move_up(s) end function edit_move_down(buf::IOBuffer) - npos = findprev(equalto(UInt8('\n')), buf.data[1:buf.size], position(buf)) + npos = coalesce(findprev(equalto(UInt8('\n')), buf.data[1:buf.size], position(buf)), 0) # We're interested in character count, not byte count offset = length(String(buf.data[(npos+1):(position(buf))])) npos2 = findnext(equalto(UInt8('\n')), buf.data[1:buf.size], position(buf)+1) - if npos2 == 0 #we're in the last line + if npos2 === nothing #we're in the last line return false end seek(buf, npos2) @@ -700,7 +701,7 @@ function edit_insert_newline(s::PromptState, align=-1) buf = buffer(s) if align < 0 beg = beginofline(buf) - align = min(findnext(_notspace, buf.data[beg+1:buf.size], 1) - 1, + align = min(coalesce(findnext(_notspace, buf.data[beg+1:buf.size], 1), 0) - 1, position(buf) - beg) # indentation must not increase align < 0 && (align = buf.size-beg) end @@ -727,11 +728,11 @@ const _space = UInt8(' ') _notspace(c) = c != _space -beginofline(buf, pos=position(buf)) = findprev(equalto(_newline), buf.data, pos) +beginofline(buf, pos=position(buf)) = coalesce(findprev(equalto(_newline), buf.data, pos), 0) function endofline(buf, pos=position(buf)) eol = findnext(equalto(_newline), buf.data[pos+1:buf.size], 1) - eol == 0 ? buf.size : pos + eol - 1 + eol === nothing ? buf.size : pos + eol - 1 end function edit_backspace(buf::IOBuffer, align::Bool=false, adjust::Bool=false) @@ -745,12 +746,12 @@ function edit_backspace(buf::IOBuffer, align::Bool=false, adjust::Bool=false) if align && c == ' ' # maybe delete multiple spaces beg = beginofline(buf, newpos) align = textwidth(String(buf.data[1+beg:newpos])) % 4 - nonspace = findprev(_notspace, buf.data, newpos) + nonspace = coalesce(findprev(_notspace, buf.data, newpos), 0) if newpos - align >= nonspace newpos -= align seek(buf, newpos) if adjust - spaces = findnext(_notspace, buf.data[newpos+2:buf.size], 1) + spaces = coalesce(findnext(_notspace, buf.data[newpos+2:buf.size], 1), 0) oldpos = spaces == 0 ? buf.size : buf.data[newpos+1+spaces] == _newline ? newpos+spaces : newpos + min(spaces, 4) @@ -1107,7 +1108,7 @@ end # compute the number of spaces from b till the next non-space on the right # (which can also be "end of line" or "end of buffer") function leadingspaces(buf::IOBuffer, b::Int)::Int - ls = findnext(_notspace, buf.data, b+1)-1 + ls = coalesce(findnext(_notspace, buf.data, b+1), 0)-1 ls == -1 && (ls = buf.size) ls -= b ls @@ -1849,7 +1850,7 @@ function move_line_start(s::MIState) if s.key_repeats > 0 move_input_start(s) else - seek(buf, findprev(equalto(UInt8('\n')), buf.data, curpos)) + seek(buf, coalesce(findprev(equalto(UInt8('\n')), buf.data, curpos), 0)) end end @@ -1863,7 +1864,7 @@ end function move_line_end(buf::IOBuffer) eof(buf) && return pos = findnext(equalto(UInt8('\n')), buf.data, position(buf)+1) - if pos == 0 + if pos === nothing move_input_end(buf) return end @@ -1922,7 +1923,7 @@ end function edit_insert_tab(buf::IOBuffer, jump_spaces=false, delete_trailing=jump_spaces) i = position(buf) if jump_spaces && i < buf.size && buf.data[i+1] == _space - spaces = findnext(_notspace, buf.data[i+1:buf.size], 1) + spaces = coalesce(findnext(_notspace, buf.data[i+1:buf.size], 1), 0) if delete_trailing && (spaces == 0 || buf.data[i+spaces] == _newline) edit_splice!(buf, i => (spaces == 0 ? buf.size : i+spaces-1)) else diff --git a/base/repl/REPL.jl b/base/repl/REPL.jl index 3858fb985902b..023ed0c90f706 100644 --- a/base/repl/REPL.jl +++ b/base/repl/REPL.jl @@ -888,7 +888,7 @@ function setup_interface( sbuffer = LineEdit.buffer(s) curspos = position(sbuffer) seek(sbuffer, 0) - shouldeval = (nb_available(sbuffer) == curspos && findfirst(equalto(UInt8('\n')), sbuffer) == 0) + shouldeval = (nb_available(sbuffer) == curspos && findfirst(equalto(UInt8('\n')), sbuffer) === nothing) seek(sbuffer, curspos) if curspos == 0 # if pasting at the beginning, strip leading whitespace @@ -1051,7 +1051,7 @@ input_color(r::StreamREPL) = r.input_color # at the end of the expression was intended for suppressing output function ends_with_semicolon(line::AbstractString) match = findlast(equalto(';'), line) - if match != 0 + if match !== nothing # state for comment parser, assuming that the `;` isn't in a string or comment # so input like ";#" will still thwart this to give the wrong (anti-conservative) answer comment = false diff --git a/base/repl/REPLCompletions.jl b/base/repl/REPLCompletions.jl index 4c80882b94a2e..f76116768dc59 100644 --- a/base/repl/REPLCompletions.jl +++ b/base/repl/REPLCompletions.jl @@ -5,6 +5,7 @@ module REPLCompletions export completions, shell_completions, bslash_completions using Base.Meta +using Base: coalesce function completes_global(x, name) return startswith(x, name) && !('#' in x) @@ -40,7 +41,7 @@ function complete_symbol(sym, ffunc) lookup_module = true t = Union{} - if findlast(occursin(non_identifier_chars), sym) < findlast(equalto('.'), sym) + if coalesce(findlast(occursin(non_identifier_chars), sym), 0) < coalesce(findlast(equalto('.'), sym), 0) # Find module lookup_name, name = rsplit(sym, ".", limit=2) @@ -258,7 +259,7 @@ function find_start_brace(s::AbstractString; c_start='(', c_end=')') end braces != 1 && return 0:-1, -1 method_name_end = reverseind(s, i) - startind = nextind(s, findprev(occursin(non_identifier_chars), s, method_name_end)) + startind = nextind(s, coalesce(findprev(occursin(non_identifier_chars), s, method_name_end), 0)) return (startind:endof(s), method_name_end) end @@ -413,8 +414,8 @@ function afterusing(string::String, startpos::Int) end function bslash_completions(string, pos) - slashpos = findprev(equalto('\\'), string, pos) - if (findprev(occursin(bslash_separators), string, pos) < slashpos && + slashpos = coalesce(findprev(equalto('\\'), string, pos), 0) + if (coalesce(findprev(occursin(bslash_separators), string, pos), 0) < slashpos && !(1 < slashpos && (string[prevind(string, slashpos)]=='\\'))) # latex / emoji symbol substitution s = string[slashpos:pos] @@ -533,8 +534,8 @@ function completions(string, pos) return String[], 0:-1, false end - dotpos = findprev(equalto('.'), string, pos) - startpos = nextind(string, findprev(occursin(non_identifier_chars), string, pos)) + dotpos = coalesce(findprev(equalto('.'), string, pos), 0) + startpos = nextind(string, coalesce(findprev(occursin(non_identifier_chars), string, pos), 0)) ffunc = (mod,x)->true suggestions = String[] diff --git a/base/sparse/abstractsparse.jl b/base/sparse/abstractsparse.jl index bb0feaf29cfea..7ec75e1e6d03e 100644 --- a/base/sparse/abstractsparse.jl +++ b/base/sparse/abstractsparse.jl @@ -45,12 +45,12 @@ end # The following two methods should be overloaded by concrete types to avoid # allocating the I = find(...) -_sparse_findnextnz(v::AbstractSparseArray, i::Integer) = (I = find(!iszero, v); n = searchsortedfirst(I, i); n<=length(I) ? I[n] : zero(indtype(v))) -_sparse_findprevnz(v::AbstractSparseArray, i::Integer) = (I = find(!iszero, v); n = searchsortedlast(I, i); !iszero(n) ? I[n] : zero(indtype(v))) +_sparse_findnextnz(v::AbstractSparseArray, i::Integer) = (I = find(!iszero, v); n = searchsortedfirst(I, i); n<=length(I) ? I[n] : nothing) +_sparse_findprevnz(v::AbstractSparseArray, i::Integer) = (I = find(!iszero, v); n = searchsortedlast(I, i); !iszero(n) ? I[n] : nothing) function findnext(f::typeof(!iszero), v::AbstractSparseArray, i::Integer) j = _sparse_findnextnz(v, i) - while !iszero(j) && !f(v[j]) + while j !== nothing && !f(v[j]) j = _sparse_findnextnz(v, j+1) end return j @@ -58,7 +58,7 @@ end function findprev(f::typeof(!iszero), v::AbstractSparseArray, i::Integer) j = _sparse_findprevnz(v, i) - while !iszero(j) && !f(v[j]) + while j !== nothing && !f(v[j]) j = _sparse_findprevnz(v, j-1) end return j diff --git a/base/sparse/sparsematrix.jl b/base/sparse/sparsematrix.jl index c9a0da3d501d2..49f8655f60792 100644 --- a/base/sparse/sparsematrix.jl +++ b/base/sparse/sparsematrix.jl @@ -1319,7 +1319,7 @@ end function _sparse_findnextnz(m::SparseMatrixCSC, i::Integer) if i > length(m) - return zero(indtype(m)) + return nothing end row, col = Tuple(CartesianIndices(m)[i]) lo, hi = m.colptr[col], m.colptr[col+1] @@ -1328,16 +1328,14 @@ function _sparse_findnextnz(m::SparseMatrixCSC, i::Integer) return LinearIndices(m)[m.rowval[n], col] end nextcol = findnext(c->(c>hi), m.colptr, col+1) - if iszero(nextcol) - return zero(indtype(m)) - end + nextcol === nothing && return nothing nextlo = m.colptr[nextcol-1] return LinearIndices(m)[m.rowval[nextlo], nextcol-1] end function _sparse_findprevnz(m::SparseMatrixCSC, i::Integer) if iszero(i) - return zero(indtype(m)) + return nothing end row, col = Tuple(CartesianIndices(m)[i]) lo, hi = m.colptr[col], m.colptr[col+1] @@ -1346,9 +1344,7 @@ function _sparse_findprevnz(m::SparseMatrixCSC, i::Integer) return LinearIndices(m)[m.rowval[n], col] end prevcol = findprev(c->(c length(v.nzind) - return zero(indtype(v)) + return nothing else return v.nzind[n] end @@ -746,7 +746,7 @@ end function _sparse_findprevnz(v::SparseVector, i::Integer) n = searchsortedlast(v.nzind, i) if iszero(n) - return zero(indtype(v)) + return nothing else return v.nzind[n] end @@ -1950,7 +1950,7 @@ function sort(x::SparseVector{Tv,Ti}; kws...) where {Tv,Ti} allvals = push!(copy(nonzeros(x)),zero(Tv)) sinds = sortperm(allvals;kws...) n,k = length(x),length(allvals) - z = findfirst(equalto(k),sinds) + z = findfirst(equalto(k),sinds)::Int newnzind = collect(Ti,1:k-1) newnzind[z:end] .+= n-k+1 newnzvals = allvals[deleteat!(sinds[1:k],z)] diff --git a/base/stacktraces.jl b/base/stacktraces.jl index 0a3c5bcd5becb..7707aa31af903 100644 --- a/base/stacktraces.jl +++ b/base/stacktraces.jl @@ -9,6 +9,7 @@ module StackTraces import Base: hash, ==, show import Base.Serializer: serialize, deserialize using Base.Printf: @printf +using Base: coalesce export StackTrace, StackFrame, stacktrace, catch_stacktrace @@ -277,12 +278,12 @@ all frames above the specified function). Primarily used to remove `StackTraces` from the `StackTrace` prior to returning it. """ function remove_frames!(stack::StackTrace, name::Symbol) - splice!(stack, 1:findlast(frame -> frame.func == name, stack)) + splice!(stack, 1:coalesce(findlast(frame -> frame.func == name, stack), 0)) return stack end function remove_frames!(stack::StackTrace, names::Vector{Symbol}) - splice!(stack, 1:findlast(frame -> frame.func in names, stack)) + splice!(stack, 1:coalesce(findlast(frame -> frame.func in names, stack), 0)) return stack end diff --git a/base/stream.jl b/base/stream.jl index 58bf399afb26b..708f296f2e14e 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -271,13 +271,13 @@ end function wait_readbyte(x::LibuvStream, c::UInt8) if isopen(x) # fast path - findfirst(equalto(c), x.buffer) > 0 && return + findfirst(equalto(c), x.buffer) !== nothing && return else return end preserve_handle(x) try - while isopen(x) && findfirst(equalto(c), x.buffer) <= 0 + while isopen(x) && coalesce(findfirst(equalto(c), x.buffer), 0) <= 0 start_reading(x) # ensure we are reading wait(x.readnotify) end @@ -1237,7 +1237,7 @@ end show(io::IO, s::BufferStream) = print(io,"BufferStream() bytes waiting:",nb_available(s.buffer),", isopen:", s.is_open) function wait_readbyte(s::BufferStream, c::UInt8) - while isopen(s) && findfirst(equalto(c), s.buffer) <= 0 + while isopen(s) && findfirst(equalto(c), s.buffer) === nothing wait(s.r_c) end end diff --git a/base/strings/search.jl b/base/strings/search.jl index 8002e9fdd59e1..86ac474c90404 100644 --- a/base/strings/search.jl +++ b/base/strings/search.jl @@ -2,23 +2,24 @@ function findnext(pred::EqualTo{Char}, s::String, i::Integer) if i < 1 || i > sizeof(s) - i == sizeof(s) + 1 && return 0 + i == sizeof(s) + 1 && return nothing throw(BoundsError(s, i)) end @inbounds isvalid(s, i) || string_index_err(s, i) c = pred.x - c ≤ '\x7f' && return _search(s, c % UInt8, i) + c ≤ '\x7f' && return nothing_sentinel(_search(s, c % UInt8, i)) while true i = _search(s, first_utf8_byte(c), i) - (i == 0 || s[i] == c) && return i + i == 0 && return nothing + s[i] == c && return i i = next(s, i)[2] end end -findfirst(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray) = _search(a, pred.x) +findfirst(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray) = nothing_sentinel(_search(a, pred.x)) findnext(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray, i::Integer) = - _search(a, pred.x, i) + nothing_sentinel(_search(a, pred.x, i)) function _search(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = 1) if i < 1 @@ -43,19 +44,20 @@ end function findprev(pred::EqualTo{Char}, s::String, i::Integer) c = pred.x - c ≤ '\x7f' && return _rsearch(s, c % UInt8, i) + c ≤ '\x7f' && return nothing_sentinel(_rsearch(s, c % UInt8, i)) b = first_utf8_byte(c) while true i = _rsearch(s, b, i) - (i == 0 || s[i] == c) && return i + i == 0 && return nothing + s[i] == c && return i i = prevind(s, i) end end -findlast(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray) = _rsearch(a, pred.x) +findlast(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray) = nothing_sentinel(_rsearch(a, pred.x)) findprev(pred::EqualTo{<:Union{Int8,UInt8}}, a::ByteArray, i::Integer) = - _rsearch(a, pred.x, i) + nothing_sentinel(_rsearch(a, pred.x, i)) function _rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = sizeof(a)) if i < 1 @@ -109,10 +111,10 @@ function findnext(testf::Function, s::AbstractString, i::Integer) end i = j end - return 0 + return nothing end -in(c::Char, s::AbstractString) = (findfirst(equalto(c),s)!=0) +in(c::Char, s::AbstractString) = (findfirst(equalto(c),s)!==nothing) function _searchindex(s::Union{AbstractString,ByteArray}, t::Union{AbstractString,Char,Int8,UInt8}, @@ -124,7 +126,7 @@ function _searchindex(s::Union{AbstractString,ByteArray}, t1, j2 = next(t,start(t)) while true i = findnext(equalto(t1),s,i) - if i == 0 return 0 end + if i === nothing return 0 end c, ii = next(s,i) j = j2; k = ii matched = true @@ -147,7 +149,7 @@ function _searchindex(s::Union{AbstractString,ByteArray}, end end -_searchindex(s::AbstractString, t::Char, i::Integer) = findnext(equalto(t), s, i) +_searchindex(s::AbstractString, t::Char, i::Integer) = coalesce(findnext(equalto(t), s, i), 0) function _search_bloom_mask(c) UInt64(1) << (c & 63) @@ -158,7 +160,7 @@ _nthbyte(a::Union{AbstractVector{UInt8},AbstractVector{Int8}}, i) = a[i] function _searchindex(s::String, t::String, i::Integer) # Check for fast case of a single byte - endof(t) == 1 && return findnext(equalto(t[1]), s, i) + endof(t) == 1 && return coalesce(findnext(equalto(t[1]), s, i), 0) _searchindex(unsafe_wrap(Vector{UInt8},s), unsafe_wrap(Vector{UInt8},t), i) end @@ -171,7 +173,7 @@ function _searchindex(s::ByteArray, t::ByteArray, i::Integer) elseif m == 0 return 0 elseif n == 1 - return findnext(equalto(_nthbyte(t,1)), s, i) + return coalesce(findnext(equalto(_nthbyte(t,1)), s, i), 0) end w = m - n @@ -284,17 +286,17 @@ findlast(pattern::AbstractString, string::AbstractString) = # AbstractString implementation of the generic findprev interface function findprev(testf::Function, s::AbstractString, i::Integer) if i < 1 - return i == 0 ? 0 : throw(BoundsError(s, i)) + return i == 0 ? nothing : throw(BoundsError(s, i)) end n = ncodeunits(s) if i > n - return i == n+1 ? 0 : throw(BoundsError(s, i)) + return i == n+1 ? nothing : throw(BoundsError(s, i)) end # r[reverseind(r,i)] == reverse(r)[i] == s[i] # s[reverseind(s,j)] == reverse(s)[j] == r[j] r = reverse(s) j = findnext(testf, r, reverseind(r, i)) - j == 0 ? 0 : reverseind(s, j) + j === nothing ? nothing : reverseind(s, j) end function _rsearchindex(s::AbstractString, @@ -310,7 +312,7 @@ function _rsearchindex(s::AbstractString, t1, j2 = next(t, start(t)) while true i = findprev(equalto(t1), s, i) - i == 0 && return 0 + i === nothing && return 0 c, ii = next(rs, reverseind(rs, i)) j = j2; k = ii matched = true @@ -334,7 +336,7 @@ end function _rsearchindex(s::String, t::String, i::Integer) # Check for fast case of a single byte if endof(t) == 1 - return findprev(equalto(t[1]), s, i) + return coalesce(findprev(equalto(t[1]), s, i), 0) elseif endof(t) != 0 j = i ≤ ncodeunits(s) ? nextind(s, i)-1 : i return _rsearchindex(unsafe_wrap(Vector{UInt8}, s), unsafe_wrap(Vector{UInt8}, t), j) @@ -356,7 +358,7 @@ function _rsearchindex(s::ByteArray, t::ByteArray, k::Integer) elseif m == 0 return 0 elseif n == 1 - return findprev(equalto(_nthbyte(t,1)), s, k) + return coalesce(findprev(equalto(_nthbyte(t,1)), s, k), 0) end w = m - n diff --git a/base/strings/util.jl b/base/strings/util.jl index 80788e9b07e13..1053804bb2ea1 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -299,7 +299,7 @@ split(str::T, splitter::Char; function _split(str::AbstractString, splitter, limit::Integer, keep_empty::Bool, strs::Array) i = start(str) n = endof(str) - r = findfirst(splitter,str) + r = coalesce(findfirst(splitter,str), 0) if r != 0:-1 j, k = first(r), nextind(str,last(r)) while 0 < j <= n && length(strs) != limit-1 @@ -310,7 +310,7 @@ function _split(str::AbstractString, splitter, limit::Integer, keep_empty::Bool, i = k end (k <= j) && (k = nextind(str,j)) - r = findnext(splitter,str,k) + r = coalesce(findnext(splitter,str,k), 0) r == 0:-1 && break j, k = first(r), nextind(str,last(r)) end @@ -366,7 +366,7 @@ rsplit(str::T, splitter::Char; function _rsplit(str::AbstractString, splitter, limit::Integer, keep_empty::Bool, strs::Array) i = start(str) n = endof(str) - r = findlast(splitter, str) + r = coalesce(findlast(splitter, str), 0) j = first(r)-1 k = last(r) while((0 <= j < n) && (length(strs) != limit-1)) @@ -375,7 +375,7 @@ function _rsplit(str::AbstractString, splitter, limit::Integer, keep_empty::Bool n = j end (k <= j) && (j = prevind(str,j)) - r = findprev(splitter,str,j) + r = coalesce(findprev(splitter,str,j), 0) j = first(r)-1 k = last(r) end @@ -400,7 +400,7 @@ function replace(str::String, pat_repl::Pair; count::Integer=typemax(Int)) n = 1 e = endof(str) i = a = start(str) - r = findnext(pattern,str,i) + r = coalesce(findnext(pattern,str,i), 0) j, k = first(r), last(r) out = IOBuffer(StringVector(floor(Int, 1.2sizeof(str))), true, true) out.size = 0 @@ -417,7 +417,7 @@ function replace(str::String, pat_repl::Pair; count::Integer=typemax(Int)) else i = k = nextind(str, k) end - r = findnext(pattern,str,k) + r = coalesce(findnext(pattern,str,k), 0) r == 0:-1 || n == count && break j, k = first(r), last(r) n += 1 diff --git a/base/threadcall.jl b/base/threadcall.jl index 151e1153ee406..357b9c881477e 100644 --- a/base/threadcall.jl +++ b/base/threadcall.jl @@ -83,7 +83,7 @@ function do_threadcall(wrapper::Function, rettype::Type, argtypes::Vector, argva # wait for a worker thread to be available acquire(threadcall_restrictor) - idx = findfirst(equalto(nothing), thread_notifiers) + idx = findfirst(equalto(nothing), thread_notifiers)::Int thread_notifiers[idx] = Condition() # queue up the work to be done diff --git a/doc/src/manual/strings.md b/doc/src/manual/strings.md index 97991a0681258..7949d57be095e 100644 --- a/doc/src/manual/strings.md +++ b/doc/src/manual/strings.md @@ -517,7 +517,6 @@ julia> findfirst(equalto('p'), "xylophone") 5 julia> findfirst(equalto('z'), "xylophone") -0 ``` You can start the search for a character at a given offset by using [`findnext`](@ref) @@ -531,7 +530,6 @@ julia> findnext(equalto('o'), "xylophone", 5) 7 julia> findnext(equalto('o'), "xylophone", 8) -0 ``` You can use the [`contains`](@ref) function to check if a substring is contained in a string: diff --git a/stdlib/DelimitedFiles/src/DelimitedFiles.jl b/stdlib/DelimitedFiles/src/DelimitedFiles.jl index 714b02b4ee609..c8cf5c873f8fe 100644 --- a/stdlib/DelimitedFiles/src/DelimitedFiles.jl +++ b/stdlib/DelimitedFiles/src/DelimitedFiles.jl @@ -487,7 +487,7 @@ function val_opts(opts) for (opt_name, opt_val) in opts in(opt_name, valid_opts) || throw(ArgumentError("unknown option $opt_name")) - opt_typ = valid_opt_types[findfirst(equalto(opt_name), valid_opts)] + opt_typ = valid_opt_types[findfirst(equalto(opt_name), valid_opts)::Int] isa(opt_val, opt_typ) || throw(ArgumentError("$opt_name should be of type $opt_typ, got $(typeof(opt_val))")) d[opt_name] = opt_val diff --git a/stdlib/SharedArrays/test/runtests.jl b/stdlib/SharedArrays/test/runtests.jl index a512cfade2926..c8d075059a99e 100644 --- a/stdlib/SharedArrays/test/runtests.jl +++ b/stdlib/SharedArrays/test/runtests.jl @@ -190,7 +190,7 @@ s = copy(sdata(d)) ds = deepcopy(d) @test ds == d pids_d = procs(d) -remotecall_fetch(setindex!, pids_d[findfirst(id->(id != myid()), pids_d)], d, 1.0, 1:10) +remotecall_fetch(setindex!, pids_d[findfirst(id->(id != myid()), pids_d)::Int], d, 1.0, 1:10) @test ds != d @test s != d copyto!(d, s) diff --git a/stdlib/SuiteSparse/src/cholmod.jl b/stdlib/SuiteSparse/src/cholmod.jl index 183010b62dc98..be0272519a89f 100644 --- a/stdlib/SuiteSparse/src/cholmod.jl +++ b/stdlib/SuiteSparse/src/cholmod.jl @@ -1165,7 +1165,7 @@ sparse(FC::FactorComponent{Tv,:LD}) where {Tv} = sparse(Sparse(Factor(FC))) # Calculate the offset into the stype field of the cholmod_sparse_struct and # change the value -let offset = fieldoffset(C_Sparse{Float64}, findfirst(name -> name === :stype, fieldnames(C_Sparse{Float64}))) +let offset = fieldoffset(C_Sparse{Float64}, findfirst(name -> name === :stype, fieldnames(C_Sparse{Float64}))::Int) global change_stype! function change_stype!(A::Sparse, i::Integer) unsafe_store!(convert(Ptr{Cint}, pointer(A)), i, div(offset, 4) + 1) diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index b69ac63ee01b7..ced6a953fc7a2 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -36,11 +36,11 @@ end function scrub_backtrace(bt) do_test_ind = findfirst(ip -> ip_has_file_and_func(ip, @__FILE__, (:do_test, :do_test_throws)), bt) - if do_test_ind != 0 && length(bt) > do_test_ind + if do_test_ind !== nothing && length(bt) > do_test_ind bt = bt[do_test_ind + 1:end] end name_ind = findfirst(ip -> ip_has_file_and_func(ip, @__FILE__, (Symbol("macro expansion"),)), bt) - if name_ind != 0 && length(bt) != 0 + if name_ind !== nothing && length(bt) != 0 bt = bt[1:name_ind] end return bt diff --git a/test/arrayops.jl b/test/arrayops.jl index 79a91b9a46405..f375e22660cb2 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -429,29 +429,29 @@ end @test find(isodd,a) == [2,4,6,8] @test findfirst(!iszero, a) == 2 @test findfirst(a.==0) == 1 - @test findfirst(a.==5) == 0 + @test findfirst(a.==5) == nothing @test findfirst(equalto(3), [1,2,4,1,2,3,4]) == 6 @test findfirst(!equalto(1), [1,2,4,1,2,3,4]) == 2 @test findfirst(isodd, [2,4,6,3,9,2,0]) == 4 - @test findfirst(isodd, [2,4,6,2,0]) == 0 + @test findfirst(isodd, [2,4,6,2,0]) == nothing @test findnext(!iszero,a,4) == 4 @test findnext(!iszero,a,5) == 6 @test findnext(!iszero,a,1) == 2 @test findnext(equalto(1),a,4) == 6 - @test findnext(equalto(5),a,4) == 0 + @test findnext(equalto(5),a,4) == nothing @test findlast(!iszero, a) == 8 @test findlast(a.==0) == 5 - @test findlast(a.==5) == 0 + @test findlast(a.==5) == nothing @test findlast(equalto(3), [1,2,4,1,2,3,4]) == 6 @test findlast(isodd, [2,4,6,3,9,2,0]) == 5 - @test findlast(isodd, [2,4,6,2,0]) == 0 + @test findlast(isodd, [2,4,6,2,0]) == nothing @test findprev(!iszero,a,4) == 4 @test findprev(!iszero,a,5) == 4 - @test findprev(!iszero,a,1) == 0 + @test findprev(!iszero,a,1) == nothing @test findprev(equalto(1),a,4) == 2 @test findprev(equalto(1),a,8) == 6 @test findprev(isodd, [2,4,5,3,9,2,0], 7) == 5 - @test findprev(isodd, [2,4,5,3,9,2,0], 2) == 0 + @test findprev(isodd, [2,4,5,3,9,2,0], 2) == nothing @test findfirst(equalto(0x00), [0x01, 0x00]) == 2 @test findlast(equalto(0x00), [0x01, 0x00]) == 2 @test findnext(equalto(0x00), [0x00, 0x01, 0x00], 2) == 3 diff --git a/test/bitarray.jl b/test/bitarray.jl index b3b9e539da90c..4a45a04333b5c 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -1078,16 +1078,16 @@ timesofar("datamove") for m = 0:v1, b1 in Any[bitrand(m), trues(m), falses(m)] @check_bit_operation count(b1) Int - @check_bit_operation findfirst(b1) Int + @check_bit_operation findfirst(b1) Union{Int,Nothing} - @check_bit_operation findfirst(!iszero, b1) Int - @check_bit_operation findfirst(iszero, b1) Int - @check_bit_operation findfirst(equalto(3), b1) Int + @check_bit_operation findfirst(!iszero, b1) Union{Int,Nothing} + @check_bit_operation findfirst(iszero, b1) Union{Int,Nothing} + @check_bit_operation findfirst(equalto(3), b1) Union{Int,Nothing} - @check_bit_operation findfirst(x->x, b1) Int - @check_bit_operation findfirst(x->!x, b1) Int - @check_bit_operation findfirst(x->true, b1) Int - @check_bit_operation findfirst(x->false, b1) Int + @check_bit_operation findfirst(x->x, b1) Union{Int,Nothing} + @check_bit_operation findfirst(x->!x, b1) Union{Int,Nothing} + @check_bit_operation findfirst(x->true, b1) Union{Int,Nothing} + @check_bit_operation findfirst(x->false, b1) Union{Int,Nothing} @check_bit_operation find(b1) Vector{Int} end @@ -1125,14 +1125,14 @@ timesofar("nnz&find") for i = 1:2:2000 @test findprev(odds,i) == findprevnot(evens,i) == i @test findnext(odds,i) == findnextnot(evens,i) == i - @test findprev(evens,i) == findprevnot(odds,i) == i-1 - @test findnext(evens,i) == findnextnot(odds,i) == (i < 2000 ? i+1 : 0) + @test findprev(evens,i) == findprevnot(odds,i) == (i > 1 ? i-1 : nothing) + @test findnext(evens,i) == findnextnot(odds,i) == (i < 2000 ? i+1 : nothing) end for i = 2:2:2000 @test findprev(odds,i) == findprevnot(evens,i) == i-1 @test findprev(evens,i) == findprevnot(odds,i) == i @test findnext(evens,i) == findnextnot(odds,i) == i - @test findnext(odds,i) == findnextnot(evens,i) == (i < 2000 ? i+1 : 0) + @test findnext(odds,i) == findnextnot(evens,i) == (i < 2000 ? i+1 : nothing) end elts = (1:64:(64*64+1)) .+ (0:64) @@ -1162,9 +1162,9 @@ timesofar("nnz&find") @test findprev(b1, 777) == findprevnot(b2, 777) == findprev(!, b2, 777) == 777 @test findprev(b1, 776) == findprevnot(b2, 776) == findprev(!, b2, 776) == 77 @test findprev(b1, 77) == findprevnot(b2, 77) == findprev(!, b2, 77) == 77 - @test findprev(b1, 76) == findprevnot(b2, 76) == findprev(!, b2, 76) == 0 - @test findprev(b1, -1) == findprevnot(b2, -1) == findprev(!, b2, -1) == 0 - @test findprev(identity, b1, -1) == findprev(x->false, b1, -1) == findprev(x->true, b1, -1) == 0 + @test findprev(b1, 76) == findprevnot(b2, 76) == findprev(!, b2, 76) == nothing + @test findprev(b1, -1) == findprevnot(b2, -1) == findprev(!, b2, -1) == nothing + @test findprev(identity, b1, -1) == findprev(x->false, b1, -1) == findprev(x->true, b1, -1) == nothing @test_throws BoundsError findnext(b1, -1) @test_throws BoundsError findnextnot(b2, -1) @test_throws BoundsError findnext(!, b2, -1) @@ -1175,41 +1175,41 @@ timesofar("nnz&find") @test findnext(b1, 77) == findnextnot(b2, 77) == findnext(!, b2, 77) == 77 @test findnext(b1, 78) == findnextnot(b2, 78) == findnext(!, b2, 78) == 777 @test findnext(b1, 777) == findnextnot(b2, 777) == findnext(!, b2, 777) == 777 - @test findnext(b1, 778) == findnextnot(b2, 778) == findnext(!, b2, 778) == 0 - @test findnext(b1, 1001) == findnextnot(b2, 1001) == findnext(!, b2, 1001) == 0 - @test findnext(identity, b1, 1001) == findnext(x->false, b1, 1001) == findnext(x->true, b1, 1001) == 0 + @test findnext(b1, 778) == findnextnot(b2, 778) == findnext(!, b2, 778) == nothing + @test findnext(b1, 1001) == findnextnot(b2, 1001) == findnext(!, b2, 1001) == nothing + @test findnext(identity, b1, 1001) == findnext(x->false, b1, 1001) == findnext(x->true, b1, 1001) == nothing @test findlast(b1) == Base.findlastnot(b2) == 777 @test findfirst(b1) == Base.findfirstnot(b2) == 77 b0 = BitVector() - @test findprev(x->true, b0, -1) == 0 + @test findprev(x->true, b0, -1) == nothing @test_throws BoundsError findprev(x->true, b0, 1) @test_throws BoundsError findnext(x->true, b0, -1) - @test findnext(x->true, b0, 1) == 0 + @test findnext(x->true, b0, 1) == nothing b1 = falses(10) @test findprev(x->true, b1, 5) == 5 @test findnext(x->true, b1, 5) == 5 - @test findprev(x->true, b1, -1) == 0 - @test findnext(x->true, b1, 11) == 0 - @test findprev(x->false, b1, 5) == 0 - @test findnext(x->false, b1, 5) == 0 - @test findprev(x->false, b1, -1) == 0 - @test findnext(x->false, b1, 11) == 0 + @test findprev(x->true, b1, -1) == nothing + @test findnext(x->true, b1, 11) == nothing + @test findprev(x->false, b1, 5) == nothing + @test findnext(x->false, b1, 5) == nothing + @test findprev(x->false, b1, -1) == nothing + @test findnext(x->false, b1, 11) == nothing @test_throws BoundsError findprev(x->true, b1, 11) @test_throws BoundsError findnext(x->true, b1, -1) for l = [1, 63, 64, 65, 127, 128, 129] f = falses(l) t = trues(l) - @test findprev(f, l) == findprevnot(t, l) == 0 + @test findprev(f, l) == findprevnot(t, l) == nothing @test findprev(t, l) == findprevnot(f, l) == l b1 = falses(l) b1[end] = true b2 = .~b1 @test findprev(b1, l) == findprevnot(b2, l) == l - @test findprevnot(b1, l) == findprev(b2, l) == l-1 + @test findprevnot(b1, l) == findprev(b2, l) == (l == 1 ? nothing : l-1) if l > 1 b1 = falses(l) b1[end-1] = true diff --git a/test/strings/search.jl b/test/strings/search.jl index 8d499207589eb..98ecb59a1f919 100644 --- a/test/strings/search.jl +++ b/test/strings/search.jl @@ -26,38 +26,38 @@ end for str in [astr, GenericString(astr)] @test_throws BoundsError findnext(equalto('z'), str, 0) @test_throws BoundsError findnext(equalto('∀'), str, 0) - @test findfirst(equalto('x'), str) == 0 - @test findfirst(equalto('\0'), str) == 0 - @test findfirst(equalto('\u80'), str) == 0 - @test findfirst(equalto('∀'), str) == 0 + @test findfirst(equalto('x'), str) == nothing + @test findfirst(equalto('\0'), str) == nothing + @test findfirst(equalto('\u80'), str) == nothing + @test findfirst(equalto('∀'), str) == nothing @test findfirst(equalto('H'), str) == 1 @test findfirst(equalto('l'), str) == 3 @test findnext(equalto('l'), str, 4) == 4 @test findnext(equalto('l'), str, 5) == 11 - @test findnext(equalto('l'), str, 12) == 0 + @test findnext(equalto('l'), str, 12) == nothing @test findfirst(equalto(','), str) == 6 - @test findnext(equalto(','), str, 7) == 0 + @test findnext(equalto(','), str, 7) == nothing @test findfirst(equalto('\n'), str) == 14 - @test findnext(equalto('\n'), str, 15) == 0 + @test findnext(equalto('\n'), str, 15) == nothing @test_throws BoundsError findnext(equalto('ε'), str, nextind(str,endof(str))+1) @test_throws BoundsError findnext(equalto('a'), str, nextind(str,endof(str))+1) end # ascii backward search for str in [astr] - @test findlast(equalto('x'), str) == 0 - @test findlast(equalto('\0'), str) == 0 - @test findlast(equalto('\u80'), str) == 0 - @test findlast(equalto('∀'), str) == 0 + @test findlast(equalto('x'), str) == nothing + @test findlast(equalto('\0'), str) == nothing + @test findlast(equalto('\u80'), str) == nothing + @test findlast(equalto('∀'), str) == nothing @test findlast(equalto('H'), str) == 1 - @test findprev(equalto('H'), str, 0) == 0 + @test findprev(equalto('H'), str, 0) == nothing @test findlast(equalto('l'), str) == 11 @test findprev(equalto('l'), str, 5) == 4 @test findprev(equalto('l'), str, 4) == 4 @test findprev(equalto('l'), str, 3) == 3 - @test findprev(equalto('l'), str, 2) == 0 + @test findprev(equalto('l'), str, 2) == nothing @test findlast(equalto(','), str) == 6 - @test findprev(equalto(','), str, 5) == 0 + @test findprev(equalto(','), str, 5) == nothing @test findlast(equalto('\n'), str) == 14 end @@ -65,53 +65,53 @@ end for str in (u8str, GenericString(u8str)) @test_throws BoundsError findnext(equalto('z'), str, 0) @test_throws BoundsError findnext(equalto('∀'), str, 0) - @test findfirst(equalto('z'), str) == 0 - @test findfirst(equalto('\0'), str) == 0 - @test findfirst(equalto('\u80'), str) == 0 - @test findfirst(equalto('∄'), str) == 0 + @test findfirst(equalto('z'), str) == nothing + @test findfirst(equalto('\0'), str) == nothing + @test findfirst(equalto('\u80'), str) == nothing + @test findfirst(equalto('∄'), str) == nothing @test findfirst(equalto('∀'), str) == 1 @test_throws StringIndexError findnext(equalto('∀'), str, 2) - @test findnext(equalto('∀'), str, 4) == 0 + @test findnext(equalto('∀'), str, 4) == nothing @test findfirst(equalto('∃'), str) == 13 @test_throws StringIndexError findnext(equalto('∃'), str, 15) - @test findnext(equalto('∃'), str, 16) == 0 + @test findnext(equalto('∃'), str, 16) == nothing @test findfirst(equalto('x'), str) == 26 @test findnext(equalto('x'), str, 27) == 43 - @test findnext(equalto('x'), str, 44) == 0 + @test findnext(equalto('x'), str, 44) == nothing @test findfirst(equalto('δ'), str) == 17 @test_throws StringIndexError findnext(equalto('δ'), str, 18) @test findnext(equalto('δ'), str, nextind(str,17)) == 33 - @test findnext(equalto('δ'), str, nextind(str,33)) == 0 + @test findnext(equalto('δ'), str, nextind(str,33)) == nothing @test findfirst(equalto('ε'), str) == 5 @test findnext(equalto('ε'), str, nextind(str,5)) == 54 - @test findnext(equalto('ε'), str, nextind(str,54)) == 0 - @test findnext(equalto('ε'), str, nextind(str,endof(str))) == 0 - @test findnext(equalto('a'), str, nextind(str,endof(str))) == 0 + @test findnext(equalto('ε'), str, nextind(str,54)) == nothing + @test findnext(equalto('ε'), str, nextind(str,endof(str))) == nothing + @test findnext(equalto('a'), str, nextind(str,endof(str))) == nothing @test_throws BoundsError findnext(equalto('ε'), str, nextind(str,endof(str))+1) @test_throws BoundsError findnext(equalto('a'), str, nextind(str,endof(str))+1) end # utf-8 backward search for str in [u8str] - @test findlast(equalto('z'), str) == 0 - @test findlast(equalto('\0'), str) == 0 - @test findlast(equalto('\u80'), str) == 0 - @test findlast(equalto('∄'), str) == 0 + @test findlast(equalto('z'), str) == nothing + @test findlast(equalto('\0'), str) == nothing + @test findlast(equalto('\u80'), str) == nothing + @test findlast(equalto('∄'), str) == nothing @test findlast(equalto('∀'), str) == 1 - @test findprev(equalto('∀'), str, 0) == 0 + @test findprev(equalto('∀'), str, 0) == nothing @test findlast(equalto('∃'), str) == 13 @test findprev(equalto('∃'), str, 14) == 13 @test findprev(equalto('∃'), str, 13) == 13 - @test findprev(equalto('∃'), str, 12) == 0 + @test findprev(equalto('∃'), str, 12) == nothing @test findlast(equalto('x'), str) == 43 @test findprev(equalto('x'), str, 42) == 26 - @test findprev(equalto('x'), str, 25) == 0 + @test findprev(equalto('x'), str, 25) == nothing @test findlast(equalto('δ'), str) == 33 @test findprev(equalto('δ'), str, 32) == 17 - @test findprev(equalto('δ'), str, 16) == 0 + @test findprev(equalto('δ'), str, 16) == nothing @test findlast(equalto('ε'), str) == 54 @test findprev(equalto('ε'), str, 53) == 5 - @test findprev(equalto('ε'), str, 4) == 0 + @test findprev(equalto('ε'), str, 4) == nothing end # string forward search with a single-char string diff --git a/test/strings/types.jl b/test/strings/types.jl index 0eefac0549c3c..48df6715da005 100644 --- a/test/strings/types.jl +++ b/test/strings/types.jl @@ -119,7 +119,7 @@ end let str = "Hello, world!" u = SubString(str, 1, 5) @test findlast("World", u) == 0:-1 - @test findlast(equalto('z'), u) == 0 + @test findlast(equalto('z'), u) == nothing @test findlast("ll", u) == 3:4 end