diff --git a/base/bitarray.jl b/base/bitarray.jl index 73f274df44a85..1c5344e657042 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -506,20 +506,23 @@ function BitArray{N}(A::AbstractArray{T,N}) where N where T Bc = B.chunks l = length(B) l == 0 && return B - ind = 1 + Aind = eachindex(A) + nextA = iterate(Aind) @inbounds begin for i = 1:length(Bc)-1 c = UInt64(0) for j = 0:63 + ind, Ast = nextA c |= (UInt64(convert(Bool, A[ind])::Bool) << j) - ind += 1 + nextA = iterate(Aind, Ast) end Bc[i] = c end c = UInt64(0) for j = 0:_mod64(l-1) + ind, Ast = nextA c |= (UInt64(convert(Bool, A[ind])::Bool) << j) - ind += 1 + nextA = iterate(Aind, Ast) end Bc[end] = c end @@ -721,24 +724,26 @@ function _unsafe_setindex!(B::BitArray, X::AbstractArray, I::BitArray) lx = length(X) last_chunk_len = _mod64(length(B)-1)+1 - c = 1 + Xind = eachindex(X) + nextX = iterate(Xind) for i = 1:lc @inbounds Imsk = Ic[i] @inbounds C = Bc[i] u = UInt64(1) for j = 1:(i < lc ? 64 : last_chunk_len) if Imsk & u != 0 - lx < c && throw_setindex_mismatch(X, c) - @inbounds x = convert(Bool, X[c]) + nextX === nothing && throw_setindex_mismatch(X, count(I)) + Xi, Xst = nextX + @inbounds x = convert(Bool, X[Xi]) C = ifelse(x, C | u, C & ~u) - c += 1 + nextX = iterate(Xind, Xst) end u <<= 1 end @inbounds Bc[i] = C end - if length(X) != c-1 - throw_setindex_mismatch(X, c-1) + if nextX !== nothing + throw_setindex_mismatch(X, count(I)) end return B end diff --git a/test/bitarray.jl b/test/bitarray.jl index d17a9856596a4..15ca0e4f7916f 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -1787,3 +1787,21 @@ end @test all(bitarray[rangein, rangeout] .== true) end end + +# issue #45825 + +isdefined(Main, :OffsetArrays) || @eval Main include("testhelpers/OffsetArrays.jl") +using .Main.OffsetArrays + +let all_false = OffsetArray(falses(2001), -1000:1000) + @test !any(==(true), all_false) + # should be run with --check-bounds=yes + @test !any(==(true), BitArray(all_false)) +end +let a = falses(1000), + msk = BitArray(rand(Bool, 1000)), + n = count(msk), + b = OffsetArray(rand(Bool, n), (-n÷2):(n÷2)-iseven(n)) + a[msk] = b + @test a[msk] == collect(b) +end