|
813 | 813 |
|
814 | 814 | Base.@propagate_inbounds dotview(args...) = Base.maybeview(args...)
|
815 | 815 |
|
| 816 | +## In specific instances, we can broadcast masked BitArrays whole chunks at a time |
| 817 | +# Very intentionally do not support much functionality here: scalar indexing would be O(n) |
| 818 | +struct BitMaskedBitArray{N,M} |
| 819 | + parent::BitArray{N} |
| 820 | + mask::BitArray{M} |
| 821 | + BitMaskedBitArray{N,M}(parent, mask) where {N,M} = new(parent, mask) |
| 822 | +end |
| 823 | +@inline function BitMaskedBitArray(parent::BitArray{N}, mask::BitArray{M}) where {N,M} |
| 824 | + @boundscheck checkbounds(parent, mask) |
| 825 | + BitMaskedBitArray{N,M}(parent, mask) |
| 826 | +end |
| 827 | +Base.@propagate_inbounds dotview(B::BitArray, i::BitArray) = BitMaskedBitArray(B, i) |
| 828 | + |
| 829 | +Base.show(io::IO, B::BitMaskedBitArray) = foreach(arg->show(io, arg), (typeof(B), (B.parent, B.mask))) |
| 830 | +broadcast!(::typeof(identity), B::BitMaskedBitArray, b::Bool) = fill!(B, b) |
| 831 | +broadcast!(f, B::BitMaskedBitArray, args...) = broadcast!(f, SubArray(B.parent, to_indices(B.parent, (B.mask,))), args...) |
| 832 | +function Base.fill!(B::BitMaskedBitArray, b::Bool) |
| 833 | + Bc = B.parent.chunks |
| 834 | + Ic = B.mask.chunks |
| 835 | + @inbounds if b |
| 836 | + for i = 1:length(Bc) |
| 837 | + Bc[i] |= Ic[i] |
| 838 | + end |
| 839 | + else |
| 840 | + for i = 1:length(Bc) |
| 841 | + Bc[i] &= ~Ic[i] |
| 842 | + end |
| 843 | + end |
| 844 | + return B |
| 845 | +end |
| 846 | + |
816 | 847 | ############################################################
|
817 | 848 | # The parser turns @. into a call to the __dot__ macro,
|
818 | 849 | # which converts all function calls and assignments into
|
|
0 commit comments