@@ -841,4 +841,107 @@ import Requires
841841 end
842842end
843843
844+ """
845+ ArrayInterface.CheckIndexNone
846+
847+ A [`ArrayInterface.CheckIndexStyle`](@ref) trait-value indicating that no bounds-checking
848+ is needed. This is only appropriate for select types such as slice indexing
849+ (e.g., `:`, `Base.Slice`).
850+
851+ # Examples
852+
853+ ```jldoctest
854+ julia> ArrayInterface.CheckIndexStyle(:)
855+ ArrayInterface.CheckIndexNone()
856+ julia> ArrayInterface.CheckIndexStyle(Base.Slice(1:10))
857+ ArrayInterface.CheckIndexNone()
858+ ```
859+ """
860+ struct CheckIndexNone <: CheckIndexStyle end
861+
862+ """
863+ ArrayInterface.CheckIndexFirstLast()
864+
865+ A [`ArrayInterface.CheckIndexStyle`](@ref) trait-value indicating that bounds-checking
866+ only need test the first and last elements in an index vector.
867+
868+ # Examples
869+
870+ ```jldoctest
871+ julia> r = 3:7; ArrayInterface.CheckIndexStyle(r)
872+ ArrayInterface.CheckIndexFirstLast()
873+ ```
874+
875+ Ranges are declared `CheckIndexFirstLast` because `x[r]` can be tested
876+ for out-of-bounds indexing using just the first and last elements of `r`.
877+
878+ See also [`ArrayInterface.CheckIndexAll`](@ref) and [`ArrayInterface.CheckIndexAxes`](@ref).
879+ """
880+ struct CheckIndexFirstLast <: CheckIndexStyle end
881+
882+ """
883+ ArrayInterface.CheckIndexAll()
884+
885+ A [`ArrayInterface.CheckIndexStyle`](@ref) trait-value indicating that bounds-checking
886+ must test all elements in an index vector.
887+
888+ # Examples
889+
890+ ```jldoctest
891+ julia> idx = [3,4,5,6,7]; ArrayInterface.CheckIndexStyle(idx)
892+ ArrayInterface.CheckIndexAll()
893+ ```
894+
895+ Since the entries in `idx` could be arbitrary, we have to check each
896+ entry for bounds violations.
897+
898+ See also [`ArrayInterface..CheckIndexFirstLast`](@ref) and [`ArrayInterface.CheckIndexAxes`](@ref).
899+ """
900+ struct CheckIndexAll <: CheckIndexStyle end
901+
902+ """
903+ ArrayInterface.CheckIndexAxes()
904+
905+ A [`CheckIndexStyle`](@ref) trait-value indicating that bounds-checking
906+ should consider the axes of the index rather than the values of the
907+ index. This is used in cases where the index acts as a filter to
908+ select elements.
909+
910+ # Examples
911+
912+ ```jldoctest
913+ julia> idx = [true, false, true]; ArrayInterface.CheckIndexStyle(idx)
914+ ArrayInterface.CheckIndexAxes()
915+ ```
916+
917+ When `idx` is used in `x[idx]`, it returns the entries in `x`
918+ corresponding to `true` entries in `idx`. Consequently, indexing
919+ should insist on `idx` and `x` having identical axes.
920+
921+ See also [`ArrayInterface.CheckIndexFirstLast`](@ref) and [`ArrayInterface.CheckIndexAll`](@ref).
922+ """
923+ struct CheckIndexAxes <: CheckIndexStyle end
924+
925+ """
926+ ArrayInterface.CheckIndexStyle(typeof(idx))
927+ ArrayInterface.CheckIndexStyle(::Type{T})
928+
929+ `CheckIndexStyle` specifies how bounds-checking of `x[idx]` should be performed. Certain
930+ types of `idx`, such as ranges, may have particularly efficient ways to perform the
931+ bounds-checking. When you define a new [`AbstractArray`](@ref) type, you can choose to
932+ define a specific value for this trait:
933+ ArrayInterface.CheckIndexStyle(::Type{<:MyRange}) = CheckIndexFirstLast()
934+ The default is [`CheckIndexAll()`](@ref), except for `AbstractVector`s with `Bool`
935+ `eltype` (which default to [`ArrayInterface.CheckIndexAxes()`](@ref)) and subtypes of `AbstractRange`
936+ (which default to [`ArrayInterface.CheckIndexFirstLast()`](@ref).)
937+ """
938+ CheckIndexStyle (x) = CheckIndexStyle (typeof (x))
939+ CheckIndexStyle (:: Type ) = CheckIndexAll ()
940+ CheckIndexStyle (@nospecialize T:: Type{<:AbstractArray} ) = eltype (T) === Bool ? CheckIndexAxes () : CheckIndexAll ()
941+ CheckIndexStyle (@nospecialize T:: Type{<:AbstractRange} ) = eltype (T) === Bool ? CheckIndexAxes () : CheckIndexFirstLast ()
942+ CheckIndexStyle (@nospecialize T:: Type{<:Base.FastContiguousSubArray} ) = CheckIndexStyle (parent_type (T))
943+ CheckIndexStyle (@nospecialize T:: Type{<:Union{Base.Slice,Colon}} ) = CheckIndexNone ()
944+ CheckIndexStyle (@nospecialize T:: Type{<:Base.Fix2{<:Union{typeof(<),typeof(isless),typeof(>=),typeof(>),typeof(isless)},<:Number}} ) = CheckIndexNone ()
945+ CheckIndexStyle (@nospecialize T:: Type{<:Number} ) = CheckIndexFirstLast ()
946+
844947end # module
0 commit comments