-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathinterface.jl
58 lines (44 loc) · 1.8 KB
/
interface.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const Tup = Union{Tuple, NamedTuple}
const EmptyTup = Union{Tuple{}, NamedTuple{(), Tuple{}}}
"""
StructArrays.component(x, i)
Default to `getfield`. It should be overloaded for custom types with a custom
schema. See [`StructArrays.staticschema`](@ref).
"""
component(x, i) = getfield(x, i)
"""
StructArrays.staticschema(T)
The default schema for an element type `T`. A schema is a `Tuple` or
`NamedTuple` type containing the necessary fields to construct `T`. By default,
this will have fields with the same names and types as `T`.
This can be overloaded for custom types if required, in which case
[`StructArrays.component`](@ref) and [`StructArrays.createinstance`](@ref)
should also be defined.
```julia-repl
julia> StructArrays.staticschema(Complex{Float64})
NamedTuple{(:re, :im),Tuple{Float64,Float64}}
```
"""
@generated function staticschema(::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)
end
staticschema(::Type{T}) where {T<:Tup} = T
"""
StructArrays.createinstance(T, args...)
Construct an instance of type `T` from its backing representation. `args` here
are the elements of the `Tuple` or `NamedTuple` type specified
[`staticschema(T)`](@ref).
```julia-repl
julia> StructArrays.createinstance(Complex{Float64}, (re=1.0, im=2.0)...)
1.0 + 2.0im
```
"""
function createinstance(::Type{T}, args...)::T where {T}
isconcretetype(T) ? bypass_constructor(T, args) : constructorof(T)(args...)
end
createinstance(::Type{T}, args...) where {T<:Tup} = T(args)
struct Instantiator{T} end
Instantiator(::Type{T}) where {T} = Instantiator{T}()
(::Instantiator{T})(args...) where {T} = createinstance(T, args...)