@@ -244,6 +244,15 @@ BlockArrays.blockindex(b::GenericBlockIndex{1}) = b.α[1]
244244function GenericBlockIndex (indcs:: Tuple{Vararg{GenericBlockIndex{1},N}} ) where {N}
245245 GenericBlockIndex (block .(indcs), blockindex .(indcs))
246246end
247+
248+ function Base. checkindex (
249+ :: Type{Bool} , axis:: AbstractBlockedUnitRange , ind:: GenericBlockIndex{1}
250+ )
251+ return checkindex (Bool, axis, block (ind)) &&
252+ checkbounds (Bool, axis[block (ind)], blockindex (ind))
253+ end
254+ Base. to_index (i:: GenericBlockIndex ) = i
255+
247256function print_tuple_elements (io:: IO , @nospecialize (t))
248257 if ! isempty (t)
249258 print (io, t[1 ])
@@ -261,6 +270,13 @@ function Base.show(io::IO, B::GenericBlockIndex)
261270 return nothing
262271end
263272
273+ # https://github.com/JuliaArrays/BlockArrays.jl/blob/v1.6.3/src/views.jl#L31-L32
274+ _maybetail (:: Tuple{} ) = ()
275+ _maybetail (t:: Tuple ) = Base. tail (t)
276+ @inline function Base. to_indices (A, inds, I:: Tuple{GenericBlockIndex{1},Vararg{Any}} )
277+ return (inds[1 ][I[1 ]], to_indices (A, _maybetail (inds), Base. tail (I))... )
278+ end
279+
264280using Base: @propagate_inbounds
265281@propagate_inbounds function Base. getindex (b:: AbstractVector , K:: GenericBlockIndex{1} )
266282 return b[Block (K. I[1 ])][K. α[1 ]]
@@ -276,35 +292,65 @@ end
276292 return b[GenericBlockIndex (tuple (K, J... ))]
277293end
278294
279- function blockindextype (TB:: Type{<:Integer} , TI:: Vararg{Type{<:Integer},N} ) where {N}
280- return BlockIndex{N,NTuple{N,TB},Tuple{TI... }}
295+ # TODO : Delete this once `BlockArrays.BlockIndex` is generalized.
296+ @inline function Base. to_indices (
297+ A, inds, I:: Tuple{AbstractVector{<:GenericBlockIndex{1}},Vararg{Any}}
298+ )
299+ return (unblock (A, inds, I), to_indices (A, _maybetail (inds), Base. tail (I))... )
281300end
282- function blockindextype (TB:: Type{<:Integer} , TI:: Vararg{Type,N} ) where {N}
283- return GenericBlockIndex{N,NTuple{N,TB},Tuple{TI... }}
301+
302+ # This is a specialization of `BlockArrays.unblock`:
303+ # https://github.com/JuliaArrays/BlockArrays.jl/blob/v1.6.3/src/views.jl#L8-L11
304+ # that is used in the `to_indices` logic for blockwise slicing in
305+ # BlockArrays.jl.
306+ # TODO : Ideally this would be defined in BlockArrays.jl once the slicing
307+ # there is made more generic.
308+ function BlockArrays. unblock (A, inds, I:: Tuple{GenericBlockIndex{1},Vararg{Any}} )
309+ B = first (I)
310+ return _blockslice (B, inds[1 ][B])
284311end
285312
286- struct BlockIndexVector{N,I<: NTuple{N,AbstractVector} ,TB<: Integer ,BT} <: AbstractArray{BT,N}
313+ # Work around the fact that it is type piracy to define
314+ # `Base.getindex(a::Block, b...)`.
315+ _getindex (a:: Block{N} , b:: Vararg{Any,N} ) where {N} = GenericBlockIndex (a, b)
316+ _getindex (a:: Block{N} , b:: Vararg{Integer,N} ) where {N} = a[b... ]
317+ # Fix ambiguity.
318+ _getindex (a:: Block{0} ) = a[]
319+
320+ struct BlockIndexVector{N,BT,I<: NTuple{N,AbstractVector} ,TB<: Integer } <: AbstractArray{BT,N}
287321 block:: Block{N,TB}
288322 indices:: I
289- function BlockIndexVector (
323+ function BlockIndexVector {N,BT} (
290324 block:: Block{N,TB} , indices:: I
291- ) where {N,I<: NTuple{N,AbstractVector} ,TB<: Integer }
292- BT = blockindextype (TB, eltype .(indices)... )
293- return new {N,I,TB,BT} (block, indices)
325+ ) where {N,BT,I<: NTuple{N,AbstractVector} ,TB<: Integer }
326+ return new {N,BT,I,TB} (block, indices)
294327 end
295328end
329+ function BlockIndexVector {1,BT} (block:: Block{1} , indices:: AbstractVector ) where {BT}
330+ return BlockIndexVector {1,BT} (block, (indices,))
331+ end
332+ function BlockIndexVector (
333+ block:: Block{N,TB} , indices:: NTuple{N,AbstractVector}
334+ ) where {N,TB<: Integer }
335+ BT = Base. promote_op (_getindex, typeof (block), eltype .(indices)... )
336+ return BlockIndexVector {N,BT} (block, indices)
337+ end
296338function BlockIndexVector (block:: Block{1} , indices:: AbstractVector )
297339 return BlockIndexVector (block, (indices,))
298340end
299341Base. size (a:: BlockIndexVector ) = length .(a. indices)
300342function Base. getindex (a:: BlockIndexVector{N} , I:: Vararg{Integer,N} ) where {N}
301- return a . block[ map ((r, i) -> r[i], a. indices, I)... ]
343+ return _getindex ( Block (a), getindex .( a. indices, I)... )
302344end
303345BlockArrays. block (b:: BlockIndexVector ) = b. block
304346BlockArrays. Block (b:: BlockIndexVector ) = b. block
305347
306348Base. copy (a:: BlockIndexVector ) = BlockIndexVector (a. block, copy .(a. indices))
307349
350+ function Base. getindex (b:: AbstractBlockedUnitRange , Kkr:: BlockIndexVector{1} )
351+ return b[block (Kkr)][Kkr. indices... ]
352+ end
353+
308354using ArrayLayouts: LayoutArray
309355@propagate_inbounds Base. getindex (b:: AbstractArray{T,N} , K:: BlockIndexVector{N} ) where {T,N} = b[block (
310356 K
@@ -316,6 +362,30 @@ using ArrayLayouts: LayoutArray
316362 K
317363)][K. indices... ]
318364
365+ function blockedunitrange_getindices (
366+ a:: AbstractBlockedUnitRange ,
367+ indices:: BlockVector{<:BlockIndex{1},<:Vector{<:BlockIndexVector{1}}} ,
368+ )
369+ return mortar (map (b -> a[b], blocks (indices)))
370+ end
371+ function blockedunitrange_getindices (
372+ a:: AbstractBlockedUnitRange ,
373+ indices:: BlockVector{<:GenericBlockIndex{1},<:Vector{<:BlockIndexVector{1}}} ,
374+ )
375+ return mortar (map (b -> a[b], blocks (indices)))
376+ end
377+
378+ # This is a specialization of `BlockArrays.unblock`:
379+ # https://github.com/JuliaArrays/BlockArrays.jl/blob/v1.6.3/src/views.jl#L8-L11
380+ # that is used in the `to_indices` logic for blockwise slicing in
381+ # BlockArrays.jl.
382+ # TODO : Ideally this would be defined in BlockArrays.jl once the slicing
383+ # there is made more generic.
384+ function BlockArrays. unblock (A, inds, I:: Tuple{BlockIndexVector{1},Vararg{Any}} )
385+ B = first (I)
386+ return _blockslice (B, inds[1 ][B])
387+ end
388+
319389function to_blockindices (a:: AbstractBlockedUnitRange{<:Integer} , I:: AbstractArray{Bool} )
320390 I_blocks = blocks (BlockedVector (I, blocklengths (a)))
321391 I′_blocks = map (eachindex (I_blocks)) do b
0 commit comments