diff --git a/src/dimindices.jl b/src/dimindices.jl index ca7900441..f643ad593 100644 --- a/src/dimindices.jl +++ b/src/dimindices.jl @@ -23,6 +23,11 @@ for f in (:getindex, :dotview, :view) rebuild(di; dims=(dims(di, 1)[i],)) @eval @propagate_inbounds Base.$f(dg::AbstractDimArrayGenerator, i::Integer) = Base.$f(dg, Tuple(CartesianIndices(dg)[i])...) + if f == :view + @eval @propagate_inbounds Base.$f(A::AbstractDimArrayGenerator) = A + else + @eval @propagate_inbounds Base.$f(::AbstractDimArrayGenerator) = () + end end @inline Base.permutedims(A::AbstractDimArrayGenerator{<:Any,2}) = @@ -163,12 +168,12 @@ that defines a `dims` method can be passed in. - `order`: determines the order of the points, the same as the order of `dims` by default. """ -struct DimPoints{T,N,D<:DimTuple,O} <: AbstractDimIndices{T,N,D} +struct DimPoints{T,N,D<:Tuple{Vararg{Dimension}},O} <: AbstractDimIndices{T,N,D} dims::D order::O end -DimPoints(dims::DimTuple; order=dims) = DimPoints(dims, order) -function DimPoints(dims::DimTuple, order::DimTuple) +DimPoints(dims::Tuple; order=dims) = DimPoints(dims, order) +function DimPoints(dims::Tuple, order::Tuple) order = map(d -> basetypeof(d)(), order) T = Tuple{map(eltype, dims)...} N = length(dims) @@ -239,15 +244,15 @@ Using `At` would make sure we only use exact interpolation, while `Contains` with sampling of `Intervals` would make sure that each values is taken only from an Interval that is present in the lookups. """ -struct DimSelectors{T,N,D<:Tuple{Dimension,Vararg{Dimension}},S<:Tuple} <: AbstractDimIndices{T,N,D} +struct DimSelectors{T,N,D<:Tuple{Vararg{Dimension}},S<:Tuple} <: AbstractDimIndices{T,N,D} dims::D selectors::S end -function DimSelectors(dims::DimTuple; atol=nothing, selectors=At()) +function DimSelectors(dims::Tuple{Vararg{Dimension}}; atol=nothing, selectors=At()) s = _format_selectors(dims, selectors, atol) DimSelectors(dims, s) end -function DimSelectors(dims::DimTuple, selectors::Tuple) +function DimSelectors(dims::Tuple{Vararg{Dimension}}, selectors::Tuple) T = typeof(map(rebuild, dims, selectors)) N = length(dims) dims = N > 0 ? _format(dims) : dims diff --git a/test/dimindices.jl b/test/dimindices.jl index 78e2aa5b0..eb7c834c9 100644 --- a/test/dimindices.jl +++ b/test/dimindices.jl @@ -6,6 +6,7 @@ A = zeros(X(4.0:7.0), Y(10.0:12.0)) @testset "DimIndices" begin di = @inferred DimIndices(A) + @test eltype(di) == Tuple{X{Int64}, Y{Int64}} ci = CartesianIndices(A) @test @inferred val.(collect(di)) == Tuple.(collect(ci)) @test A[di] == view(A, di) == A @@ -40,6 +41,17 @@ A = zeros(X(4.0:7.0), Y(10.0:12.0)) @test @inferred A1[X=1, Y=1][di[:]] isa DimArray{Float64,1} # Indexing with no matching dims is like [] (?) @test @inferred view(A1, X=1, Y=1, Ti=1)[di[:]] == 0.0 + + @testset "zero dimensional" begin + di0 = DimIndices(()) + @test di0[] == () + @test view(di0) == di0 + @test first(di0) == () + @test eltype(di0) == Tuple{} + @test ndims(di0) == 0 + @test dims(di0) == () + @test size(di0) == () + end end @testset "DimPoints" begin @@ -53,6 +65,17 @@ end @test_throws ArgumentError DimPoints(nothing) # Vector @test @inferred DimPoints(X(1.0:2.0)) == [(1.0,), (2.0,)] + + @testset "zero dimensional" begin + dp0 = DimPoints(()) + @test dp0[] == () + @test view(dp0) == dp0 + @test first(dp0) == () + @test eltype(dp0) == Tuple{} + @test ndims(dp0) == 0 + @test dims(dp0) == () + @test size(dp0) == () + end end @testset "DimSelectors" begin @@ -77,6 +100,17 @@ end @test @inferred DimSelectors(X(1.0:2.0)) == [(X(At(1.0; atol=eps(Float64))),), (X(At(2.0; atol=eps(Float64))),)] + @testset "zero dimensional" begin + ds0 = DimSelectors(()) + @test ds0[] == () + @test view(ds0) == ds0 + @test first(ds0) == () + @test eltype(ds0) == Tuple{} + @test ndims(ds0) == 0 + @test dims(ds0) == () + @test size(ds0) == () + end + @testset "atol" begin dsa = @inferred DimSelectors(A; atol=0.3) # Mess up the lookups a little...