From e39240070862da8108fdac81aa929992f9077259 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Mon, 19 Aug 2019 15:59:45 +0200 Subject: [PATCH 01/11] Make searchsorted* return values of keytype --- base/sort.jl | 18 +++++++++--------- test/sorting.jl | 13 +++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/base/sort.jl b/base/sort.jl index cb482792362c6..31a2c744fd69c 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -170,7 +170,7 @@ partialsort(v::AbstractVector, k::Union{Int,OrdinalRange}; kws...) = # index of the first value of vector a that is greater than or equal to x; # returns length(v)+1 if x is greater than all values in v. -function searchsortedfirst(v::AbstractVector, x, lo::T, hi::T, o::Ordering) where T<:Integer +function searchsortedfirst(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keytype(v) where T<:Integer u = T(1) lo = lo - u hi = hi + u @@ -187,7 +187,7 @@ end # index of the last value of vector a that is less than or equal to x; # returns 0 if x is less than all values of v. -function searchsortedlast(v::AbstractVector, x, lo::T, hi::T, o::Ordering) where T<:Integer +function searchsortedlast(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keytype(v) where T<:Integer u = T(1) lo = lo - u hi = hi + u @@ -221,10 +221,10 @@ function searchsorted(v::AbstractVector, x, ilo::T, ihi::T, o::Ordering) where T return a : b end end - return (lo + 1) : (hi - 1) + return convert(keytype(v), lo + 1) : convert(keytype(v), hi - 1) end -function searchsortedlast(a::AbstractRange{<:Real}, x::Real, o::DirectOrdering) +function searchsortedlast(a::AbstractRange{<:Real}, x::Real, o::DirectOrdering)::keytype(a) require_one_based_indexing(a) if step(a) == 0 lt(o, x, first(a)) ? 0 : length(a) @@ -234,7 +234,7 @@ function searchsortedlast(a::AbstractRange{<:Real}, x::Real, o::DirectOrdering) end end -function searchsortedfirst(a::AbstractRange{<:Real}, x::Real, o::DirectOrdering) +function searchsortedfirst(a::AbstractRange{<:Real}, x::Real, o::DirectOrdering)::keytype(a) require_one_based_indexing(a) if step(a) == 0 lt(o, first(a), x) ? length(a) + 1 : 1 @@ -244,7 +244,7 @@ function searchsortedfirst(a::AbstractRange{<:Real}, x::Real, o::DirectOrdering) end end -function searchsortedlast(a::AbstractRange{<:Integer}, x::Real, o::DirectOrdering) +function searchsortedlast(a::AbstractRange{<:Integer}, x::Real, o::DirectOrdering)::keytype(a) require_one_based_indexing(a) if step(a) == 0 lt(o, x, first(a)) ? 0 : length(a) @@ -253,7 +253,7 @@ function searchsortedlast(a::AbstractRange{<:Integer}, x::Real, o::DirectOrderin end end -function searchsortedfirst(a::AbstractRange{<:Integer}, x::Real, o::DirectOrdering) +function searchsortedfirst(a::AbstractRange{<:Integer}, x::Real, o::DirectOrdering)::keytype(a) require_one_based_indexing(a) if step(a) == 0 lt(o, first(a), x) ? length(a)+1 : 1 @@ -262,7 +262,7 @@ function searchsortedfirst(a::AbstractRange{<:Integer}, x::Real, o::DirectOrderi end end -function searchsortedfirst(a::AbstractRange{<:Integer}, x::Unsigned, o::DirectOrdering) +function searchsortedfirst(a::AbstractRange{<:Integer}, x::Unsigned, o::DirectOrdering)::keytype(a) require_one_based_indexing(a) if lt(o, first(a), x) if step(a) == 0 @@ -275,7 +275,7 @@ function searchsortedfirst(a::AbstractRange{<:Integer}, x::Unsigned, o::DirectOr end end -function searchsortedlast(a::AbstractRange{<:Integer}, x::Unsigned, o::DirectOrdering) +function searchsortedlast(a::AbstractRange{<:Integer}, x::Unsigned, o::DirectOrdering)::keytype(a) require_one_based_indexing(a) if lt(o, x, first(a)) 0 diff --git a/test/sorting.jl b/test/sorting.jl index 8b58a2d2620ef..fd2bec99384ec 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -99,6 +99,19 @@ end @test searchsortedlast(500:1.0:600, -1.0e20) == 0 @test searchsortedlast(500:1.0:600, 1.0e20) == 101 end + + @testset "issue 32568" begin + for R in numTypes, T in numTypes + for arr in [R[1:5;], R(1):R(5), R(1):2:R(5)] + @test eltype(searchsorted(arr, T(2))) == keytype(arr) + @test eltype(searchsorted(arr, T(2), big(1), big(4), Forward)) == keytype(arr) + @test searchsortedfirst(arr, T(2)) isa keytype(arr) + @test searchsortedfirst(arr, T(2), big(1), big(4), Forward) isa keytype(arr) + @test searchsortedlast(arr, T(2)) isa keytype(arr) + @test searchsortedlast(arr, T(2), big(1), big(4), Forward) isa keytype(arr) + end + end + end end # exercise the codepath in searchsorted* methods for ranges that check for zero step range struct ConstantRange{T} <: AbstractRange{T} From 555811321f2b95da692a68684ec5392429a91827 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Tue, 20 Aug 2019 13:22:20 +0200 Subject: [PATCH 02/11] Make findnext/findprev return keytype --- base/array.jl | 8 +++---- base/bitarray.jl | 14 ++++++----- base/strings/search.jl | 6 ++--- stdlib/SparseArrays/test/sparse.jl | 26 ++++++++++++++++++++ test/arrayops.jl | 20 ++++++++++++++++ test/bitarray.jl | 35 +++++++++++++++++++++++++++ test/strings/search.jl | 38 ++++++++++++++++++++++++++++++ test/tuple.jl | 7 ++++++ 8 files changed, 141 insertions(+), 13 deletions(-) diff --git a/base/array.jl b/base/array.jl index 1811e44f9e376..04ddc8d536dae 100644 --- a/base/array.jl +++ b/base/array.jl @@ -1617,7 +1617,7 @@ CartesianIndex(2, 1) """ function findnext(A, start) l = last(keys(A)) - i = start + i = oftype(l, start) i > l && return nothing while true A[i] && return i @@ -1699,7 +1699,7 @@ CartesianIndex(1, 1) """ function findnext(testf::Function, A, start) l = last(keys(A)) - i = start + i = oftype(l, start) i > l && return nothing while true testf(A[i]) && return i @@ -1796,8 +1796,8 @@ CartesianIndex(2, 1) ``` """ function findprev(A, start) - i = start f = first(keys(A)) + i = oftype(f, start) i < f && return nothing while true A[i] && return i @@ -1887,8 +1887,8 @@ CartesianIndex(2, 1) ``` """ function findprev(testf::Function, A, start) - i = start f = first(keys(A)) + i = oftype(f, start) i < f && return nothing while true testf(A[i]) && return i diff --git a/base/bitarray.jl b/base/bitarray.jl index a7549e832cbb7..4305841171beb 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -1385,7 +1385,7 @@ end function findnext(B::BitArray, start::Integer) start > 0 || throw(BoundsError(B, start)) start > length(B) && return nothing - unsafe_bitfindnext(B.chunks, start) + unsafe_bitfindnext(B.chunks, Int(start)) end #findfirst(B::BitArray) = findnext(B, 1) ## defined in array.jl @@ -1399,8 +1399,9 @@ function findnextnot(B::BitArray, start::Integer) l = length(Bc) l == 0 && return nothing - chunk_start = _div64(start-1)+1 - within_chunk_start = _mod64(start-1) + st = Int(start) + chunk_start = _div64(st-1)+1 + within_chunk_start = _mod64(st-1) mask = ~(_msk64 << within_chunk_start) @inbounds if chunk_start < l @@ -1468,7 +1469,7 @@ end function findprev(B::BitArray, start::Integer) start > 0 || return nothing start > length(B) && throw(BoundsError(B, start)) - unsafe_bitfindprev(B.chunks, start) + unsafe_bitfindprev(B.chunks, Int(start)) end function findprevnot(B::BitArray, start::Integer) @@ -1477,8 +1478,9 @@ function findprevnot(B::BitArray, start::Integer) Bc = B.chunks - chunk_start = _div64(start-1)+1 - mask = ~_msk_end(start) + st = Int(start) + chunk_start = _div64(st-1)+1 + mask = ~_msk_end(st) @inbounds begin if Bc[chunk_start] | mask != _msk64 diff --git a/base/strings/search.jl b/base/strings/search.jl index 9840944da35df..7f474cc0eddf3 100644 --- a/base/strings/search.jl +++ b/base/strings/search.jl @@ -130,7 +130,7 @@ function findnext(testf::Function, s::AbstractString, i::Integer) @inbounds i == z || isvalid(s, i) || string_index_err(s, i) for (j, d) in pairs(SubString(s, i)) if testf(d) - return i + j - 1 + return Int(i + j - 1) end end return nothing @@ -272,7 +272,7 @@ julia> findnext("Lang", "JuliaLang", 2) 6:9 ``` """ -findnext(t::AbstractString, s::AbstractString, i::Integer) = _search(s, t, i) +findnext(t::AbstractString, s::AbstractString, i::Integer) = _search(s, t, Int(i)) """ findnext(ch::AbstractChar, string::AbstractString, start::Integer) @@ -484,7 +484,7 @@ julia> findprev("Julia", "JuliaLang", 6) 1:5 ``` """ -findprev(t::AbstractString, s::AbstractString, i::Integer) = _rsearch(s, t, i) +findprev(t::AbstractString, s::AbstractString, i::Integer) = _rsearch(s, t, Int(i)) """ findprev(ch::AbstractChar, string::AbstractString, start::Integer) diff --git a/stdlib/SparseArrays/test/sparse.jl b/stdlib/SparseArrays/test/sparse.jl index a3acbd3cdd411..89e3075ff7960 100644 --- a/stdlib/SparseArrays/test/sparse.jl +++ b/stdlib/SparseArrays/test/sparse.jl @@ -2333,6 +2333,32 @@ end @test findnext(!iszero, z,i) == findnext(!iszero, z_sp,i) @test findprev(!iszero, z,i) == findprev(!iszero, z_sp,i) end + + # issue 32568 + @test findnext(!iszero, x_sp, big(4)) isa keytype(x_sp) + @test findnext(!iszero, x_sp, big(5)) isa keytype(x_sp) + @test findnext(!iszero, x_sp, UInt(4)) isa keytype(x_sp) + @test findnext(!iszero, x_sp, UInt(5)) isa keytype(x_sp) + @test findprev(!iszero, x_sp, big(5)) isa keytype(x_sp) + @test findprev(!iszero, x_sp, big(6)) isa keytype(x_sp) + @test findprev(!iszero, x_sp, UInt(5)) isa keytype(x_sp) + @test findprev(!iszero, x_sp, UInt(6)) isa keytype(x_sp) + @test findnext(iseven, x_sp, big(4)) isa keytype(x_sp) + @test findnext(iseven, x_sp, big(5)) isa keytype(x_sp) + @test findnext(iseven, x_sp, UInt(4)) isa keytype(x_sp) + @test findnext(iseven, x_sp, UInt(5)) isa keytype(x_sp) + @test findprev(iseven, x_sp, big(4)) isa keytype(x_sp) + @test findprev(iseven, x_sp, big(5)) isa keytype(x_sp) + @test findprev(iseven, x_sp, UInt(4)) isa keytype(x_sp) + @test findprev(iseven, x_sp, UInt(5)) isa keytype(x_sp) + @test findnext(!iszero, z_sp, big(4)) isa keytype(z_sp) + @test findnext(!iszero, z_sp, big(5)) isa keytype(z_sp) + @test findnext(!iszero, z_sp, UInt(4)) isa keytype(z_sp) + @test findnext(!iszero, z_sp, UInt(5)) isa keytype(z_sp) + @test findprev(!iszero, z_sp, big(4)) isa keytype(z_sp) + @test findprev(!iszero, z_sp, big(5)) isa keytype(z_sp) + @test findprev(!iszero, z_sp, UInt(4)) isa keytype(z_sp) + @test findprev(!iszero, z_sp, UInt(5)) isa keytype(z_sp) end # #20711 diff --git a/test/arrayops.jl b/test/arrayops.jl index 7a2fa864f543c..63f6abcf5de69 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -561,6 +561,26 @@ end @test findlast(isequal(0x00), [0x01, 0x00]) == 2 @test findnext(isequal(0x00), [0x00, 0x01, 0x00], 2) == 3 @test findprev(isequal(0x00), [0x00, 0x01, 0x00], 2) == 1 + + @testset "issue 32568" begin + @test findnext(!iszero,a,big(1)) isa keytype(a) + @test findnext(!iszero,a,big(2)) isa keytype(a) + @test findnext(!iszero,a,UInt(1)) isa keytype(a) + @test findnext(!iszero,a,UInt(2)) isa keytype(a) + @test findprev(!iszero,a,big(4)) isa keytype(a) + @test findprev(!iszero,a,big(5)) isa keytype(a) + @test findprev(!iszero,a,UInt(4)) isa keytype(a) + @test findprev(!iszero,a,UInt(5)) isa keytype(a) + b = [true,false,true] + @test findnext(b,big(2)) isa keytype(b) + @test findnext(b,big(3)) isa keytype(b) + @test findnext(b,UInt(2)) isa keytype(b) + @test findnext(b,UInt(3)) isa keytype(b) + @test findprev(b,big(1)) isa keytype(b) + @test findprev(b,big(2)) isa keytype(b) + @test findprev(b,UInt(1)) isa keytype(b) + @test findprev(b,UInt(2)) isa keytype(b) + end end @testset "find with Matrix" begin A = [1 2 0; 3 4 0] diff --git a/test/bitarray.jl b/test/bitarray.jl index cbc615ac0b19c..9c520d9d5d2c9 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -1301,6 +1301,41 @@ timesofar("find") @test_throws BoundsError findprev(x->true, b1, 11) @test_throws BoundsError findnext(x->true, b1, -1) + @testset "issue 32568" begin + @test findnext(evens, big(1)) isa keytype(evens) + @test findnext(evens, big(2)) isa keytype(evens) + @test findnext(evens, UInt(1)) isa keytype(evens) + @test findnext(evens, UInt(2)) isa keytype(evens) + @test findprev(evens, big(3)) isa keytype(evens) + @test findprev(evens, big(4)) isa keytype(evens) + @test findprev(evens, UInt(3)) isa keytype(evens) + @test findprev(evens, UInt(4)) isa keytype(evens) + @test findnext(iseven, evens, big(1)) isa keytype(evens) + @test findnext(iseven, evens, big(2)) isa keytype(evens) + @test findnext(iseven, evens, UInt(1)) isa keytype(evens) + @test findnext(iseven, evens, UInt(2)) isa keytype(evens) + @test findprev(iseven, evens, big(3)) isa keytype(evens) + @test findprev(iseven, evens, big(4)) isa keytype(evens) + @test findprev(iseven, evens, UInt(3)) isa keytype(evens) + @test findprev(iseven, evens, UInt(4)) isa keytype(evens) + @test findnext(isequal(true), evens, big(1)) isa keytype(evens) + @test findnext(isequal(true), evens, big(2)) isa keytype(evens) + @test findnext(isequal(true), evens, UInt(1)) isa keytype(evens) + @test findnext(isequal(true), evens, UInt(2)) isa keytype(evens) + @test findprev(isequal(true), evens, big(3)) isa keytype(evens) + @test findprev(isequal(true), evens, big(4)) isa keytype(evens) + @test findprev(isequal(true), evens, UInt(3)) isa keytype(evens) + @test findprev(isequal(true), evens, UInt(4)) isa keytype(evens) + @test findnext(isequal(false), evens, big(1)) isa keytype(evens) + @test findnext(isequal(false), evens, big(2)) isa keytype(evens) + @test findnext(isequal(false), evens, UInt(1)) isa keytype(evens) + @test findnext(isequal(false), evens, UInt(2)) isa keytype(evens) + @test findprev(isequal(false), evens, big(3)) isa keytype(evens) + @test findprev(isequal(false), evens, big(4)) isa keytype(evens) + @test findprev(isequal(false), evens, UInt(3)) isa keytype(evens) + @test findprev(isequal(false), evens, UInt(4)) isa keytype(evens) + end + for l = [1, 63, 64, 65, 127, 128, 129] f = falses(l) t = trues(l) diff --git a/test/strings/search.jl b/test/strings/search.jl index 8de73e5c652e5..630115b1202e8 100644 --- a/test/strings/search.jl +++ b/test/strings/search.jl @@ -382,3 +382,41 @@ s_18109 = "fooα🐨βcd3" @test findall("aa", "aaaaaa") == [1:2, 3:4, 5:6] @test findall("aa", "aaaaaa", overlap=true) == [1:2, 2:3, 3:4, 4:5, 5:6] end + +# issue 32568 +@test eltype(findnext(r"l", astr, big(4))) == Int +@test eltype(findnext(r"l", astr, big(5))) == Int +@test eltype(findnext(r"l", astr, UInt(4))) == Int +@test eltype(findnext(r"l", astr, UInt(5))) == Int +@test findnext(isequal('l'), astr, big(4)) isa Int +@test findnext(isequal('l'), astr, big(5)) isa Int +@test findnext(isequal('l'), astr, UInt(4)) isa Int +@test findnext(isequal('l'), astr, UInt(5)) isa Int +@test findprev(isequal('l'), astr, big(5)) isa Int +@test findprev(isequal('l'), astr, big(4)) isa Int +@test findprev(isequal('l'), astr, UInt(4)) isa Int +@test findprev(isequal('l'), astr, UInt(5)) isa Int +@test findnext('l', astr, big(4)) isa Int +@test findnext('l', astr, big(5)) isa Int +@test findnext('l', astr, UInt(4)) isa Int +@test findnext('l', astr, UInt(5)) isa Int +@test findprev('l', astr, big(4)) isa Int +@test findprev('l', astr, big(5)) isa Int +@test findprev('l', astr, UInt(4)) isa Int +@test findprev('l', astr, UInt(5)) isa Int +@test findnext(isletter, astr, big(7)) isa Int +@test findnext(isletter, astr, big(8)) isa Int +@test findnext(isletter, astr, UInt(7)) isa Int +@test findnext(isletter, astr, UInt(8)) isa Int +@test findprev(isletter, astr, big(7)) isa Int +@test findprev(isletter, astr, big(8)) isa Int +@test findprev(isletter, astr, UInt(7)) isa Int +@test findprev(isletter, astr, UInt(8)) isa Int +@test eltype(findnext(",b", "foo,bar,baz", big(7))) == Int +@test eltype(findnext(",b", "foo,bar,baz", big(8))) == Int +@test eltype(findnext(",b", "foo,bar,baz", UInt(7))) == Int +@test eltype(findnext(",b", "foo,bar,baz", UInt(8))) == Int +@test eltype(findprev(",b", "foo,bar,baz", big(5))) == Int +@test eltype(findprev(",b", "foo,bar,baz", big(6))) == Int +@test eltype(findprev(",b", "foo,bar,baz", UInt(5))) == Int +@test eltype(findprev(",b", "foo,bar,baz", UInt(6))) == Int diff --git a/test/tuple.jl b/test/tuple.jl index 26d5d5f58d953..efd40aec02f93 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -439,6 +439,13 @@ end @test findprev(isequal(1), (1, 1), 1) == 1 @test findnext(isequal(1), (2, 3), 1) === nothing @test findprev(isequal(1), (2, 3), 2) === nothing + + @testset "issue 32568" begin + @test findnext(isequal(1), (1, 2), big(1)) isa Int + @test findprev(isequal(1), (1, 2), big(2)) isa Int + @test findnext(isequal(1), (1, 1), UInt(2)) isa Int + @test findprev(isequal(1), (1, 1), UInt(1)) isa Int + end end @testset "properties" begin From 831f607f40e6415e566303adccf248244586f814 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Tue, 20 Aug 2019 19:55:35 +0200 Subject: [PATCH 03/11] Use explicit return type in searchsorted --- base/sort.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/sort.jl b/base/sort.jl index 31a2c744fd69c..6c20fd47dee86 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -205,7 +205,7 @@ end # returns the range of indices of v equal to x # if v does not contain x, returns a 0-length range # indicating the insertion point of x -function searchsorted(v::AbstractVector, x, ilo::T, ihi::T, o::Ordering) where T<:Integer +function searchsorted(v::AbstractVector, x, ilo::T, ihi::T, o::Ordering)::UnitRange{keytype(v)} where T<:Integer u = T(1) lo = ilo - u hi = ihi + u @@ -221,7 +221,7 @@ function searchsorted(v::AbstractVector, x, ilo::T, ihi::T, o::Ordering) where T return a : b end end - return convert(keytype(v), lo + 1) : convert(keytype(v), hi - 1) + return (lo + 1) : (hi - 1) end function searchsortedlast(a::AbstractRange{<:Real}, x::Real, o::DirectOrdering)::keytype(a) From d820a592ed43cc084bb599a060effe787ca3913c Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Tue, 21 Apr 2020 14:44:03 +0200 Subject: [PATCH 04/11] Resolve bootstrap issue --- base/sort.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/sort.jl b/base/sort.jl index 7f0bc53c5f167..6370cc4beea65 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -10,7 +10,7 @@ using .Base: copymutable, LinearIndices, length, (:), AbstractVector, @inbounds, AbstractRange, @eval, @inline, Vector, @noinline, AbstractMatrix, AbstractUnitRange, isless, identity, eltype, >, <, <=, >=, |, +, -, *, !, extrema, sub_with_overflow, add_with_overflow, oneunit, div, getindex, setindex!, - length, resize!, fill, Missing, require_one_based_indexing + length, resize!, fill, Missing, require_one_based_indexing, keytype using .Base: >>>, !== From f55346e6fe9cfdaabf30fce4bea145b757d248ac Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Tue, 21 Apr 2020 20:04:10 +0200 Subject: [PATCH 05/11] Fix searchsortedfirst for unsigned integers --- base/sort.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base/sort.jl b/base/sort.jl index 6370cc4beea65..9a3dc2fd2e79a 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -280,7 +280,8 @@ function searchsortedfirst(a::AbstractRange{<:Integer}, x::Real, o::DirectOrderi elseif h < 0 && x < last(a) lastindex(a) + 1 else - -fld(floor(Integer, -x) + first(a), h) + 1 + y = isa(x, Unsigned) ? floor(-Signed(x)) : floor(Integer, -x) + -fld(y + Signed(first(a)), h) + 1 end end From ee5c89813aacc9a8a87bcdda957a029b932a26df Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Wed, 22 Apr 2020 14:25:50 +0200 Subject: [PATCH 06/11] Make tests more compact --- stdlib/SparseArrays/test/sparse.jl | 38 ++++++++------------- test/arrayops.jl | 28 ++++++---------- test/bitarray.jl | 46 ++++++++------------------ test/strings/search.jl | 53 ++++++++++-------------------- 4 files changed, 54 insertions(+), 111 deletions(-) diff --git a/stdlib/SparseArrays/test/sparse.jl b/stdlib/SparseArrays/test/sparse.jl index b89bbf052a9cf..8e50e8c8428bf 100644 --- a/stdlib/SparseArrays/test/sparse.jl +++ b/stdlib/SparseArrays/test/sparse.jl @@ -2464,30 +2464,20 @@ end end # issue 32568 - @test findnext(!iszero, x_sp, big(4)) isa keytype(x_sp) - @test findnext(!iszero, x_sp, big(5)) isa keytype(x_sp) - @test findnext(!iszero, x_sp, UInt(4)) isa keytype(x_sp) - @test findnext(!iszero, x_sp, UInt(5)) isa keytype(x_sp) - @test findprev(!iszero, x_sp, big(5)) isa keytype(x_sp) - @test findprev(!iszero, x_sp, big(6)) isa keytype(x_sp) - @test findprev(!iszero, x_sp, UInt(5)) isa keytype(x_sp) - @test findprev(!iszero, x_sp, UInt(6)) isa keytype(x_sp) - @test findnext(iseven, x_sp, big(4)) isa keytype(x_sp) - @test findnext(iseven, x_sp, big(5)) isa keytype(x_sp) - @test findnext(iseven, x_sp, UInt(4)) isa keytype(x_sp) - @test findnext(iseven, x_sp, UInt(5)) isa keytype(x_sp) - @test findprev(iseven, x_sp, big(4)) isa keytype(x_sp) - @test findprev(iseven, x_sp, big(5)) isa keytype(x_sp) - @test findprev(iseven, x_sp, UInt(4)) isa keytype(x_sp) - @test findprev(iseven, x_sp, UInt(5)) isa keytype(x_sp) - @test findnext(!iszero, z_sp, big(4)) isa keytype(z_sp) - @test findnext(!iszero, z_sp, big(5)) isa keytype(z_sp) - @test findnext(!iszero, z_sp, UInt(4)) isa keytype(z_sp) - @test findnext(!iszero, z_sp, UInt(5)) isa keytype(z_sp) - @test findprev(!iszero, z_sp, big(4)) isa keytype(z_sp) - @test findprev(!iszero, z_sp, big(5)) isa keytype(z_sp) - @test findprev(!iszero, z_sp, UInt(4)) isa keytype(z_sp) - @test findprev(!iszero, z_sp, UInt(5)) isa keytype(z_sp) + for T = (UInt, BigInt) + @test findnext(!iszero, x_sp, T(4)) isa keytype(x_sp) + @test findnext(!iszero, x_sp, T(5)) isa keytype(x_sp) + @test findprev(!iszero, x_sp, T(5)) isa keytype(x_sp) + @test findprev(!iszero, x_sp, T(6)) isa keytype(x_sp) + @test findnext(iseven, x_sp, T(4)) isa keytype(x_sp) + @test findnext(iseven, x_sp, T(5)) isa keytype(x_sp) + @test findprev(iseven, x_sp, T(4)) isa keytype(x_sp) + @test findprev(iseven, x_sp, T(5)) isa keytype(x_sp) + @test findnext(!iszero, z_sp, T(4)) isa keytype(z_sp) + @test findnext(!iszero, z_sp, T(5)) isa keytype(z_sp) + @test findprev(!iszero, z_sp, T(4)) isa keytype(z_sp) + @test findprev(!iszero, z_sp, T(5)) isa keytype(z_sp) + end end # #20711 diff --git a/test/arrayops.jl b/test/arrayops.jl index 7a070532727c9..3a2b31b094b79 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -565,24 +565,16 @@ end @test findnext(isequal(0x00), [0x00, 0x01, 0x00], 2) == 3 @test findprev(isequal(0x00), [0x00, 0x01, 0x00], 2) == 1 - @testset "issue 32568" begin - @test findnext(!iszero,a,big(1)) isa keytype(a) - @test findnext(!iszero,a,big(2)) isa keytype(a) - @test findnext(!iszero,a,UInt(1)) isa keytype(a) - @test findnext(!iszero,a,UInt(2)) isa keytype(a) - @test findprev(!iszero,a,big(4)) isa keytype(a) - @test findprev(!iszero,a,big(5)) isa keytype(a) - @test findprev(!iszero,a,UInt(4)) isa keytype(a) - @test findprev(!iszero,a,UInt(5)) isa keytype(a) - b = [true,false,true] - @test findnext(b,big(2)) isa keytype(b) - @test findnext(b,big(3)) isa keytype(b) - @test findnext(b,UInt(2)) isa keytype(b) - @test findnext(b,UInt(3)) isa keytype(b) - @test findprev(b,big(1)) isa keytype(b) - @test findprev(b,big(2)) isa keytype(b) - @test findprev(b,UInt(1)) isa keytype(b) - @test findprev(b,UInt(2)) isa keytype(b) + @testset "issue 32568" for T = (UInt, BigInt) + @test findnext(!iszero, a, T(1)) isa keytype(a) + @test findnext(!iszero, a, T(2)) isa keytype(a) + @test findprev(!iszero, a, T(4)) isa keytype(a) + @test findprev(!iszero, a, T(5)) isa keytype(a) + b = [true, false, true] + @test findnext(b, T(2)) isa keytype(b) + @test findnext(b, T(3)) isa keytype(b) + @test findprev(b, T(1)) isa keytype(b) + @test findprev(b, T(2)) isa keytype(b) end end @testset "find with Matrix" begin diff --git a/test/bitarray.jl b/test/bitarray.jl index 77fae35fddac0..a12d93cbef5b0 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -1307,39 +1307,19 @@ timesofar("find") @test_throws BoundsError findprev(x->true, b1, 11) @test_throws BoundsError findnext(x->true, b1, -1) - @testset "issue 32568" begin - @test findnext(evens, big(1)) isa keytype(evens) - @test findnext(evens, big(2)) isa keytype(evens) - @test findnext(evens, UInt(1)) isa keytype(evens) - @test findnext(evens, UInt(2)) isa keytype(evens) - @test findprev(evens, big(3)) isa keytype(evens) - @test findprev(evens, big(4)) isa keytype(evens) - @test findprev(evens, UInt(3)) isa keytype(evens) - @test findprev(evens, UInt(4)) isa keytype(evens) - @test findnext(iseven, evens, big(1)) isa keytype(evens) - @test findnext(iseven, evens, big(2)) isa keytype(evens) - @test findnext(iseven, evens, UInt(1)) isa keytype(evens) - @test findnext(iseven, evens, UInt(2)) isa keytype(evens) - @test findprev(iseven, evens, big(3)) isa keytype(evens) - @test findprev(iseven, evens, big(4)) isa keytype(evens) - @test findprev(iseven, evens, UInt(3)) isa keytype(evens) - @test findprev(iseven, evens, UInt(4)) isa keytype(evens) - @test findnext(isequal(true), evens, big(1)) isa keytype(evens) - @test findnext(isequal(true), evens, big(2)) isa keytype(evens) - @test findnext(isequal(true), evens, UInt(1)) isa keytype(evens) - @test findnext(isequal(true), evens, UInt(2)) isa keytype(evens) - @test findprev(isequal(true), evens, big(3)) isa keytype(evens) - @test findprev(isequal(true), evens, big(4)) isa keytype(evens) - @test findprev(isequal(true), evens, UInt(3)) isa keytype(evens) - @test findprev(isequal(true), evens, UInt(4)) isa keytype(evens) - @test findnext(isequal(false), evens, big(1)) isa keytype(evens) - @test findnext(isequal(false), evens, big(2)) isa keytype(evens) - @test findnext(isequal(false), evens, UInt(1)) isa keytype(evens) - @test findnext(isequal(false), evens, UInt(2)) isa keytype(evens) - @test findprev(isequal(false), evens, big(3)) isa keytype(evens) - @test findprev(isequal(false), evens, big(4)) isa keytype(evens) - @test findprev(isequal(false), evens, UInt(3)) isa keytype(evens) - @test findprev(isequal(false), evens, UInt(4)) isa keytype(evens) + @testset "issue 32568" for T = (UInt, BigInt) + for x = (1, 2) + @test findnext(evens, T(x)) isa keytype(evens) + @test findnext(iseven, evens, T(x)) isa keytype(evens) + @test findnext(isequal(true), evens, T(x)) isa keytype(evens) + @test findnext(isequal(false), evens, T(x)) isa keytype(evens) + end + for x = (3, 4) + @test findprev(evens, T(x)) isa keytype(evens) + @test findprev(iseven, evens, T(x)) isa keytype(evens) + @test findprev(isequal(true), evens, T(x)) isa keytype(evens) + @test findprev(isequal(false), evens, T(x)) isa keytype(evens) + end end for l = [1, 63, 64, 65, 127, 128, 129] diff --git a/test/strings/search.jl b/test/strings/search.jl index 741904f904956..f952229afdfe2 100644 --- a/test/strings/search.jl +++ b/test/strings/search.jl @@ -391,39 +391,20 @@ s_18109 = "fooα🐨βcd3" end # issue 32568 -@test eltype(findnext(r"l", astr, big(4))) == Int -@test eltype(findnext(r"l", astr, big(5))) == Int -@test eltype(findnext(r"l", astr, UInt(4))) == Int -@test eltype(findnext(r"l", astr, UInt(5))) == Int -@test findnext(isequal('l'), astr, big(4)) isa Int -@test findnext(isequal('l'), astr, big(5)) isa Int -@test findnext(isequal('l'), astr, UInt(4)) isa Int -@test findnext(isequal('l'), astr, UInt(5)) isa Int -@test findprev(isequal('l'), astr, big(5)) isa Int -@test findprev(isequal('l'), astr, big(4)) isa Int -@test findprev(isequal('l'), astr, UInt(4)) isa Int -@test findprev(isequal('l'), astr, UInt(5)) isa Int -@test findnext('l', astr, big(4)) isa Int -@test findnext('l', astr, big(5)) isa Int -@test findnext('l', astr, UInt(4)) isa Int -@test findnext('l', astr, UInt(5)) isa Int -@test findprev('l', astr, big(4)) isa Int -@test findprev('l', astr, big(5)) isa Int -@test findprev('l', astr, UInt(4)) isa Int -@test findprev('l', astr, UInt(5)) isa Int -@test findnext(isletter, astr, big(7)) isa Int -@test findnext(isletter, astr, big(8)) isa Int -@test findnext(isletter, astr, UInt(7)) isa Int -@test findnext(isletter, astr, UInt(8)) isa Int -@test findprev(isletter, astr, big(7)) isa Int -@test findprev(isletter, astr, big(8)) isa Int -@test findprev(isletter, astr, UInt(7)) isa Int -@test findprev(isletter, astr, UInt(8)) isa Int -@test eltype(findnext(",b", "foo,bar,baz", big(7))) == Int -@test eltype(findnext(",b", "foo,bar,baz", big(8))) == Int -@test eltype(findnext(",b", "foo,bar,baz", UInt(7))) == Int -@test eltype(findnext(",b", "foo,bar,baz", UInt(8))) == Int -@test eltype(findprev(",b", "foo,bar,baz", big(5))) == Int -@test eltype(findprev(",b", "foo,bar,baz", big(6))) == Int -@test eltype(findprev(",b", "foo,bar,baz", UInt(5))) == Int -@test eltype(findprev(",b", "foo,bar,baz", UInt(6))) == Int +for T = (UInt, BigInt) + for x = (4, 5) + @test eltype(findnext(r"l", astr, T(x))) == Int + @test findnext(isequal('l'), astr, T(x)) isa Int + @test findprev(isequal('l'), astr, T(x)) isa Int + @test findnext('l', astr, T(x)) isa Int + @test findprev('l', astr, T(x)) isa Int + end + for x = (5, 6) + @test eltype(findprev(",b", "foo,bar,baz", T(x))) == Int + end + for x = (7, 8) + @test eltype(findnext(",b", "foo,bar,baz", T(x))) == Int + @test findnext(isletter, astr, T(x)) isa Int + @test findprev(isletter, astr, T(x)) isa Int + end +end From c666306b373cc9f916517f52471c39f6ec7a8003 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Thu, 23 Apr 2020 20:30:15 +0200 Subject: [PATCH 07/11] Restrict unsafe_bitfindnext to Int --- base/bitarray.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/bitarray.jl b/base/bitarray.jl index 190fa0535ce4d..807d87ba0dc0b 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -1374,7 +1374,7 @@ end count(B::BitArray) = bitcount(B.chunks) -function unsafe_bitfindnext(Bc::Vector{UInt64}, start::Integer) +function unsafe_bitfindnext(Bc::Vector{UInt64}, start::Int) chunk_start = _div64(start-1)+1 within_chunk_start = _mod64(start-1) mask = _msk64 << within_chunk_start From 61abe1d0df784f90d9bbece294f748e1230c74a2 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Thu, 23 Apr 2020 20:38:28 +0200 Subject: [PATCH 08/11] Rename st -> start --- base/bitarray.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/base/bitarray.jl b/base/bitarray.jl index 807d87ba0dc0b..8df821b06a515 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -1404,6 +1404,7 @@ end # aux function: same as findnext(~B, start), but performed without temporaries function findnextnot(B::BitArray, start::Integer) + start = Int(start) start > 0 || throw(BoundsError(B, start)) start > length(B) && return nothing @@ -1411,9 +1412,8 @@ function findnextnot(B::BitArray, start::Integer) l = length(Bc) l == 0 && return nothing - st = Int(start) - chunk_start = _div64(st-1)+1 - within_chunk_start = _mod64(st-1) + chunk_start = _div64(start-1)+1 + within_chunk_start = _mod64(start-1) mask = ~(_msk64 << within_chunk_start) @inbounds if chunk_start < l @@ -1485,14 +1485,14 @@ function findprev(B::BitArray, start::Integer) end function findprevnot(B::BitArray, start::Integer) + start = Int(start) start > 0 || return nothing start > length(B) && throw(BoundsError(B, start)) Bc = B.chunks - st = Int(start) - chunk_start = _div64(st-1)+1 - mask = ~_msk_end(st) + chunk_start = _div64(start-1)+1 + mask = ~_msk_end(start) @inbounds begin if Bc[chunk_start] | mask != _msk64 From 57dd806019966f75128a8279f683a11e7c826837 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Fri, 24 Apr 2020 09:53:17 +0200 Subject: [PATCH 09/11] Remove unnecessary Unsigned check --- base/sort.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/base/sort.jl b/base/sort.jl index 532d04a1839de..ff8edf15bd645 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -285,11 +285,10 @@ function searchsortedfirst(a::AbstractRange{<:Integer}, x::Real, o::DirectOrderi lastindex(a) + 1 else if o isa ForwardOrdering - y = isa(x, Unsigned) ? floor(-Signed(x)) : floor(Integer, -x) + -fld(floor(Integer, -x) + Signed(first(a)), h) + 1 else - y = isa(x, Unsigned) ? ceil(-Signed(x)) : ceil(Integer, -x) + -fld(ceil(Integer, -x) + Signed(first(a)), h) + 1 end - -fld(y + Signed(first(a)), h) + 1 end end From 1e4db5237dfc4bfb32c9859e1fb8baf67e5c5bb3 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Fri, 24 Apr 2020 10:31:59 +0200 Subject: [PATCH 10/11] Move Int conversion --- base/strings/search.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base/strings/search.jl b/base/strings/search.jl index 7deb96622b62c..9dec4f1db66cc 100644 --- a/base/strings/search.jl +++ b/base/strings/search.jl @@ -125,12 +125,13 @@ findfirst(ch::AbstractChar, string::AbstractString) = findfirst(==(ch), string) # AbstractString implementation of the generic findnext interface function findnext(testf::Function, s::AbstractString, i::Integer) + i = Int(i) z = ncodeunits(s) + 1 1 ≤ i ≤ z || throw(BoundsError(s, i)) @inbounds i == z || isvalid(s, i) || string_index_err(s, i) for (j, d) in pairs(SubString(s, i)) if testf(d) - return Int(i + j - 1) + return i + j - 1 end end return nothing From 62d3586558b672339d84ced2f8c155721e8b3090 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Fri, 24 Apr 2020 11:47:18 +0200 Subject: [PATCH 11/11] Restrict unsafe_bitfindprev to Int --- base/bitarray.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/bitarray.jl b/base/bitarray.jl index 8df821b06a515..b5d47000f84a5 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -1459,7 +1459,7 @@ function findnext(testf::Function, B::BitArray, start::Integer) end #findfirst(testf::Function, B::BitArray) = findnext(testf, B, 1) ## defined in array.jl -function unsafe_bitfindprev(Bc::Vector{UInt64}, start::Integer) +function unsafe_bitfindprev(Bc::Vector{UInt64}, start::Int) chunk_start = _div64(start-1)+1 mask = _msk_end(start)