Skip to content

Commit 4d7a5a4

Browse files
author
Pietro Vertechi
authored
add opt in support for non trivial inner constuctors (JuliaArrays#17)
* remove createinstance * Make skipping constructor opt in
1 parent 2ddd78c commit 4d7a5a4

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

src/utils.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ eltypes(::Type{T}) where {T<:Tuple} =
55
tuple_type_cons(eltype(tuple_type_head(T)), eltypes(tuple_type_tail(T)))
66
eltypes(::Type{NamedTuple{K, V}}) where {K, V} = eltypes(V)
77

8+
Base.@pure SkipConstructor(::Type) = false
9+
810
@generated function get_ith(s::StructArray{T}, I...) where {T}
911
args = []
1012
for key in fields(T)
@@ -31,8 +33,18 @@ end
3133
end
3234
end
3335

34-
createinstance(::Type{T}, args...) where {T} = T(args...)
36+
function createinstance(::Type{T}, args...) where {T}
37+
SkipConstructor(T) ? unsafe_createinstance(T, args...) : T(args...)
38+
end
39+
3540
createinstance(::Type{T}, args...) where {T<:Union{Tuple, NamedTuple}} = T(args)
3641

42+
@generated function unsafe_createinstance(::Type{T}, args...) where {T}
43+
v = fieldnames(T)
44+
new_tup = Expr(:(=), Expr(:tuple, v...), :args)
45+
construct = Expr(:new, :T, (:(convert(fieldtype(T, $(Expr(:quote, sym))), $sym)) for sym in v)...)
46+
Expr(:block, new_tup, construct)
47+
end
48+
3749
createtype(::Type{T}, ::Type{C}) where {T<:NamedTuple{N}, C} where {N} = NamedTuple{N, C}
3850
createtype(::Type{T}, ::Type{C}) where {T, C} = T

test/runtests.jl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,17 @@ end
116116
@test Tables.rowaccess(s)
117117
@test Tables.columnaccess(s)
118118
end
119-
119+
120+
struct S
121+
x::Int
122+
y::Float64
123+
S(x) = new(x, x)
124+
end
125+
126+
StructArrays.SkipConstructor(::Type{<:S}) = true
127+
128+
@testset "inner" begin
129+
v = StructArray{S}([1], [1])
130+
@test v[1] == S(1)
131+
@test v[1].y isa Float64
132+
end

0 commit comments

Comments
 (0)