@@ -87,32 +87,77 @@ ERROR: BlockBoundsError: attempt to access 2×2-blocked 2×3 BlockMatrix{Float64
87
87
[...]
88
88
```
89
89
"""
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... )
91
+ blockcheckbounds (Bool, A, i... ) || throw (BlockBoundsError (A, i))
96
92
end
97
93
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)
96
+ blockcheckindex (Bool, BlockRange (blocklength (A)), i)
97
+ end
98
+ # cartesian block indexing
99
+ @inline function blockcheckbounds (:: Type{Bool} , A:: AbstractArray , i... )
100
+ blockcheckbounds_indices (Bool, blockaxes (A), i)
110
101
end
111
102
112
103
blockcheckbounds (A:: AbstractArray{T, N} , i:: Block{N} ) where {T,N} = blockcheckbounds (A, i. n... )
113
104
blockcheckbounds (A:: AbstractArray{T, N} , i:: Vararg{Block{1},N} ) where {T,N} = blockcheckbounds (A, Int .(i)... )
114
105
blockcheckbounds (A:: AbstractVector{T} , i:: Block{1} ) where {T} = blockcheckbounds (A, Int (i))
115
106
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 )
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 )
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
+
116
161
@propagate_inbounds Base. setindex! (block_arr:: AbstractBlockArray{T,N} , v, block:: Block{N} ) where {T,N} =
117
162
setindex! (block_arr, v, Block .(block. n)... )
118
163
@inline @propagate_inbounds function Base. setindex! (block_arr:: AbstractBlockArray{T,N} , v, block:: Vararg{Block{1}, N} ) where {T,N}
0 commit comments