@@ -23,7 +23,7 @@ function Base.last(x::AbstractVector, n::StaticInt)
2323end
2424
2525"""
26- to_indices(A, I::Tuple) -> Tuple
26+ ArrayInterface. to_indices(A, I::Tuple) -> Tuple
2727
2828Converts the tuple of indexing arguments, `I`, into an appropriate form for indexing into `A`.
2929Typically, each index should be an `Int`, `StaticInt`, a collection with values of `Int`, or a collection with values of `CartesianIndex`
@@ -183,16 +183,50 @@ end
183183end
184184
185185"""
186- to_index([::IndexStyle, ]axis, arg) -> index
186+ ArrayInterface. to_index([::IndexStyle, ]axis, arg) -> index
187187
188- Convert the argument `arg` that was originally passed to `getindex` for the dimension
189- corresponding to `axis` into a form for native indexing (`Int`, Vector{Int}, etc.). New
190- axis types with unique behavior should use an `IndexStyle` trait:
188+ Convert the argument `arg` that was originally passed to `ArrayInterface.getindex` for the
189+ dimension corresponding to `axis` into a form for native indexing (`Int`, Vector{Int}, etc.).
191190
191+ `ArrayInterface.to_index` supports passing a function as an index. This function-index is
192+ transformed into a proper index.
193+
194+ ```julia
195+ julia> using ArrayInterface, Static
196+
197+ julia> ArrayInterface.to_index(static(1):static(10), 5)
198+ 5
199+
200+ julia> ArrayInterface.to_index(static(1):static(10), <(5))
201+ static(1):4
202+
203+ julia> ArrayInterface.to_index(static(1):static(10), <=(5))
204+ static(1):5
205+
206+ julia> ArrayInterface.to_index(static(1):static(10), >(5))
207+ 6:static(10)
208+
209+ julia> ArrayInterface.to_index(static(1):static(10), >=(5))
210+ 5:static(10)
211+
212+ ```
213+
214+ Use of a function-index helps ensure that indices are inbounds
215+
216+ ```julia
217+ julia> ArrayInterface.to_index(static(1):static(10), <(12))
218+ static(1):10
219+
220+ julia> ArrayInterface.to_index(static(1):static(10), >(-1))
221+ 1:static(10)
222+ ```
223+
224+ New axis types with unique behavior should use an `IndexStyle` trait:
192225```julia
193226to_index(axis::MyAxisType, arg) = to_index(IndexStyle(axis), axis, arg)
194227to_index(::MyIndexStyle, axis, arg) = ...
195228```
229+
196230"""
197231to_index (x, i:: Slice ) = i
198232to_index (x, :: Colon ) = indices (x)
@@ -207,6 +241,18 @@ to_index(x::LinearIndices, i::AbstractArray{Bool}) = LogicalIndex{Int}(i)
207241@inline to_index (x, i:: CartesianIndex ) = Tuple (i)
208242@inline to_index (x, i:: NDIndex ) = Tuple (i)
209243@inline to_index (x, i:: AbstractArray{<:AbstractCartesianIndex} ) = i
244+ @inline function to_index (x, i:: Base.Fix2{<:Union{typeof(<),typeof(isless)},<:Union{Base.BitInteger,StaticInt}} )
245+ offset1 (x): min (_sub1 (canonicalize (i. x)), static_lastindex (x))
246+ end
247+ @inline function to_index (x, i:: Base.Fix2{typeof(<=),<:Union{Base.BitInteger,StaticInt}} )
248+ offset1 (x): min (canonicalize (i. x), static_lastindex (x))
249+ end
250+ @inline function to_index (x, i:: Base.Fix2{typeof(>=),<:Union{Base.BitInteger,StaticInt}} )
251+ max (canonicalize (i. x), offset1 (x)): static_lastindex (x)
252+ end
253+ @inline function to_index (x, i:: Base.Fix2{typeof(>),<:Union{Base.BitInteger,StaticInt}} )
254+ max (_add1 (canonicalize (i. x)), offset1 (x)): static_lastindex (x)
255+ end
210256# integer indexing
211257to_index (x, i:: AbstractArray{<:Integer} ) = i
212258to_index (x, @nospecialize (i:: StaticInt )) = i
0 commit comments