@@ -441,4 +441,95 @@ Base.@propagate_inbounds function Base.getindex(ind::TridiagonalIndex, i::Int)
441441 end
442442end
443443
444+ _cartesian_index (i:: Tuple{Vararg{Int}} ) = CartesianIndex (i)
445+ _cartesian_index (:: Any ) = nothing
446+
447+ """
448+ known_first(::Type{T}) -> Union{Int,Nothing}
449+
450+ If `first` of an instance of type `T` is known at compile time, return it.
451+ Otherwise, return `nothing`.
452+
453+ ```julia
454+ julia> ArrayInterface.known_first(typeof(1:4))
455+ nothing
456+
457+ julia> ArrayInterface.known_first(typeof(Base.OneTo(4)))
458+ 1
459+ ```
460+ """
461+ known_first (x) = known_first (typeof (x))
462+ function known_first (:: Type{T} ) where {T}
463+ if parent_type (T) <: T
464+ return nothing
465+ else
466+ return known_first (parent_type (T))
467+ end
468+ end
469+ known_first (:: Type{Base.OneTo{T}} ) where {T} = 1
470+ function known_first (:: Type{<:CartesianIndices{N,R}} ) where {N,R}
471+ _cartesian_index (ntuple (i -> known_first (R. parameters[i]), Val (N)))
472+ end
473+
474+ """
475+ known_last(::Type{T}) -> Union{Int,Nothing}
476+
477+ If `last` of an instance of type `T` is known at compile time, return it.
478+ Otherwise, return `nothing`.
479+
480+ ```julia
481+ julia> ArrayInterface.known_last(typeof(1:4))
482+ nothing
483+
484+ julia> ArrayInterface.known_first(typeof(static(1):static(4)))
485+ 4
486+
487+ ```
488+ """
489+ known_last (x) = known_last (typeof (x))
490+ known_last (:: Type{T} ) where {T} = parent_type (T) <: T ? nothing : known_last (parent_type (T))
491+ function known_last (:: Type{<:CartesianIndices{N,R}} ) where {N,R}
492+ _cartesian_index (ntuple (i -> known_last (R. parameters[i]), Val (N)))
493+ end
494+
495+ """
496+ known_step(::Type{T}) -> Union{Int,Nothing}
497+
498+ If `step` of an instance of type `T` is known at compile time, return it.
499+ Otherwise, return `nothing`.
500+
501+ ```julia
502+ julia> ArrayInterface.known_step(typeof(1:2:8))
503+ nothing
504+
505+ julia> ArrayInterface.known_step(typeof(1:4))
506+ 1
507+
508+ ```
509+ """
510+ known_step (x) = known_step (typeof (x))
511+ known_step (:: Type{T} ) where {T} = parent_type (T) <: T ? nothing : known_step (parent_type (T))
512+ known_step (:: Type{<:AbstractUnitRange} ) = 1
513+
514+ """
515+ is_splat_index(::Type{T}) -> Bool
516+ Returns `static(true)` if `T` is a type that splats across multiple dimensions.
517+ """
518+ is_splat_index (@nospecialize (x)) = is_splat_index (typeof (x))
519+ is_splat_index (T:: Type ) = false
520+
521+ """
522+ ndims_index(::Type{I}) -> Int
523+
524+ Returns the number of dimension that an instance of `I` maps to when indexing. For example,
525+ `CartesianIndex{3}` maps to 3 dimensions. If this method is not explicitly defined, then `1`
526+ is returned.
527+ """
528+ ndims_index (@nospecialize (i)) = ndims_index (typeof (i))
529+ ndims_index (:: Type{I} ) where {I} = 1
530+ ndims_index (:: Type{<:Base.AbstractCartesianIndex{N}} ) where {N} = N
531+ ndims_index (:: Type{<:AbstractArray{T}} ) where {T} = ndims_index (T)
532+ ndims_index (:: Type{<:AbstractArray{Bool,N}} ) where {N} = N
533+ ndims_index (:: Type{<:Base.LogicalIndex{<:Any,<:AbstractArray{Bool,N}}} ) where {N} = N
534+
444535end # module
0 commit comments