Skip to content

Support empty components #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Aug 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/componentarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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() = ()
Expand Down
9 changes: 5 additions & 4 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
12 changes: 11 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -612,4 +622,4 @@ end

@testset "GPU" begin
include("gpu_tests.jl")
end
end