@@ -154,8 +154,8 @@ linearindexing(::LinearIndexing, ::LinearIndexing) = LinearSlow()
154
154
# The overall hierarchy is
155
155
# `checkbounds(A, I...)` ->
156
156
# `checkbounds(Bool, A, I...)` -> either of:
157
- # - `checkbounds_indices(IA, I)` which calls `checkindex(Bool, inds, i)`
158
- # - `checkbounds_logical(A, I)` when `I` is a single logical array
157
+ # - `checkbounds_logical(Bool, A, I)` when `I` is a single logical array
158
+ # - `checkbounds_indices(Bool, IA, I)` otherwise (uses `checkindex`)
159
159
#
160
160
# See the "boundscheck" devdocs for more information.
161
161
#
@@ -177,23 +177,35 @@ See also `checkindex`.
177
177
"""
178
178
function checkbounds (:: Type{Bool} , A:: AbstractArray , I... )
179
179
@_inline_meta
180
- checkbounds_indices (indices (A), I)
180
+ checkbounds_indices (Bool, indices (A), I)
181
181
end
182
182
function checkbounds (:: Type{Bool} , A:: AbstractArray , I:: AbstractArray{Bool} )
183
183
@_inline_meta
184
- checkbounds_logical (A, I)
184
+ checkbounds_logical (Bool, A, I)
185
185
end
186
186
187
187
"""
188
- checkbounds_indices(IA, I)
188
+ checkbounds(A, I...)
189
+
190
+ Throw an error if the specified indices `I` are not in bounds for the given array `A`.
191
+ """
192
+ function checkbounds (A:: AbstractArray , I... )
193
+ @_inline_meta
194
+ checkbounds (Bool, A, I... ) || throw_boundserror (A, I)
195
+ nothing
196
+ end
197
+ checkbounds (A:: AbstractArray ) = checkbounds (A, 1 ) # 0-d case
189
198
190
- checks whether the "requested" indices in the tuple `I` fall within
199
+ """
200
+ checkbounds_indices(Bool, IA, I)
201
+
202
+ Return `true` if the "requested" indices in the tuple `I` fall within
191
203
the bounds of the "permitted" indices specified by the tuple
192
204
`IA`. This function recursively consumes elements of these tuples,
193
205
usually in a 1-for-1 fashion,
194
206
195
- checkbounds_indices((IA1, IA...), (I1, I...)) = checkindex(Bool, IA1, I1) &
196
- checkbounds_indices(IA, I)
207
+ checkbounds_indices(Bool, (IA1, IA...), (I1, I...)) = checkindex(Bool, IA1, I1) &
208
+ checkbounds_indices(Bool, IA, I)
197
209
198
210
Note that `checkindex` is being used to perform the actual
199
211
bounds-check for a single dimension of the array.
@@ -202,48 +214,55 @@ There are two important exceptions to the 1-1 rule: linear indexing and
202
214
CartesianIndex{N}, both of which may "consume" more than one element
203
215
of `IA`.
204
216
"""
205
- function checkbounds_indices (IA:: Tuple , I:: Tuple )
217
+ function checkbounds_indices (:: Type{Bool} , IA:: Tuple , I:: Tuple )
206
218
@_inline_meta
207
- checkindex (Bool, IA[1 ], I[1 ]) & checkbounds_indices (tail (IA), tail (I))
219
+ checkindex (Bool, IA[1 ], I[1 ]) & checkbounds_indices (Bool, tail (IA), tail (I))
208
220
end
209
- checkbounds_indices (:: Tuple{} , :: Tuple{} ) = true
210
- checkbounds_indices (:: Tuple{} , I:: Tuple{Any} ) = (@_inline_meta ; checkindex (Bool, 1 : 1 , I[1 ]))
211
- function checkbounds_indices (:: Tuple{} , I:: Tuple )
221
+ checkbounds_indices (:: Type{Bool} , :: Tuple{} , :: Tuple{} ) = true
222
+ checkbounds_indices (:: Type{Bool} , :: Tuple{} , I:: Tuple{Any} ) = (@_inline_meta ; checkindex (Bool, 1 : 1 , I[1 ]))
223
+ function checkbounds_indices (:: Type{Bool} , :: Tuple{} , I:: Tuple )
212
224
@_inline_meta
213
- checkindex (Bool, 1 : 1 , I[1 ]) & checkbounds_indices ((), tail (I))
225
+ checkindex (Bool, 1 : 1 , I[1 ]) & checkbounds_indices (Bool, (), tail (I))
214
226
end
215
- function checkbounds_indices (IA:: Tuple{Any} , I:: Tuple{Any} )
227
+ function checkbounds_indices (:: Type{Bool} , IA:: Tuple{Any} , I:: Tuple{Any} )
216
228
@_inline_meta
217
229
checkindex (Bool, IA[1 ], I[1 ])
218
230
end
219
- function checkbounds_indices (IA:: Tuple , I:: Tuple{Any} )
231
+ function checkbounds_indices (:: Type{Bool} , IA:: Tuple , I:: Tuple{Any} )
220
232
@_inline_meta
221
233
checkindex (Bool, 1 : prod (map (dimlength, IA)), I[1 ]) # linear indexing
222
234
end
223
235
224
236
"""
225
- checkbounds_logical(A, I::AbstractArray{Bool})
237
+ checkbounds_logical(Bool, A, I::AbstractArray{Bool})
226
238
227
- tests whether the logical array `I` is consistent with the indices of `A`.
239
+ Return `true` if the logical array `I` is consistent with the indices
240
+ of `A`. `I` and `A` should have the same size and compatible indices.
228
241
"""
229
- checkbounds_logical (A:: AbstractArray , I:: AbstractArray{Bool} ) = indices (A) == indices (I)
230
- checkbounds_logical (A:: AbstractArray , I:: AbstractVector{Bool} ) = length (A) == length (I)
231
- checkbounds_logical (A:: AbstractVector , I:: AbstractArray{Bool} ) = length (A) == length (I)
232
- checkbounds_logical (A:: AbstractVector , I:: AbstractVector{Bool} ) = indices (A) == indices (I)
233
-
234
- throw_boundserror (A, I) = (@_noinline_meta ; throw (BoundsError (A, I)))
242
+ function checkbounds_logical (:: Type{Bool} , A:: AbstractArray , I:: AbstractArray{Bool} )
243
+ indices (A) == indices (I)
244
+ end
245
+ function checkbounds_logical (:: Type{Bool} , A:: AbstractArray , I:: AbstractVector{Bool} )
246
+ length (A) == length (I)
247
+ end
248
+ function checkbounds_logical (:: Type{Bool} , A:: AbstractVector , I:: AbstractArray{Bool} )
249
+ length (A) == length (I)
250
+ end
251
+ function checkbounds_logical (:: Type{Bool} , A:: AbstractVector , I:: AbstractVector{Bool} )
252
+ indices (A) == indices (I)
253
+ end
235
254
236
255
"""
237
- checkbounds (A, I... )
256
+ checkbounds_logical (A, I::AbstractArray{Bool} )
238
257
239
- Throw an error if the specified indices `I` are not in bounds for the given array `A`.
258
+ Throw an error if the logical array `I` is inconsistent with the indices of `A`.
240
259
"""
241
- function checkbounds (A:: AbstractArray , I... )
242
- @_inline_meta
243
- checkbounds (Bool, A, I... ) || throw_boundserror (A, I)
260
+ function checkbounds_logical (A, I:: AbstractVector{Bool} )
261
+ checkbounds_logical (Bool, A, I) || throw_boundserror (A, I)
244
262
nothing
245
263
end
246
- checkbounds (A:: AbstractArray ) = checkbounds (A, 1 ) # 0-d case
264
+
265
+ throw_boundserror (A, I) = (@_noinline_meta ; throw (BoundsError (A, I)))
247
266
248
267
@generated function trailingsize {T,N,n} (A:: AbstractArray{T,N} , :: Type{Val{n}} )
249
268
(isa (n, Int) && isa (N, Int)) || error (" Must have concrete type" )
0 commit comments