#include #include #include #include enum class FillRule : uint8_t { A, B, }; /// This will have a destructor manually implemented via variant_body, and /// similarly a Drop impl in Rust. template struct OwnedSlice { uintptr_t len; T *ptr; ~OwnedSlice() {} }; template struct Polygon { FillRule fill; OwnedSlice coordinates; }; template struct Foo { enum class Tag : uint8_t { Bar, Polygon1, Slice1, Slice2, Slice3, Slice4, }; struct Polygon1_Body { Polygon _0; }; struct Slice1_Body { OwnedSlice _0; }; struct Slice2_Body { OwnedSlice _0; }; struct Slice3_Body { FillRule fill; OwnedSlice coords; }; struct Slice4_Body { FillRule fill; OwnedSlice coords; }; Tag tag; union { Polygon1_Body polygon1; Slice1_Body slice1; Slice2_Body slice2; Slice3_Body slice3; Slice4_Body slice4; }; static Foo Bar() { Foo result; result.tag = Tag::Bar; return result; } static Foo Polygon1(const Polygon &a0) { Foo result; ::new (&result.polygon1._0) (Polygon)(a0); result.tag = Tag::Polygon1; return result; } static Foo Slice1(const OwnedSlice &a0) { Foo result; ::new (&result.slice1._0) (OwnedSlice)(a0); result.tag = Tag::Slice1; return result; } static Foo Slice2(const OwnedSlice &a0) { Foo result; ::new (&result.slice2._0) (OwnedSlice)(a0); result.tag = Tag::Slice2; return result; } static Foo Slice3(const FillRule &aFill, const OwnedSlice &aCoords) { Foo result; ::new (&result.slice3.fill) (FillRule)(aFill); ::new (&result.slice3.coords) (OwnedSlice)(aCoords); result.tag = Tag::Slice3; return result; } static Foo Slice4(const FillRule &aFill, const OwnedSlice &aCoords) { Foo result; ::new (&result.slice4.fill) (FillRule)(aFill); ::new (&result.slice4.coords) (OwnedSlice)(aCoords); result.tag = Tag::Slice4; return result; } bool IsBar() const { return tag == Tag::Bar; } bool IsPolygon1() const { return tag == Tag::Polygon1; } bool IsSlice1() const { return tag == Tag::Slice1; } bool IsSlice2() const { return tag == Tag::Slice2; } bool IsSlice3() const { return tag == Tag::Slice3; } bool IsSlice4() const { return tag == Tag::Slice4; } private: Foo() { } public: ~Foo() { switch (tag) { case Tag::Polygon1: polygon1.~Polygon1_Body(); break; case Tag::Slice1: slice1.~Slice1_Body(); break; case Tag::Slice2: slice2.~Slice2_Body(); break; case Tag::Slice3: slice3.~Slice3_Body(); break; case Tag::Slice4: slice4.~Slice4_Body(); break; default: break; } } Foo(const Foo& other) : tag(other.tag) { switch (tag) { case Tag::Polygon1: ::new (&polygon1) (Polygon1_Body)(other.polygon1); break; case Tag::Slice1: ::new (&slice1) (Slice1_Body)(other.slice1); break; case Tag::Slice2: ::new (&slice2) (Slice2_Body)(other.slice2); break; case Tag::Slice3: ::new (&slice3) (Slice3_Body)(other.slice3); break; case Tag::Slice4: ::new (&slice4) (Slice4_Body)(other.slice4); break; default: break; } } Foo& operator=(const Foo& other) { if (this != &other) { this->~Foo(); new (this) Foo(other); } return *this; } }; template union Baz { enum class Tag : uint8_t { Bar2, Polygon21, Slice21, Slice22, Slice23, Slice24, }; struct Polygon21_Body { Tag tag; Polygon _0; }; struct Slice21_Body { Tag tag; OwnedSlice _0; }; struct Slice22_Body { Tag tag; OwnedSlice _0; }; struct Slice23_Body { Tag tag; FillRule fill; OwnedSlice coords; }; struct Slice24_Body { Tag tag; FillRule fill; OwnedSlice coords; }; struct { Tag tag; }; Polygon21_Body polygon21; Slice21_Body slice21; Slice22_Body slice22; Slice23_Body slice23; Slice24_Body slice24; static Baz Bar2() { Baz result; result.tag = Tag::Bar2; return result; } static Baz Polygon21(const Polygon &a0) { Baz result; ::new (&result.polygon21._0) (Polygon)(a0); result.tag = Tag::Polygon21; return result; } static Baz Slice21(const OwnedSlice &a0) { Baz result; ::new (&result.slice21._0) (OwnedSlice)(a0); result.tag = Tag::Slice21; return result; } static Baz Slice22(const OwnedSlice &a0) { Baz result; ::new (&result.slice22._0) (OwnedSlice)(a0); result.tag = Tag::Slice22; return result; } static Baz Slice23(const FillRule &aFill, const OwnedSlice &aCoords) { Baz result; ::new (&result.slice23.fill) (FillRule)(aFill); ::new (&result.slice23.coords) (OwnedSlice)(aCoords); result.tag = Tag::Slice23; return result; } static Baz Slice24(const FillRule &aFill, const OwnedSlice &aCoords) { Baz result; ::new (&result.slice24.fill) (FillRule)(aFill); ::new (&result.slice24.coords) (OwnedSlice)(aCoords); result.tag = Tag::Slice24; return result; } bool IsBar2() const { return tag == Tag::Bar2; } bool IsPolygon21() const { return tag == Tag::Polygon21; } bool IsSlice21() const { return tag == Tag::Slice21; } bool IsSlice22() const { return tag == Tag::Slice22; } bool IsSlice23() const { return tag == Tag::Slice23; } bool IsSlice24() const { return tag == Tag::Slice24; } private: Baz() { } public: ~Baz() { switch (tag) { case Tag::Polygon21: polygon21.~Polygon21_Body(); break; case Tag::Slice21: slice21.~Slice21_Body(); break; case Tag::Slice22: slice22.~Slice22_Body(); break; case Tag::Slice23: slice23.~Slice23_Body(); break; case Tag::Slice24: slice24.~Slice24_Body(); break; default: break; } } Baz(const Baz& other) : tag(other.tag) { switch (tag) { case Tag::Polygon21: ::new (&polygon21) (Polygon21_Body)(other.polygon21); break; case Tag::Slice21: ::new (&slice21) (Slice21_Body)(other.slice21); break; case Tag::Slice22: ::new (&slice22) (Slice22_Body)(other.slice22); break; case Tag::Slice23: ::new (&slice23) (Slice23_Body)(other.slice23); break; case Tag::Slice24: ::new (&slice24) (Slice24_Body)(other.slice24); break; default: break; } } Baz& operator=(const Baz& other) { if (this != &other) { this->~Baz(); new (this) Baz(other); } return *this; } }; union Taz { enum class Tag : uint8_t { Bar3, Taz1, Taz3, }; struct Taz1_Body { Tag tag; int32_t _0; }; struct Taz3_Body { Tag tag; OwnedSlice _0; }; struct { Tag tag; }; Taz1_Body taz1; Taz3_Body taz3; static Taz Bar3() { Taz result; result.tag = Tag::Bar3; return result; } static Taz Taz1(const int32_t &a0) { Taz result; ::new (&result.taz1._0) (int32_t)(a0); result.tag = Tag::Taz1; return result; } static Taz Taz3(const OwnedSlice &a0) { Taz result; ::new (&result.taz3._0) (OwnedSlice)(a0); result.tag = Tag::Taz3; return result; } bool IsBar3() const { return tag == Tag::Bar3; } bool IsTaz1() const { return tag == Tag::Taz1; } bool IsTaz3() const { return tag == Tag::Taz3; } private: Taz() { } public: ~Taz() { switch (tag) { case Tag::Taz1: taz1.~Taz1_Body(); break; case Tag::Taz3: taz3.~Taz3_Body(); break; default: break; } } Taz(const Taz& other) : tag(other.tag) { switch (tag) { case Tag::Taz1: ::new (&taz1) (Taz1_Body)(other.taz1); break; case Tag::Taz3: ::new (&taz3) (Taz3_Body)(other.taz3); break; default: break; } } Taz& operator=(const Taz& other) { if (this != &other) { this->~Taz(); new (this) Taz(other); } return *this; } }; union Tazz { enum class Tag : uint8_t { Bar4, Taz2, }; struct Taz2_Body { Tag tag; int32_t _0; }; struct { Tag tag; }; Taz2_Body taz2; static Tazz Bar4() { Tazz result; result.tag = Tag::Bar4; return result; } static Tazz Taz2(const int32_t &a0) { Tazz result; ::new (&result.taz2._0) (int32_t)(a0); result.tag = Tag::Taz2; return result; } bool IsBar4() const { return tag == Tag::Bar4; } bool IsTaz2() const { return tag == Tag::Taz2; } private: Tazz() { } public: }; extern "C" { void root(const Foo *a, const Baz *b, const Taz *c, Tazz d); } // extern "C"