Ideally we'd just do this when we need it, but the ostream derivation will be controlled by both global config and per-structure config, so it's hard to know exactly when we need it and when we don't.
394 lines
6.5 KiB
C++
394 lines
6.5 KiB
C++
#include <cstdarg>
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <ostream>
|
|
#include <new>
|
|
#include <cassert>
|
|
|
|
template<typename T>
|
|
struct StylePoint {
|
|
T x;
|
|
T y;
|
|
};
|
|
|
|
template<typename T>
|
|
union StyleFoo {
|
|
enum class Tag : uint8_t {
|
|
Foo,
|
|
Bar,
|
|
Baz,
|
|
Bazz,
|
|
};
|
|
|
|
struct Foo_Body {
|
|
Tag tag;
|
|
int32_t x;
|
|
StylePoint<T> y;
|
|
StylePoint<float> z;
|
|
};
|
|
|
|
struct Bar_Body {
|
|
Tag tag;
|
|
T _0;
|
|
};
|
|
|
|
struct Baz_Body {
|
|
Tag tag;
|
|
StylePoint<T> _0;
|
|
};
|
|
|
|
struct {
|
|
Tag tag;
|
|
};
|
|
Foo_Body foo;
|
|
Bar_Body bar;
|
|
Baz_Body baz;
|
|
|
|
static StyleFoo Foo(const int32_t &x,
|
|
const StylePoint<T> &y,
|
|
const StylePoint<float> &z) {
|
|
StyleFoo result;
|
|
::new (&result.foo.x) (int32_t)(x);
|
|
::new (&result.foo.y) (StylePoint<T>)(y);
|
|
::new (&result.foo.z) (StylePoint<float>)(z);
|
|
result.tag = Tag::Foo;
|
|
return result;
|
|
}
|
|
|
|
bool IsFoo() const {
|
|
return tag == Tag::Foo;
|
|
}
|
|
|
|
const Foo_Body& AsFoo() const {
|
|
assert(IsFoo());
|
|
return foo;
|
|
}
|
|
|
|
Foo_Body& AsFoo() {
|
|
assert(IsFoo());
|
|
return foo;
|
|
}
|
|
|
|
static StyleFoo Bar(const T &_0) {
|
|
StyleFoo result;
|
|
::new (&result.bar._0) (T)(_0);
|
|
result.tag = Tag::Bar;
|
|
return result;
|
|
}
|
|
|
|
bool IsBar() const {
|
|
return tag == Tag::Bar;
|
|
}
|
|
|
|
const T& AsBar() const {
|
|
assert(IsBar());
|
|
return bar._0;
|
|
}
|
|
|
|
T& AsBar() {
|
|
assert(IsBar());
|
|
return bar._0;
|
|
}
|
|
|
|
static StyleFoo Baz(const StylePoint<T> &_0) {
|
|
StyleFoo result;
|
|
::new (&result.baz._0) (StylePoint<T>)(_0);
|
|
result.tag = Tag::Baz;
|
|
return result;
|
|
}
|
|
|
|
bool IsBaz() const {
|
|
return tag == Tag::Baz;
|
|
}
|
|
|
|
const StylePoint<T>& AsBaz() const {
|
|
assert(IsBaz());
|
|
return baz._0;
|
|
}
|
|
|
|
StylePoint<T>& AsBaz() {
|
|
assert(IsBaz());
|
|
return baz._0;
|
|
}
|
|
|
|
static StyleFoo Bazz() {
|
|
StyleFoo result;
|
|
result.tag = Tag::Bazz;
|
|
return result;
|
|
}
|
|
|
|
bool IsBazz() const {
|
|
return tag == Tag::Bazz;
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct StyleBar {
|
|
enum class Tag {
|
|
Bar1,
|
|
Bar2,
|
|
Bar3,
|
|
Bar4,
|
|
};
|
|
|
|
struct StyleBar1_Body {
|
|
int32_t x;
|
|
StylePoint<T> y;
|
|
StylePoint<float> z;
|
|
int32_t (*u)(int32_t);
|
|
};
|
|
|
|
struct StyleBar2_Body {
|
|
T _0;
|
|
};
|
|
|
|
struct StyleBar3_Body {
|
|
StylePoint<T> _0;
|
|
};
|
|
|
|
Tag tag;
|
|
union {
|
|
StyleBar1_Body bar1;
|
|
StyleBar2_Body bar2;
|
|
StyleBar3_Body bar3;
|
|
};
|
|
|
|
static StyleBar Bar1(const int32_t &x,
|
|
const StylePoint<T> &y,
|
|
const StylePoint<float> &z,
|
|
int32_t (*&u)(int32_t)) {
|
|
StyleBar result;
|
|
::new (&result.bar1.x) (int32_t)(x);
|
|
::new (&result.bar1.y) (StylePoint<T>)(y);
|
|
::new (&result.bar1.z) (StylePoint<float>)(z);
|
|
::new (&result.bar1.u) (int32_t(*)(int32_t))(u);
|
|
result.tag = Tag::Bar1;
|
|
return result;
|
|
}
|
|
|
|
bool IsBar1() const {
|
|
return tag == Tag::Bar1;
|
|
}
|
|
|
|
const StyleBar1_Body& AsBar1() const {
|
|
assert(IsBar1());
|
|
return bar1;
|
|
}
|
|
|
|
StyleBar1_Body& AsBar1() {
|
|
assert(IsBar1());
|
|
return bar1;
|
|
}
|
|
|
|
static StyleBar Bar2(const T &_0) {
|
|
StyleBar result;
|
|
::new (&result.bar2._0) (T)(_0);
|
|
result.tag = Tag::Bar2;
|
|
return result;
|
|
}
|
|
|
|
bool IsBar2() const {
|
|
return tag == Tag::Bar2;
|
|
}
|
|
|
|
const T& AsBar2() const {
|
|
assert(IsBar2());
|
|
return bar2._0;
|
|
}
|
|
|
|
T& AsBar2() {
|
|
assert(IsBar2());
|
|
return bar2._0;
|
|
}
|
|
|
|
static StyleBar Bar3(const StylePoint<T> &_0) {
|
|
StyleBar result;
|
|
::new (&result.bar3._0) (StylePoint<T>)(_0);
|
|
result.tag = Tag::Bar3;
|
|
return result;
|
|
}
|
|
|
|
bool IsBar3() const {
|
|
return tag == Tag::Bar3;
|
|
}
|
|
|
|
const StylePoint<T>& AsBar3() const {
|
|
assert(IsBar3());
|
|
return bar3._0;
|
|
}
|
|
|
|
StylePoint<T>& AsBar3() {
|
|
assert(IsBar3());
|
|
return bar3._0;
|
|
}
|
|
|
|
static StyleBar Bar4() {
|
|
StyleBar result;
|
|
result.tag = Tag::Bar4;
|
|
return result;
|
|
}
|
|
|
|
bool IsBar4() const {
|
|
return tag == Tag::Bar4;
|
|
}
|
|
};
|
|
|
|
union StyleBaz {
|
|
enum class Tag : uint8_t {
|
|
Baz1,
|
|
Baz2,
|
|
Baz3,
|
|
};
|
|
|
|
struct Baz1_Body {
|
|
Tag tag;
|
|
StyleBar<uint32_t> _0;
|
|
};
|
|
|
|
struct Baz2_Body {
|
|
Tag tag;
|
|
StylePoint<int32_t> _0;
|
|
};
|
|
|
|
struct {
|
|
Tag tag;
|
|
};
|
|
Baz1_Body baz1;
|
|
Baz2_Body baz2;
|
|
|
|
static StyleBaz Baz1(const StyleBar<uint32_t> &_0) {
|
|
StyleBaz result;
|
|
::new (&result.baz1._0) (StyleBar<uint32_t>)(_0);
|
|
result.tag = Tag::Baz1;
|
|
return result;
|
|
}
|
|
|
|
bool IsBaz1() const {
|
|
return tag == Tag::Baz1;
|
|
}
|
|
|
|
const StyleBar<uint32_t>& AsBaz1() const {
|
|
assert(IsBaz1());
|
|
return baz1._0;
|
|
}
|
|
|
|
StyleBar<uint32_t>& AsBaz1() {
|
|
assert(IsBaz1());
|
|
return baz1._0;
|
|
}
|
|
|
|
static StyleBaz Baz2(const StylePoint<int32_t> &_0) {
|
|
StyleBaz result;
|
|
::new (&result.baz2._0) (StylePoint<int32_t>)(_0);
|
|
result.tag = Tag::Baz2;
|
|
return result;
|
|
}
|
|
|
|
bool IsBaz2() const {
|
|
return tag == Tag::Baz2;
|
|
}
|
|
|
|
const StylePoint<int32_t>& AsBaz2() const {
|
|
assert(IsBaz2());
|
|
return baz2._0;
|
|
}
|
|
|
|
StylePoint<int32_t>& AsBaz2() {
|
|
assert(IsBaz2());
|
|
return baz2._0;
|
|
}
|
|
|
|
static StyleBaz Baz3() {
|
|
StyleBaz result;
|
|
result.tag = Tag::Baz3;
|
|
return result;
|
|
}
|
|
|
|
bool IsBaz3() const {
|
|
return tag == Tag::Baz3;
|
|
}
|
|
};
|
|
|
|
struct StyleTaz {
|
|
enum class Tag : uint8_t {
|
|
Taz1,
|
|
Taz2,
|
|
Taz3,
|
|
};
|
|
|
|
struct StyleTaz1_Body {
|
|
StyleBar<uint32_t> _0;
|
|
};
|
|
|
|
struct StyleTaz2_Body {
|
|
StyleBaz _0;
|
|
};
|
|
|
|
Tag tag;
|
|
union {
|
|
StyleTaz1_Body taz1;
|
|
StyleTaz2_Body taz2;
|
|
};
|
|
|
|
static StyleTaz Taz1(const StyleBar<uint32_t> &_0) {
|
|
StyleTaz result;
|
|
::new (&result.taz1._0) (StyleBar<uint32_t>)(_0);
|
|
result.tag = Tag::Taz1;
|
|
return result;
|
|
}
|
|
|
|
bool IsTaz1() const {
|
|
return tag == Tag::Taz1;
|
|
}
|
|
|
|
const StyleBar<uint32_t>& AsTaz1() const {
|
|
assert(IsTaz1());
|
|
return taz1._0;
|
|
}
|
|
|
|
StyleBar<uint32_t>& AsTaz1() {
|
|
assert(IsTaz1());
|
|
return taz1._0;
|
|
}
|
|
|
|
static StyleTaz Taz2(const StyleBaz &_0) {
|
|
StyleTaz result;
|
|
::new (&result.taz2._0) (StyleBaz)(_0);
|
|
result.tag = Tag::Taz2;
|
|
return result;
|
|
}
|
|
|
|
bool IsTaz2() const {
|
|
return tag == Tag::Taz2;
|
|
}
|
|
|
|
const StyleBaz& AsTaz2() const {
|
|
assert(IsTaz2());
|
|
return taz2._0;
|
|
}
|
|
|
|
StyleBaz& AsTaz2() {
|
|
assert(IsTaz2());
|
|
return taz2._0;
|
|
}
|
|
|
|
static StyleTaz Taz3() {
|
|
StyleTaz result;
|
|
result.tag = Tag::Taz3;
|
|
return result;
|
|
}
|
|
|
|
bool IsTaz3() const {
|
|
return tag == Tag::Taz3;
|
|
}
|
|
};
|
|
|
|
extern "C" {
|
|
|
|
void foo(const StyleFoo<int32_t> *foo,
|
|
const StyleBar<int32_t> *bar,
|
|
const StyleBaz *baz,
|
|
const StyleTaz *taz);
|
|
|
|
} // extern "C"
|