#define MY_ASSERT(...) do { } while (0) #include #include #include #include struct I; struct H { enum class Tag : uint8_t { H_Foo, H_Bar, H_Baz, }; struct H_Foo_Body { int16_t _0; }; struct H_Bar_Body { uint8_t x; int16_t y; }; Tag tag; union { H_Foo_Body foo; H_Bar_Body bar; }; static H H_Foo(const int16_t &a0) { H result; ::new (&result.foo._0) (int16_t)(a0); result.tag = Tag::H_Foo; return result; } static H H_Bar(const uint8_t &aX, const int16_t &aY) { H result; ::new (&result.bar.x) (uint8_t)(aX); ::new (&result.bar.y) (int16_t)(aY); result.tag = Tag::H_Bar; return result; } static H H_Baz() { H result; result.tag = Tag::H_Baz; return result; } bool IsH_Foo() const { return tag == Tag::H_Foo; } bool IsH_Bar() const { return tag == Tag::H_Bar; } bool IsH_Baz() const { return tag == Tag::H_Baz; } const int16_t& AsH_Foo() const { MY_ASSERT(IsH_Foo()); return foo._0; } int16_t& AsH_Foo() { MY_ASSERT(IsH_Foo()); return foo._0; } const H_Bar_Body& AsH_Bar() const { MY_ASSERT(IsH_Bar()); return bar; } H_Bar_Body& AsH_Bar() { MY_ASSERT(IsH_Bar()); return bar; } }; struct J { enum class Tag : uint8_t { J_Foo, J_Bar, J_Baz, }; struct J_Foo_Body { int16_t _0; }; struct J_Bar_Body { uint8_t x; int16_t y; }; Tag tag; union { J_Foo_Body foo; J_Bar_Body bar; }; static J J_Foo(const int16_t &a0) { J result; ::new (&result.foo._0) (int16_t)(a0); result.tag = Tag::J_Foo; return result; } static J J_Bar(const uint8_t &aX, const int16_t &aY) { J result; ::new (&result.bar.x) (uint8_t)(aX); ::new (&result.bar.y) (int16_t)(aY); result.tag = Tag::J_Bar; return result; } static J J_Baz() { J result; result.tag = Tag::J_Baz; return result; } bool IsJ_Foo() const { return tag == Tag::J_Foo; } bool IsJ_Bar() const { return tag == Tag::J_Bar; } bool IsJ_Baz() const { return tag == Tag::J_Baz; } const int16_t& AsJ_Foo() const { MY_ASSERT(IsJ_Foo()); return foo._0; } int16_t& AsJ_Foo() { MY_ASSERT(IsJ_Foo()); return foo._0; } const J_Bar_Body& AsJ_Bar() const { MY_ASSERT(IsJ_Bar()); return bar; } J_Bar_Body& AsJ_Bar() { MY_ASSERT(IsJ_Bar()); return bar; } }; union K { enum class Tag : uint8_t { K_Foo, K_Bar, K_Baz, }; struct K_Foo_Body { Tag tag; int16_t _0; }; struct K_Bar_Body { Tag tag; uint8_t x; int16_t y; }; struct { Tag tag; }; K_Foo_Body foo; K_Bar_Body bar; static K K_Foo(const int16_t &a0) { K result; ::new (&result.foo._0) (int16_t)(a0); result.tag = Tag::K_Foo; return result; } static K K_Bar(const uint8_t &aX, const int16_t &aY) { K result; ::new (&result.bar.x) (uint8_t)(aX); ::new (&result.bar.y) (int16_t)(aY); result.tag = Tag::K_Bar; return result; } static K K_Baz() { K result; result.tag = Tag::K_Baz; return result; } bool IsK_Foo() const { return tag == Tag::K_Foo; } bool IsK_Bar() const { return tag == Tag::K_Bar; } bool IsK_Baz() const { return tag == Tag::K_Baz; } const int16_t& AsK_Foo() const { MY_ASSERT(IsK_Foo()); return foo._0; } int16_t& AsK_Foo() { MY_ASSERT(IsK_Foo()); return foo._0; } const K_Bar_Body& AsK_Bar() const { MY_ASSERT(IsK_Bar()); return bar; } K_Bar_Body& AsK_Bar() { MY_ASSERT(IsK_Bar()); return bar; } }; extern "C" { void foo(H h, I i, J j, K k); } // extern "C"