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

Fixes for JuliaLang/julia/pull/26436. #517

Merged
merged 1 commit into from
Mar 17, 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
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ Currently, the `@compat` macro supports the following syntaxes:
`cov(::AbstractVector; corrected=)` and `cov(::AbstractVector, ::AbstractVector; corrected=)`
are only available on 0.6. ([#21709])

* `equalto` constructs an `EqualTo` object that can be used as a predicate ([#23812]).
* `isequal`, `==` and `in` have one argument "curried" forms. For example `isequal(x)`
returns a function that compares its arguments to `x` using `isequal` ([#26436]).

* `*(::Union{Char,AbstractString},::Union{Char,AbstractString})` concatenation. ([#22512])

Expand Down Expand Up @@ -350,18 +351,18 @@ 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]).
sometimes combined with `isequal` or `in` ([#24673], [#26436]).

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

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

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

* `Compat.indexin` accepts any iterable as first argument, returns `nothing` (rather than `0`)
for entries with no match and gives the index of the first (rather than the last) match
for entries with no match and gives the index of the first (rather than the last) match
([#25662], [#25998]).

* `isabstract` and `isleaftype` are now `isabstracttype` and `isconcretetype`, respectively
Expand Down Expand Up @@ -532,7 +533,6 @@ includes this fix. Find the minimum version from there.
[#23642]: https://github.com/JuliaLang/julia/issues/23642
[#23666]: https://github.com/JuliaLang/julia/issues/23666
[#23757]: https://github.com/JuliaLang/julia/issues/23757
[#23812]: https://github.com/JuliaLang/julia/issues/23812
[#23931]: https://github.com/JuliaLang/julia/issues/23931
[#24047]: https://github.com/JuliaLang/julia/issues/24047
[#24182]: https://github.com/JuliaLang/julia/issues/24182
Expand Down Expand Up @@ -599,4 +599,5 @@ includes this fix. Find the minimum version from there.
[#26149]: https://github.com/JuliaLang/julia/issues/26149
[#26156]: https://github.com/JuliaLang/julia/issues/26156
[#26316]: https://github.com/JuliaLang/julia/issues/26316
[#26442]: https://github.com/JuliaLang/julia/issues/26442
[#26436]: https://github.com/JuliaLang/julia/issues/26436
[#26442]: https://github.com/JuliaLang/julia/issues/26442
83 changes: 43 additions & 40 deletions src/Compat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -868,27 +868,39 @@ else
import Serialization
end

# 0.7.0-DEV.1993
@static if !isdefined(Base, :EqualTo)
if VERSION >= v"0.6.0"
include_string(@__MODULE__, """
struct EqualTo{T} <: Function
x::T
@static if VERSION < v"0.7.0-DEV.4592"
struct Fix2{F,T} <: Function
f::F
x::T
Fix2(f::F, x::T) where {F,T} = new{F,T}(f, x)
Fix2(f::Type{F}, x::T) where {F,T} = new{F,T}(f, x)
end
(f::Fix2)(y) = f.f(y, f.x)

EqualTo(x::T) where {T} = new{T}(x)
end
""")
Base.:(==)(x) = Fix2(==, x)
@static if VERSION >= v"0.7.0-DEV.1993"
Base.isequal(x) = Base.equalto(x)
else
include_string(@__MODULE__, """
immutable EqualTo{T} <: Function
x::T
end
""")
Base.isequal(x) = Fix2(isequal, x)
end
@static if VERSION >= v"0.7.0-DEV.3272"
Base.in(x) = Base.occursin(x)
else
Base.in(x) = Fix2(in, x)
end
(f::EqualTo)(y) = isequal(f.x, y)
const equalto = EqualTo
end
# keep these definitions to be non breaking for 0.6 usage
@static if VERSION < v"0.7.0-DEV.1993"
const EqualTo{T} = Fix2{typeof(isequal),T}
export equalto
equalto(x) = isequal(x)
end
@static if VERSION < v"0.7.0-DEV.3272"
const OccursIn{T} = Fix2{typeof(in),T}
export occursin
occursin(x) = in(x)
end


# 0.7.0-DEV.912
if VERSION < v"0.7.0-DEV.912"
Expand Down Expand Up @@ -1486,15 +1498,6 @@ end
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::AbstractUnitRange{<:Integer}) = x == 0:-1 ? nothing : x
zero2nothing(x) = x
Expand All @@ -1506,41 +1509,41 @@ else

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) =
Base.findnext(c::Fix2{typeof(isequal),Char}, s::AbstractString, i::Integer) = search(s, c.x, i)
Base.findfirst(c::Fix2{typeof(isequal),Char}, s::AbstractString) = search(s, c.x)
Base.findnext(b::Fix2{typeof(isequal),<: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}}) =
Base.findfirst(b::Fix2{typeof(isequal),<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
search(a, b.x)

Base.findnext(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
Base.findnext(c::Fix2{typeof(in),<: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}}},
Base.findfirst(c::Fix2{typeof(in),<: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::Base.IOBuffer) = search(buf, delim.x)
Base.findfirst(delim::Fix2{typeof(isequal),UInt8}, buf::Base.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) =
Base.findprev(c::Fix2{typeof(isequal),Char}, s::AbstractString, i::Integer) = rsearch(s, c.x, i)
Base.findlast(c::Fix2{typeof(isequal),Char}, s::AbstractString) = rsearch(s, c.x)
Base.findprev(b::Fix2{typeof(isequal),<: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}}) =
Base.findlast(b::Fix2{typeof(isequal),<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
rsearch(a, b.x)

Base.findprev(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
Base.findprev(c::Fix2{typeof(in),<: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}}},
Base.findlast(c::Fix2{typeof(in),<: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)
findall(b::Fix2{typeof(in)}, a) = findin(a, b.x)
# To fix ambiguity
findall(b::OccursIn, a::Number) = a in b.x ? [1] : Vector{Int}()
findall(b::Fix2{typeof(in)}, a::Number) = a in b.x ? [1] : Vector{Int}()
end

@static if VERSION < v"0.7.0-DEV.4047" #26089
Expand Down
65 changes: 46 additions & 19 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -947,13 +947,26 @@ module Test24648
end

let a = [0,1,2,3,0,1,2,3]
@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 findnext(equalto(1), a, 4) == 6
# @test findnext(equalto(5), a, 4) == 0
@test findlast(equalto(3), [1,2,4,1,2,3,4]) == 6
@test findprev(equalto(1), a, 4) == 2
@test findprev(equalto(1), a, 8) == 6
# curried isequal
@test findfirst(isequal(3), [1,2,4,1,2,3,4]) == 6
@test findfirst(!isequal(1), [1,2,4,1,2,3,4]) == 2
@test findnext(isequal(1), a, 4) == 6
# @test findnext(isequal(5), a, 4) == 0
@test findlast(isequal(3), [1,2,4,1,2,3,4]) == 6
@test findprev(isequal(1), a, 4) == 2
@test findprev(isequal(1), a, 8) == 6
if VERSION < v"0.7.0-DEV.4592"
# test that equalto work on 0.6
@test findfirst(equalto(3), [1,2,4,1,2,3,4]) == 6
@test findfirst(!equalto(1), [1,2,4,1,2,3,4]) == 2
end
# curried ==
@test findfirst(==(3), [1,2,4,1,2,3,4]) == 6
@test findfirst(!(==(1)), [1,2,4,1,2,3,4]) == 2
@test findnext(==(1), a, 4) == 6
@test findlast(==(3), [1,2,4,1,2,3,4]) == 6
@test findprev(==(1), a, 4) == 2
@test findprev(==(1), a, 8) == 6
end

# 0.7
Expand Down Expand Up @@ -1358,24 +1371,34 @@ end
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(isequal(0), [1, 0]) == f2(isequal(0), [1, 0], i) == 2
@test f1(isequal(9), [1, 0]) == f2(isequal(9), [1, 0], i) == nothing
@test f1(in([0, 2]), [1, 0]) == f2(in([0, 2]), [1, 0], i) == 2
@test f1(in([0, 2]), [1, 9]) == f2(in([0, 2]), [1, 9], i) == nothing
if VERSION < v"0.7.0-DEV.4592"
# test that occursin work on 0.6
@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
end
@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
@test f2(isequal('a'), "ba", i) == f1(isequal('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
@test f2(isequal(S(1)), T[0, 1], i) == f1(isequal(S(1)), T[0, 1]) == 2
@test f2(isequal(S(9)), T[0, 1], i) == f1(isequal(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
@test f2(in(chars), "ba", i) == f1(in(chars), "ba") == 2
@test f2(in(chars), "bx", i) == f1(in(chars), "bx") == nothing
if VERSION < v"0.7.0-DEV.4592"
# test that occursin work on 0.6
@test f2(occursin(chars), "ba", i) == f1(occursin(chars), "ba") == 2
@test f2(occursin(chars), "bx", i) == f1(occursin(chars), "bx") == nothing
end
end
end
@test findnext("a", "ba", 1) == findfirst("a", "ba") == 2:2
Expand All @@ -1392,11 +1415,15 @@ end
@test Compat.findnext(r"a", "ba", 1) == Compat.findfirst(r"a", "ba") == 2:2
@test Compat.findnext(r"z", "ba", 1) == Compat.findfirst(r"z", "ba") == nothing

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

@test findall([true, false, true]) == [1, 3]
@test findall(occursin([1, 2]), [1]) == [1]
@test findall(in([1, 2]), [1]) == [1]
if VERSION < v"0.7.0-DEV.4592"
# test that occursin work on 0.6
@test findall(occursin([1, 2]), [1]) == [1]
end

# 0.7.0-DEV.3666
module TestUUIDs
Expand Down