Skip to content
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
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,14 @@ Currently, the `@compat` macro supports the following syntaxes:

* `find` is now `findall` ([#25545]).

* `search` is now `findfirst`/`findnext` and `rsearch` is now `findlast`/`findprev`,
sometimes combined with `equalto` or `occursin` ([#24673]).

* `Compat.findfirst`, `Compat.findnext`, `Compat.findlast` and `Compat.findprev`,
return `nothing` when no match is found (rather than `0`) as on Julia 0.7 ([#24673]).

* `findin(a, b)` is now `findall(occursin(b), a)` ([#24673]).

* `indmin` and `indmax` are now `argmin` and `argmax`, respectively ([#25654]).

* `isabstract` and `isleaftype` are now `isabstracttype` and `isconcretetype`, respectively
Expand Down Expand Up @@ -540,3 +548,4 @@ includes this fix. Find the minimum version from there.
[#25705]: https://github.com/JuliaLang/julia/issues/25705
[#25780]: https://github.com/JuliaLang/julia/issues/25780
[#24182]: https://github.com/JuliaLang/julia/issues/24182
[#24673]: https://github.com/JuliaLang/julia/issues/24673
65 changes: 64 additions & 1 deletion src/Compat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,7 @@ end

@static if VERSION < v"0.7.0-DEV.3025"
import Base: convert, ndims, getindex, size, length, eltype,
start, next, done, first, last
start, next, done, first, last, in, tail
export CartesianIndices, LinearIndices

struct CartesianIndices{N,R<:NTuple{N,AbstractUnitRange{Int}}} <: AbstractArray{CartesianIndex{N},N}
Expand Down Expand Up @@ -1433,6 +1433,7 @@ else
@eval const $(Symbol("@error")) = Base.$(Symbol("@error"))
end

# 0.7.0-DEV.3415
if !isdefined(Base, :findall)
const findall = find
export findall
Expand Down Expand Up @@ -1557,6 +1558,68 @@ end
export objectid
end

@static if VERSION >= v"0.7.0-DEV.3272"
findnext(xs...) = Base.findnext(xs...)
findfirst(xs...) = Base.findfirst(xs...)
findprev(xs...) = Base.findprev(xs...)
findlast(xs...) = Base.findlast(xs...)
else
struct OccursIn{T} <: Function
x::T

OccursIn(x::T) where {T} = new{T}(x)
end
(f::OccursIn)(y) = y in f.x
const occursin = OccursIn
export occursin

zero2nothing(x::Integer) = x == 0 ? nothing : x
zero2nothing(x) = x

findnext(xs...) = zero2nothing(Base.findnext(xs...))
findfirst(xs...) = zero2nothing(Base.findfirst(xs...))
findprev(xs...) = zero2nothing(Base.findprev(xs...))
findlast(xs...) = zero2nothing(Base.findlast(xs...))

Base.findnext(r::Regex, s::AbstractString, idx::Integer) = search(s, r, idx)
Base.findfirst(r::Regex, s::AbstractString) = search(s, r)
Base.findnext(c::EqualTo{Char}, s::AbstractString, i::Integer) = search(s, c.x, i)
Base.findfirst(c::EqualTo{Char}, s::AbstractString) = search(s, c.x)
Base.findnext(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) =
search(a, b.x, i)
Base.findfirst(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
search(a, b.x)

Base.findnext(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
s::AbstractString, i::Integer) =
search(s, c.x, i)
Base.findfirst(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
s::AbstractString) =
search(s, c.x)
Base.findnext(t::AbstractString, s::AbstractString, i::Integer) = search(s, t, i)
Base.findfirst(t::AbstractString, s::AbstractString) = search(s, t)

Base.findfirst(delim::EqualTo{UInt8}, buf::IOBuffer) = search(buf, delim.x)

Base.findprev(c::EqualTo{Char}, s::AbstractString, i::Integer) = rsearch(s, c.x, i)
Base.findlast(c::EqualTo{Char}, s::AbstractString) = rsearch(s, c.x)
Base.findprev(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) =
rsearch(a, b.x, i)
Base.findlast(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
rsearch(a, b.x)

Base.findprev(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
s::AbstractString, i::Integer) = rsearch(s, c.x, i)
Base.findlast(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
s::AbstractString) = rsearch(s, c.x)
Base.findprev(t::AbstractString, s::AbstractString, i::Integer) = rsearch(s, t, i)
Base.findlast(t::AbstractString, s::AbstractString) = rsearch(s, t)

findall(b::OccursIn, a) = findin(a, b.x)
# To fix ambiguity
findall(b::OccursIn, a::Number) = a in b.x ? [1] : Vector{Int}()
end

include("deprecated.jl")

end # module Compat
44 changes: 44 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,7 @@ let c = CartesianIndices(1:3, 1:2), l = LinearIndices(1:3, 1:2)
@test c[1:6] == vec(c)
@test l == l[c] == map(i -> l[i], c)
@test l[vec(c)] == collect(1:6)
@test CartesianIndex(1, 1) in CartesianIndices((3, 4))
end

if !isdefined(Base, Symbol("@info"))
Expand Down Expand Up @@ -1340,4 +1341,47 @@ let x = y = 1
@test objectid(x) == objectid(y)
end

# 0.7.0-DEV.3415
for (f1, f2, i) in ((Compat.findfirst, Compat.findnext, 1),
(Compat.findlast, Compat.findprev, 2))
# Generic methods
@test f1(equalto(0), [1, 0]) == f2(equalto(0), [1, 0], i) == 2
@test f1(equalto(9), [1, 0]) == f2(equalto(9), [1, 0], i) == nothing
@test f1(occursin([0, 2]), [1, 0]) == f2(occursin([0, 2]), [1, 0], i) == 2
@test f1(occursin([0, 2]), [1, 9]) == f2(occursin([0, 2]), [1, 9], i) == nothing
@test f1([true, false]) == f2([true, false], i) == 1
@test f1([false, false]) == f2([false, false], i) == nothing

# Specific methods
@test f2(equalto('a'), "ba", i) == f1(equalto('a'), "ba") == 2
for S in (Int8, UInt8), T in (Int8, UInt8)
# Bug in Julia 0.6
f1 === Compat.findlast && VERSION < v"0.7.0-DEV.3272" && continue
@test f2(equalto(S(1)), T[0, 1], i) == f1(equalto(S(1)), T[0, 1]) == 2
@test f2(equalto(S(9)), T[0, 1], i) == f1(equalto(S(9)), T[0, 1]) == nothing
end
for chars in (['a', 'z'], Set(['a', 'z']), ('a', 'z'))
@test f2(occursin(chars), "ba", i) == f1(occursin(chars), "ba") == 2
@test f2(occursin(chars), "bx", i) == f1(occursin(chars), "bx") == nothing
end
end
for (f1, f2, i) in ((findfirst, findnext, 1),
(findlast, findprev, 2),
(Compat.findfirst, Compat.findnext, 1),
(Compat.findlast, Compat.findprev, 2))
@test f2("a", "ba", i) == f1("a", "ba") == 2:2
@test f2("z", "ba", i) == f1("z", "ba") == 0:-1
end
for (f1, f2, i) in ((findfirst, findnext, 1),
(Compat.findfirst, Compat.findnext, 1))
@test f2(r"a", "ba", 1) == f1(r"a", "ba") == 2:2
@test f2(r"z", "ba", 1) == f1(r"z", "ba") == 0:-1
end

@test Compat.findfirst(equalto(UInt8(0)), IOBuffer(UInt8[1, 0])) == 2
@test Compat.findfirst(equalto(UInt8(9)), IOBuffer(UInt8[1, 0])) == nothing

@test findall([true, false, true]) == [1, 3]
@test findall(occursin([1, 2]), [1]) == [1]

nothing