diff --git a/src/axis.jl b/src/axis.jl index 29ea4222..3e7e27cc 100644 --- a/src/axis.jl +++ b/src/axis.jl @@ -140,8 +140,11 @@ const NotShapedOrPartitionedAxis = Union{Axis{IdxMap}, FlatAxis, NullAxis} where Base.merge(axs::Axis...) = Axis(merge(indexmap.(axs)...)) +# TODO: broken for FlatAxis Base.firstindex(ax::AbstractAxis) = first(viewindex(first(indexmap(ax)))) Base.lastindex(ax::AbstractAxis) = last(viewindex(last(indexmap(ax)))) +Base.length(ax::AbstractAxis) = lastindex(ax) - firstindex(ax) + 1 +Base.length(ax::NullorFlatAxis) = error("NullorFlatAxis has no length") Base.keys(ax::AbstractAxis) = keys(indexmap(ax)) diff --git a/src/componentarray.jl b/src/componentarray.jl index ea09fa84..955ed230 100644 --- a/src/componentarray.jl +++ b/src/componentarray.jl @@ -235,6 +235,19 @@ last_index(x) = last(x) last_index(x::ViewAxis) = last_index(viewindex(x)) last_index(x::AbstractAxis) = last_index(last(indexmap(x))) +# length information is in Axis, use it to make SVector creation type stable +@inline _hasNullOrFlatAxis(ca) = any(map(ax -> ax isa NullorFlatAxis, getaxes(ca))) +function Base.length(ca::ComponentArray) + # vca2 = vcat(ca2', ca2') #has not length - is it a valid ComponentVector + # or rather a Vector + _hasNullOrFlatAxis(ca) && return(length(getdata(ca))) + prod(length.(getaxes(ca))) +end +function Base.size(ca::ComponentArray) + _hasNullOrFlatAxis(ca) && return(size(getdata(ca))) + map(length, getaxes(ca)) +end + # Reduce singleton dimensions remove_nulls() = () remove_nulls(x1, args...) = (x1, remove_nulls(args...)...) diff --git a/test/runtests.jl b/test/runtests.jl index a863af41..7b27cec5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -598,6 +598,14 @@ end @test convert(Cholesky{Float32,Matrix{Float32}}, chol).factors isa Matrix{Float32} end +@testset "length typestable" begin + # function boundary, so that cv is type-inferred + test_create_svector = (cv) -> SVector{length(cv)}(cv) + @inferred test_create_svector(ComponentVector(a=1:3)); + test_create_smatrix = (cmat) -> SMatrix{size(cmat)...}(cmat) + @test (@inferred test_create_smatrix(cmat)) isa SMatrix +end; + @testset "Autodiff" begin include("autodiff_tests.jl") end \ No newline at end of file