@@ -141,22 +141,6 @@ to_index(::IndexLinear, axis, arg::CartesianIndices{1}) = axes(arg, 1)
141
141
@propagate_inbounds function to_index (:: IndexLinear , axis, arg:: AbstractCartesianIndex{1} )
142
142
return to_index (axis, first (Tuple (arg)))
143
143
end
144
- function to_index (:: IndexLinear , x, arg:: AbstractCartesianIndex{N} ) where {N}
145
- inds = Tuple (arg)
146
- o = offsets (x)
147
- s = size (x)
148
- return first (inds) + (static (1 ) - first (o)) + _subs2int (first (s), tail (s), tail (o), tail (inds))
149
- end
150
- @inline function _subs2int (stride, s:: Tuple{Any,Vararg} , o:: Tuple{Any,Vararg} , inds:: Tuple{Any,Vararg} )
151
- i = ((first (inds) - first (o)) * stride)
152
- return i + _subs2int (stride * first (s), tail (s), tail (o), tail (inds))
153
- end
154
- function _subs2int (stride, s:: Tuple{Any} , o:: Tuple{Any} , inds:: Tuple{Any} )
155
- return (first (inds) - first (o)) * stride
156
- end
157
- # trailing inbounds can only be 1 or 1:1
158
- _subs2int (stride, :: Tuple{} , :: Tuple{} , :: Tuple{Any} ) = static (0 )
159
-
160
144
@propagate_inbounds function to_index (:: IndexLinear , x, arg:: Union{Array{Bool}, BitArray} )
161
145
@boundscheck checkbounds (x, arg)
162
146
return LogicalIndex {Int} (arg)
@@ -215,13 +199,18 @@ end
215
199
@boundscheck checkbounds (x, arg)
216
200
return LogicalIndex {Int} (arg)
217
201
end
218
- to_index ( :: IndexCartesian , x, i :: Integer ) = NDIndex ( _int2subs ( offsets (x), size (x), i - static ( 1 )))
219
- @inline function _int2subs (o :: Tuple{Any,Vararg{Any}} , s :: Tuple{Any,Vararg{Any}} , i)
220
- len = first (s)
221
- inext = div (i, len )
222
- return ( canonicalize (i - len * inext + first (o)), _int2subs ( tail (o ), tail (s), inext) ... )
202
+
203
+ # TODO delete this once the layout interface is working
204
+ _array_index ( :: IndexLinear , a, i :: CanonicalInt ) = i
205
+ @inline function _array_index ( :: IndexStyle , a, i :: CanonicalInt )
206
+ CartesianIndices ( ntuple (dim -> indices (a, dim ), Val ( ndims (a))))[i]
223
207
end
224
- _int2subs (o:: Tuple{Any} , s:: Tuple{Any} , i) = canonicalize (i + first (o))
208
+ _array_index (:: IndexLinear , a, i:: AbstractCartesianIndex{1} ) = getfield (Tuple (i), 1 )
209
+ @inline function _array_index (:: IndexLinear , a, i:: AbstractCartesianIndex )
210
+ N = ndims (a)
211
+ StrideIndex {N,ntuple(+, Val(N)),nothing} (size_to_strides (size (a), static (1 )), offsets (a))[i]
212
+ end
213
+ _array_index (:: IndexStyle , a, i:: AbstractCartesianIndex ) = i
225
214
226
215
"""
227
216
unsafe_reconstruct(A, data; kwargs...)
@@ -326,54 +315,50 @@ another instance of `ArrayInterface.getindex` should only be done by overloading
326
315
Changing indexing based on a given argument from `args` should be done through,
327
316
[`to_index`](@ref), or [`to_axis`](@ref).
328
317
"""
329
- @propagate_inbounds getindex (A, args... ) = unsafe_get_index (A, to_indices (A, args))
318
+ @propagate_inbounds getindex (A, args... ) = unsafe_getindex (A, to_indices (A, args)... )
330
319
@propagate_inbounds function getindex (A; kwargs... )
331
- return unsafe_get_index (A, to_indices (A, order_named_inds (dimnames (A), values (kwargs))))
320
+ return unsafe_getindex (A, to_indices (A, order_named_inds (dimnames (A), values (kwargs)))... )
332
321
end
333
322
@propagate_inbounds getindex (x:: Tuple , i:: Int ) = getfield (x, i)
334
323
@propagate_inbounds getindex (x:: Tuple , :: StaticInt{i} ) where {i} = getfield (x, i)
335
324
336
- # # unsafe_get_index ##
337
- unsafe_get_index (A, i:: Tuple{} ) = unsafe_get_element (A, ())
338
- unsafe_get_index (A, i:: Tuple{CanonicalInt} ) = unsafe_get_element (A, getfield (i, 1 ))
339
- function unsafe_get_index (A, i:: Tuple{CanonicalInt,Vararg{CanonicalInt}} )
340
- unsafe_get_element (A, NDIndex (i))
325
+ # # unsafe_getindex ##
326
+ function unsafe_getindex (a:: A ) where {A}
327
+ parent_type (A) <: A && throw (MethodError (unsafe_getindex, (A,)))
328
+ return unsafe_getindex (parent (a))
341
329
end
342
- unsafe_get_index (A, i:: Tuple ) = unsafe_get_collection (A, i)
343
-
344
- #=
345
- unsafe_get_element(A::AbstractArray{T}, inds::Tuple) -> T
346
-
347
- Returns an element of `A` at the indices `inds`. This method assumes all `inds`
348
- have been checked for being in bounds. Any new array type using `ArrayInterface.getindex`
349
- must define `unsafe_get_element(::NewArrayType, inds)`.
350
- =#
351
- unsafe_get_element (a:: A , inds) where {A} = _unsafe_get_element (has_parent (A), a, inds)
352
- _unsafe_get_element (:: True , a, inds) = unsafe_get_element (parent (a), inds)
353
- _unsafe_get_element (:: False , a, inds) = @inbounds (parent (a)[inds])
354
- _unsafe_get_element (:: False , a:: AbstractArray2 , i) = unsafe_get_element_error (a, i)
355
-
356
- # # Array ##
357
- unsafe_get_element (A:: Array , :: Tuple{} ) = Base. arrayref (false , A, 1 )
358
- unsafe_get_element (A:: Array , i:: Integer ) = Base. arrayref (false , A, Int (i))
359
- unsafe_get_element (A:: Array , i:: NDIndex ) = unsafe_get_element (A, to_index (A, i))
330
+ function unsafe_getindex (a:: A , i:: CanonicalInt ) where {A}
331
+ idx = _array_index (IndexStyle (A), a, i)
332
+ if idx === i
333
+ parent_type (A) <: A && throw (MethodError (unsafe_getindex, (A, i)))
334
+ return unsafe_getindex (parent (a), i)
335
+ else
336
+ return unsafe_getindex (a, idx)
337
+ end
338
+ end
339
+ function unsafe_getindex (a:: A , i:: AbstractCartesianIndex ) where {A}
340
+ idx = _array_index (IndexStyle (A), a, i)
341
+ if idx === i
342
+ parent_type (A) <: A && throw (MethodError (unsafe_getindex, (A, i)))
343
+ return unsafe_getindex (parent (a), i)
344
+ else
345
+ return unsafe_getindex (a, idx)
346
+ end
347
+ end
348
+ function unsafe_getindex (a, i:: CanonicalInt , ii:: Vararg{CanonicalInt} )
349
+ unsafe_getindex (a, NDIndex (i, ii... ))
350
+ end
351
+ unsafe_getindex (a, i:: Vararg{Any} ) = unsafe_get_collection (a, i)
360
352
361
- # # LinearIndices ##
362
- unsafe_get_element (A:: LinearIndices , i:: Integer ) = Int (i)
363
- unsafe_get_element (A:: LinearIndices , i:: NDIndex ) = unsafe_get_element (A, to_index (A, i))
353
+ unsafe_getindex (A:: Array ) = Base. arrayref (false , A, 1 )
354
+ unsafe_getindex (A:: Array , i:: CanonicalInt ) = Base. arrayref (false , A, Int (i))
364
355
365
- unsafe_get_element (A:: CartesianIndices , i:: NDIndex ) = CartesianIndex (i)
366
- unsafe_get_element (A:: CartesianIndices , i:: Integer ) = unsafe_get_element (A, to_index (A, i))
356
+ unsafe_getindex (A:: LinearIndices , i:: CanonicalInt ) = Int (i)
367
357
368
- unsafe_get_element (A:: ReshapedArray , i:: Integer ) = unsafe_get_element (parent (A), i)
369
- function unsafe_get_element (A:: ReshapedArray , i:: NDIndex )
370
- return unsafe_get_element (parent (A), to_index (IndexLinear (), A, i))
371
- end
358
+ unsafe_getindex (A:: CartesianIndices , i:: AbstractCartesianIndex ) = CartesianIndex (i)
372
359
373
- unsafe_get_element (A:: SubArray , i) = @inbounds (A[i])
374
- function unsafe_get_element_error (@nospecialize (A), @nospecialize (i))
375
- throw (MethodError (unsafe_get_element, (A, i)))
376
- end
360
+ unsafe_getindex (A:: SubArray , i:: CanonicalInt ) = @inbounds (A[i])
361
+ unsafe_getindex (A:: SubArray , i:: AbstractCartesianIndex ) = @inbounds (A[i])
377
362
378
363
# This is based on Base._unsafe_getindex from https://github.com/JuliaLang/julia/blob/c5ede45829bf8eb09f2145bfd6f089459d77b2b1/base/multidimensional.jl#L755.
379
364
#=
@@ -402,7 +387,7 @@ function _generate_unsafe_get_index!_body(N::Int)
402
387
# the optimizer is not clever enough to split the union without it
403
388
Dy === nothing && return dest
404
389
(idx, state) = Dy
405
- dest[idx] = unsafe_get_element (src, NDIndex (Base. Cartesian. @ntuple ($ N, j)))
390
+ dest[idx] = unsafe_getindex (src, NDIndex (Base. Cartesian. @ntuple ($ N, j)))
406
391
Dy = iterate (D, state)
407
392
end
408
393
return dest
@@ -441,45 +426,49 @@ Store the given values at the given key or index within a collection.
441
426
"""
442
427
@propagate_inbounds function setindex! (A, val, args... )
443
428
if can_setindex (A)
444
- return unsafe_set_index ! (A, val, to_indices (A, args))
429
+ return unsafe_setindex ! (A, val, to_indices (A, args)... )
445
430
else
446
431
error (" Instance of type $(typeof (A)) are not mutable and cannot change elements after construction." )
447
432
end
448
433
end
449
434
@propagate_inbounds function setindex! (A, val; kwargs... )
450
- return unsafe_set_index ! (A, val, to_indices (A, order_named_inds (dimnames (A), values (kwargs))))
435
+ return unsafe_setindex ! (A, val, to_indices (A, order_named_inds (dimnames (A), values (kwargs)))... )
451
436
end
452
437
453
- # # unsafe_get_index ##
454
- unsafe_set_index! (A, v, i:: Tuple{} ) = unsafe_set_element! (A, v, ())
455
- unsafe_set_index! (A, v, i:: Tuple{CanonicalInt} ) = unsafe_set_element! (A, v, getfield (i, 1 ))
456
- function unsafe_set_index! (A, v, i:: Tuple{CanonicalInt,Vararg{CanonicalInt}} )
457
- unsafe_set_element! (A, v, NDIndex (i))
438
+ # # unsafe_setindex! ##
439
+ function unsafe_setindex! (a:: A , v) where {A}
440
+ parent_type (A) <: A && throw (MethodError (unsafe_setindex!, (A, v)))
441
+ return unsafe_setindex! (parent (a), v)
458
442
end
459
- unsafe_set_index! (A, v, i:: Tuple ) = unsafe_set_collection! (A, v, i)
460
-
461
- #=
462
- unsafe_set_element!(A, val, inds::Tuple)
463
-
464
- Sets an element of `A` to `val` at indices `inds`. This method assumes all `inds`
465
- have been checked for being in bounds. Any new array type using `ArrayInterface.setindex!`
466
- must define `unsafe_set_element!(::NewArrayType, val, inds)`.
467
- =#
468
- unsafe_set_element! (a, val, inds) = _unsafe_set_element! (has_parent (a), a, val, inds)
469
- _unsafe_set_element! (:: True , a, val, inds) = unsafe_set_element! (parent (a), val, inds)
470
- _unsafe_set_element! (:: False , a, val, inds) = @inbounds (parent (a)[inds] = val)
471
-
472
- function _unsafe_set_element! (:: False , a:: AbstractArray2 , val, inds)
473
- unsafe_set_element_error (a, val, inds)
443
+ function unsafe_setindex! (a:: A , v, i:: CanonicalInt ) where {A}
444
+ idx = _array_index (IndexStyle (A), a, i)
445
+ if idx === i
446
+ parent_type (A) <: A && throw (MethodError (unsafe_setindex!, (A, v, i)))
447
+ return unsafe_setindex! (parent (a), v, i)
448
+ else
449
+ return unsafe_setindex! (a, v, idx)
450
+ end
474
451
end
475
- unsafe_set_element_error (A, v, i) = throw (MethodError (unsafe_set_element!, (A, v, i)))
476
-
477
- function unsafe_set_element! (A:: Array{T} , val, :: Tuple{} ) where {T}
478
- Base. arrayset (false , A, convert (T, val):: T , 1 )
452
+ function unsafe_setindex! (a:: A , v, i:: AbstractCartesianIndex ) where {A}
453
+ idx = _array_index (IndexStyle (A), a, i)
454
+ if idx === i
455
+ parent_type (A) <: A && throw (MethodError (unsafe_setindex!, (A, v, i)))
456
+ return unsafe_setindex! (parent (a), v, i)
457
+ else
458
+ return unsafe_setindex! (a, v, idx)
459
+ end
460
+ end
461
+ function unsafe_setindex! (a, v, i:: CanonicalInt , ii:: Vararg{CanonicalInt} )
462
+ unsafe_setindex! (a, v, NDIndex (i, ii... ))
479
463
end
480
- function unsafe_set_element ! (A:: Array{T} , val, i :: Integer ) where {T}
481
- return Base. arrayset (false , A, convert (T, val ):: T , Int (i) )
464
+ function unsafe_setindex ! (A:: Array{T} , v ) where {T}
465
+ Base. arrayset (false , A, convert (T, v ):: T , 1 )
482
466
end
467
+ function unsafe_setindex! (A:: Array{T} , v, i:: CanonicalInt ) where {T}
468
+ return Base. arrayset (false , A, convert (T, v):: T , Int (i))
469
+ end
470
+
471
+ unsafe_setindex! (a, v, i:: Vararg{Any} ) = unsafe_set_collection! (a, v, i)
483
472
484
473
# This is based on Base._unsafe_setindex!.
485
474
#=
@@ -501,7 +490,7 @@ function _generate_unsafe_setindex!_body(N::Int)
501
490
# the optimizer that it does not need to emit error paths
502
491
Xy === nothing && break
503
492
(val, state) = Xy
504
- unsafe_set_element ! (A, val, NDIndex (Base. Cartesian. @ntuple ($ N, i)))
493
+ unsafe_setindex ! (A, val, NDIndex (Base. Cartesian. @ntuple ($ N, i)))
505
494
Xy = iterate (x′, state)
506
495
end
507
496
A
0 commit comments