diff --git a/Project.toml b/Project.toml index 78508430..c278bc75 100644 --- a/Project.toml +++ b/Project.toml @@ -4,15 +4,19 @@ version = "1.10.7" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +Static = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" [compat] Adapt = "2, 3" Aqua = "0.5" +ArrayInterface = "3" CatIndices = "0.2" DistributedArrays = "0.6" Documenter = "0.27" EllipsisNotation = "1" FillArrays = "0.11" +Static = "0.3" StaticArrays = "1" julia = "0.7, 1" diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index 84f9fdab..d25e538f 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -1,11 +1,13 @@ module OffsetArrays +using ArrayInterface using Base: tail, @propagate_inbounds @static if !isdefined(Base, :IdentityUnitRange) const IdentityUnitRange = Base.Slice else using Base: IdentityUnitRange end +using Static export OffsetArray, OffsetMatrix, OffsetVector @@ -119,6 +121,8 @@ struct OffsetArray{T,N,AA<:AbstractArray{T,N}} <: AbstractArray{T,N} end end +ArrayInterface.parent_type(::Type{O}) where {T,N,A<:AbstractArray{T,N},O<:OffsetArrays.OffsetArray{T,N,A}} = A + """ OffsetVector(v, index) @@ -284,10 +288,20 @@ Base.parent(A::OffsetArray) = A.parent # Base.Broadcast.BroadcastStyle(::Type{<:OffsetArray{<:Any, <:Any, AA}}) where AA = Base.Broadcast.BroadcastStyle(AA) @inline Base.size(A::OffsetArray) = size(parent(A)) +@inline Base.size(A::OffsetArray, dim) = size(parent(A), ArrayInterface.to_dims(A, dim)) -@inline Base.axes(A::OffsetArray) = map(IdOffsetRange, axes(parent(A)), A.offsets) -@inline Base.axes(A::OffsetArray, d) = d <= ndims(A) ? IdOffsetRange(axes(parent(A), d), A.offsets[d]) : IdOffsetRange(axes(parent(A), d)) +@inline Base.axes(A::OffsetArray) = map(IdOffsetRange, ArrayInterface.axes(parent(A)), A.offsets) +Base.axes(A::OffsetArray, d) = axes(A, ArrayInterface.to_dims(A, d)) +@inline function Base.axes(A::OffsetArray, d::Union{Int,StaticInt}) + d <= ndims(A) ? IdOffsetRange(axes(parent(A), d), A.offsets[d]) : IdOffsetRange(axes(parent(A), d)) +end @inline Base.axes1(A::OffsetArray{T,0}) where {T} = IdOffsetRange(axes(parent(A), 1)) # we only need to specialize this one +function _offset_axis_type(::Type{T}, dim::StaticInt{D}) where {T,D} + OffsetArrays.IdOffsetRange{Int,ArrayInterface.axes_types(T, dim)} +end +function ArrayInterface.axes_types(::Type{T}) where {T<:OffsetArrays.OffsetArray} + Static.eachop_tuple(_offset_axis_type, Static.nstatic(Val(ndims(T))), ArrayInterface.parent_type(T)) +end # Issue 128 # See https://github.com/JuliaLang/julia/issues/37274 for the issue reported in Base diff --git a/src/axes.jl b/src/axes.jl index d67df67e..5b5e19fa 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -164,6 +164,7 @@ end offset_coerce(::Type{I}, r::AbstractUnitRange) where I<:AbstractUnitRange = convert(I, r)::I, 0 +ArrayInterface.parent_type(::Type{<:IdOffsetRange{<:Any,I}}) where {I} = I @inline Base.parent(r::IdOffsetRange) = r.parent @inline Base.axes(r::IdOffsetRange) = (Base.axes1(r),) @inline Base.axes1(r::IdOffsetRange) = IdOffsetRange(Base.axes1(r.parent), r.offset)