|
137 | 137 | function generate_constructor_exprs(T_name, T_params, T_params_constrained, T_nameparam, constructors) |
138 | 138 | out = Expr(:toplevel) |
139 | 139 | converts = [] |
140 | | - foreach(constructors) do nt |
| 140 | + for nt ∈ constructors |
141 | 141 | name = nt.name |
142 | 142 | gname = nt.gname |
143 | 143 | params = nt.params |
@@ -190,16 +190,27 @@ function generate_constructor_exprs(T_name, T_params, T_params_constrained, T_na |
190 | 190 | enumerate_constructors = collect(enumerate(constructors)) |
191 | 191 |
|
192 | 192 | if true |
| 193 | + @gensym N M _tag _T x |
| 194 | + |
| 195 | + if_nest_conv = mapfoldr(((cond, data), old) -> Expr(:if, cond, data, old), enumerate_constructors, init=:(error("invalid tag"))) do (i, nt) |
| 196 | + :($_tag == $(i-1) ), :($make($T_init, $unwrap(x, $(nt.store_type)) , $_tag)) |
| 197 | + end |
| 198 | + |
193 | 199 | push!(converts, T_uninit => quote |
194 | | - $Base.convert(::Type{$T_init}, x::$T_uninit) where {$(T_params...)} = |
195 | | - $make($T_init, $unwrap(x), $getfield(x, $(QuoteNode(tag)) )) |
196 | | - $T_init(x::$T_uninit) where {$(T_params...)} = $convert($T_init, x) |
| 200 | + $Base.convert(::$Type{$_T}, $x::$_T) where {$_T <: $T_name} = $x |
| 201 | + $Base.convert(::$Type{<:$T_init}, x::$T_uninit) where {$(T_params...)} = let $_tag = $get_tag(x) |
| 202 | + $if_nest_conv |
| 203 | + end |
| 204 | + (::$Type{<:$T_init})(x::$T_uninit) where {$(T_params...)} = $convert($T_init, x) |
| 205 | + $Base.convert(::$Type{<:$T_init}, x::$T_uninit{$N, $M}) where {$(T_params...), $N, $M} = let $_tag = $get_tag(x) |
| 206 | + $if_nest_conv |
| 207 | + end |
| 208 | + (::$Type{<:$_T})(x::$T_name) where {$_T <: $T_name} = $convert($_T, x) |
197 | 209 | end) |
198 | 210 | end |
199 | 211 | end |
200 | 212 | unique!(x -> x[1], converts) |
201 | 213 | append!(out.args, map(x -> x[2], converts)) |
202 | | - |
203 | 214 | out |
204 | 215 | end |
205 | 216 |
|
@@ -228,11 +239,12 @@ function generate_sum_struct_expr(T, T_name, T_params, T_params_constrained, T_p |
228 | 239 | end |
229 | 240 |
|
230 | 241 | only_define_with_params = if !isempty(T_params) |
| 242 | + @gensym x |
231 | 243 | quote |
232 | 244 | $SumTypes.constructors(::Type{<:$T_nameparam}) where {$(T_params...)} = |
233 | 245 | $NamedTuple{$tags($T_name)}($(Expr(:tuple, (nt.store_type for nt ∈ constructors)...))) |
234 | 246 | $Base.adjoint(::Type{<:$T_nameparam}) where {$(T_params...)} = |
235 | | - $NamedTuple{$tags($T_name)}($(Expr(:tuple, (nt.value ? :($T_nameparam($(nt.gname))) : nt.gouter_type for nt ∈ constructors)...))) |
| 247 | + $NamedTuple{$tags($T_name)}($(Expr(:tuple, (nt.value ? :($T_nameparam($(nt.gname))) : :($Converter{$T_nameparam, $(nt.gouter_type)}()) for nt ∈ constructors)...))) |
236 | 248 | $SumTypes.variants_Tuple(::Type{<:$T_nameparam}) where {$(T_params...)} = |
237 | 249 | $Tuple{$((nt.store_type for nt ∈ constructors)...)} |
238 | 250 | $SumTypes.full_type(::Type{$T_name}) = $full_type($T_name{$(T_param_bounds...)}, $variants_Tuple($T_nameparam{$(T_param_bounds...)})) |
@@ -269,6 +281,7 @@ function generate_sum_struct_expr(T, T_name, T_params, T_params_constrained, T_p |
269 | 281 | $NamedTuple{$tags($T_name)}($(Expr(:tuple, (nt.gname for nt ∈ constructors)...))) |
270 | 282 |
|
271 | 283 | $SumTypes.full_type(::Type{$T_nameparam}) where {$(T_params...)} = $full_type($T_nameparam, $variants_Tuple($T_nameparam)) |
| 284 | + $SumTypes.full_type(::Type{$T_nameparam{$N, $M}}) where {$(T_params...), $N, $M} = $T_nameparam{$N, $M} |
272 | 285 |
|
273 | 286 | $Base.show(io::IO, x::$T_name) = $show_sumtype(io, x) |
274 | 287 | $Base.show(io::IO, m::MIME"text/plain", x::$T_name) = $show_sumtype(io, m, x) |
|
0 commit comments