1 #include <cstdarg>
2 #include <cstdint>
3 #include <cstdlib>
4 #include <ostream>
5 #include <new>
6 #include <cassert>
7 
8 template<typename T>
9 struct StylePoint {
10   T x;
11   T y;
12 };
13 
14 template<typename T>
15 union StyleFoo {
16   enum class Tag : uint8_t {
17     Foo,
18     Bar,
19     Baz,
20     Bazz,
21   };
22 
23   struct Foo_Body {
24     Tag tag;
25     int32_t x;
26     StylePoint<T> y;
27     StylePoint<float> z;
28   };
29 
30   struct Bar_Body {
31     Tag tag;
32     T _0;
33   };
34 
35   struct Baz_Body {
36     Tag tag;
37     StylePoint<T> _0;
38   };
39 
40   struct {
41     Tag tag;
42   };
43   Foo_Body foo;
44   Bar_Body bar;
45   Baz_Body baz;
46 
Foo(const int32_t & x,const StylePoint<T> & y,const StylePoint<float> & z)47   static StyleFoo Foo(const int32_t &x,
48                       const StylePoint<T> &y,
49                       const StylePoint<float> &z) {
50     StyleFoo result;
51     ::new (&result.foo.x) (int32_t)(x);
52     ::new (&result.foo.y) (StylePoint<T>)(y);
53     ::new (&result.foo.z) (StylePoint<float>)(z);
54     result.tag = Tag::Foo;
55     return result;
56   }
57 
IsFoo() const58   bool IsFoo() const {
59     return tag == Tag::Foo;
60   }
61 
AsFoo() const62   const Foo_Body& AsFoo() const {
63     assert(IsFoo());
64     return foo;
65   }
66 
AsFoo()67   Foo_Body& AsFoo() {
68     assert(IsFoo());
69     return foo;
70   }
71 
Bar(const T & _0)72   static StyleFoo Bar(const T &_0) {
73     StyleFoo result;
74     ::new (&result.bar._0) (T)(_0);
75     result.tag = Tag::Bar;
76     return result;
77   }
78 
IsBar() const79   bool IsBar() const {
80     return tag == Tag::Bar;
81   }
82 
AsBar() const83   const T& AsBar() const {
84     assert(IsBar());
85     return bar._0;
86   }
87 
AsBar()88   T& AsBar() {
89     assert(IsBar());
90     return bar._0;
91   }
92 
Baz(const StylePoint<T> & _0)93   static StyleFoo Baz(const StylePoint<T> &_0) {
94     StyleFoo result;
95     ::new (&result.baz._0) (StylePoint<T>)(_0);
96     result.tag = Tag::Baz;
97     return result;
98   }
99 
IsBaz() const100   bool IsBaz() const {
101     return tag == Tag::Baz;
102   }
103 
AsBaz() const104   const StylePoint<T>& AsBaz() const {
105     assert(IsBaz());
106     return baz._0;
107   }
108 
AsBaz()109   StylePoint<T>& AsBaz() {
110     assert(IsBaz());
111     return baz._0;
112   }
113 
Bazz()114   static StyleFoo Bazz() {
115     StyleFoo result;
116     result.tag = Tag::Bazz;
117     return result;
118   }
119 
IsBazz() const120   bool IsBazz() const {
121     return tag == Tag::Bazz;
122   }
123 };
124 
125 template<typename T>
126 struct StyleBar {
127   enum class Tag {
128     Bar1,
129     Bar2,
130     Bar3,
131     Bar4,
132   };
133 
134   struct StyleBar1_Body {
135     int32_t x;
136     StylePoint<T> y;
137     StylePoint<float> z;
138     int32_t (*u)(int32_t);
139   };
140 
141   struct StyleBar2_Body {
142     T _0;
143   };
144 
145   struct StyleBar3_Body {
146     StylePoint<T> _0;
147   };
148 
149   Tag tag;
150   union {
151     StyleBar1_Body bar1;
152     StyleBar2_Body bar2;
153     StyleBar3_Body bar3;
154   };
155 
Bar1StyleBar156   static StyleBar Bar1(const int32_t &x,
157                        const StylePoint<T> &y,
158                        const StylePoint<float> &z,
159                        int32_t (*&u)(int32_t)) {
160     StyleBar result;
161     ::new (&result.bar1.x) (int32_t)(x);
162     ::new (&result.bar1.y) (StylePoint<T>)(y);
163     ::new (&result.bar1.z) (StylePoint<float>)(z);
164     ::new (&result.bar1.u) (int32_t(*)(int32_t))(u);
165     result.tag = Tag::Bar1;
166     return result;
167   }
168 
IsBar1StyleBar169   bool IsBar1() const {
170     return tag == Tag::Bar1;
171   }
172 
AsBar1StyleBar173   const StyleBar1_Body& AsBar1() const {
174     assert(IsBar1());
175     return bar1;
176   }
177 
AsBar1StyleBar178   StyleBar1_Body& AsBar1() {
179     assert(IsBar1());
180     return bar1;
181   }
182 
Bar2StyleBar183   static StyleBar Bar2(const T &_0) {
184     StyleBar result;
185     ::new (&result.bar2._0) (T)(_0);
186     result.tag = Tag::Bar2;
187     return result;
188   }
189 
IsBar2StyleBar190   bool IsBar2() const {
191     return tag == Tag::Bar2;
192   }
193 
AsBar2StyleBar194   const T& AsBar2() const {
195     assert(IsBar2());
196     return bar2._0;
197   }
198 
AsBar2StyleBar199   T& AsBar2() {
200     assert(IsBar2());
201     return bar2._0;
202   }
203 
Bar3StyleBar204   static StyleBar Bar3(const StylePoint<T> &_0) {
205     StyleBar result;
206     ::new (&result.bar3._0) (StylePoint<T>)(_0);
207     result.tag = Tag::Bar3;
208     return result;
209   }
210 
IsBar3StyleBar211   bool IsBar3() const {
212     return tag == Tag::Bar3;
213   }
214 
AsBar3StyleBar215   const StylePoint<T>& AsBar3() const {
216     assert(IsBar3());
217     return bar3._0;
218   }
219 
AsBar3StyleBar220   StylePoint<T>& AsBar3() {
221     assert(IsBar3());
222     return bar3._0;
223   }
224 
Bar4StyleBar225   static StyleBar Bar4() {
226     StyleBar result;
227     result.tag = Tag::Bar4;
228     return result;
229   }
230 
IsBar4StyleBar231   bool IsBar4() const {
232     return tag == Tag::Bar4;
233   }
234 };
235 
236 union StyleBaz {
237   enum class Tag : uint8_t {
238     Baz1,
239     Baz2,
240     Baz3,
241   };
242 
243   struct Baz1_Body {
244     Tag tag;
245     StyleBar<uint32_t> _0;
246   };
247 
248   struct Baz2_Body {
249     Tag tag;
250     StylePoint<int32_t> _0;
251   };
252 
253   struct {
254     Tag tag;
255   };
256   Baz1_Body baz1;
257   Baz2_Body baz2;
258 
Baz1(const StyleBar<uint32_t> & _0)259   static StyleBaz Baz1(const StyleBar<uint32_t> &_0) {
260     StyleBaz result;
261     ::new (&result.baz1._0) (StyleBar<uint32_t>)(_0);
262     result.tag = Tag::Baz1;
263     return result;
264   }
265 
IsBaz1() const266   bool IsBaz1() const {
267     return tag == Tag::Baz1;
268   }
269 
AsBaz1() const270   const StyleBar<uint32_t>& AsBaz1() const {
271     assert(IsBaz1());
272     return baz1._0;
273   }
274 
AsBaz1()275   StyleBar<uint32_t>& AsBaz1() {
276     assert(IsBaz1());
277     return baz1._0;
278   }
279 
Baz2(const StylePoint<int32_t> & _0)280   static StyleBaz Baz2(const StylePoint<int32_t> &_0) {
281     StyleBaz result;
282     ::new (&result.baz2._0) (StylePoint<int32_t>)(_0);
283     result.tag = Tag::Baz2;
284     return result;
285   }
286 
IsBaz2() const287   bool IsBaz2() const {
288     return tag == Tag::Baz2;
289   }
290 
AsBaz2() const291   const StylePoint<int32_t>& AsBaz2() const {
292     assert(IsBaz2());
293     return baz2._0;
294   }
295 
AsBaz2()296   StylePoint<int32_t>& AsBaz2() {
297     assert(IsBaz2());
298     return baz2._0;
299   }
300 
Baz3()301   static StyleBaz Baz3() {
302     StyleBaz result;
303     result.tag = Tag::Baz3;
304     return result;
305   }
306 
IsBaz3() const307   bool IsBaz3() const {
308     return tag == Tag::Baz3;
309   }
310 };
311 
312 struct StyleTaz {
313   enum class Tag : uint8_t {
314     Taz1,
315     Taz2,
316     Taz3,
317   };
318 
319   struct StyleTaz1_Body {
320     StyleBar<uint32_t> _0;
321   };
322 
323   struct StyleTaz2_Body {
324     StyleBaz _0;
325   };
326 
327   Tag tag;
328   union {
329     StyleTaz1_Body taz1;
330     StyleTaz2_Body taz2;
331   };
332 
Taz1StyleTaz333   static StyleTaz Taz1(const StyleBar<uint32_t> &_0) {
334     StyleTaz result;
335     ::new (&result.taz1._0) (StyleBar<uint32_t>)(_0);
336     result.tag = Tag::Taz1;
337     return result;
338   }
339 
IsTaz1StyleTaz340   bool IsTaz1() const {
341     return tag == Tag::Taz1;
342   }
343 
AsTaz1StyleTaz344   const StyleBar<uint32_t>& AsTaz1() const {
345     assert(IsTaz1());
346     return taz1._0;
347   }
348 
AsTaz1StyleTaz349   StyleBar<uint32_t>& AsTaz1() {
350     assert(IsTaz1());
351     return taz1._0;
352   }
353 
Taz2StyleTaz354   static StyleTaz Taz2(const StyleBaz &_0) {
355     StyleTaz result;
356     ::new (&result.taz2._0) (StyleBaz)(_0);
357     result.tag = Tag::Taz2;
358     return result;
359   }
360 
IsTaz2StyleTaz361   bool IsTaz2() const {
362     return tag == Tag::Taz2;
363   }
364 
AsTaz2StyleTaz365   const StyleBaz& AsTaz2() const {
366     assert(IsTaz2());
367     return taz2._0;
368   }
369 
AsTaz2StyleTaz370   StyleBaz& AsTaz2() {
371     assert(IsTaz2());
372     return taz2._0;
373   }
374 
Taz3StyleTaz375   static StyleTaz Taz3() {
376     StyleTaz result;
377     result.tag = Tag::Taz3;
378     return result;
379   }
380 
IsTaz3StyleTaz381   bool IsTaz3() const {
382     return tag == Tag::Taz3;
383   }
384 };
385 
386 extern "C" {
387 
388 void foo(const StyleFoo<int32_t> *foo,
389          const StyleBar<int32_t> *bar,
390          const StyleBaz *baz,
391          const StyleTaz *taz);
392 
393 } // extern "C"
394