diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 2440a1901..126103195 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 97cb35564..7ca7d0bd2 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 0dc739240..ef6e1f512 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 66d3ee8f2..0369f8969 100644 Binary files a/tests/monster_test.bfbs and b/tests/monster_test.bfbs differ