@@ -806,65 +806,45 @@ error_if_canonical_indexing(::LinearIndexing, ::AbstractArray, ::Any...) = nothi
806
806
_getindex (:: LinearIndexing , A:: AbstractArray , I... ) = error (" indexing $(typeof (A)) with types $(typeof (I)) is not supported" )
807
807
808
808
# # LinearFast Scalar indexing: canonical method is one Int
809
- _getindex (:: LinearFast , A:: AbstractVector , i:: Int ) = (@_propagate_inbounds_meta ; getindex (A, i))
810
- _getindex (:: LinearFast , A:: AbstractArray , i:: Int ) = (@_propagate_inbounds_meta ; getindex (A, i))
811
- _getindex {T} (:: LinearFast , A:: AbstractArray{T,0} ) = A[1 ]
812
- function _getindex {T,N} (:: LinearFast , A:: AbstractArray{T,N} , I:: Vararg{Int,N} )
813
- # We must check bounds for sub2ind; so we can then use @inbounds
809
+ _getindex (:: LinearFast , A:: AbstractArray , i:: Int ) = (@_propagate_inbounds_meta ; getindex (A, i))
810
+ _getindex (:: LinearFast , A:: AbstractArray ) = (@_propagate_inbounds_meta ; getindex (A, _to_linear_index (A)))
811
+ function _getindex (:: LinearFast , A:: AbstractArray , I:: Int... )
814
812
@_inline_meta
815
- @boundscheck checkbounds (A, I... )
816
- @inbounds r = getindex (A, sub2ind (A, I... ))
817
- r
818
- end
819
- function _getindex (:: LinearFast , A:: AbstractVector , I1:: Int , I:: Int... )
820
- @_inline_meta
821
- @boundscheck checkbounds (A, I1, I... )
822
- @inbounds r = getindex (A, I1)
823
- r
824
- end
825
- function _getindex (:: LinearFast , A:: AbstractArray , I:: Int... ) # TODO : DEPRECATE FOR #14770
826
- @_inline_meta
827
- @boundscheck checkbounds (A, I... )
828
- @inbounds r = getindex (A, sub2ind (A, I... ))
813
+ @boundscheck checkbounds (A, I... ) # generally _to_linear_index requires bounds checking
814
+ @inbounds r = getindex (A, _to_linear_index (A, I... ))
829
815
r
830
816
end
831
-
817
+ _to_linear_index (A:: AbstractArray , i:: Int ) = i
818
+ _to_linear_index (A:: AbstractVector , i:: Int , I:: Int... ) = i # TODO : DEPRECATE FOR #14770
819
+ _to_linear_index {T,N} (A:: AbstractArray{T,N} , I:: Vararg{Int,N} ) = (@_inline_meta ; sub2ind (A, I... ))
820
+ _to_linear_index (A:: AbstractArray ) = 1 # TODO : DEPRECATE FOR #14770
821
+ _to_linear_index (A:: AbstractArray , I:: Int... ) = (@_inline_meta ; sub2ind (A, I... )) # TODO : DEPRECATE FOR #14770
832
822
833
823
# # LinearSlow Scalar indexing: Canonical method is full dimensionality of Ints
834
- _getindex {T,N} (:: LinearSlow , A:: AbstractArray{T,N} , I:: Vararg{Int, N} ) = (@_propagate_inbounds_meta ; getindex (A, I... ))
835
- function _getindex (:: LinearSlow , A:: AbstractArray , i:: Int )
836
- # ind2sub requires all dimensions to be > 0; may as well just check bounds
824
+ _getindex (:: LinearSlow , A:: AbstractArray ) = (@_propagate_inbounds_meta ; getindex (A, _to_subscript_indices (A)... ))
825
+ function _getindex (:: LinearSlow , A:: AbstractArray , I:: Int... )
837
826
@_inline_meta
838
- @boundscheck checkbounds (A, i)
839
- @inbounds r = getindex (A, ind2sub (A, i )... )
827
+ @boundscheck checkbounds (A, I ... ) # generally _to_subscript_indices requires bounds checking
828
+ @inbounds r = getindex (A, _to_subscript_indices (A, I ... )... )
840
829
r
841
830
end
842
- @generated function _getindex {T,AN} (:: LinearSlow , A:: AbstractArray{T,AN} , I:: Int... ) # TODO : DEPRECATE FOR #14770
843
- N = length (I)
844
- if N > AN
845
- # Drop trailing ones
846
- Isplat = Expr[:(I[$ d]) for d = 1 : AN]
847
- Osplat = Expr[:(I[$ d] == 1 ) for d = AN+ 1 : N]
848
- quote
849
- @_propagate_inbounds_meta
850
- @boundscheck (& )($ (Osplat... )) || throw_boundserror (A, I)
851
- getindex (A, $ (Isplat... ))
852
- end
853
- else
854
- # Expand the last index into the appropriate number of indices
855
- Isplat = Expr[:(I[$ d]) for d = 1 : N- 1 ]
856
- sz = Expr (:tuple )
857
- sz. args = Expr[:(size (A, $ d)) for d= max (N,1 ): AN]
858
- szcheck = Expr[:(size (A, $ d) > 0 ) for d= max (N,1 ): AN]
859
- last_idx = N > 0 ? :(I[$ N]) : 1
860
- quote
861
- # ind2sub requires all dimensions to be > 0:
862
- @_propagate_inbounds_meta
863
- @boundscheck (& )($ (szcheck... )) || throw_boundserror (A, I)
864
- getindex (A, $ (Isplat... ), ind2sub ($ sz, $ last_idx)... )
865
- end
866
- end
831
+ _getindex {T,N} (:: LinearSlow , A:: AbstractArray{T,N} , I:: Vararg{Int, N} ) = (@_propagate_inbounds_meta ; getindex (A, I... ))
832
+ _to_subscript_indices (A:: AbstractArray , i:: Int ) = (@_inline_meta ; _unsafe_ind2sub (A, i))
833
+ _to_subscript_indices {T,N} (A:: AbstractArray{T,N} ) = (@_inline_meta ; fill_to_length ((), 1 , Val{N})) # TODO : DEPRECATE FOR #14770
834
+ _to_subscript_indices {T} (A:: AbstractArray{T,0} ) = () # TODO : REMOVE FOR #14770
835
+ _to_subscript_indices {T} (A:: AbstractArray{T,0} , i:: Int ) = () # TODO : REMOVE FOR #14770
836
+ _to_subscript_indices {T} (A:: AbstractArray{T,0} , I:: Int... ) = () # TODO : DEPRECATE FOR #14770
837
+ function _to_subscript_indices {T,N} (A:: AbstractArray{T,N} , I:: Int... ) # TODO : DEPRECATE FOR #14770
838
+ @_inline_meta
839
+ J, _ = IteratorsMD. split (I, Val{N}) # (maybe) drop any trailing indices
840
+ sz = _remaining_size (J, size (A)) # compute trailing size (overlapping the final index)
841
+ (front (J)... , _unsafe_ind2sub (sz, last (J))... ) # (maybe) extend the last index
867
842
end
843
+ _to_subscript_indices {T,N} (A:: AbstractArray{T,N} , I:: Vararg{Int,N} ) = I
844
+ _remaining_size (:: Tuple{Any} , t:: Tuple ) = t
845
+ _remaining_size (h:: Tuple , t:: Tuple ) = (@_inline_meta ; _remaining_size (tail (h), tail (t)))
846
+ _unsafe_ind2sub (:: Tuple{} , i) = () # ind2sub may throw(BoundsError()) in this case
847
+ _unsafe_ind2sub (sz, i) = (@_inline_meta ; ind2sub (sz, i))
868
848
869
849
# # Setindex! is defined similarly. We first dispatch to an internal _setindex!
870
850
# function that allows dispatch on array storage
@@ -882,65 +862,24 @@ end
882
862
_setindex! (:: LinearIndexing , A:: AbstractArray , v, I... ) = error (" indexing $(typeof (A)) with types $(typeof (I)) is not supported" )
883
863
884
864
# # LinearFast Scalar indexing
885
- _setindex! (:: LinearFast , A:: AbstractVector , v, i:: Int ) = (@_propagate_inbounds_meta ; setindex! (A, v, i))
886
865
_setindex! (:: LinearFast , A:: AbstractArray , v, i:: Int ) = (@_propagate_inbounds_meta ; setindex! (A, v, i))
887
- _setindex! {T} (:: LinearFast , A:: AbstractArray{T,0} , v) = (@_propagate_inbounds_meta ; setindex! (A, v, 1 ))
888
- function _setindex! {T,N} (:: LinearFast , A:: AbstractArray{T,N} , v, I:: Vararg{Int,N} )
889
- # We must check bounds for sub2ind; so we can then use @inbounds
890
- @_inline_meta
891
- @boundscheck checkbounds (A, I... )
892
- @inbounds r = setindex! (A, v, sub2ind (A, I... ))
893
- r
894
- end
895
- function _setindex! (:: LinearFast , A:: AbstractVector , v, I1:: Int , I:: Int... )
896
- @_inline_meta
897
- @boundscheck checkbounds (A, I1, I... )
898
- @inbounds r = setindex! (A, v, I1)
899
- r
900
- end
901
- function _setindex! (:: LinearFast , A:: AbstractArray , v, I:: Int... ) # TODO : DEPRECATE FOR #14770
866
+ _setindex! (:: LinearFast , A:: AbstractArray , v) = (@_propagate_inbounds_meta ; setindex! (A, v, _to_linear_index (A)))
867
+ function _setindex! (:: LinearFast , A:: AbstractArray , v, I:: Int... )
902
868
@_inline_meta
903
869
@boundscheck checkbounds (A, I... )
904
- @inbounds r = setindex! (A, v, sub2ind (A, I... ))
870
+ @inbounds r = setindex! (A, v, _to_linear_index (A, I... ))
905
871
r
906
872
end
907
873
908
874
# LinearSlow Scalar indexing
909
875
_setindex! {T,N} (:: LinearSlow , A:: AbstractArray{T,N} , v, I:: Vararg{Int, N} ) = (@_propagate_inbounds_meta ; setindex! (A, v, I... ))
910
- function _setindex! (:: LinearSlow , A:: AbstractArray , v, i :: Int )
911
- # ind2sub requires all dimensions to be > 0; may as well just check bounds
876
+ _setindex! (:: LinearSlow , A:: AbstractArray , v) = ( @_propagate_inbounds_meta ; setindex! (A, v, _to_subscript_indices (A) ... ) )
877
+ function _setindex! ( :: LinearSlow , A :: AbstractArray , v, I :: Int... )
912
878
@_inline_meta
913
- @boundscheck checkbounds (A, i )
914
- @inbounds r = setindex! (A, v, ind2sub (A, i )... )
879
+ @boundscheck checkbounds (A, I ... )
880
+ @inbounds r = setindex! (A, v, _to_subscript_indices (A, I ... )... )
915
881
r
916
882
end
917
- @generated function _setindex! {T,AN} (:: LinearSlow , A:: AbstractArray{T,AN} , v, I:: Int... ) # TODO : DEPRECATE FOR #14770
918
- N = length (I)
919
- if N > AN
920
- # Drop trailing ones
921
- Isplat = Expr[:(I[$ d]) for d = 1 : AN]
922
- Osplat = Expr[:(I[$ d] == 1 ) for d = AN+ 1 : N]
923
- quote
924
- # We only check the trailing ones, so just propagate @inbounds state
925
- @_propagate_inbounds_meta
926
- @boundscheck (& )($ (Osplat... )) || throw_boundserror (A, I)
927
- setindex! (A, v, $ (Isplat... ))
928
- end
929
- else
930
- # Expand the last index into the appropriate number of indices
931
- Isplat = Expr[:(I[$ d]) for d = 1 : N- 1 ]
932
- sz = Expr (:tuple )
933
- sz. args = Expr[:(size (A, $ d)) for d= max (N,1 ): AN]
934
- szcheck = Expr[:(size (A, $ d) > 0 ) for d= max (N,1 ): AN]
935
- last_idx = N > 0 ? :(I[$ N]) : 1
936
- quote
937
- # ind2sub requires all dimensions to be > 0:
938
- @_propagate_inbounds_meta
939
- @boundscheck (& )($ (szcheck... )) || throw_boundserror (A, I)
940
- setindex! (A, v, $ (Isplat... ), ind2sub ($ sz, $ last_idx)... )
941
- end
942
- end
943
- end
944
883
945
884
# # get (getindex with a default value) ##
946
885
0 commit comments