Skip to content

Commit

Permalink
Merge search into findfirst/findnext and rsearch into findlast/findprev
Browse files Browse the repository at this point in the history
  • Loading branch information
nalimilan committed Jan 4, 2018
1 parent 69f9c2e commit 93eef2d
Show file tree
Hide file tree
Showing 33 changed files with 620 additions and 460 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,10 @@ Deprecated or removed
in favor of dot overloading (`getproperty`) so factors should now be accessed as e.g.
`F.Q` instead of `F[:Q]` ([#25184]).

* `search` and `rsearch` have been deprecated in favor of `findfirst`/`findnext` and
`findlast`/`findprev` respectively, in combination with the new `equalto` and `occursin`
predicates for some methods ([#24673]

Command-line option changes
---------------------------

Expand Down
2 changes: 1 addition & 1 deletion base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1237,7 +1237,7 @@ _cs(d, a, b) = (a == b ? a : throw(DimensionMismatch(
"mismatch in dimension $d (expected $a got $b)")))

dims2cat(::Val{n}) where {n} = ntuple(i -> (i == n), Val(n))
dims2cat(dims) = ntuple(i -> (i in dims), maximum(dims))
dims2cat(dims) = ntuple(occursin(dims), maximum(dims))

cat(dims, X...) = cat_t(dims, promote_eltypeof(X...), X...)

Expand Down
39 changes: 37 additions & 2 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3806,16 +3806,51 @@ end
@deprecate getq(F::Factorization) F.Q
end

# issue #5290
@deprecate lexcmp(x::AbstractArray, y::AbstractArray) cmp(x, y)
@deprecate lexcmp(x::Real, y::Real) cmp(isless, x, y)
@deprecate lexcmp(x::Complex, y::Complex) cmp((real(x),imag(x)), (real(y),imag(y)))
@deprecate lexcmp(x, y) cmp(x, y)

@deprecate lexless isless

# END 0.7 deprecations
@deprecate search(str::Union{String,SubString}, re::Regex, idx::Integer) findnext(re, str, idx)
@deprecate search(s::AbstractString, r::Regex, idx::Integer) findnext(r, s, idx)
@deprecate search(s::AbstractString, r::Regex) findfirst(r, s)
@deprecate search(s::AbstractString, c::Char, i::Integer) findnext(equalto(c), s, i)
@deprecate search(s::AbstractString, c::Char) findfirst(equalto(c), s)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}, i::Integer) findnext(equalto(b), a, i)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}) findfirst(equalto(b), a)
@deprecate search(a::String, b::Union{Int8,UInt8}, i::Integer) findnext(equalto(b), unsafe_wrap(Vector{UInt8}, a), i)
@deprecate search(a::String, b::Union{Int8,UInt8}) findfirst(equalto(b), unsafe_wrap(Vector{UInt8}, a))
@deprecate search(a::ByteArray, b::Char, i::Integer) findnext(equalto(UInt8(b)), a, i)
@deprecate search(a::ByteArray, b::Char) findfirst(equalto(UInt8(b)), a)

@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) findnext(occursin(c), s, i)
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) findfirst(occursin(c), s)
@deprecate search(s::AbstractString, t::AbstractString, i::Integer) findnext(t, s, i)
@deprecate search(s::AbstractString, t::AbstractString) findfirst(t, s)

@deprecate search(buf::IOBuffer, delim::UInt8) findfirst(equalto(delim), buf)
@deprecate search(buf::Base.GenericIOBuffer, delim::UInt8) findfirst(equalto(delim), buf)

@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) findprev(occursin(c), s, i)
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) findlast(occursin(c), s)
@deprecate rsearch(s::AbstractString, t::AbstractString, i::Integer) findprev(t, s, i)
@deprecate rsearch(s::AbstractString, t::AbstractString) findlast(t, s)
@deprecate rsearch(s::ByteArray, t::ByteArray, i::Integer) findprev(t, s, i)
@deprecate rsearch(s::ByteArray, t::ByteArray) findlast(t, s)

@deprecate rsearch(str::Union{String,SubString}, re::Regex, idx::Integer) findprev(re, str, idx)
@deprecate rsearch(str::Union{String,SubString}, re::Regex) findlast(re, str)
@deprecate rsearch(s::AbstractString, r::Regex, idx::Integer) findprev(r, s, idx)
@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)

# END 0.7 deprecations
# BEGIN 1.0 deprecations

# END 1.0 deprecations
2 changes: 1 addition & 1 deletion base/docs/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ completions(name::Symbol) = completions(string(name))
# Searching and apropos

# Docsearch simply returns true or false if an object contains the given needle
docsearch(haystack::AbstractString, needle) = !isempty(search(haystack, needle))
docsearch(haystack::AbstractString, needle) = !isempty(findfirst(needle, haystack))
docsearch(haystack::Symbol, needle) = docsearch(string(haystack), needle)
docsearch(::Nothing, needle) = false
function docsearch(haystack::Array, needle)
Expand Down
55 changes: 28 additions & 27 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -409,18 +409,6 @@ export
extrema,
fill!,
fill,
find,
findfirst,
findlast,
findin,
findmax,
findmin,
findmin!,
findmax!,
findn,
findnext,
findprev,
findnz,
first,
flipdim,
hcat,
Expand Down Expand Up @@ -476,9 +464,6 @@ export
rot180,
rotl90,
rotr90,
searchsorted,
searchsortedfirst,
searchsortedlast,
shuffle,
shuffle!,
size,
Expand All @@ -501,6 +486,34 @@ export
view,
zeros,

# search, find, match and related functions
contains,
eachmatch,
endswith,
equalto,
find,
findfirst,
findlast,
findin,
findmax,
findmin,
findmin!,
findmax!,
findn,
findnext,
findprev,
findnz,
ismatch,
occursin,
match,
matchall,
rsearchindex,
searchindex,
searchsorted,
searchsortedfirst,
searchsortedlast,
startswith,

# linear algebra
bkfact!,
bkfact,
Expand Down Expand Up @@ -611,7 +624,6 @@ export
any!,
any,
collect,
contains,
count,
delete!,
deleteat!,
Expand Down Expand Up @@ -679,7 +691,6 @@ export
# strings and text output
ascii,
base,
startswith,
bin,
bitstring,
bytes2hex,
Expand All @@ -691,22 +702,17 @@ export
digits,
digits!,
dump,
eachmatch,
endswith,
escape_string,
hex,
hex2bytes,
hex2bytes!,
info,
isascii,
ismatch,
isvalid,
join,
logging,
lpad,
lstrip,
match,
matchall,
ncodeunits,
ndigits,
nextind,
Expand All @@ -723,12 +729,8 @@ export
repr,
reverseind,
rpad,
rsearch,
rsearchindex,
rsplit,
rstrip,
search,
searchindex,
show,
showcompact,
showerror,
Expand Down Expand Up @@ -800,7 +802,6 @@ export
identity,
isbits,
isequal,
equalto,
isimmutable,
isless,
ifelse,
Expand Down
8 changes: 4 additions & 4 deletions base/iobuffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -426,18 +426,18 @@ read(io::GenericIOBuffer) = read!(io,StringVector(nb_available(io)))
readavailable(io::GenericIOBuffer) = read(io)
read(io::GenericIOBuffer, nb::Integer) = read!(io,StringVector(min(nb, nb_available(io))))

function search(buf::IOBuffer, delim::UInt8)
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,nb_available(buf))
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
end

function search(buf::GenericIOBuffer, delim::UInt8)
function findfirst(delim::EqualTo{UInt8}, buf::GenericIOBuffer)
data = buf.data
for i = buf.ptr : buf.size
@inbounds b = data[i]
if b == delim
if b == delim.x
return i - buf.ptr + 1
end
end
Expand Down
4 changes: 2 additions & 2 deletions base/libgit2/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -894,8 +894,8 @@ function Base.split(ce::ConfigEntry)
key = unsafe_string(ce.name)

# Determine the positions of the delimiters
subsection_delim = search(key, '.')
name_delim = rsearch(key, '.')
subsection_delim = findfirst(equalto('.'), key)
name_delim = findlast(equalto('.'), key)

section = SubString(key, 1, subsection_delim - 1)
subsection = SubString(key, subsection_delim + 1, name_delim - 1)
Expand Down
2 changes: 1 addition & 1 deletion base/methodshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function argtype_decl(env, n, sig::DataType, i::Int, nargs, isva::Bool) # -> (ar
n = n.args[1] # handle n::T in arg list
end
s = string(n)
i = search(s,'#')
i = findfirst(equalto('#'), s)
if i > 0
s = s[1:i-1]
end
Expand Down
19 changes: 19 additions & 0 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -843,3 +843,22 @@ The returned function is of type `Base.EqualTo`. This allows dispatching to
specialized methods by using e.g. `f::Base.EqualTo` in a method signature.
"""
const equalto = EqualTo

struct OccursIn{T} <: Function
x::T

OccursIn(x::T) where {T} = new{T}(x)
end

(f::OccursIn)(y) = y in f.x

"""
occursin(x)
Create a function that checks whether its argument is [`in`](@ref) `x`; i.e. returns
`y -> y in x`.
The returned function is of type `Base.OccursIn`. This allows dispatching to
specialized methods by using e.g. `f::Base.OccursIn` in a method signature.
"""
const occursin = OccursIn
8 changes: 4 additions & 4 deletions base/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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₊ = search(s, ('+','-'), i)
i₊ = findnext(occursin(('+','-')), s, i)
if i₊ == i # leading ± sign
i₊ = search(s, ('+','-'), i₊+1)
i₊ = findnext(occursin(('+','-')), s, i₊+1)
end
if i₊ != 0 && s[i₊-1] in ('e','E') # exponent sign
i₊ = search(s, ('+','-'), i₊+1)
i₊ = findnext(occursin(('+','-')), s, i₊+1)
end

# find trailing im/i/j
iᵢ = rsearch(s, ('m','i','j'), e)
iᵢ = findprev(occursin(('m','i','j')), s, e)
if iᵢ > 0 && s[iᵢ] == 'm' # im
iᵢ -= 1
if s[iᵢ] != 'i'
Expand Down
18 changes: 9 additions & 9 deletions base/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,16 @@ precompile(Tuple{typeof(Base.REPL.ip_matches_func), Ptr{Cvoid}, Symbol})
precompile(Tuple{typeof(Base.throw_boundserror), Array{Ptr{Cvoid}, 1}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Base.unsafe_copyto!), Array{Ptr{Cvoid}, 1}, Int64, Array{Ptr{Cvoid}, 1}, Int64, Int64})
precompile(Tuple{Type{Base.Channel{Any}}, Int64})
precompile(Tuple{typeof(Base.rsearch), String, UInt8, Int64})
precompile(Tuple{typeof(Base.rsearch), String, Char, Int64})
precompile(Tuple{typeof(Base.rsearch), Array{UInt8, 1}, UInt8, Int64})
precompile(Tuple{typeof(Base._rsearch), String, UInt8, Int64})
precompile(Tuple{typeof(Base._rsearch), String, Char, Int64})
precompile(Tuple{typeof(Base._rsearch), Array{UInt8, 1}, UInt8, Int64})
precompile(Tuple{typeof(Base._rsearchindex), Array{UInt8, 1}, Array{UInt8, 1}, Int64})
precompile(Tuple{typeof(Base._rsearch), Array{UInt8, 1}, Array{UInt8, 1}, Int64})
precompile(Tuple{typeof(Base.rsearch), Array{Int8, 1}, UInt8, Int64})
precompile(Tuple{typeof(Base._rsearch), Array{Int8, 1}, UInt8, Int64})
precompile(Tuple{typeof(Base._rsearchindex), Array{Int8, 1}, Array{UInt8, 1}, Int64})
precompile(Tuple{typeof(Base._rsearch), Array{Int8, 1}, Array{UInt8, 1}, Int64})
precompile(Tuple{typeof(Base.rsearch), Array{UInt8, 1}, Char, Int64})
precompile(Tuple{typeof(Base.rsearch), Array{Int8, 1}, Char, Int64})
precompile(Tuple{typeof(Base._rsearch), Array{UInt8, 1}, Char, Int64})
precompile(Tuple{typeof(Base._rsearch), Array{Int8, 1}, Char, Int64})
precompile(Tuple{typeof(Base.splice!), Array{Base.Multimedia.AbstractDisplay, 1}, Int64, Array{Any, 1}})
precompile(Tuple{typeof(Core.Inference.isbits), Base.LineEdit.EmptyCompletionProvider})
precompile(Tuple{typeof(Core.Inference.isbits), Base.LineEdit.EmptyHistoryProvider})
Expand Down Expand Up @@ -547,7 +547,7 @@ precompile(Tuple{typeof(Base.LineEdit.complete_line), Base.LineEdit.PromptState,
precompile(Tuple{typeof(Base.LineEdit.input_string_newlines_aftercursor), Base.LineEdit.PromptState})
precompile(Tuple{typeof(Base.LineEdit.complete_line), Base.REPL.REPLCompletionProvider, Base.LineEdit.PromptState})
precompile(Tuple{getfield(Base, Symbol("#kw##parse")), Array{Any, 1}, typeof(Base.parse), String})
precompile(Tuple{typeof(Base.rsearch), String, Array{Char, 1}, Int64})
precompile(Tuple{typeof(Base._rsearch), String, Array{Char, 1}, Int64})
precompile(Tuple{getfield(Base.REPLCompletions, Symbol("#kw##find_start_brace")), Array{Any, 1}, typeof(Base.REPLCompletions.find_start_brace), String})
precompile(Tuple{typeof(Core.Inference.isbits), Tuple{Nothing, Nothing, Nothing}})
precompile(Tuple{typeof(Base.isidentifier), Base.SubString{String}})
Expand Down Expand Up @@ -625,7 +625,7 @@ precompile(Tuple{typeof(Base.rsearchindex), String, String, Int64})
precompile(Tuple{typeof(Base._rsearch), String, String, Int64})
precompile(Tuple{typeof(Base.pushfirst!), Array{Base.SubString{String}, 1}, Base.SubString{String}})
precompile(Tuple{typeof(Base.startswith), String, Base.SubString{String}})
precompile(Tuple{typeof(Base.rsearch), String, Array{Char, 1}})
precompile(Tuple{typeof(Base._rsearch), String, Array{Char, 1}})
precompile(Tuple{getfield(Base, Symbol("#kw##rsplit")), Array{Any, 1}, typeof(Base.rsplit), String, String})
precompile(Tuple{typeof(Base.sort!), Array{String, 1}, Base.Sort.MergeSortAlg, Base.Order.ForwardOrdering})
precompile(Tuple{typeof(Base.sort!), Array{String, 1}, Int64, Int64, Base.Sort.InsertionSortAlg, Base.Order.ForwardOrdering})
Expand Down Expand Up @@ -1157,7 +1157,7 @@ precompile(Tuple{typeof(Base.resize!), Array{Base.Semaphore, 1}, Int64})
precompile(Tuple{typeof(Base.acquire), Base.Semaphore})
precompile(Tuple{typeof(Base.release), Base.Semaphore})
precompile(Tuple{typeof(Base.isreadable), Base.PipeEndpoint})
precompile(Tuple{typeof(Base.search), Base.GenericIOBuffer{Array{UInt8, 1}}, UInt8})
precompile(Tuple{typeof(Base.findfirst), UInt8, Base.GenericIOBuffer{Array{UInt8, 1}}})
precompile(Tuple{typeof(Base.start_reading), Base.PipeEndpoint})
precompile(Tuple{typeof(Base.wait_readbyte), Base.PipeEndpoint, UInt8})
precompile(Tuple{typeof(Base.readuntil), Base.PipeEndpoint, UInt8})
Expand Down
7 changes: 4 additions & 3 deletions base/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,8 @@ end
matchall(re::Regex, str::SubString, overlap::Bool=false) =
matchall(re, String(str), overlap)

function search(str::Union{String,SubString}, re::Regex, idx::Integer)
# TODO: return only start index and update deprecation
function findnext(re::Regex, str::Union{String,SubString}, idx::Integer)
if idx > nextind(str,endof(str))
throw(BoundsError())
end
Expand All @@ -294,10 +295,10 @@ function search(str::Union{String,SubString}, re::Regex, idx::Integer)
PCRE.exec(re.regex, str, idx-1, opts, re.match_data) ?
((Int(re.ovec[1])+1):prevind(str,Int(re.ovec[2])+1)) : (0:-1)
end
search(s::AbstractString, r::Regex, idx::Integer) = throw(ArgumentError(
findnext(r::Regex, s::AbstractString, idx::Integer) = throw(ArgumentError(
"regex search is only available for the String type; use String(s) to convert"
))
search(s::AbstractString, r::Regex) = search(s,r,start(s))
findfirst(r::Regex, s::AbstractString) = findnext(r,s,start(s))

struct SubstitutionString{T<:AbstractString} <: AbstractString
string::T
Expand Down
Loading

0 comments on commit 93eef2d

Please sign in to comment.