164164
165165block (b:: BlockIndex ) = Block (b. I... )
166166blockindex (b:: BlockIndex{1} ) = b. α[1 ]
167+ blockindex (b:: BlockIndex ) = CartesianIndex (b. α)
167168
168169BlockIndex (indcs:: Tuple{Vararg{BlockIndex{1},N}} ) where N = BlockIndex (block .(indcs), blockindex .(indcs))
169170
@@ -172,15 +173,16 @@ BlockIndex(indcs::Tuple{Vararg{BlockIndex{1},N}}) where N = BlockIndex(block.(in
172173# #
173174
174175@inline checkbounds (:: Type{Bool} , A:: AbstractArray{<:Any,N} , I:: Block{N} ) where N = blockcheckbounds (Bool, A, I. n... )
176+
175177@inline function checkbounds (:: Type{Bool} , A:: AbstractArray{<:Any,N} , I:: BlockIndex{N} ) where N
176178 bl = block (I)
177179 checkbounds (Bool, A, bl) || return false
178- B = A[bl]
179- checkbounds (Bool, B, blockindex (I)... )
180+ # TODO : Replace with `eachblockaxes(A)[bl]` once that is defined.
181+ binds = map (Base. axes1 ∘ getindex, axes (A), Tuple (bl))
182+ Base. checkbounds_indices (Bool, binds, (blockindex (I),))
180183end
181-
182- checkbounds (:: Type{Bool} , A:: AbstractArray{<:Any,N} , I:: AbstractVector{<:BlockIndex{N}} ) where N =
183- all (checkbounds .(Bool, Ref (A), I))
184+ checkbounds (:: Type{Bool} , A:: AbstractArray{<:Any,N} , I:: AbstractArray{<:BlockIndex{N}} ) where N =
185+ all (i -> checkbounds (Bool, A, i), I)
184186
185187struct BlockIndexRange{N,R<: Tuple{Vararg{AbstractUnitRange{<:Integer},N}} ,I<: Tuple{Vararg{Integer,N}} ,BI<: Integer } <: AbstractArray{BlockIndex{N,NTuple{N,BI},I},N}
186188 block:: Block{N,BI}
@@ -243,6 +245,17 @@ length(iter::BlockIndexRange) = prod(size(iter))
243245
244246Block (bs:: BlockIndexRange ) = bs. block
245247
248+ # #
249+ # checkindex
250+ # #
251+
252+ function checkbounds (:: Type{Bool} , A:: AbstractArray{<:Any,N} , I:: BlockIndexRange{N} ) where N
253+ bl = block (I)
254+ checkbounds (Bool, A, bl) || return false
255+ # TODO : Replace with `eachblockaxes(A)[bl]` once that is defined.
256+ binds = map (Base. axes1 ∘ getindex, axes (A), Tuple (bl))
257+ Base. checkbounds_indices (Bool, binds, I. indices)
258+ end
246259
247260# #################
248261# # support for pointers
324337
325338# deleted code that isn't used, such as 0-dimensional case
326339"""
327- BlockRange(axes::Tuple{AbstractUnitRange{Int }})
328- BlockRange(sizes::Vararg{Integer})
340+ BlockRange(axes::Tuple{Vararg{ AbstractUnitRange{<:Integer} }})
341+ BlockRange(sizes::Tuple{ Vararg{Integer} })
329342
330343Represent a Cartesian range of blocks.
331344
@@ -334,18 +347,18 @@ The relationship between `Block` and `BlockRange` mimics the relationship betwee
334347
335348# Examples
336349```jldoctest
337- julia> BlockRange(2:3, 3:4) |> collect
350+ julia> BlockRange(( 2:3, 3:4) ) |> collect
3383512×2 Matrix{Block{2, Int64}}:
339352 Block(2, 3) Block(2, 4)
340353 Block(3, 3) Block(3, 4)
341354
342- julia> BlockRange(2, 2) |> collect # number of elements, starting at 1
355+ julia> BlockRange(( 2, 2) ) |> collect # number of elements, starting at 1
3433562×2 Matrix{Block{2, Int64}}:
344357 Block(1, 1) Block(1, 2)
345358 Block(2, 1) Block(2, 2)
346359
347360julia> Block(1):Block(2)
348- BlockRange(1:2)
361+ BlockRange(( 1:2,) )
349362```
350363"""
351364BlockRange
360373
361374BlockRange (inds:: Tuple{Vararg{AbstractUnitRange{<:Integer}}} ) =
362375 BlockRange {length(inds),typeof(inds)} (inds)
363- BlockRange (inds:: Vararg{AbstractUnitRange{<:Integer}} ) = BlockRange (inds)
364376
365- BlockRange () = BlockRange (())
366377BlockRange (sizes:: Tuple{Integer, Vararg{Integer}} ) = BlockRange (map (oneto, sizes))
367- BlockRange (sizes:: Vararg{Integer} ) = BlockRange (sizes)
368378
369379BlockRange (B:: AbstractArray ) = BlockRange (blockaxes (B))
370380
@@ -433,13 +443,29 @@ _in(b, ::Tuple{}, ::Tuple{}, ::Tuple{}) = b
433443@inline _in (b, i, start, stop) = _in (b & (start[1 ] <= i[1 ] <= stop[1 ]), tail (i), tail (start), tail (stop))
434444
435445# We sometimes need intersection of BlockRange to return a BlockRange
436- intersect (a:: BlockRange{1} , b:: BlockRange{1} ) = BlockRange (intersect (a. indices[1 ], b. indices[1 ]))
446+ intersect (a:: BlockRange{1} , b:: BlockRange{1} ) = BlockRange ((intersect (a. indices[1 ], b. indices[1 ]),))
447+
448+ # #
449+ # checkindex
450+ # #
451+
452+ # Used to ensure a `BlockBoundsError` is thrown instead of a `BoundsError`,
453+ # see https://github.com/JuliaArrays/BlockArrays.jl/issues/458
454+ checkbounds (A:: AbstractArray{<:Any,N} , I:: BlockRange{N} ) where N = blockcheckbounds (A, I)
455+ checkbounds (A:: AbstractArray , I1:: BlockRange{1} , Irest:: BlockRange{1} ...) =
456+ blockcheckbounds (A, I1, Irest... )
457+
458+ # Convert Block inputs to integers.
459+ checkbounds (:: Type{Bool} , A:: AbstractArray{<:Any,N} , I:: BlockRange{N} ) where N =
460+ blockcheckbounds (Bool, A, I. indices... )
461+ checkbounds (:: Type{Bool} , A:: AbstractArray , I1:: AbstractVector{<:Block{1}} , Irest:: AbstractVector{<:Block{1}} ...) =
462+ blockcheckbounds (Bool, A, map (I -> Int .(I), (I1, Irest... ))... )
437463
438464# needed for scalar-like broadcasting
439465
440466BlockSlice {Block{1,BT},T,RT} (a:: Base.OneTo ) where {BT,T,RT<: AbstractUnitRange } =
441467 BlockSlice (Block (convert (BT, 1 )), convert (RT, a)):: BlockSlice{Block{1,BT},T,RT}
442468BlockSlice {BlockRange{1,Tuple{BT}},T,RT} (a:: Base.OneTo ) where {BT<: AbstractUnitRange ,T,RT<: AbstractUnitRange } =
443- BlockSlice (BlockRange (convert (BT, Base. OneTo (1 ))), convert (RT, a)):: BlockSlice{BlockRange{1,Tuple{BT}},T,RT}
469+ BlockSlice (BlockRange (( convert (BT, Base. OneTo (1 )), )), convert (RT, a)):: BlockSlice{BlockRange{1,Tuple{BT}},T,RT}
444470BlockSlice {BlockIndexRange{1,Tuple{BT},I,BI},T,RT} (a:: Base.OneTo ) where {BT<: AbstractUnitRange ,T,RT<: AbstractUnitRange ,I,BI} =
445471 BlockSlice (BlockIndexRange (Block (BI (1 )), convert (BT, Base. OneTo (1 ))), convert (RT, a)):: BlockSlice{BlockIndexRange{1,Tuple{BT},I,BI},T,RT}
0 commit comments