|
28 | 28 | const _getproperty = getproperty |
29 | 29 | end |
30 | 30 |
|
31 | | -function _foreachfield(names, xs) |
| 31 | +function _sstuple(::Type{<:NTuple{N, Any}}) where {N} |
| 32 | + ntuple(j->Symbol(j), N) |
| 33 | +end |
| 34 | + |
| 35 | +function _sstuple(::Type{NT}) where {NT<:NamedTuple} |
| 36 | + _map_params(x->_sstuple(staticschema(x)), NT) |
| 37 | +end |
| 38 | + |
| 39 | +function _getcolproperties!(exprs, s, es=[]) |
| 40 | + if typeof(s) <: Symbol |
| 41 | + push!(exprs, es) |
| 42 | + return |
| 43 | + end |
| 44 | + for key in keys(s) |
| 45 | + _getcolproperties!(exprs, getproperty(s,key), vcat(es, key)) |
| 46 | + end |
| 47 | +end |
| 48 | + |
| 49 | +@generated function foreachfield(::Type{T}, f, xs...) where {T<:Tup} |
| 50 | + # TODO get columnsproperties directly from T without converting to the |
| 51 | + # tuple s. |
| 52 | + s = _sstuple(T) |
| 53 | + columnsproperties = [] |
| 54 | + _getcolproperties!(columnsproperties, s) |
| 55 | + |
32 | 56 | exprs = Expr[] |
33 | | - for field in names |
34 | | - sym = QuoteNode(field) |
35 | | - args = [Expr(:call, :_getproperty, :(getfield(xs, $j)), sym) for j in 1:length(xs)] |
| 57 | + for col in columnsproperties |
| 58 | + args = Expr[] |
| 59 | + for prop in col |
| 60 | + sym = QuoteNode(prop) |
| 61 | + if length(args) == 0 |
| 62 | + args = [Expr(:call, :_getproperty, :(getfield(xs, $j)), sym) for j in 1:length(xs)] |
| 63 | + else |
| 64 | + for j in 1:length(xs) |
| 65 | + args[j] = Expr(:call, :_getproperty, args[j], sym) |
| 66 | + end |
| 67 | + end |
| 68 | + end |
36 | 69 | push!(exprs, Expr(:call, :f, args...)) |
37 | 70 | end |
38 | 71 | push!(exprs, :(return nothing)) |
39 | 72 | return Expr(:block, exprs...) |
40 | 73 | end |
41 | 74 |
|
42 | | -@generated foreachfield(::Type{<:NamedTuple{names}}, f, xs...) where {names} = _foreachfield(names, xs) |
43 | | -@generated foreachfield(::Type{<:NTuple{N, Any}}, f, xs...) where {N} = _foreachfield(Base.OneTo(N), xs) |
44 | | - |
45 | 75 | foreachfield(f, x::T, xs...) where {T} = foreachfield(staticschema(T), f, x, xs...) |
46 | 76 |
|
47 | 77 | """ |
|
0 commit comments