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

Improve corner cases of deleteat! #42144

Merged
merged 13 commits into from
Sep 22, 2021
18 changes: 14 additions & 4 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1462,12 +1462,22 @@ julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1
```
"""
deleteat!(a::Vector, i::Integer) = (_deleteat!(a, i, 1); a)
function deleteat!(a::Vector, i::Integer)
i isa Bool && depwarn("passing Bool as an index is deprecated", deleteat!)
JeffBezanson marked this conversation as resolved.
Show resolved Hide resolved
_deleteat!(a, i, 1)
return a
end

function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
n = length(a)
isempty(r) || _deleteat!(a, first(r), length(r))
return a
if eltype(r) === Bool
return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
else
n = length(a)
f = first(r)
f isa Bool && depwarn("passing Bool as an index is deprecated", deleteat!)
JeffBezanson marked this conversation as resolved.
Show resolved Hide resolved
isempty(r) || _deleteat!(a, f, length(r))
return a
end
end

"""
Expand Down
45 changes: 44 additions & 1 deletion base/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,7 @@ function _deleteat!(B::BitVector, i::Int)
end

function deleteat!(B::BitVector, i::Integer)
i isa Bool && depwarn("passing Bool as an index is deprecated", deleteat!)
JeffBezanson marked this conversation as resolved.
Show resolved Hide resolved
i = Int(i)
n = length(B)
1 <= i <= n || throw(BoundsError(B, i))
Expand Down Expand Up @@ -992,13 +993,14 @@ function deleteat!(B::BitVector, inds)
y = iterate(inds, s)
while y !== nothing
(i, s) = y
i isa Bool && depwarn("passing Bool as an index is deprecated", deleteat!)
if !(q <= i <= n)
i < q && throw(ArgumentError("indices must be unique and sorted"))
throw(BoundsError(B, i))
end
new_l -= 1
if i > q
copy_chunks!(Bc, p, Bc, Int(q), Int(i-q))
copy_chunks!(Bc, Int(p), Bc, Int(q), Int(i-q))
p += i-q
end
q = i+1
Expand All @@ -1019,6 +1021,47 @@ function deleteat!(B::BitVector, inds)
return B
end

function deleteat!(B::BitVector, inds::AbstractVector{Bool})
length(inds) == length(B) || throw(BoundsError(a, inds))

n = new_l = length(B)
y = findfirst(inds)
y === nothing && return B

Bc = B.chunks

p = y
s = y + 1
checkbounds(B, p)
q = p + 1
new_l -= 1
y = findnext(inds, s)
while y !== nothing
i = y
s = y + 1
new_l -= 1
if i > q
copy_chunks!(Bc, Int(p), Bc, Int(q), Int(i-q))
p += i - q
end
q = i + 1
y = findnext(inds, s)
end

q <= n && copy_chunks!(Bc, p, Bc, Int(q), Int(n - q + 1))

delta_k = num_bit_chunks(new_l) - length(Bc)
delta_k < 0 && _deleteend!(Bc, -delta_k)

B.len = new_l

if new_l > 0
Bc[end] &= _msk_end(new_l)
end

return B
end

function splice!(B::BitVector, i::Integer)
i = Int(i)
n = length(B)
Expand Down
32 changes: 32 additions & 0 deletions test/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1711,3 +1711,35 @@ end
@test typeof([a a ;;; a a]) <: BitArray
@test typeof([a a ;;; [a a]]) <: BitArray
end

@testset "deleteat! additional tests" begin
for v in ([1, 2, 3], [true, true, true], trues(3))
@test_throws BoundsError deleteat!(v, true:true)
end

for v in ([1], [true], trues(1))
@test length(deleteat!(v, false:false)) == 1
@test isempty(deleteat!(v, true:true))
end

x = trues(3)
x[3] = false
@test deleteat!(x, [UInt8(2)]) == [true, false]

function test_equivalence(n::Int)
x1 = rand(Bool, n)
x2 = BitVector(x1)
inds1 = rand(Bool, n)
inds2 = BitVector(inds1)
return deleteat!(copy(x1), findall(inds1)) ==
deleteat!(copy(x1), inds1) ==
deleteat!(copy(x2), inds1) ==
deleteat!(copy(x1), inds2) ==
deleteat!(copy(x2), inds2)
end

Random.seed!(1234)
for n in 1:20, _ in 1:100
@test test_equivalence(n)
end
end