Improved union copy constructor.

It now at least works in simple cases.

Change-Id: I3af0738e676e62166b69accaa6bd19f531fbe5ee
Tested: on Linux.
parent 728bb64f
......@@ -77,8 +77,9 @@ struct EquipmentUnion {
EquipmentUnion(EquipmentUnion&& u) FLATBUFFERS_NOEXCEPT :
type(Equipment_NONE), value(nullptr)
{ std::swap(type, u.type); std::swap(value, u.value); }
EquipmentUnion(const EquipmentUnion &) { assert(false); }
EquipmentUnion &operator=(const EquipmentUnion &) { assert(false); return *this; }
EquipmentUnion(const EquipmentUnion &) FLATBUFFERS_NOEXCEPT;
EquipmentUnion &operator=(EquipmentUnion u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
EquipmentUnion &operator=(EquipmentUnion &&u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
~EquipmentUnion() { Reset(); }
......@@ -555,6 +556,17 @@ inline flatbuffers::Offset<void> EquipmentUnion::Pack(flatbuffers::FlatBufferBui
}
}
inline EquipmentUnion::EquipmentUnion(const EquipmentUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
switch (type) {
case Equipment_Weapon: {
value = new WeaponT(*reinterpret_cast<WeaponT *>(u.value));
break;
}
default:
break;
}
}
inline void EquipmentUnion::Reset() {
switch (type) {
case Equipment_Weapon: {
......
......@@ -687,8 +687,9 @@ class CppGenerator : public BaseGenerator {
code_ += " {{NAME}}Union({{NAME}}Union&& u) FLATBUFFERS_NOEXCEPT :";
code_ += " type({{NONE}}), value(nullptr)";
code_ += " { std::swap(type, u.type); std::swap(value, u.value); }";
code_ += " {{NAME}}Union(const {{NAME}}Union &) { assert(false); }";
code_ += " {{NAME}}Union &operator=(const {{NAME}}Union &) { assert(false); return *this; }";
code_ += " {{NAME}}Union(const {{NAME}}Union &) FLATBUFFERS_NOEXCEPT;";
code_ += " {{NAME}}Union &operator=({{NAME}}Union u) FLATBUFFERS_NOEXCEPT";
code_ += " { std::swap(type, u.type); std::swap(value, u.value); return *this; }";
code_ += " {{NAME}}Union &operator=({{NAME}}Union &&u) FLATBUFFERS_NOEXCEPT";
code_ += " { std::swap(type, u.type); std::swap(value, u.value); return *this; }";
code_ += " ~{{NAME}}Union() { Reset(); }";
......@@ -865,6 +866,49 @@ class CppGenerator : public BaseGenerator {
code_ += "}";
code_ += "";
// Union copy constructor
code_ += "inline {{ENUM_NAME}}Union::{{ENUM_NAME}}Union(const "
"{{ENUM_NAME}}Union &u) FLATBUFFERS_NOEXCEPT : type(u.type), "
"value(nullptr) {";
code_ += " switch (type) {";
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
++it) {
const auto &ev = **it;
if (!ev.value) {
continue;
}
code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
code_.SetValue("TYPE", NativeName(GetUnionElement(ev, true, true, true),
ev.union_type.struct_def));
code_ += " case {{LABEL}}: {";
bool copyable = true;
if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
// Don't generate code to copy if table is not copyable.
// TODO(wvo): make tables copyable instead.
for (auto fit = ev.union_type.struct_def->fields.vec.begin();
fit != ev.union_type.struct_def->fields.vec.end(); ++fit) {
const auto &field = **fit;
if (!field.deprecated && field.value.type.struct_def) {
copyable = false;
break;
}
}
}
if (copyable) {
code_ += " value = new {{TYPE}}(*reinterpret_cast<{{TYPE}} *>"
"(u.value));";
} else {
code_ += " assert(false); // {{TYPE}} not copyable.";
}
code_ += " break;";
code_ += " }";
}
code_ += " default:";
code_ += " break;";
code_ += " }";
code_ += "}";
code_ += "";
// Union Reset() function.
code_.SetValue("NONE",
GetEnumValUse(enum_def, *enum_def.vals.Lookup("NONE")));
......@@ -877,11 +921,9 @@ class CppGenerator : public BaseGenerator {
if (!ev.value) {
continue;
}
code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
code_.SetValue("TYPE", NativeName(GetUnionElement(ev, true, true, true),
ev.union_type.struct_def));
code_ += " case {{LABEL}}: {";
code_ += " auto ptr = reinterpret_cast<{{TYPE}} *>(value);";
code_ += " delete ptr;";
......
......@@ -108,8 +108,9 @@ struct AnyUnion {
AnyUnion(AnyUnion&& u) FLATBUFFERS_NOEXCEPT :
type(Any_NONE), value(nullptr)
{ std::swap(type, u.type); std::swap(value, u.value); }
AnyUnion(const AnyUnion &) { assert(false); }
AnyUnion &operator=(const AnyUnion &) { assert(false); return *this; }
AnyUnion(const AnyUnion &) FLATBUFFERS_NOEXCEPT;
AnyUnion &operator=(AnyUnion u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
AnyUnion &operator=(AnyUnion &&u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
~AnyUnion() { Reset(); }
......@@ -1333,6 +1334,25 @@ inline flatbuffers::Offset<void> AnyUnion::Pack(flatbuffers::FlatBufferBuilder &
}
}
inline AnyUnion::AnyUnion(const AnyUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
switch (type) {
case Any_Monster: {
assert(false); // MonsterT not copyable.
break;
}
case Any_TestSimpleTableWithEnum: {
value = new TestSimpleTableWithEnumT(*reinterpret_cast<TestSimpleTableWithEnumT *>(u.value));
break;
}
case Any_MyGame_Example2_Monster: {
value = new MyGame::Example2::MonsterT(*reinterpret_cast<MyGame::Example2::MonsterT *>(u.value));
break;
}
default:
break;
}
}
inline void AnyUnion::Reset() {
switch (type) {
case Any_Monster: {
......
......@@ -55,8 +55,9 @@ struct CharacterUnion {
CharacterUnion(CharacterUnion&& u) FLATBUFFERS_NOEXCEPT :
type(Character_NONE), value(nullptr)
{ std::swap(type, u.type); std::swap(value, u.value); }
CharacterUnion(const CharacterUnion &) { assert(false); }
CharacterUnion &operator=(const CharacterUnion &) { assert(false); return *this; }
CharacterUnion(const CharacterUnion &) FLATBUFFERS_NOEXCEPT;
CharacterUnion &operator=(CharacterUnion u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
CharacterUnion &operator=(CharacterUnion &&u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
~CharacterUnion() { Reset(); }
......@@ -491,6 +492,37 @@ inline flatbuffers::Offset<void> CharacterUnion::Pack(flatbuffers::FlatBufferBui
}
}
inline CharacterUnion::CharacterUnion(const CharacterUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
switch (type) {
case Character_MuLan: {
value = new AttackerT(*reinterpret_cast<AttackerT *>(u.value));
break;
}
case Character_Rapunzel: {
value = new Rapunzel(*reinterpret_cast<Rapunzel *>(u.value));
break;
}
case Character_Belle: {
value = new BookReader(*reinterpret_cast<BookReader *>(u.value));
break;
}
case Character_BookFan: {
value = new BookReader(*reinterpret_cast<BookReader *>(u.value));
break;
}
case Character_Other: {
value = new std::string(*reinterpret_cast<std::string *>(u.value));
break;
}
case Character_Unused: {
value = new std::string(*reinterpret_cast<std::string *>(u.value));
break;
}
default:
break;
}
}
inline void CharacterUnion::Reset() {
switch (type) {
case Character_MuLan: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment