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}
@@ -247,6 +249,17 @@ length(iter::BlockIndexRange) = prod(size(iter))
247249
248250Block (bs:: BlockIndexRange ) = bs. block
249251
252+ # #
253+ # checkindex
254+ # #
255+
256+ function checkbounds (:: Type{Bool} , A:: AbstractArray{<:Any,N} , I:: BlockIndexRange{N} ) where N
257+ bl = block (I)
258+ checkbounds (Bool, A, bl) || return false
259+ # TODO : Replace with `eachblockaxes(A)[bl]` once that is defined.
260+ binds = map (Base. axes1 ∘ getindex, axes (A), Tuple (bl))
261+ Base. checkbounds_indices (Bool, binds, I. indices)
262+ end
250263
251264# #################
252265# # support for pointers
328341
329342# deleted code that isn't used, such as 0-dimensional case
330343"""
331- BlockRange(axes::Tuple{AbstractUnitRange{Int }})
332- BlockRange(sizes::Vararg{Integer})
344+ BlockRange(axes::Tuple{Vararg{ AbstractUnitRange{<:Integer} }})
345+ BlockRange(sizes::Tuple{ Vararg{Integer} })
333346
334347Represent a Cartesian range of blocks.
335348
@@ -338,18 +351,18 @@ The relationship between `Block` and `BlockRange` mimics the relationship betwee
338351
339352# Examples
340353```jldoctest
341- julia> BlockRange(2:3, 3:4) |> collect
354+ julia> BlockRange(( 2:3, 3:4) ) |> collect
3423552×2 Matrix{Block{2, Int64}}:
343356 Block(2, 3) Block(2, 4)
344357 Block(3, 3) Block(3, 4)
345358
346- julia> BlockRange(2, 2) |> collect # number of elements, starting at 1
359+ julia> BlockRange(( 2, 2) ) |> collect # number of elements, starting at 1
3473602×2 Matrix{Block{2, Int64}}:
348361 Block(1, 1) Block(1, 2)
349362 Block(2, 1) Block(2, 2)
350363
351364julia> Block(1):Block(2)
352- BlockRange(1:2)
365+ BlockRange(( 1:2,) )
353366```
354367"""
355368BlockRange
364377
365378BlockRange (inds:: Tuple{Vararg{AbstractUnitRange{<:Integer}}} ) =
366379 BlockRange {length(inds),typeof(inds)} (inds)
367- BlockRange (inds:: Vararg{AbstractUnitRange{<:Integer}} ) = BlockRange (inds)
368380
369- BlockRange () = BlockRange (())
370381BlockRange (sizes:: Tuple{Integer, Vararg{Integer}} ) = BlockRange (map (oneto, sizes))
371- BlockRange (sizes:: Vararg{Integer} ) = BlockRange (sizes)
372382
373383BlockRange (B:: AbstractArray ) = BlockRange (blockaxes (B))
374384
@@ -437,13 +447,29 @@ _in(b, ::Tuple{}, ::Tuple{}, ::Tuple{}) = b
437447@inline _in (b, i, start, stop) = _in (b & (start[1 ] <= i[1 ] <= stop[1 ]), tail (i), tail (start), tail (stop))
438448
439449# We sometimes need intersection of BlockRange to return a BlockRange
440- intersect (a:: BlockRange{1} , b:: BlockRange{1} ) = BlockRange (intersect (a. indices[1 ], b. indices[1 ]))
450+ intersect (a:: BlockRange{1} , b:: BlockRange{1} ) = BlockRange ((intersect (a. indices[1 ], b. indices[1 ]),))
451+
452+ # #
453+ # checkindex
454+ # #
455+
456+ # Used to ensure a `BlockBoundsError` is thrown instead of a `BoundsError`,
457+ # see https://github.com/JuliaArrays/BlockArrays.jl/issues/458
458+ checkbounds (A:: AbstractArray{<:Any,N} , I:: BlockRange{N} ) where N = blockcheckbounds (A, I)
459+ checkbounds (A:: AbstractArray , I1:: BlockRange{1} , Irest:: BlockRange{1} ...) =
460+ blockcheckbounds (A, I1, Irest... )
461+
462+ # Convert Block inputs to integers.
463+ checkbounds (:: Type{Bool} , A:: AbstractArray{<:Any,N} , I:: BlockRange{N} ) where N =
464+ blockcheckbounds (Bool, A, I. indices... )
465+ checkbounds (:: Type{Bool} , A:: AbstractArray , I1:: AbstractVector{<:Block{1}} , Irest:: AbstractVector{<:Block{1}} ...) =
466+ blockcheckbounds (Bool, A, map (I -> Int .(I), (I1, Irest... ))... )
441467
442468# needed for scalar-like broadcasting
443469
444470BlockSlice {Block{1,BT},T,RT} (a:: Base.OneTo ) where {BT,T,RT<: AbstractUnitRange } =
445471 BlockSlice (Block (convert (BT, 1 )), convert (RT, a)):: BlockSlice{Block{1,BT},T,RT}
446472BlockSlice {BlockRange{1,Tuple{BT}},T,RT} (a:: Base.OneTo ) where {BT<: AbstractUnitRange ,T,RT<: AbstractUnitRange } =
447- BlockSlice (BlockRange (convert (BT, Base. OneTo (1 ))), convert (RT, a)):: BlockSlice{BlockRange{1,Tuple{BT}},T,RT}
473+ BlockSlice (BlockRange (( convert (BT, Base. OneTo (1 )), )), convert (RT, a)):: BlockSlice{BlockRange{1,Tuple{BT}},T,RT}
448474BlockSlice {BlockIndexRange{1,Tuple{BT},I,BI},T,RT} (a:: Base.OneTo ) where {BT<: AbstractUnitRange ,T,RT<: AbstractUnitRange ,I,BI} =
449475 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