diff --git a/ext/StructArraysStaticArraysExt.jl b/ext/StructArraysStaticArraysExt.jl index 19fc72a..a02ead7 100644 --- a/ext/StructArraysStaticArraysExt.jl +++ b/ext/StructArraysStaticArraysExt.jl @@ -33,12 +33,12 @@ function StructArrays.component(s::StructArray{<:Union{SVector,MVector}}, key::S StructArrays.component(s, i) end -# invoke general fallbacks for a `FieldArray` type. +# use general fallbacks for a `FieldArray` type. @inline function StructArrays.staticschema(T::Type{<:FieldArray}) - invoke(StructArrays.staticschema, Tuple{Type{<:Any}}, T) + StructArrays.staticschema_generic(T) end -StructArrays.component(s::FieldArray, i) = invoke(StructArrays.component, Tuple{Any, Any}, s, i) -StructArrays.createinstance(T::Type{<:FieldArray}, args...) = invoke(StructArrays.createinstance, Tuple{Type{<:Any}, Vararg}, T, args...) +StructArrays.component(s::FieldArray, i) = getfield(s, i) +StructArrays.createinstance(T::Type{<:FieldArray}, args...) = StructArrays.createinstance_generic(T, args...) # disambiguation Base.similar(s::StructArray, S::Type, sz::Tuple{Union{Integer, Base.OneTo, SOneTo}, Vararg{Union{Union{Integer, Base.OneTo, SOneTo}}}}) = StructArrays._similar(s, S, sz) diff --git a/src/interface.jl b/src/interface.jl index 64c53f9..51dee9e 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -25,7 +25,11 @@ julia> StructArrays.staticschema(Complex{Float64}) NamedTuple{(:re, :im),Tuple{Float64,Float64}} ``` """ -@generated function staticschema(::Type{T}) where {T} +function staticschema(::Type{T}) where {T} + return staticschema_generic(T) +end + +@generated function staticschema_generic(::Type{T}) where {T} name_tuple = Expr(:tuple, [QuoteNode(f) for f in fieldnames(T)]...) type_tuple = Expr(:curly, :Tuple, [Expr(:call, :fieldtype, :T, i) for i in 1:fieldcount(T)]...) Expr(:curly, :NamedTuple, name_tuple, type_tuple) @@ -46,6 +50,10 @@ julia> StructArrays.createinstance(Complex{Float64}, (re=1.0, im=2.0)...) ``` """ function createinstance(::Type{T}, args...)::T where {T} + return createinstance_generic(T, args...) +end + +function createinstance_generic(::Type{T}, args...)::T where {T} isconcretetype(T) ? bypass_constructor(T, args) : constructorof(T)(args...) end