Add support for fixed-size arrays (#5313)

This commit is contained in:
svenk177
2019-06-18 00:15:13 +02:00
committed by Wouter van Oortmerssen
parent 0d2cebccfe
commit e635141d5b
40 changed files with 2113 additions and 220 deletions

View File

@@ -697,6 +697,13 @@ class CppGenerator : public BaseGenerator {
bool user_facing_type) {
if (IsScalar(type.base_type)) {
return GenTypeBasic(type, user_facing_type) + afterbasic;
} else if (IsArray(type)) {
auto element_type = type.VectorType();
return beforeptr +
(IsScalar(element_type.base_type)
? GenTypeBasic(element_type, user_facing_type)
: GenTypePointer(element_type)) +
afterptr;
} else {
return beforeptr + GenTypePointer(type) + afterptr;
}
@@ -2689,7 +2696,8 @@ class CppGenerator : public BaseGenerator {
static void PaddingInitializer(int bits, std::string *code_ptr, int *id) {
(void)bits;
*code_ptr += ",\n padding" + NumToString((*id)++) + "__(0)";
if (*code_ptr != "") *code_ptr += ",\n ";
*code_ptr += "padding" + NumToString((*id)++) + "__(0)";
}
static void PaddingNoop(int bits, std::string *code_ptr, int *id) {
@@ -2717,10 +2725,14 @@ class CppGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
code_.SetValue("FIELD_TYPE",
GenTypeGet(field.value.type, " ", "", " ", false));
const auto &field_type = field.value.type;
code_.SetValue("FIELD_TYPE", GenTypeGet(field_type, " ", "", " ", false));
code_.SetValue("FIELD_NAME", Name(field));
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}_;";
code_.SetValue("ARRAY",
IsArray(field_type)
? "[" + NumToString(field_type.fixed_length) + "]"
: "");
code_ += (" {{FIELD_TYPE}}{{FIELD_NAME}}_{{ARRAY}};");
if (field.padding) {
std::string padding;
@@ -2745,33 +2757,40 @@ class CppGenerator : public BaseGenerator {
// Generate a default constructor.
code_ += " {{STRUCT_NAME}}() {";
code_ += " memset(static_cast<void *>(this), 0, sizeof({{STRUCT_NAME}}));";
code_ +=
" memset(static_cast<void *>(this), 0, sizeof({{STRUCT_NAME}}));";
code_ += " }";
// Generate a constructor that takes all fields as arguments.
// Generate a constructor that takes all fields as arguments,
// excluding arrays
std::string arg_list;
std::string init_list;
padding_id = 0;
auto first = struct_def.fields.vec.begin();
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
if (IsArray(field.value.type)) {
first++;
continue;
}
const auto member_name = Name(field) + "_";
const auto arg_name = "_" + Name(field);
const auto arg_type =
GenTypeGet(field.value.type, " ", "const ", " &", true);
if (it != struct_def.fields.vec.begin()) {
arg_list += ", ";
init_list += ",\n ";
}
if (it != first) { arg_list += ", "; }
arg_list += arg_type;
arg_list += arg_name;
init_list += member_name;
if (IsScalar(field.value.type.base_type)) {
auto type = GenUnderlyingCast(field, false, arg_name);
init_list += "(flatbuffers::EndianScalar(" + type + "))";
} else {
init_list += "(" + arg_name + ")";
if (!IsArray(field.value.type)) {
if (it != first && init_list != "") { init_list += ",\n "; }
init_list += member_name;
if (IsScalar(field.value.type.base_type)) {
auto type = GenUnderlyingCast(field, false, arg_name);
init_list += "(flatbuffers::EndianScalar(" + type + "))";
} else {
init_list += "(" + arg_name + ")";
}
}
if (field.padding) {
GenPadding(field, &init_list, &padding_id, PaddingInitializer);
@@ -2781,12 +2800,21 @@ class CppGenerator : public BaseGenerator {
if (!arg_list.empty()) {
code_.SetValue("ARG_LIST", arg_list);
code_.SetValue("INIT_LIST", init_list);
code_ += " {{STRUCT_NAME}}({{ARG_LIST}})";
code_ += " : {{INIT_LIST}} {";
if (!init_list.empty()) {
code_ += " {{STRUCT_NAME}}({{ARG_LIST}})";
code_ += " : {{INIT_LIST}} {";
} else {
code_ += " {{STRUCT_NAME}}({{ARG_LIST}}) {";
}
padding_id = 0;
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
if (IsArray(field.value.type)) {
const auto &member = Name(field) + "_";
code_ +=
" std::memset(" + member + ", 0, sizeof(" + member + "));";
}
if (field.padding) {
std::string padding;
GenPadding(field, &padding, &padding_id, PaddingNoop);
@@ -2802,7 +2830,9 @@ class CppGenerator : public BaseGenerator {
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
auto field_type = GenTypeGet(field.value.type, " ", "const ", " &", true);
auto field_type = GenTypeGet(field.value.type, " ",
IsArray(field.value.type) ? "" : "const ",
IsArray(field.value.type) ? "" : " &", true);
auto is_scalar = IsScalar(field.value.type.base_type);
auto member = Name(field) + "_";
auto value =
@@ -2813,12 +2843,29 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, value));
GenComment(field.doc_comment, " ");
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
code_ += " return {{FIELD_VALUE}};";
code_ += " }";
// Generate a const accessor function.
if (IsArray(field.value.type)) {
auto underlying = GenTypeGet(field.value.type, "", "", "", false);
code_ += " const flatbuffers::Array<" + field_type + ", " +
NumToString(field.value.type.fixed_length) + "> *" +
"{{FIELD_NAME}}() const {";
code_ += " return reinterpret_cast<const flatbuffers::Array<" +
field_type + ", " +
NumToString(field.value.type.fixed_length) +
"> *>({{FIELD_VALUE}});";
code_ += " }";
} else {
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
code_ += " return {{FIELD_VALUE}};";
code_ += " }";
}
// Generate a mutable accessor function.
if (parser_.opts.mutable_buffer) {
auto mut_field_type = GenTypeGet(field.value.type, " ", "", " &", true);
auto mut_field_type =
GenTypeGet(field.value.type, " ", "",
IsArray(field.value.type) ? "" : " &", true);
code_.SetValue("FIELD_TYPE", mut_field_type);
if (is_scalar) {
code_.SetValue("ARG", GenTypeBasic(field.value.type, true));
@@ -2830,9 +2877,19 @@ class CppGenerator : public BaseGenerator {
" flatbuffers::WriteScalar(&{{FIELD_NAME}}_, "
"{{FIELD_VALUE}});";
code_ += " }";
} else if (IsArray(field.value.type)) {
auto underlying = GenTypeGet(field.value.type, "", "", "", false);
code_ += " flatbuffers::Array<" + mut_field_type + ", " +
NumToString(field.value.type.fixed_length) +
"> *" + "mutable_{{FIELD_NAME}}() {";
code_ += " return reinterpret_cast<flatbuffers::Array<" +
mut_field_type + ", " +
NumToString(field.value.type.fixed_length) +
"> *>({{FIELD_VALUE}});";
code_ += " }";
} else {
code_ += " {{FIELD_TYPE}}mutable_{{FIELD_NAME}}() {";
code_ += " return {{FIELD_NAME}}_;";
code_ += " return {{FIELD_VALUE}};";
code_ += " }";
}
}