@@ -87,32 +87,77 @@ ERROR: BlockBoundsError: attempt to access 2×2-blocked 2×3 BlockMatrix{Float64
8787[...]
8888```
8989"""
90- @inline function blockcheckbounds (A:: AbstractArray{T, N} , i:: Vararg{Integer, N} ) where {T,N}
91- if blockcheckbounds (Bool, A, i... )
92- return
93- else
94- throw (BlockBoundsError (A, i))
95- end
90+ @inline function blockcheckbounds (A:: AbstractArray , i:: Integer... )
91+ blockcheckbounds (Bool, A, i... ) || throw (BlockBoundsError (A, i))
9692end
9793
98- @inline function blockcheckbounds (:: Type{Bool} , A:: AbstractArray{T, N} , i:: Vararg{Integer, N} ) where {T,N}
99- n = blockaxes (A)
100- k = 0
101- for idx in 1 : N # using enumerate here will allocate
102- k += 1
103- @inbounds _i = i[idx]
104- Block (_i) in n[k] || return false
105- end
106- for idx = N+ 1 : length (i)
107- isone (i[idx]) || return false
108- end
109- return true
94+ # linear block indexing
95+ @inline function blockcheckbounds (:: Type{Bool} , A:: AbstractArray , i:: Integer )
96+ blockcheckindex (Bool, BlockRange (blocklength (A)), i)
97+ end
98+ # cartesian block indexing
99+ @inline function blockcheckbounds (:: Type{Bool} , A:: AbstractArray , i:: Integer... )
100+ blockcheckbounds_indices (Bool, blockaxes (A), i)
110101end
111102
112103blockcheckbounds (A:: AbstractArray{T, N} , i:: Block{N} ) where {T,N} = blockcheckbounds (A, i. n... )
113104blockcheckbounds (A:: AbstractArray{T, N} , i:: Vararg{Block{1},N} ) where {T,N} = blockcheckbounds (A, Int .(i)... )
114105blockcheckbounds (A:: AbstractVector{T} , i:: Block{1} ) where {T} = blockcheckbounds (A, Int (i))
115106
107+ """
108+ blockcheckbounds_indices(Bool, IA::Tuple{Vararg{BlockRange{1}}}, I::Tuple{Vararg{Integer}})
109+
110+ Return true if the "requested" indices in the tuple `Block.(I)` fall within the bounds of the "permitted"
111+ indices specified by the tuple `IA`. This function recursively consumes elements of these tuples
112+ in a 1-for-1 fashion.
113+
114+ The actual bounds-checking is performed by [`blockcheckindex`](@ref).
115+
116+ # Examples
117+ ```jldoctest
118+ julia> B = BlockArray(zeros(6,6), 1:3, 1:3);
119+
120+ julia> blockaxes(B)
121+ (BlockRange(Base.OneTo(3)), BlockRange(Base.OneTo(3)))
122+
123+ julia> BlockArrays.blockcheckbounds_indices(Bool, blockaxes(B), (1,2))
124+ true
125+
126+ julia> BlockArrays.blockcheckbounds_indices(Bool, blockaxes(B), (4,1))
127+ false
128+ ```
129+ """
130+ @inline blockcheckbounds_indices (:: Type{Bool} , :: Tuple{} , :: Tuple{} ) = true
131+ @inline function blockcheckbounds_indices (:: Type{Bool} , blockaxes:: Tuple{Vararg{BlockRange{1}}} , i:: Tuple{} )
132+ # the trailing blocks must be Block(1)
133+ b = first (blockaxes)
134+ length (b) == 1 && Int (b[]) == 1 && blockcheckbounds_indices (Bool, blockaxes[2 : end ], i)
135+ end
136+ @inline function blockcheckbounds_indices (:: Type{Bool} , blockaxes:: Tuple{} , i:: Tuple{Vararg{Integer}} )
137+ # the trailing indices must be 1
138+ first (i) == 1 && blockcheckbounds_indices (Bool, blockaxes, i[2 : end ])
139+ end
140+ @inline function blockcheckbounds_indices (:: Type{Bool} , blockaxes:: Tuple{Vararg{BlockRange{1}}} , i:: Tuple{Vararg{Integer}} )
141+ blockcheckindex (Bool, first (blockaxes), first (i)) &&
142+ blockcheckbounds_indices (Bool, blockaxes[2 : end ], i[2 : end ])
143+ end
144+
145+ """
146+ blockcheckindex(Bool, inds::BlockRange{1}, index::Integer)
147+
148+ Return `true` if `Block(index)` is within the bounds of `inds`.
149+
150+ # Examples
151+ ```jldoctest
152+ julia> BlockArrays.blockcheckindex(Bool, BlockRange(1:2), 1)
153+ true
154+
155+ julia> BlockArrays.blockcheckindex(Bool, BlockRange(1:2), 3)
156+ false
157+ ```
158+ """
159+ @inline blockcheckindex (:: Type{Bool} , inds:: BlockRange{1} , i:: Integer ) = Block (i) in inds
160+
116161@propagate_inbounds Base. setindex! (block_arr:: AbstractBlockArray{T,N} , v, block:: Block{N} ) where {T,N} =
117162 setindex! (block_arr, v, Block .(block. n)... )
118163@inline @propagate_inbounds function Base. setindex! (block_arr:: AbstractBlockArray{T,N} , v, block:: Vararg{Block{1}, N} ) where {T,N}
0 commit comments