Skip to content

Commit 506bdc5

Browse files
committed
Create repo
1 parent 00c9cd6 commit 506bdc5

File tree

3 files changed

+78
-3
lines changed

3 files changed

+78
-3
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2021 chriselrod <[email protected]> and contributors
3+
Copyright (c) 2021 Julia Computing, Inc. and Contributors
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

src/ArgDecomposition.jl

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,70 @@
11
module ArgDecomposition
22

3-
# Write your package code here.
3+
export flatten_to_tuple, reassemble_tuple
4+
5+
struct StaticType{T} end
6+
gettype(::StaticType{T}) where {T} = T
7+
8+
function _append_fields!(t::Expr, body::Expr, sym::Symbol, ::Type{T}) where {T}
9+
for f 1:fieldcount(T)
10+
TF = fieldtype(T, f)
11+
Base.issingletontype(TF) && continue
12+
gfcall = Expr(:call, getfield, sym, f)
13+
if fieldcount(TF) 0
14+
push!(t.args, gfcall)
15+
elseif TF <: DataType
16+
push!(t.args, :(StaticType{$gfcall}()))
17+
else
18+
newsym = gensym(sym)
19+
push!(body.args, Expr(:(=), newsym, gfcall))
20+
_append_fields!(t, body, newsym, TF)
21+
end
22+
end
23+
return nothing
24+
end
25+
@generated function flatten_to_tuple(r::T) where {T}
26+
body = Expr(:block, Expr(:meta,:inline))
27+
t = Expr(:tuple)
28+
if Base.issingletontype(T)
29+
nothing
30+
elseif fieldcount(T) 0
31+
push!(t.args, :r)
32+
elseif T <: DataType
33+
push!(t.args, :(StaticType{r}()))
34+
else
35+
_append_fields!(t, body, :r, T)
36+
end
37+
push!(body.args, t)
38+
body
39+
end
40+
function rebuild_fields(offset::Int, ::Type{T}) where {T}
41+
call = (T <: Tuple) ? Expr(:tuple) : Expr(:new, T)
42+
for f 1:fieldcount(T)
43+
TF = fieldtype(T, f)
44+
if Base.issingletontype(TF)
45+
push!(call.args, TF.instance)
46+
elseif fieldcount(TF) 0
47+
push!(call.args, :($getfield(t, $(offset += 1), false)))
48+
elseif TF <: DataType
49+
push!(call.args, :($gettype($getfield(t, $(offset += 1), false))))
50+
else
51+
arg, offset = rebuild_fields(offset, TF)
52+
push!(call.args, arg)
53+
end
54+
end
55+
return call, offset
56+
end
57+
@generated function reassemble_tuple(::Type{T}, t::Tuple) where {T}
58+
if Base.issingletontype(T)
59+
return T.instance
60+
elseif fieldcount(T) 0
61+
call = :($getfield(t, 1, false))
62+
elseif T <: DataType
63+
call = :($gettype($getfield(t, 1, false)))
64+
else
65+
call, _ = rebuild_fields(0, T)
66+
end
67+
Expr(:block, Expr(:meta,:inline), call)
68+
end
469

570
end

test/runtests.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,15 @@ using ArgDecomposition
22
using Test
33

44
@testset "ArgDecomposition.jl" begin
5-
# Write your tests here.
5+
6+
for t (
7+
Val(4), Float32, 8.9, (a = 3, b = (3,2), d = Float64, e = (1f0, '2', 3.0, 4, 0x05)),
8+
(a = 3, b = (3,(2,21f0,3.0)), c = "hello, world!", d = Float64, e = (1f0, '2', 3.0, 4, 0x05))
9+
)
10+
11+
ft = flatten_to_tuple(t)
12+
@test ft isa Tuple
13+
rt = reassemble_tuple(typeof(t), ft)
14+
@test rt === t
15+
end
616
end

0 commit comments

Comments
 (0)