Files
cbindgen/tests/expectations/derive-eq.cpp
T
Emilio Cobos Álvarez b2e224354b Use placement new for constructing in tagged unions' helper methods.
Using operator= is not quite sound in presence of destructors and operator
overloading.

It's perfectly fine to assume that the left-hand-side of an operator= expression
is valid memory, however we're using uninitialized memory here, that may not be
the case.

Use placement new to properly construct tagged unions. I don't need this with
any urgency, but it's the right thing to do in presence of complex types, and
the current code seems a bomb waiting to explode :)
2019-05-10 18:15:39 +02:00

99 lines
1.9 KiB
C++

#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <new>
struct Foo {
bool a;
int32_t b;
bool operator==(const Foo& aOther) const {
return a == aOther.a &&
b == aOther.b;
}
bool operator!=(const Foo& aOther) const {
return a != aOther.a ||
b != aOther.b;
}
};
union Bar {
enum class Tag : uint8_t {
Baz,
Bazz,
FooNamed,
FooParen,
};
struct Bazz_Body {
Tag tag;
Foo named;
bool operator==(const Bazz_Body& aOther) const {
return named == aOther.named;
}
bool operator!=(const Bazz_Body& aOther) const {
return named != aOther.named;
}
};
struct FooNamed_Body {
Tag tag;
int32_t different;
uint32_t fields;
bool operator==(const FooNamed_Body& aOther) const {
return different == aOther.different &&
fields == aOther.fields;
}
bool operator!=(const FooNamed_Body& aOther) const {
return different != aOther.different ||
fields != aOther.fields;
}
};
struct FooParen_Body {
Tag tag;
int32_t _0;
Foo _1;
bool operator==(const FooParen_Body& aOther) const {
return _0 == aOther._0 &&
_1 == aOther._1;
}
bool operator!=(const FooParen_Body& aOther) const {
return _0 != aOther._0 ||
_1 != aOther._1;
}
};
struct {
Tag tag;
};
Bazz_Body bazz;
FooNamed_Body foo_named;
FooParen_Body foo_paren;
bool operator==(const Bar& aOther) const {
if (tag != aOther.tag) {
return false;
}
switch (tag) {
case Tag::Bazz: return bazz == aOther.bazz;
case Tag::FooNamed: return foo_named == aOther.foo_named;
case Tag::FooParen: return foo_paren == aOther.foo_paren;
default: return true;
}
}
bool operator!=(const Bar& aOther) const {
return !(*this == aOther);
}
};
extern "C" {
Foo root(Bar aBar);
} // extern "C"