Add default values (if they exist) to native tables.
From cl/142307012.
Change-Id: I54d550573f6506b92ad18e7cc90bcd8589259e52
diff --git a/samples/monster_generated.h b/samples/monster_generated.h
index 2504e83..ded7846 100644
--- a/samples/monster_generated.h
+++ b/samples/monster_generated.h
@@ -111,6 +111,10 @@
Color color;
std::vector<std::unique_ptr<WeaponT>> weapons;
EquipmentUnion equipped;
+ MonsterT()
+ : mana(150),
+ hp(100),
+ color(Color_Blue) {}
};
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@@ -228,6 +232,8 @@
typedef Weapon TableType;
std::string name;
int16_t damage;
+ WeaponT()
+ : damage(0) {}
};
struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp
index 8e33b59..0436f4d 100644
--- a/src/idl_gen_cpp.cpp
+++ b/src/idl_gen_cpp.cpp
@@ -691,26 +691,72 @@
: field.value.constant;
}
- void GenSimpleParam(std::string &code, FieldDef &field) {
- code += ",\n " + GenTypeWire(field.value.type, " ", true);
- code += field.name + " = ";
+ std::string GetDefaultScalarValue(const FieldDef &field) {
if (field.value.type.enum_def && IsScalar(field.value.type.base_type)) {
auto ev = field.value.type.enum_def->ReverseLookup(
static_cast<int>(StringToInt(field.value.constant.c_str())), false);
if (ev) {
- code += WrapInNameSpace(
+ return WrapInNameSpace(
field.value.type.enum_def->defined_namespace,
GetEnumValUse(*field.value.type.enum_def, *ev, parser_.opts));
} else {
- code += GenUnderlyingCast(field, true, field.value.constant);
+ return GenUnderlyingCast(field, true, field.value.constant);
}
} else if (field.value.type.base_type == BASE_TYPE_BOOL) {
- code += field.value.constant == "0" ? "false" : "true";
+ return field.value.constant == "0" ? "false" : "true";
} else {
- code += GenDefaultConstant(field);
+ return GenDefaultConstant(field);
}
}
+ void GenSimpleParam(std::string &code, FieldDef &field) {
+ code += ",\n " + GenTypeWire(field.value.type, " ", true);
+ code += field.name + " = " + GetDefaultScalarValue(field);
+ }
+
+ // Generate a member, including a default value for scalars and raw pointers.
+ void GenMember(std::string& code, const FieldDef &field) {
+ if (!field.deprecated && // Deprecated fields won't be accessible.
+ field.value.type.base_type != BASE_TYPE_UTYPE) {
+ auto type = GenTypeNative(field.value.type, false, field);
+ auto cpp_type = field.attributes.Lookup("cpp_type");
+ code += " " + (cpp_type ? cpp_type->constant + " *" : type+ " ") +
+ field.name + ";\n";
+ }
+ }
+
+ // Generate the default constructor for this struct. Properly initialize all
+ // scalar members with default values.
+ void GenDefaultConstructor(std::string& code, const StructDef& struct_def) {
+ code += " " + NativeName(struct_def.name) + "()";
+ std::string initializer_list;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (!field.deprecated && // Deprecated fields won't be accessible.
+ field.value.type.base_type != BASE_TYPE_UTYPE) {
+ auto cpp_type = field.attributes.Lookup("cpp_type");
+ // Scalar types get parsed defaults, raw pointers get nullptrs.
+ if (IsScalar(field.value.type.base_type)) {
+ if (!initializer_list.empty()) {
+ initializer_list += ",\n ";
+ }
+ initializer_list += field.name + "(" +GetDefaultScalarValue(field) +
+ ")";
+ } else if (cpp_type) {
+ if (!initializer_list.empty()) {
+ code += ",\n ";
+ }
+ initializer_list += field.name + "(0)";
+ }
+ }
+ }
+ if (!initializer_list.empty()) {
+ code += "\n : " + initializer_list;
+ }
+ code += " {}\n";
+ }
+
// Generate an accessor struct, builder structs & function for a table.
void GenTable(StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr;
@@ -726,14 +772,9 @@
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
- if (!field.deprecated && // Deprecated fields won't be accessible.
- field.value.type.base_type != BASE_TYPE_UTYPE) {
- auto type = GenTypeNative(field.value.type, false, field);
- auto cpp_type = field.attributes.Lookup("cpp_type");
- code += " " + (cpp_type ? cpp_type->constant + " *" : type+ " ") +
- field.name + ";\n";
- }
+ GenMember(code, field);
}
+ GenDefaultConstructor(code, struct_def);
code += "};\n\n";
}
diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h
index 8a2a111..5714f58 100644
--- a/tests/monster_test_generated.h
+++ b/tests/monster_test_generated.h
@@ -162,6 +162,7 @@
struct MonsterT : public flatbuffers::NativeTable {
typedef Monster TableType;
+ MonsterT() {}
};
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@@ -199,6 +200,8 @@
struct TestSimpleTableWithEnumT : public flatbuffers::NativeTable {
typedef TestSimpleTableWithEnum TableType;
Color color;
+ TestSimpleTableWithEnumT()
+ : color(Color_Green) {}
};
struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@@ -243,6 +246,9 @@
std::string id;
int64_t val;
uint16_t count;
+ StatT()
+ : val(0),
+ count(0) {}
};
struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@@ -333,6 +339,22 @@
float testf2;
float testf3;
std::vector<std::string> testarrayofstring2;
+ MonsterT()
+ : mana(150),
+ hp(100),
+ color(Color_Blue),
+ testbool(false),
+ testhashs32_fnv1(0),
+ testhashu32_fnv1(0),
+ testhashs64_fnv1(0),
+ testhashu64_fnv1(0),
+ testhashs32_fnv1a(0),
+ testhashu32_fnv1a(0),
+ testhashs64_fnv1a(0),
+ testhashu64_fnv1a(0),
+ testf(3.14159f),
+ testf2(3.0f),
+ testf3(0.0f) {}
};
/// an example documentation comment: monster object