From 641b397f8b79701b44184a52b5b9c6da98eb7580 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Fri, 2 Dec 2016 14:25:08 -0800 Subject: [PATCH] Allows structs to be stored directly as member variables. Introduce a "native_inline" attribute that can be applied on fields that are structs. This results in NativeTable code generation that sets the struct "inline" rather than storing it in a pointer. From cl/140527470. Change-Id: I208724f552b8b921b20923e0bf82f42cb3582416 --- include/flatbuffers/idl.h | 3 +++ src/idl_gen_cpp.cpp | 32 ++++++++++++++++++++++++++------ src/idl_parser.cpp | 8 +++++--- tests/monster_test.bfbs | Bin 3320 -> 3384 bytes 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 2440a19..1261031 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -234,6 +234,8 @@ struct FieldDef : public Definition { // written in new data nor accessed in new code. bool required; // Field must always be present. bool key; // Field functions as a key for creating sorted vectors. + bool native_inline; // Field will be defined inline (instead of as a pointer) + // for native tables if field is a struct. size_t padding; // Bytes to always pad after this field. }; @@ -454,6 +456,7 @@ class Parser : public ParserState { known_attributes_["idempotent"] = true; known_attributes_["cpp_type"] = true; known_attributes_["cpp_ptr_type"] = true; + known_attributes_["native_inline"] = true; } ~Parser() { diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 97cb355..7ca7d0b 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -332,7 +332,7 @@ class CppGenerator : public BaseGenerator { ">"; case BASE_TYPE_STRUCT: if (IsStruct(type)) { - if (invector) { + if (invector || field.native_inline) { return WrapInNameSpace(*type.struct_def); } else { return GenTypeNativePtr(WrapInNameSpace(*type.struct_def), &field, @@ -1016,7 +1016,7 @@ class CppGenerator : public BaseGenerator { return val + "->str()"; case BASE_TYPE_STRUCT: if (IsStruct(type)) { - if (invector) { + if (invector || afield.native_inline) { return "*" + val; } else { return GenTypeNativePtr(WrapInNameSpace(*type.struct_def), @@ -1059,7 +1059,11 @@ class CppGenerator : public BaseGenerator { code += "{ for (flatbuffers::uoffset_t _i = 0;"; code += " _i < _e->size(); _i++) { "; code += dest + ".push_back("; - std::string indexing = "_e->Get(_i)"; + std::string indexing; + if (field.value.type.enum_def) { + indexing += "(" + field.value.type.enum_def->name + ")"; + } + indexing += "_e->Get(_i)"; if (field.value.type.element == BASE_TYPE_BOOL) indexing += "!=0"; code += GenUnpackVal(field.value.type.VectorType(), @@ -1151,15 +1155,27 @@ class CppGenerator : public BaseGenerator { code += "_fbb.CreateVectorOfStructs(" + accessor + ")"; } else { code += "_fbb.CreateVectorname + ">>(" + accessor; + code += WrapInNameSpace(*vector_type.struct_def) + ">>(" + + accessor; code += ".size(), [&](size_t i) { return Create"; code += vector_type.struct_def->name + "(_fbb, " + accessor; code += "[i]" + GenPtrGet(field) + ", rehasher); })"; } break; - default: + case BASE_TYPE_BOOL: code += "_fbb.CreateVector(" + accessor + ")"; break; + default: { + std::string args = accessor; + if (field.value.type.enum_def) { + const std::string basetype = GenTypeBasic( + field.value.type.enum_def->underlying_type, false); + args = "(const " + basetype + "*)" + accessor + + ".data(), " + accessor + ".size()"; + } + code += "_fbb.CreateVector(" + args + ")"; + break; + } } code += postfix; break; @@ -1169,7 +1185,11 @@ class CppGenerator : public BaseGenerator { break; case BASE_TYPE_STRUCT: if (IsStruct(field.value.type)) { - code += ptrprefix + accessor + GenPtrGet(field) + postfix; + if (field.native_inline) { + code += "&" + accessor; + } else { + code += ptrprefix + accessor + GenPtrGet(field) + postfix; + } } else { code += ptrprefix + "Create"; code += field.value.type.struct_def->name; diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 0dc7392..ef6e1f5 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -680,6 +680,11 @@ CheckedError Parser::ParseField(StructDef &struct_def) { return Error("'key' field must be string or scalar type"); } } + + field->native_inline = field->attributes.Lookup("native_inline") != nullptr; + if (field->native_inline && !IsStruct(field->value.type)) + return Error("native_inline can only be defined on structs'"); + auto nested = field->attributes.Lookup("nested_flatbuffer"); if (nested) { if (nested->type.base_type != BASE_TYPE_STRING) @@ -1758,9 +1763,6 @@ CheckedError Parser::SkipAnyJsonValue() { case kTokenFloatConstant: EXPECT(kTokenFloatConstant); break; - case kTokenNull: - EXPECT(kTokenNull); - break; default: return Error(std::string("Unexpected token:") + std::string(1, static_cast(token_))); } diff --git a/tests/monster_test.bfbs b/tests/monster_test.bfbs index 66d3ee8f215a67b4978d70df9bdb2e6d344e89b8..0369f896935ecf0822e50268c42f9fa4dfb9da87 100644 GIT binary patch literal 3384 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 n?e~5