Skip to content

Commit 8417b55

Browse files
author
Pietro Vertechi
authored
refactor foreach_expr (JuliaArrays#21)
* refactor foreach_expr * use integers for tuples and symbols otherwise * test tuple push and setindex * ups * move to utils
1 parent 4ed2677 commit 8417b55

File tree

3 files changed

+28
-30
lines changed

3 files changed

+28
-30
lines changed

src/structarray.jl

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,27 +83,19 @@ end
8383
return :($(Expr(:tuple, [QuoteNode(Symbol("x$f")) for f in fieldnames(T)]...)))
8484
end
8585

86+
@inline getfieldindex(v::Tuple, field::Symbol, index::Integer) = getfield(v, index)
87+
@inline getfieldindex(v, field::Symbol, index::Integer) = getproperty(v, field)
8688

8789
@generated function Base.push!(s::StructArray{T, 1}, vals) where {T}
88-
args = []
89-
for key in fields(T)
90-
field = Expr(:., :s, Expr(:quote, key))
91-
val = Expr(:., :vals, Expr(:quote, key))
92-
push!(args, :(push!($field, $val)))
93-
end
94-
push!(args, :s)
95-
Expr(:block, args...)
90+
exprs = foreach_expr((args...) -> Expr(:call, :push!, args...), T, :s, :vals)
91+
push!(exprs, :s)
92+
Expr(:block, exprs...)
9693
end
9794

9895
@generated function Base.append!(s::StructArray{T, 1}, vals) where {T}
99-
args = []
100-
for key in fields(T)
101-
field = Expr(:., :s, Expr(:quote, key))
102-
val = Expr(:., :vals, Expr(:quote, key))
103-
push!(args, :(append!($field, $val)))
104-
end
105-
push!(args, :s)
106-
Expr(:block, args...)
96+
exprs = foreach_expr((args...) -> Expr(:call, :append!, args...), T, :s, :vals)
97+
push!(exprs, :s)
98+
Expr(:block, exprs...)
10799
end
108100

109101
function Base.cat(args::StructArray...; dims)

src/utils.jl

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,29 @@ eltypes(::Type{NamedTuple{K, V}}) where {K, V} = eltypes(V)
77

88
Base.@pure SkipConstructor(::Type) = false
99

10-
@generated function get_ith(s::StructArray{T}, I...) where {T}
11-
args = []
12-
for key in fields(T)
13-
field = Expr(:., :s, Expr(:quote, key))
14-
push!(args, :($field[I...]))
10+
function foreach_expr(f, T, args...)
11+
exprs = []
12+
for (ind, key) in enumerate(fields(T))
13+
new_args = (Expr(:call, :getfieldindex, arg, Expr(:quote, key), ind) for arg in args)
14+
push!(exprs, f(new_args...))
1515
end
16+
exprs
17+
end
18+
19+
@generated function get_ith(s::StructArray{T}, I...) where {T}
20+
exprs = foreach_expr(field -> :($field[I...]), T, :s)
1621
return quote
1722
@boundscheck checkbounds(s, I...)
18-
@inbounds $(Expr(:call, :createinstance, :T, args...))
23+
@inbounds $(Expr(:call, :createinstance, :T, exprs...))
1924
end
2025
end
2126

2227
@generated function set_ith!(s::StructArray{T}, vals, I...) where {T}
23-
args = []
24-
for key in fields(T)
25-
field = Expr(:., :s, Expr(:quote, key))
26-
val = Expr(:., :vals, Expr(:quote, key))
27-
push!(args, :($field[I...] = $val))
28-
end
29-
push!(args, :s)
28+
exprs = foreach_expr((field, val) -> :($field[I...] = $val), T, :s, :vals)
29+
push!(exprs, :s)
3030
return quote
3131
@boundscheck checkbounds(s, I...)
32-
@inbounds $(Expr(:block, args...))
32+
@inbounds $(Expr(:block, exprs...))
3333
end
3434
end
3535

test/runtests.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ end
3030
@test Base.getproperty(s, 2) == ["test"]
3131
t = StructArray{Tuple{Int, Float64}}([1], [1.2])
3232
@test t[1] == (1, 1.2)
33+
34+
t[1] = (2, 3)
35+
@test t[1] == (2, 3.0)
36+
push!(t, (1, 2))
37+
@test getproperty(t, 1) == [2, 1]
38+
@test getproperty(t, 2) == [3.0, 2.0]
3339
end
3440

3541
@testset "kwargs constructor" begin

0 commit comments

Comments
 (0)