From a5b1238e091ad9a8387da0ed35da59cde6f07381 Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Sat, 14 Oct 2017 01:03:52 -0700 Subject: [PATCH] Migrate API to use equalto, following JuliaLang/julia#23812 --- README.md | 8 +++-- REQUIRE | 1 + src/UniqueVectors.jl | 44 ++++++++++++++++++---------- test/runtests.jl | 70 +++++++++++++++++++++++--------------------- 4 files changed, 70 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 6d9bf01..ee90cc3 100644 --- a/README.md +++ b/README.md @@ -18,17 +18,19 @@ julia> ia[1] "cat" - julia> findfirst(ia, "dog") # executes quickly via a dictionary lookup, not sequential search + julia> findfirst(equalto("dog"), ia) # executes quickly via a dictionary lookup, not sequential search 2 +(Note that on julia 0.6, one must specify `using Compat` to bring `equalto` into the current namespace.) + As might be expected, `UniqueVector` supports many of the usual methods for `Vector`, but all operations enforce the condition that each element of the array must be unique. The mutating methods `push!`, `pop!`, and `empty!` are implemented as well, as these operations keep constant the indices of existing elements in the array, allowing the dictionary to be updated efficiently. In addition, `UniqueVector` implements a mutating `findfirst!` method, which returns the index of an element if it exists in the array, or otherwise appends the element and returns its new index: - julia> findfirst!(ia, "cat") + julia> findfirst!(equalto("cat"), ia) 1 - julia> findfirst!(ia, "horse") + julia> findfirst!(equalto("horse"), ia) 4 julia> ia diff --git a/REQUIRE b/REQUIRE index 137767a..e0ee8c3 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1 +1,2 @@ julia 0.6 +Compat 0.33.0 diff --git a/src/UniqueVectors.jl b/src/UniqueVectors.jl index ce24d8e..360fe92 100644 --- a/src/UniqueVectors.jl +++ b/src/UniqueVectors.jl @@ -2,6 +2,8 @@ __precompile__() module UniqueVectors +using Compat + include("delegate.jl") import Base: copy, in, getindex, findfirst, findlast, length, size, isempty, start, done, next, empty!, push!, pop!, setindex!, indexin, findin, findnext, findprev @@ -45,44 +47,54 @@ end in(item::T, ia::UniqueVector{T}) where {T} = haskey(ia.lookup, item) in(item, ia::UniqueVector{T}) where {T} = in(convert(T, item), ia) -findfirst(ia::UniqueVector{T}, item::T) where {T} = - get(ia.lookup, item, 0) +findfirst(p::equalto{<:T}, ia::UniqueVector{T}) where {T} = + get(ia.lookup, p.x, 0) -function findfirst!(ia::UniqueVector{T}, item::T) where {T} - rv = get!(ia.lookup, item) do +function findfirst!(p::equalto{<:T}, ia::UniqueVector{T}) where {T} + rv = get!(ia.lookup, p.x) do # NOTE: does not provide any exception safety guarantee - push!(ia.items, item) + push!(ia.items, p.x) return length(ia.items) end @assert length(ia.items) == length(ia.lookup) return rv end -findfirst(ia::UniqueVector{T}, item) where {T} = - findfirst(ia, convert(T, item)) +findfirst(p::equalto, ia::UniqueVector{T}) where {T} = + findfirst(equalto(convert(T, p.x)), ia) + +findfirst!(p::equalto, ia::UniqueVector{T}) where {T} = + findfirst!(equalto(convert(T, p.x)), ia) + +findlast(p::equalto, ia::UniqueVector) = + findfirst(p, ia) -findfirst!(ia::UniqueVector{T}, item) where {T} = - findfirst!(ia, convert(T, item)) +@deprecate findfirst(ia::UniqueVector, item) findfirst(equalto(item), ia) -findlast(ia::UniqueVector, item) = - findfirst(ia, item) +@deprecate findfirst!(ia::UniqueVector, item) findfirst!(equalto(item), ia) + +@deprecate findlast(ia::UniqueVector, item) findlast(equalto(item), ia) indexin(a::AbstractArray, b::UniqueVector) = - [findfirst(b, elt) for elt in a] + [findfirst(equalto(elt), b) for elt in a] findin(a, b::UniqueVector) = [i for (i, ai) in enumerate(a) if ai ∈ b] -function findnext(A::UniqueVector, v, i::Integer) - idx = findfirst(A, v) +function findnext(p::equalto, A::UniqueVector, i::Integer) + idx = findfirst(p, A) idx >= i ? idx : 0 end -function findprev(A::UniqueVector, v, i::Integer) - idx = findfirst(A, v) +@deprecate findnext(A::UniqueVector, v, i::Integer) findnext(equalto(v), A, i) + +function findprev(p::equalto, A::UniqueVector, i::Integer) + idx = findfirst(p, A) idx <= i ? idx : 0 end +@deprecate findprev(A::UniqueVector, v, i::Integer) findprev(equalto(v), A, i) + function push!(ia::UniqueVector{T}, item::T) where {T} if item in ia throw(ArgumentError("cannot add duplicate item to UniqueVector")) diff --git a/test/runtests.jl b/test/runtests.jl index a50149f..cf5c200 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,8 @@ using UniqueVectors using Base.Test +using Compat + @test length(UniqueVector([1,5,6,3])) == 4 @test_throws ArgumentError UniqueVector([1,3,5,6,3]) @@ -8,19 +10,19 @@ ia = UniqueVector{String}() @test isempty(ia) @test_throws ArgumentError pop!(ia) -@test findfirst(ia, "cat") == 0 -@test findfirst!(ia, "cat") == 1 +@test findfirst(equalto("cat"), ia) == 0 +@test findfirst!(equalto("cat"), ia) == 1 @test !isempty(ia) @test "cat" in ia @test "dog" ∉ ia -@test findfirst!(ia, "dog") == 2 -@test findfirst!(ia, "cat") == 1 -@test findfirst!(ia, "mouse") == 3 -@test findfirst!(ia, "dog") == 2 -@test findfirst(ia, "cat") == 1 -@test findlast(ia, "cat") == 1 -@test findfirst(ia, "dog") == 2 -@test findfirst(ia, "mouse") == 3 +@test findfirst!(equalto("dog"), ia) == 2 +@test findfirst!(equalto("cat"), ia) == 1 +@test findfirst!(equalto("mouse"), ia) == 3 +@test findfirst!(equalto("dog"), ia) == 2 +@test findfirst(equalto("cat"), ia) == 1 +@test findlast(equalto("cat"), ia) == 1 +@test findfirst(equalto("dog"), ia) == 2 +@test findfirst(equalto("mouse"), ia) == 3 @test ia[1] == "cat" @test ia[2] == "dog" @test ia[3] == "mouse" @@ -30,8 +32,8 @@ ia = UniqueVector{String}() @test endof(ia) == 3 ia2 = UniqueVector([1, 2, 3]) -@test findfirst(ia2, 0x02) == 2 -@test findfirst!(ia2, 0x02) == 2 +@test findfirst(equalto(0x02), ia2) == 2 +@test findfirst!(equalto(0x02), ia2) == 2 @test ia2 == UniqueVector(i for i in 1:3) for elt in [3,2,1] @test pop!(ia2) == elt @@ -43,19 +45,19 @@ ia2 = copy(ia) @test empty!(ia) === ia @test isempty(ia) -@test findfirst(ia, "cat") == 0 -@test findfirst!(ia, "horse") == 1 +@test findfirst(equalto("cat"), ia) == 0 +@test findfirst!(equalto("horse"), ia) == 1 @test_throws ArgumentError push!(ia, "horse") @test length(ia) == 1 @test push!(ia, "human") === ia -@test findfirst(ia, "human") == 2 +@test findfirst(equalto("human"), ia) == 2 @test pop!(ia) == "human" @test length(ia) == 1 @test ia[:] == ["horse"] -@test findfirst(ia, "human") == 0 +@test findfirst(equalto("human"), ia) == 0 @test ia2[:] == ["cat", "dog", "mouse"] -@test findfirst(ia2, "cat") == 1 +@test findfirst(equalto("cat"), ia2) == 1 let ia = UniqueVector(["cat", "dog", "mouse", "human"]), original = copy(ia) @@ -66,11 +68,11 @@ let ia = UniqueVector(["cat", "dog", "mouse", "human"]), original = copy(ia) swap!(ia, 2, 3) - @test findfirst(ia, "mouse") == 2 - @test findfirst(original, "mouse") == 3 + @test findfirst(equalto("mouse"), ia) == 2 + @test findfirst(equalto("mouse"), original) == 3 - @test findfirst(ia, "dog") == 3 - @test findfirst(original, "dog") == 2 + @test findfirst(equalto("dog"), ia) == 3 + @test findfirst(equalto("dog"), original) == 2 end @test UniqueVector([1,2,3,4]) == UniqueVector(1:4) @@ -78,9 +80,9 @@ end # Test it works with `Any` datatype let ia3 = UniqueVector([1,"cat",2,"dog"]) @test eltype(ia3) == Any - @test findfirst(ia3, 1) == 1 - @test findfirst!(ia3, "dog") == 4 - @test findfirst!(ia3, "horse") == 5 + @test findfirst(equalto(1), ia3) == 1 + @test findfirst!(equalto("dog"), ia3) == 4 + @test findfirst!(equalto("horse"), ia3) == 5 end # Test setindex! @@ -101,19 +103,19 @@ push!(ia5, 3) ia5[1] = 4 @test ia5[:] == [4.0] @test 4 ∈ ia5 -@test findfirst(ia5, 4) == 1 -@test findlast(ia5, 4) == 1 +@test findfirst(equalto(4), ia5) == 1 +@test findlast(equalto(4), ia5) == 1 # Test indexin and findin @test indexin([1,2,34,0,5,56], UniqueVector([34,56,35,1,5,0])) == [4,0,1,6,5,2] @test findin([1,2,34,0,5,56], UniqueVector([34,56,35,1,5,0])) == [1,3,4,5,6] # Test findnext and findprev -@test findnext(UniqueVector([3,5,7,9]), 7, 1) == 3 -@test findnext(UniqueVector([3,5,7,9]), 7, 2) == 3 -@test findnext(UniqueVector([3,5,7,9]), 7, 3) == 3 -@test findnext(UniqueVector([3,5,7,9]), 7, 4) == 0 -@test findprev(UniqueVector([3,5,7,9]), 7, 1) == 0 -@test findprev(UniqueVector([3,5,7,9]), 7, 2) == 0 -@test findprev(UniqueVector([3,5,7,9]), 7, 3) == 3 -@test findprev(UniqueVector([3,5,7,9]), 7, 4) == 3 +@test findnext(equalto(7), UniqueVector([3,5,7,9]), 1) == 3 +@test findnext(equalto(7), UniqueVector([3,5,7,9]), 2) == 3 +@test findnext(equalto(7), UniqueVector([3,5,7,9]), 3) == 3 +@test findnext(equalto(7), UniqueVector([3,5,7,9]), 4) == 0 +@test findprev(equalto(7), UniqueVector([3,5,7,9]), 1) == 0 +@test findprev(equalto(7), UniqueVector([3,5,7,9]), 2) == 0 +@test findprev(equalto(7), UniqueVector([3,5,7,9]), 3) == 3 +@test findprev(equalto(7), UniqueVector([3,5,7,9]), 4) == 3