Skip to content

Commit 8ae5933

Browse files
Make construction with StaticArrays kinda work (#215)
1 parent 877f35a commit 8ae5933

File tree

4 files changed

+18
-14
lines changed

4 files changed

+18
-14
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ComponentArrays"
22
uuid = "b0b7db55-cfe3-40fc-9ded-d10e2dbeff66"
33
authors = ["Jonnie Diegelman <47193959+jonniedie@users.noreply.github.com>"]
4-
version = "0.13.14"
4+
version = "0.13.15"
55

66
[deps]
77
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"

src/componentarray.jl

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ const AbstractComponentMatrix = Union{ComponentMatrix, AdjOrTransComponentMatrix
132132

133133

134134
## Constructor helpers
135+
allocate_numeric_container(x) = allocate_numeric_container(recursive_eltype(x))
136+
allocate_numeric_container(::Type{T}) where {T<:Number} = T[]
137+
allocate_numeric_container(::Type) = []
138+
135139
# For making ComponentArrays from named tuples
136140
make_carray_args(::NamedTuple{(), Tuple{}}) = (Any[], FlatAxis())
137141
make_carray_args(::Type{T}, ::NamedTuple{(), Tuple{}}) where {T} = (T[], FlatAxis())
@@ -142,8 +146,7 @@ function make_carray_args(nt)
142146
end
143147
make_carray_args(::Type{T}, nt) where {T} = make_carray_args(Vector{T}, nt)
144148
function make_carray_args(A::Type{<:AbstractArray}, nt)
145-
T = recursive_eltype(nt)
146-
init = isbitstype(T) ? T[] : []
149+
init = allocate_numeric_container(nt)
147150
data, idx = make_idx(init, nt, 0)
148151
return (A(data), Axis(idx))
149152
end
@@ -153,8 +156,8 @@ function make_idx(data, nt::Union{NamedTuple, AbstractDict}, last_val)
153156
len = recursive_length(nt)
154157
kvs = []
155158
lv = 0
156-
for (k,v) in zip(keys(nt), values(nt))
157-
(_,val) = make_idx(data, v, lv)
159+
for (k, v) in pairs(nt)
160+
(_, val) = make_idx(data, v, lv)
158161
push!(kvs, k => val)
159162
lv = val
160163
end
@@ -170,14 +173,14 @@ make_idx(data, x, last_val) = (
170173
ViewAxis(last_index(last_val) + 1)
171174
)
172175
make_idx(data, x::ComponentVector, last_val) = (
173-
pushcat!(data, x),
176+
append!(data, x),
174177
ViewAxis(
175178
last_index(last_val) .+ (1:length(x)),
176179
getaxes(x)[1]
177180
)
178181
)
179182
function make_idx(data, x::AbstractArray, last_val)
180-
pushcat!(data, x)
183+
append!(data, x)
181184
out = last_index(last_val) .+ (1:length(x))
182185
return (data, ViewAxis(out, ShapedAxis(size(x))))
183186
end
@@ -186,7 +189,7 @@ function make_idx(data, x::A, last_val) where {A<:AbstractArray{<:Union{NamedTup
186189
if eltype(x) |> isconcretetype
187190
out = ()
188191
for elem in x
189-
(_,out) = make_idx(data, elem, last_val)
192+
_, out = make_idx(data, elem, last_val)
190193
end
191194
return (
192195
data,
@@ -222,8 +225,6 @@ function _update_field(x, pair)
222225
return x_copy
223226
end
224227

225-
pushcat!(a, b) = reduce((x1,x2) -> push!(x1,x2), b; init=a)
226-
227228
# Reshape ComponentArrays with ShapedAxis axes
228229
maybe_reshape(data, ::NotShapedOrPartitionedAxis...) = data
229230
function maybe_reshape(data, axs::AbstractAxis...)

src/utils.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ filter_by_type(::Type{T}, part::Tuple, ax::T, args...) where T = filter_by_type(
3939
# Flat length of an arbitrarily nested named tuple
4040
recursive_length(x) = length(x)
4141
recursive_length(a::AbstractArray{T,N}) where {T<:Number,N} = length(a)
42-
recursive_length(a::AbstractArray) = recursive_length.(a) |> sum
43-
recursive_length(nt::NamedTuple) = values(nt) .|> recursive_length |> sum
42+
recursive_length(a::AbstractArray) = mapreduce(recursive_length, +, a; init=0)
43+
recursive_length(nt::NamedTuple) = mapreduce(recursive_length, +, values(nt); init=0)
4444
recursive_length(::Union{Nothing, Missing}) = 1
4545
recursive_length(nt::NamedTuple{(), Tuple{}}) = 0
4646

4747
# Find the highest element type
4848
recursive_eltype(nt::NamedTuple) = isempty(nt) ? Base.Bottom : mapreduce(recursive_eltype, promote_type, nt)
49-
recursive_eltype(x::Vector{Any}) = isempty(x) ? Base.Bottom : mapreduce(recursive_eltype, promote_type, x)
49+
recursive_eltype(x::AbstractArray{<:Any}) = isempty(x) ? Base.Bottom : mapreduce(recursive_eltype, promote_type, x)
5050
recursive_eltype(x::Dict) = isempty(x) ? Base.Bottom : mapreduce(recursive_eltype, promote_type, values(x))
5151
recursive_eltype(::AbstractArray{T,N}) where {T<:Number, N} = T
5252
recursive_eltype(x) = typeof(x)

test/runtests.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,10 @@ end
132132
@test ComponentArray(a = Any[one(Int32)], b=T[]) == ComponentVector{T}(a = [one(T)], b = T[])
133133
end
134134
@test ComponentArray(NamedTuple()) == ComponentVector{Any}()
135-
@test_broken ComponentArray(a=[])
135+
@test ComponentArray(a=[]).a == []
136+
137+
# Make sure type promotion works correctly with StaticArrays of NamedTuples
138+
@test ComponentVector(a=SA[(a=2, b=true)], b=false) isa ComponentVector{Int}
136139
end
137140

138141
@testset "Attributes" begin

0 commit comments

Comments
 (0)