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

replace BitArray(shape...) constructors/calls with BitArray(uninitialized, shape...) #24785

Merged
merged 7 commits into from
Nov 29, 2017
8 changes: 8 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ Language changes
For example, `f() = (global sin = "gluttony"; nothing)` will now resolve which module
contains `sin` eagerly, rather than delaying that decision until `f` is run. ([#22984]).

* Uninitialized `BitArray` constructors of the form `BitArray[{N}](shape...)` have been
deprecated in favor of equivalents accepting `uninitialized` (an alias for
`Uninitialized()`) as their first argument, as in
`BitArray[{N}](uninitialized, shape...)`. For example, `BitVector(3)` is now
`BitVector(uninitialized, 3)`, `BitMatrix((2, 4))` is now
`BitMatrix(uninitialized, (2, 4))`, and `BitArray{3}(11, 13, 17)` is now
`BitArray{3}(uninitialized, 11, 14, 17)` ([#24785]).

* Dispatch rules have been simplified:
method matching is now determined exclusively by subtyping;
the rule that method type parameters must also be captured has been removed.
Expand Down
67 changes: 35 additions & 32 deletions base/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mutable struct BitArray{N} <: DenseArray{Bool, N}
chunks::Vector{UInt64}
len::Int
dims::NTuple{N,Int}
function BitArray{N}(dims::Vararg{Int,N}) where N
function BitArray{N}(::Uninitialized, dims::Vararg{Int,N}) where N
n = 1
i = 1
for d in dims
Expand All @@ -34,33 +34,35 @@ end
# the first one is recognized by the help system; it would be nice
# to fix this.
"""
BitArray(dims::Integer...)
BitArray{N}(dims::NTuple{N,Int})
BitArray(uninitialized, dims::Integer...)
BitArray{N}(uninitialized, dims::NTuple{N,Int})

Construct an uninitialized [`BitArray`](@ref) with the given dimensions.
Behaves identically to the [`Array`](@ref) constructor.
Behaves identically to the [`Array`](@ref) constructor. See [`uninitialized`](@ref).

# Examples
```julia-repl
julia> BitArray(2, 2)
julia> BitArray(uninitialized, 2, 2)
2×2 BitArray{2}:
false false
false true

julia> BitArray((3, 1))
julia> BitArray(uninitialized, (3, 1))
3×1 BitArray{2}:
false
true
false
```
"""
BitArray(dims::Integer...) = BitArray(map(Int,dims))
BitArray(dims::NTuple{N,Int}) where {N} = BitArray{N}(dims...)
BitArray(::Uninitialized, dims::Integer...) = BitArray(uninitialized, map(Int,dims))
BitArray{N}(::Uninitialized, dims::Integer...) where {N} = BitArray{N}(uninitialized, map(Int,dims))
BitArray(::Uninitialized, dims::NTuple{N,Int}) where {N} = BitArray{N}(uninitialized, dims...)
BitArray{N}(::Uninitialized, dims::NTuple{N,Int}) where {N} = BitArray{N}(uninitialized, dims...)

const BitVector = BitArray{1}
const BitMatrix = BitArray{2}

BitVector() = BitArray{1}(0)
BitVector() = BitArray{1}(uninitialized, 0)

## utility functions ##

Expand Down Expand Up @@ -341,15 +343,17 @@ done(B::BitArray, i::Int) = i >= length(B)

## similar, fill!, copy! etc ##

similar(B::BitArray) = BitArray(size(B))
similar(B::BitArray, dims::Int...) = BitArray(dims)
similar(B::BitArray, dims::Dims) = BitArray(dims...)
similar(B::BitArray) = BitArray(uninitialized, size(B))
similar(B::BitArray, dims::Int...) = BitArray(uninitialized, dims)
similar(B::BitArray, dims::Dims) = BitArray(uninitialized, dims...)

similar(B::BitArray, T::Type{Bool}, dims::Dims) = BitArray(dims)
similar(B::BitArray, T::Type{Bool}, dims::Dims) = BitArray(uninitialized, dims)
# changing type to a non-Bool returns an Array
# (this triggers conversions like float(bitvector) etc.)
similar(B::BitArray, T::Type, dims::Dims) = Array{T}(uninitialized, dims)

similar(::Type{T}, shape::Tuple) where {T<:BitArray} = T(uninitialized, to_shape(shape))

function fill!(B::BitArray, x)
y = convert(Bool, x)
isempty(B) && return B
Expand All @@ -376,7 +380,7 @@ julia> falses(2,3)
false false false
```
"""
falses(dims::Dims) = fill!(BitArray(dims), false)
falses(dims::Dims) = fill!(BitArray(uninitialized, dims), false)
falses(dims::Integer...) = falses(map(Int,dims))
"""
falses(A)
Expand Down Expand Up @@ -411,7 +415,7 @@ julia> trues(2,3)
true true true
```
"""
trues(dims::Dims) = fill!(BitArray(dims), true)
trues(dims::Dims) = fill!(BitArray(uninitialized, dims), true)
trues(dims::Integer...) = trues(map(Int,dims))
"""
trues(A)
Expand Down Expand Up @@ -490,7 +494,7 @@ reshape(B::BitArray, dims::Tuple{Vararg{Int}}) = _bitreshape(B, dims)
function _bitreshape(B::BitArray, dims::NTuple{N,Int}) where N
prod(dims) == length(B) ||
throw(DimensionMismatch("new dimensions $(dims) must be consistent with array size $(length(B))"))
Br = BitArray{N}(ntuple(i->0,Val(N))...)
Br = BitArray{N}(uninitialized, ntuple(i->0,Val(N))...)
Br.chunks = B.chunks
Br.len = prod(dims)
N != 1 && (Br.dims = dims)
Expand All @@ -512,7 +516,7 @@ end

convert(::Type{BitArray}, A::AbstractArray{T,N}) where {T,N} = convert(BitArray{N}, A)
function convert(::Type{BitArray{N}}, A::AbstractArray{T,N}) where N where T
B = BitArray(size(A))
B = BitArray(uninitialized, size(A))
Bc = B.chunks
l = length(B)
l == 0 && return B
Expand All @@ -537,7 +541,7 @@ function convert(::Type{BitArray{N}}, A::AbstractArray{T,N}) where N where T
end

function convert(::Type{BitArray{N}}, A::Array{Bool,N}) where N
B = BitArray(size(A))
B = BitArray(uninitialized, size(A))
Bc = B.chunks
l = length(B)
l == 0 && return B
Expand Down Expand Up @@ -595,7 +599,7 @@ gen_bitarray(isz::IteratorSize, itr) = gen_bitarray_from_itr(itr, start(itr))

# generic iterable with known shape
function gen_bitarray(::HasShape, itr)
B = BitArray(size(itr))
B = BitArray(uninitialized, size(itr))
for (I,x) in zip(CartesianRange(indices(itr)), itr)
B[I] = x
end
Expand All @@ -604,13 +608,12 @@ end

# generator with known shape or length
function gen_bitarray(::HasShape, itr::Generator)
B = BitArray(size(itr))
B = BitArray(uninitialized, size(itr))
return fill_bitarray_from_itr!(B, itr, start(itr))
end
function gen_bitarray(::HasLength, itr)
n = length(itr)
B = BitArray(n)
return fill_bitarray_from_itr!(B, itr, start(itr))
b = BitVector(uninitialized, length(itr))
return fill_bitarray_from_itr!(b, itr, start(itr))
end

gen_bitarray(::IsInfinite, itr) = throw(ArgumentError("infinite-size iterable used in BitArray constructor"))
Expand All @@ -619,7 +622,7 @@ gen_bitarray(::IsInfinite, itr) = throw(ArgumentError("infinite-size iterable u
# use a Vector{Bool} cache for performance reasons

function gen_bitarray_from_itr(itr, st)
B = empty!(BitArray(bitcache_size))
B = empty!(BitVector(uninitialized, bitcache_size))
C = Vector{Bool}(uninitialized, bitcache_size)
Bc = B.chunks
ind = 1
Expand Down Expand Up @@ -1050,7 +1053,7 @@ function splice!(B::BitVector, i::Integer)
return v
end

const _default_bit_splice = BitVector(0)
const _default_bit_splice = BitVector()

function splice!(B::BitVector, r::Union{UnitRange{Int}, Integer}, ins::AbstractArray = _default_bit_splice)
n = length(B)
Expand All @@ -1064,7 +1067,7 @@ function splice!(B::BitVector, r::Union{UnitRange{Int}, Integer}, ins::AbstractA

if (i_f > n)
append!(B, Bins)
return BitVector(0)
return BitVector()
end

v = B[r] # TODO: change to a copy if/when subscripting becomes an ArrayView
Expand Down Expand Up @@ -1094,7 +1097,7 @@ function splice!(B::BitVector, r::Union{UnitRange{Int}, Integer}, ins::AbstractA
end

function splice!(B::BitVector, r::Union{UnitRange{Int}, Integer}, ins)
Bins = BitArray(length(ins))
Bins = BitVector(uninitialized, length(ins))
i = 1
for x in ins
Bins[i] = Bool(x)
Expand Down Expand Up @@ -1221,7 +1224,7 @@ broadcast(::typeof(xor), x::Bool, B::BitArray) = broadcast(xor, B, x)
for f in (:&, :|, :xor)
@eval begin
function broadcast(::typeof($f), A::BitArray, B::BitArray)
F = BitArray(promote_shape(size(A),size(B))...)
F = BitArray(uninitialized, promote_shape(size(A),size(B))...)
Fc = F.chunks
Ac = A.chunks
Bc = B.chunks
Expand Down Expand Up @@ -1803,7 +1806,7 @@ function hcat(B::BitVector...)
length(B[j]) == height ||
throw(DimensionMismatch("dimensions must match"))
end
M = BitArray(height, length(B))
M = BitMatrix(uninitialized, height, length(B))
for j = 1:length(B)
copy_chunks!(M.chunks, (height*(j-1))+1, B[j].chunks, 1, height)
end
Expand All @@ -1815,7 +1818,7 @@ function vcat(V::BitVector...)
for Vk in V
n += length(Vk)
end
B = BitArray(n)
B = BitVector(uninitialized, n)
j = 1
for Vk in V
copy_chunks!(B.chunks, j, Vk.chunks, 1, length(Vk))
Expand All @@ -1837,7 +1840,7 @@ function hcat(A::Union{BitMatrix,BitVector}...)
throw(DimensionMismatch("row lengths must match"))
end

B = BitArray(nrows, ncols)
B = BitMatrix(uninitialized, nrows, ncols)

pos = 1
for k = 1:nargs
Expand All @@ -1857,7 +1860,7 @@ function vcat(A::BitMatrix...)
size(A[j], 2) == ncols ||
throw(DimensionMismatch("column lengths must match"))
end
B = BitArray(nrows, ncols)
B = BitMatrix(uninitialized, nrows, ncols)
Bc = B.chunks
nrowsA = [size(a, 1) for a in A]
Ac = [a.chunks for a in A]
Expand Down
5 changes: 5 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,11 @@ end
@deprecate diagm(v::AbstractVector, k::Integer) diagm(k => v)
@deprecate diagm(x::Number) fill(x, 1, 1)

# deprecate BitArray{...}(shape...) constructors to BitArray{...}(uninitialized, shape...) equivalents
@deprecate BitArray{N}(dims::Vararg{Int,N}) where {N} BitArray{N}(uninitialized, dims)
@deprecate BitArray(dims::NTuple{N,Int}) where {N} BitArray(uninitialized, dims...)
@deprecate BitArray(dims::Integer...) BitArray(uninitialized, dims)

## deprecate full
export full
# full no-op fallback
Expand Down
4 changes: 2 additions & 2 deletions base/pkg/cache.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ function prefetch(pkg::AbstractString, url::AbstractString, sha1s::Vector)
end
try
LibGit2.set_remote_url(repo, "origin", normalized_url)
in_cache = BitArray(map(sha1->LibGit2.iscommit(sha1, repo), sha1s))
in_cache = BitVector(map(sha1->LibGit2.iscommit(sha1, repo), sha1s))
if !all(in_cache)
info("Updating cache of $pkg...")
LibGit2.fetch(repo)
in_cache = BitArray(map(sha1->LibGit2.iscommit(sha1, repo), sha1s))
in_cache = BitVector(map(sha1->LibGit2.iscommit(sha1, repo), sha1s))
end
sha1s[.!in_cache]
finally
Expand Down
8 changes: 4 additions & 4 deletions base/random/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ julia> bitrand(rng, 10)
true
```
"""
bitrand(r::AbstractRNG, dims::Dims) = rand!(r, BitArray(dims))
bitrand(r::AbstractRNG, dims::Integer...) = rand!(r, BitArray(convert(Dims, dims)))
bitrand(r::AbstractRNG, dims::Dims) = rand!(r, BitArray(uninitialized, dims))
bitrand(r::AbstractRNG, dims::Integer...) = rand!(r, BitArray(uninitialized, convert(Dims, dims)))

bitrand(dims::Dims) = rand!(BitArray(dims))
bitrand(dims::Integer...) = rand!(BitArray(convert(Dims, dims)))
bitrand(dims::Dims) = rand!(BitArray(uninitialized, dims))
bitrand(dims::Integer...) = rand!(BitArray(uninitialized, convert(Dims, dims)))


## randstring (often useful for temporary filenames/dirnames)
Expand Down
2 changes: 1 addition & 1 deletion doc/src/stdlib/arrays.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Base.getindex(::Type, ::Any...)
Base.zeros
Base.ones
Base.BitArray
Base.BitArray(::Integer...)
Base.BitArray(::Uninitialized, ::Integer...)
Base.BitArray(::Any)
Base.trues
Base.falses
Expand Down
2 changes: 1 addition & 1 deletion stdlib/Mmap/src/Mmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ function mmap(io::IOStream, ::Type{<:BitArray}, dims::NTuple{N,Integer},
throw(ArgumentError("the given file does not contain a valid BitArray of size $(join(dims, 'x')) (open with \"r+\" mode to override)"))
end
end
B = BitArray{N}(ntuple(i->0,Val(N))...)
B = BitArray{N}(uninitialized, ntuple(i->0,Val(N))...)
B.chunks = chunks
B.len = n
if N != 1
Expand Down
5 changes: 4 additions & 1 deletion test/TestHelpers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@ function Base.similar(A::AbstractArray, T::Type, inds::Tuple{UnitRange,Vararg{Un
OffsetArray(B, map(indsoffset, inds))
end

Base.similar(f::Union{Function,Type}, shape::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(f(map(length, shape)), map(indsoffset, shape))
Base.similar(f::Union{Function,Type}, shape::Tuple{UnitRange,Vararg{UnitRange}}) =
OffsetArray(f(map(length, shape)), map(indsoffset, shape))
Base.similar(::Type{T}, shape::Tuple{UnitRange,Vararg{UnitRange}}) where {T<:BitArray} =
OffsetArray(T(uninitialized, map(length, shape)), map(indsoffset, shape))

Base.reshape(A::AbstractArray, inds::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(reshape(A, map(length, inds)), map(indsoffset, inds))

Expand Down
Loading