Improve generated comparisons for tables (#6486)

* Improve generated comparisons for tables

Previously, the generated code called std::unique_ptr<>::operator== on
non-scalar members, which would be correct only if the member was null
on both sides. After this CL, comparison is done on the pointed-to
values (including using a default-constructed value if the pointer is
null).

* Don't equate null Tables with all defaults

Also removes the cost of default-constructing tables for comparisons.

* Regenerate code

* fix formatting
This commit is contained in:
Mika Raento
2021-06-21 21:37:56 +03:00
committed by GitHub
parent 06fd6d640c
commit 962751a6ec
10 changed files with 362 additions and 297 deletions

View File

@@ -1819,7 +1819,18 @@ class CppGenerator : public BaseGenerator {
field.value.type.element != BASE_TYPE_UTYPE)) {
if (!compare_op.empty()) { compare_op += " &&\n "; }
auto accessor = Name(field) + accessSuffix;
compare_op += "(lhs." + accessor + " == rhs." + accessor + ")";
if (struct_def.fixed ||
field.value.type.base_type != BASE_TYPE_STRUCT) {
compare_op += "(lhs." + accessor + " == rhs." + accessor + ")";
} else {
// Deep compare of std::unique_ptr. Null is not equal to empty.
std::string both_null =
"(lhs." + accessor + " == rhs." + accessor + ")";
std::string not_null_and_equal = "(lhs." + accessor + " && rhs." +
accessor + " && *lhs." + accessor +
" == *rhs." + accessor + ")";
compare_op += "(" + both_null + " || " + not_null_and_equal + ")";
}
}
}
@@ -1885,10 +1896,19 @@ class CppGenerator : public BaseGenerator {
GenOperatorNewDelete(struct_def);
GenDefaultConstructor(struct_def);
code_ += "};";
if (opts_.gen_compare) GenCompareOperator(struct_def);
code_ += "";
}
void GenNativeTablePost(const StructDef &struct_def) {
if (opts_.gen_compare) {
const auto native_name = NativeName(Name(struct_def), &struct_def, opts_);
code_.SetValue("STRUCT_NAME", Name(struct_def));
code_.SetValue("NATIVE_NAME", native_name);
GenCompareOperator(struct_def);
code_ += "";
}
}
// Generate the code to call the appropriate Verify function(s) for a field.
void GenVerifyCall(const FieldDef &field, const char *prefix) {
code_.SetValue("PRE", prefix);
@@ -2999,6 +3019,8 @@ class CppGenerator : public BaseGenerator {
// Generate code for tables that needs to come after the regular definition.
void GenTablePost(const StructDef &struct_def) {
if (opts_.generate_object_based_api) { GenNativeTablePost(struct_def); }
code_.SetValue("STRUCT_NAME", Name(struct_def));
code_.SetValue("NATIVE_NAME",
NativeName(Name(struct_def), &struct_def, opts_));