diff --git a/src/componentarray.jl b/src/componentarray.jl index 32b4d8f3..453dc7ee 100644 --- a/src/componentarray.jl +++ b/src/componentarray.jl @@ -143,14 +143,11 @@ end make_carray_args(::Type{T}, nt) where {T} = make_carray_args(Vector{T}, nt) function make_carray_args(A::Type{<:AbstractArray}, nt) T = recursive_eltype(nt) - init = _isbitstype(T) ? T[] : [] + init = isbitstype(T) ? T[] : [] data, idx = make_idx(init, nt, 0) return (A(data), Axis(idx)) end -_isbitstype(::Type{<:Union{T, Nothing, Missing}}) where {T} = isbitstype(T) -_isbitstype(T) = isbitstype(T) - # Builds up data vector and returns appropriate AbstractAxis type for each input type function make_idx(data, nt::Union{NamedTuple, AbstractDict}, last_val) len = recursive_length(nt) @@ -238,6 +235,11 @@ end last_index(x) = last(x) last_index(x::ViewAxis) = last_index(viewindex(x)) last_index(x::AbstractAxis) = last_index(last(indexmap(x))) +function last_index(f::FlatAxis) + nt = indexmap(f) + length(nt) == 0 && return 0 + return last_index(last(nt)) +end # Reduce singleton dimensions remove_nulls() = () diff --git a/src/utils.jl b/src/utils.jl index 7d0d129c..2926ee5e 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -42,10 +42,11 @@ recursive_length(a::AbstractArray{T,N}) where {T<:Number,N} = length(a) recursive_length(a::AbstractArray) = recursive_length.(a) |> sum recursive_length(nt::NamedTuple) = values(nt) .|> recursive_length |> sum recursive_length(::Union{Nothing, Missing}) = 1 +recursive_length(nt::NamedTuple{(), Tuple{}}) = 0 # Find the highest element type -recursive_eltype(nt::NamedTuple) = mapreduce(recursive_eltype, promote_type, nt) -recursive_eltype(x::Vector) = mapreduce(recursive_eltype, promote_type, x) -recursive_eltype(x::Dict) = mapreduce(recursive_eltype, promote_type, values(x)) -recursive_eltype(::AbstractArray{T,N}) where {T<:Number, N}= T +recursive_eltype(nt::NamedTuple) = isempty(nt) ? Base.Bottom : mapreduce(recursive_eltype, promote_type, nt) +recursive_eltype(x::Vector{Any}) = isempty(x) ? Base.Bottom : mapreduce(recursive_eltype, promote_type, x) +recursive_eltype(x::Dict) = isempty(x) ? Base.Bottom : mapreduce(recursive_eltype, promote_type, values(x)) +recursive_eltype(::AbstractArray{T,N}) where {T<:Number, N} = T recursive_eltype(x) = typeof(x) diff --git a/test/runtests.jl b/test/runtests.jl index 740aea6f..fea49957 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -112,6 +112,16 @@ end # Issue #116 # Part 2: Arrays of arrays @test_throws Exception ComponentVector(a = [[3], [4, 5]], b = 1) + + # empty components + for T in [Int64, Int32, Float64, Float32, ComplexF64, ComplexF32] + @test ComponentArray(a = T[]) == ComponentVector{T}(a = T[]) + @test ComponentArray(a = T[], b = T[]) == ComponentVector{T}(a = T[], b = T[]) + @test ComponentArray(a = T[], b = (;)) == ComponentVector{T}(a = T[], b = T[]) + @test ComponentArray(a = Any[one(Int32)], b=T[]) == ComponentVector{T}(a = [one(T)], b = T[]) + end + @test ComponentArray(NamedTuple()) == ComponentVector{Any}() + @test_broken ComponentArray(a=[]) end @testset "Attributes" begin @@ -612,4 +622,4 @@ end @testset "GPU" begin include("gpu_tests.jl") -end \ No newline at end of file +end