From b57e867740e9b848bccdde98ca23914ae361461b Mon Sep 17 00:00:00 2001 From: mtfishman Date: Fri, 27 Jun 2025 14:24:36 -0400 Subject: [PATCH 1/2] More general blockcheckbounds --- Project.toml | 2 +- src/abstractblockarray.jl | 32 ++++++++++++--- src/blockindices.jl | 49 ++++++++++++++++++++--- test/test_blockarrays.jl | 83 +++++++++++++++++++++++++++++++++++++++ test/test_blockindices.jl | 8 ++++ 5 files changed, 163 insertions(+), 11 deletions(-) diff --git a/Project.toml b/Project.toml index edf66627..e455ea42 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "BlockArrays" uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" -version = "1.6.3" +version = "1.6.4" [deps] ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" diff --git a/src/abstractblockarray.jl b/src/abstractblockarray.jl index eceb4023..7af9996c 100644 --- a/src/abstractblockarray.jl +++ b/src/abstractblockarray.jl @@ -88,6 +88,7 @@ ERROR: BlockBoundsError: attempt to access 2×2-blocked 2×3 BlockMatrix{Float64 """ @inline function blockcheckbounds(A::AbstractArray, i...) blockcheckbounds(Bool, A, i...) || throw(BlockBoundsError(A, i)) + return nothing end # linear block indexing @@ -99,15 +100,24 @@ end blockcheckbounds_indices(Bool, blockaxes(A), i) end +checkbounds(A::AbstractArray{T, N}, i::Block{N}) where {T,N} = blockcheckbounds(A, i) +checkbounds(A::AbstractArray{T}, i1::Block{1}, irest::Block{1}...) where {T} = blockcheckbounds(A, i1, irest...) +checkbounds(A::AbstractArray{T, N}, i::AbstractArray{<:Block{N}}) where {T,N} = blockcheckbounds(A, i) +checkbounds(A::AbstractArray{T}, i1::AbstractVector{<:Block{1}}, irest::AbstractVector{<:Block{1}}) where {T} = + blockcheckbounds(A, i1, irest...) + blockcheckbounds(A::AbstractArray{T, N}, i::Block{N}) where {T,N} = blockcheckbounds(A, i.n...) blockcheckbounds(A::AbstractArray{T, N}, i::Vararg{Block{1},N}) where {T,N} = blockcheckbounds(A, Int.(i)...) blockcheckbounds(::AbstractArray{T, 0}) where {T} = true blockcheckbounds(A::AbstractVector{T}, i::Block{1}) where {T} = blockcheckbounds(A, Int(i)) +blockcheckbounds(A::AbstractArray{T,N}, I::Vararg{BlockRange{1},N}) where {T,N} = blockcheckbounds(A, map(i -> Int.(i), I)...) +blockcheckbounds(A::AbstractArray{T,N}, I::BlockRange{N}) where {T,N} = blockcheckbounds(A, I.indices...) + """ - blockcheckbounds_indices(Bool, IA::Tuple{Vararg{BlockRange{1}}}, I::Tuple{Vararg{Integer}}) + blockcheckbounds_indices(Bool, IA::Tuple{Vararg{BlockRange{1}}}, I::Tuple) -Return true if the "requested" indices in the tuple `Block.(I)` fall within the bounds of the "permitted" +Return true if the "requested" indices in the tuple `map(i -> Block.(i), I)` fall within the bounds of the "permitted" indices specified by the tuple `IA`. This function recursively consumes elements of these tuples in a 1-for-1 fashion. @@ -125,6 +135,12 @@ true julia> BlockArrays.blockcheckbounds_indices(Bool, blockaxes(B), (4,1)) false + +julia> BlockArrays.blockcheckbounds_indices(Bool, blockaxes(B), (1:2,2:3)) +true + +julia> BlockArrays.blockcheckbounds_indices(Bool, blockaxes(B), (1:2,2:4)) +false ``` """ @inline blockcheckbounds_indices(::Type{Bool}, ::Tuple{}, ::Tuple{}) = true @@ -143,9 +159,9 @@ end end """ - blockcheckindex(Bool, inds::BlockRange{1}, index::Integer) + blockcheckindex(Bool, inds::BlockRange{1}, index) -Return `true` if `Block(index)` is within the bounds of `inds`. +Return `true` if `Block.(index)` is within the bounds of `inds`. # Examples ```jldoctest @@ -154,9 +170,15 @@ true julia> BlockArrays.blockcheckindex(Bool, BlockRange(1:2), 3) false + +julia> BlockArrays.blockcheckindex(Bool, BlockRange(1:3), 2:3) +true + +julia> BlockArrays.blockcheckindex(Bool, BlockRange(1:3), 2:4) +false ``` """ -@inline blockcheckindex(::Type{Bool}, inds::BlockRange{1}, i::Integer) = Block(i) in inds +@inline blockcheckindex(::Type{Bool}, inds::BlockRange{1}, i) = checkindex(Bool, Int.(inds), i) @propagate_inbounds setindex!(block_arr::AbstractBlockArray{T,N}, v, block::Block{N}) where {T,N} = setindex!(block_arr, v, Block.(block.n)...) diff --git a/src/blockindices.jl b/src/blockindices.jl index 1226e8af..662a9f0c 100644 --- a/src/blockindices.jl +++ b/src/blockindices.jl @@ -164,6 +164,7 @@ end block(b::BlockIndex) = Block(b.I...) blockindex(b::BlockIndex{1}) = b.α[1] +blockindex(b::BlockIndex) = CartesianIndex(b.α) BlockIndex(indcs::Tuple{Vararg{BlockIndex{1},N}}) where N = BlockIndex(block.(indcs), blockindex.(indcs)) @@ -172,15 +173,18 @@ BlockIndex(indcs::Tuple{Vararg{BlockIndex{1},N}}) where N = BlockIndex(block.(in ## @inline checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::Block{N}) where N = blockcheckbounds(Bool, A, I.n...) +checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::AbstractArray{<:Block{N}}) where N = + all(i -> checkbounds(Bool, A, i), I) + @inline function checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::BlockIndex{N}) where N bl = block(I) checkbounds(Bool, A, bl) || return false - B = A[bl] - checkbounds(Bool, B, blockindex(I)...) + # TODO: Replace with `eachblockaxes(A)[bl]` once that is defined. + binds = map(Base.axes1 ∘ getindex, axes(A), Tuple(bl)) + Base.checkbounds_indices(Bool, binds, (blockindex(I),)) end - -checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::AbstractVector{<:BlockIndex{N}}) where N = - all(checkbounds.(Bool, Ref(A), I)) +checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::AbstractArray{<:BlockIndex{N}}) where N = + all(i -> checkbounds(Bool, A, i), I) struct BlockIndexRange{N,R<:Tuple{Vararg{AbstractUnitRange{<:Integer},N}},I<:Tuple{Vararg{Integer,N}},BI<:Integer} <: AbstractArray{BlockIndex{N,NTuple{N,BI},I},N} block::Block{N,BI} @@ -242,6 +246,17 @@ length(iter::BlockIndexRange) = prod(size(iter)) Block(bs::BlockIndexRange) = bs.block +## +# checkindex +## + +function checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::BlockIndexRange{N}) where N + bl = block(I) + checkbounds(Bool, A, bl) || return false + # TODO: Replace with `eachblockaxes(A)[bl]` once that is defined. + binds = map(Base.axes1 ∘ getindex, axes(A), Tuple(bl)) + Base.checkbounds_indices(Bool, binds, I.indices) +end # ################# # # support for pointers @@ -413,6 +428,30 @@ _in(b, ::Tuple{}, ::Tuple{}, ::Tuple{}) = b # We sometimes need intersection of BlockRange to return a BlockRange intersect(a::BlockRange{1}, b::BlockRange{1}) = BlockRange(intersect(a.indices[1], b.indices[1])) +## +# checkindex +## + +# Used to ensure a `BlockBoundsError` is thrown instead of a `BoundsError`, +# see https://github.com/JuliaArrays/BlockArrays.jl/issues/458. +function checkbounds(A::AbstractArray{<:Any,N}, I::BlockRange{N}) where N + return blockcheckbounds(A, I.indices...) +end +function checkbounds(A::AbstractArray, I1::BlockRange{1}, Irest::BlockRange{1}...) + return blockcheckbounds(A, map(I -> Int.(I), (I1, Irest...))...) +end +function checkbounds(A::AbstractArray, I1::AbstractVector{<:Block{1}}, Irest::AbstractVector{<:Block{1}}...) + return blockcheckbounds(A, map(I -> Int.(I), (I1, Irest...))...) +end + +# Convert Block inputs to integers. +function checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::BlockRange{N}) where N + return blockcheckbounds(Bool, A, I.indices...) +end +function checkbounds(::Type{Bool}, A::AbstractArray, I1::AbstractVector{<:Block{1}}, Irest::AbstractVector{<:Block{1}}...) + return blockcheckbounds(Bool, A, map(I -> Int.(I), (I1, Irest...))...) +end + # needed for scalar-like broadcasting BlockSlice{Block{1,BT},T,RT}(a::Base.OneTo) where {BT,T,RT<:AbstractUnitRange} = diff --git a/test/test_blockarrays.jl b/test/test_blockarrays.jl index 30457f2b..f351f499 100644 --- a/test/test_blockarrays.jl +++ b/test/test_blockarrays.jl @@ -467,6 +467,60 @@ end BA_1 = BlockArray(undef_blocks, Vector{Float64}, [1,2,3]) @test Base.IndexStyle(typeof(BA_1)) == IndexCartesian() + @test checkbounds(Bool, BA_1, Block(1)) + @test isnothing(checkbounds(BA_1, Block(1))) + @test blockcheckbounds(Bool, BA_1, 1) + @test isnothing(blockcheckbounds(BA_1, 1)) + @test checkbounds(Bool, BA_1, Block(2)) + @test isnothing(checkbounds(BA_1, Block(2))) + @test blockcheckbounds(Bool, BA_1, 2) + @test isnothing(blockcheckbounds(BA_1, 2)) + @test checkbounds(Bool, BA_1, Block(3)) + @test isnothing(checkbounds(BA_1, Block(3))) + @test blockcheckbounds(Bool, BA_1, 3) + @test isnothing(blockcheckbounds(BA_1, 3)) + @test !checkbounds(Bool, BA_1, Block(4)) + @test_throws BlockBoundsError checkbounds(BA_1, Block(4)) + @test !blockcheckbounds(Bool, BA_1, 4) + @test_throws BlockBoundsError blockcheckbounds(BA_1, 4) + + @test checkbounds(Bool, BA_1, Block.(1:3)) + @test isnothing(checkbounds(BA_1, Block.(1:3))) + @test blockcheckbounds(Bool, BA_1, 1:3) + @test isnothing(blockcheckbounds(BA_1, 1:3)) + @test !checkbounds(Bool, BA_1, Block.(1:4)) + @test_throws BlockBoundsError checkbounds(BA_1, Block.(1:4)) + @test !blockcheckbounds(Bool, BA_1, 1:4) + @test_throws BlockBoundsError blockcheckbounds(BA_1, 1:4) + + @test checkbounds(Bool, BA_1, [Block(1), Block(3)]) + @test isnothing(checkbounds(BA_1, [Block(1), Block(3)])) + @test blockcheckbounds(Bool, BA_1, [1, 3]) + @test isnothing(blockcheckbounds(BA_1, [1, 3])) + @test !checkbounds(Bool, BA_1, [Block(1), Block(4)]) + @test_throws BlockBoundsError checkbounds(BA_1, [Block(1), Block(4)]) + @test !blockcheckbounds(Bool, BA_1, [1, 4]) + @test_throws BlockBoundsError blockcheckbounds(BA_1, [1, 4]) + + @test checkbounds(Bool, BA_1, Block(2)[2]) + @test isnothing(checkbounds(BA_1, Block(2)[2])) + @test !checkbounds(Bool, BA_1, Block(2)[3]) + @test_throws BoundsError checkbounds(BA_1, Block(2)[3]) + @test !checkbounds(Bool, BA_1, Block(4)[2]) + @test_throws BoundsError checkbounds(BA_1, Block(4)[2]) + + @test checkbounds(Bool, BA_1, Block(2)[1:2]) + @test isnothing(checkbounds(BA_1, Block(2)[1:2])) + @test !checkbounds(Bool, BA_1, Block(2)[1:3]) + @test_throws BoundsError checkbounds(BA_1, Block(2)[1:3]) + + @test checkbounds(Bool, BA_1, [Block(2)[2], Block(3)[3]]) + @test isnothing(checkbounds(BA_1, [Block(2)[2], Block(3)[3]])) + @test !checkbounds(Bool, BA_1, [Block(2)[2], Block(2)[3]]) + @test_throws BoundsError checkbounds(BA_1, [Block(2)[2], Block(2)[3]]) + @test !checkbounds(Bool, BA_1, [Block(2)[2], Block(4)[2]]) + @test_throws BoundsError checkbounds(BA_1, [Block(2)[2], Block(4)[2]]) + a_1 = rand(2) BA_1[Block(2)] = a_1 @test BA_1[BlockIndex(2, 1)] == a_1[1] @@ -491,6 +545,35 @@ end @test BA_2[Block(1,2)] == a_2 BA_2[Block(1,2)] = a_2 + @test checkbounds(Bool, BA_2, BlockRange(1:2,1:2)) + @test isnothing(checkbounds(BA_2, BlockRange(1:2,1:2))) + @test checkbounds(Bool, BA_2, Block.(1:2), Block.(1:2)) + @test isnothing(checkbounds(BA_2, Block.(1:2), Block.(1:2))) + @test blockcheckbounds(Bool, BA_2, 1:2, 1:2) + @test isnothing(blockcheckbounds(BA_2, 1:2, 1:2)) + + @test !checkbounds(Bool, BA_2, BlockRange(1:2,1:3)) + @test_throws BlockBoundsError checkbounds(BA_2, BlockRange(1:2,1:3)) + @test !checkbounds(Bool, BA_2, Block.(1:2), Block.(1:3)) + @test_throws BlockBoundsError checkbounds(BA_2, Block.(1:2), Block.(1:3)) + @test !blockcheckbounds(Bool, BA_2, 1:2, 1:3) + @test_throws BlockBoundsError blockcheckbounds(BA_2, 1:2, 1:3) + + @test checkbounds(Bool, BA_2, Block(1,1)[1,1]) + @test isnothing(checkbounds(BA_2, Block(1,1)[1,1])) + @test checkbounds(Bool, BA_2, Block(1)[1], Block(1)[1]) + @test checkbounds(Bool, BA_2, Block(1,2)[1,2]) + @test !checkbounds(Bool, BA_2, Block(1,2)[2,2]) + @test checkbounds(Bool, BA_2, Block(2,2)[1:1,1:2]) + @test checkbounds(Bool, BA_2, Matrix(Block(2,2)[1:1,1:2])) + @test isnothing(checkbounds(BA_2, Matrix(Block(2,2)[1:1,1:2]))) + @test checkbounds(Bool, BA_2, Block(1,2)[1:1,1:2]) + @test checkbounds(Bool, BA_2, Block(1)[1:1], Block(2)[1:2]) + @test !checkbounds(Bool, BA_2, Block(2,2)[1:3,1:2]) + @test !checkbounds(Bool, BA_2, Block(2)[1:3], Block(2)[1:2]) + @test checkbounds(Bool, BA_2, [Block(2)[1], Block(2)[2]], Block(2)[1:2]) + @test !checkbounds(Bool, BA_2, [Block(2)[1], Block(2)[3]], Block(2)[1:2]) + @test BA_2[1,5] == a_2[2] @test_throws DimensionMismatch BA_2[Block(1,2)] = rand(1,5) diff --git a/test/test_blockindices.jl b/test/test_blockindices.jl index b57512be..be1700a7 100644 --- a/test/test_blockindices.jl +++ b/test/test_blockindices.jl @@ -374,6 +374,14 @@ end @test !checkbounds(Bool, b, Block(3)[4]) @test !checkbounds(Bool, b, Block(0)[1]) @test !checkbounds(Bool, b, Block(1)[0]) + @test checkbounds(Bool, b, Block(1)) + @test checkbounds(Bool, b, Block(2)) + @test checkbounds(Bool, b, Block(3)) + @test !checkbounds(Bool, b, Block(4)) + @test checkbounds(Bool, b, Block.(1:3)) + @test !checkbounds(Bool, b, Block.(1:4)) + @test_throws BlockBoundsError checkbounds(b, Block(4)) + @test_throws BlockBoundsError checkbounds(b, Block.(1:4)) # treat b as the axis @test checkindex(Bool, b, Block(1)[1]) @test checkindex(Bool, b, Block(1)[1:1]) From 593e7f355c86cf4b6b72565e3435bd45416f40ed Mon Sep 17 00:00:00 2001 From: mtfishman Date: Fri, 27 Jun 2025 17:13:47 -0400 Subject: [PATCH 2/2] Improve test coverage and code logic --- src/abstractblockarray.jl | 33 +++++++++++++++++++-------------- src/blockindices.jl | 26 ++++++++------------------ test/test_blockarrays.jl | 25 +++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 32 deletions(-) diff --git a/src/abstractblockarray.jl b/src/abstractblockarray.jl index 7af9996c..82444446 100644 --- a/src/abstractblockarray.jl +++ b/src/abstractblockarray.jl @@ -88,7 +88,7 @@ ERROR: BlockBoundsError: attempt to access 2×2-blocked 2×3 BlockMatrix{Float64 """ @inline function blockcheckbounds(A::AbstractArray, i...) blockcheckbounds(Bool, A, i...) || throw(BlockBoundsError(A, i)) - return nothing + nothing end # linear block indexing @@ -100,19 +100,24 @@ end blockcheckbounds_indices(Bool, blockaxes(A), i) end -checkbounds(A::AbstractArray{T, N}, i::Block{N}) where {T,N} = blockcheckbounds(A, i) -checkbounds(A::AbstractArray{T}, i1::Block{1}, irest::Block{1}...) where {T} = blockcheckbounds(A, i1, irest...) -checkbounds(A::AbstractArray{T, N}, i::AbstractArray{<:Block{N}}) where {T,N} = blockcheckbounds(A, i) -checkbounds(A::AbstractArray{T}, i1::AbstractVector{<:Block{1}}, irest::AbstractVector{<:Block{1}}) where {T} = - blockcheckbounds(A, i1, irest...) - -blockcheckbounds(A::AbstractArray{T, N}, i::Block{N}) where {T,N} = blockcheckbounds(A, i.n...) -blockcheckbounds(A::AbstractArray{T, N}, i::Vararg{Block{1},N}) where {T,N} = blockcheckbounds(A, Int.(i)...) -blockcheckbounds(::AbstractArray{T, 0}) where {T} = true -blockcheckbounds(A::AbstractVector{T}, i::Block{1}) where {T} = blockcheckbounds(A, Int(i)) - -blockcheckbounds(A::AbstractArray{T,N}, I::Vararg{BlockRange{1},N}) where {T,N} = blockcheckbounds(A, map(i -> Int.(i), I)...) -blockcheckbounds(A::AbstractArray{T,N}, I::BlockRange{N}) where {T,N} = blockcheckbounds(A, I.indices...) +# Used to ensure a `BlockBoundsError` is thrown instead of a `BoundsError`, +# see https://github.com/JuliaArrays/BlockArrays.jl/issues/458 +checkbounds(A::AbstractArray{T, N}, I::Block{N}) where {T,N} = blockcheckbounds(A, I) +checkbounds(A::AbstractArray{T}, I1::Block{1}, Irest::Block{1}...) where {T} = blockcheckbounds(A, I1, Irest...) +checkbounds(A::AbstractArray{T}, I1::AbstractVector{<:Block{1}}, Irest::AbstractVector{<:Block{1}}...) where {T} = + blockcheckbounds(A, I1, Irest...) + +blockcheckbounds(::Type{Bool}, A::AbstractArray{T, N}, I::Block{N}) where {T,N} = blockcheckbounds(Bool, A, Int.(Tuple(I))...) +blockcheckbounds(::Type{Bool}, A::AbstractArray{T, N}, I::Vararg{Block{1},N}) where {T,N} = + blockcheckbounds(Bool, A, Int.(I)...) +blockcheckbounds(::Type{Bool}, ::AbstractArray{T, 0}) where {T} = true +blockcheckbounds(::Type{Bool}, A::AbstractVector{T}, I::Block{1}) where {T} = blockcheckbounds(Bool, A, Int(I)) +blockcheckbounds(::Type{Bool}, A::AbstractArray{T,N}, I::Vararg{AbstractVector{<:Block{1}},N}) where {T,N} = + blockcheckbounds(Bool, A, map(i -> Int.(i), I)...) + +blockcheckbounds(::Type{Bool}, A::AbstractArray{T,N}, I::Vararg{BlockRange{1},N}) where {T,N} = + blockcheckbounds(Bool, A, map(i -> Int.(i), I)...) +blockcheckbounds(::Type{Bool}, A::AbstractArray{T,N}, I::BlockRange{N}) where {T,N} = blockcheckbounds(Bool, A, I.indices...) """ blockcheckbounds_indices(Bool, IA::Tuple{Vararg{BlockRange{1}}}, I::Tuple) diff --git a/src/blockindices.jl b/src/blockindices.jl index 662a9f0c..42699fd1 100644 --- a/src/blockindices.jl +++ b/src/blockindices.jl @@ -173,8 +173,6 @@ BlockIndex(indcs::Tuple{Vararg{BlockIndex{1},N}}) where N = BlockIndex(block.(in ## @inline checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::Block{N}) where N = blockcheckbounds(Bool, A, I.n...) -checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::AbstractArray{<:Block{N}}) where N = - all(i -> checkbounds(Bool, A, i), I) @inline function checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::BlockIndex{N}) where N bl = block(I) @@ -433,24 +431,16 @@ intersect(a::BlockRange{1}, b::BlockRange{1}) = BlockRange(intersect(a.indices[1 ## # Used to ensure a `BlockBoundsError` is thrown instead of a `BoundsError`, -# see https://github.com/JuliaArrays/BlockArrays.jl/issues/458. -function checkbounds(A::AbstractArray{<:Any,N}, I::BlockRange{N}) where N - return blockcheckbounds(A, I.indices...) -end -function checkbounds(A::AbstractArray, I1::BlockRange{1}, Irest::BlockRange{1}...) - return blockcheckbounds(A, map(I -> Int.(I), (I1, Irest...))...) -end -function checkbounds(A::AbstractArray, I1::AbstractVector{<:Block{1}}, Irest::AbstractVector{<:Block{1}}...) - return blockcheckbounds(A, map(I -> Int.(I), (I1, Irest...))...) -end +# see https://github.com/JuliaArrays/BlockArrays.jl/issues/458 +checkbounds(A::AbstractArray{<:Any,N}, I::BlockRange{N}) where N = blockcheckbounds(A, I) +checkbounds(A::AbstractArray, I1::BlockRange{1}, Irest::BlockRange{1}...) = + blockcheckbounds(A, I1, Irest...) # Convert Block inputs to integers. -function checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::BlockRange{N}) where N - return blockcheckbounds(Bool, A, I.indices...) -end -function checkbounds(::Type{Bool}, A::AbstractArray, I1::AbstractVector{<:Block{1}}, Irest::AbstractVector{<:Block{1}}...) - return blockcheckbounds(Bool, A, map(I -> Int.(I), (I1, Irest...))...) -end +checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::BlockRange{N}) where N = + blockcheckbounds(Bool, A, I.indices...) +checkbounds(::Type{Bool}, A::AbstractArray, I1::AbstractVector{<:Block{1}}, Irest::AbstractVector{<:Block{1}}...) = + blockcheckbounds(Bool, A, map(I -> Int.(I), (I1, Irest...))...) # needed for scalar-like broadcasting diff --git a/test/test_blockarrays.jl b/test/test_blockarrays.jl index f351f499..1241056c 100644 --- a/test/test_blockarrays.jl +++ b/test/test_blockarrays.jl @@ -545,19 +545,44 @@ end @test BA_2[Block(1,2)] == a_2 BA_2[Block(1,2)] = a_2 + @test checkbounds(Bool, BA_2, Block(1,1)) + @test isnothing(checkbounds(BA_2, Block(1,1))) + @test checkbounds(Bool, BA_2, Block(1), Block(1)) + @test isnothing(checkbounds(BA_2, Block(1), Block(1))) + @test !checkbounds(Bool, BA_2, Block(1,3)) + @test_throws BlockBoundsError checkbounds(BA_2, Block(1,3)) + @test !checkbounds(Bool, BA_2, Block(1), Block(3)) + @test_throws BlockBoundsError checkbounds(BA_2, Block(1), Block(3)) + @test checkbounds(Bool, BA_2, BlockRange(1:2,1:2)) + @test blockcheckbounds(Bool, BA_2, BlockRange(1:2,1:2)) @test isnothing(checkbounds(BA_2, BlockRange(1:2,1:2))) + @test isnothing(blockcheckbounds(BA_2, BlockRange(1:2,1:2))) @test checkbounds(Bool, BA_2, Block.(1:2), Block.(1:2)) + @test checkbounds(Bool, BA_2, Block.([1,2]), Block.([1,2])) @test isnothing(checkbounds(BA_2, Block.(1:2), Block.(1:2))) + @test isnothing(checkbounds(BA_2, Block.([1,2]), Block.([1,2]))) @test blockcheckbounds(Bool, BA_2, 1:2, 1:2) + @test blockcheckbounds(Bool, BA_2, [1,2], [1,2]) @test isnothing(blockcheckbounds(BA_2, 1:2, 1:2)) + @test isnothing(blockcheckbounds(BA_2, Block.(1:2), Block.(1:2))) + @test isnothing(blockcheckbounds(BA_2, [1,2], [1,2])) + @test isnothing(blockcheckbounds(BA_2, Block.([1,2]), Block.([1,2]))) @test !checkbounds(Bool, BA_2, BlockRange(1:2,1:3)) + @test !blockcheckbounds(Bool, BA_2, BlockRange(1:2,1:3)) @test_throws BlockBoundsError checkbounds(BA_2, BlockRange(1:2,1:3)) + @test_throws BlockBoundsError blockcheckbounds(BA_2, BlockRange(1:2,1:3)) @test !checkbounds(Bool, BA_2, Block.(1:2), Block.(1:3)) + @test !checkbounds(Bool, BA_2, Block.([1,2]), Block.([1,3])) @test_throws BlockBoundsError checkbounds(BA_2, Block.(1:2), Block.(1:3)) + @test_throws BlockBoundsError checkbounds(BA_2, Block.([1,2]), Block.([1,3])) @test !blockcheckbounds(Bool, BA_2, 1:2, 1:3) + @test !blockcheckbounds(Bool, BA_2, [1,2], [1,3]) @test_throws BlockBoundsError blockcheckbounds(BA_2, 1:2, 1:3) + @test_throws BlockBoundsError blockcheckbounds(BA_2, Block.(1:2), Block.(1:3)) + @test_throws BlockBoundsError blockcheckbounds(BA_2, [1,2], [1,3]) + @test_throws BlockBoundsError blockcheckbounds(BA_2, Block.([1,2]), Block.([1,3])) @test checkbounds(Bool, BA_2, Block(1,1)[1,1]) @test isnothing(checkbounds(BA_2, Block(1,1)[1,1]))