From d9fe4e2769045f0b90f7a82c03c7a3693fd14fff Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen <wvo@google.com> Date: Wed, 12 Oct 2016 16:46:03 -0700 Subject: [PATCH] Allow other pointer types than unique_ptr for object API. Change-Id: I945890ce667a2f5a6c0495e78fd5326ed33b9914 Tested: on Linux. Bug: 30135763 --- docs/source/CppUsage.md | 11 ++- include/flatbuffers/idl.h | 3 + include/flatbuffers/reflection_generated.h | 20 +++- samples/monster_generated.h | 40 +++++--- src/flatc.cpp | 6 +- src/idl_gen_cpp.cpp | 110 ++++++++++++++------- tests/monster_test_generated.h | 72 +++++++++----- tests/test.cpp | 4 +- 8 files changed, 184 insertions(+), 82 deletions(-) diff --git a/docs/source/CppUsage.md b/docs/source/CppUsage.md index 88b6e455..4a9c78e6 100755 --- a/docs/source/CppUsage.md +++ b/docs/source/CppUsage.md @@ -99,7 +99,7 @@ construction, access and mutation. To use: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} - auto monsterobj = GetMonster(buffer)->UnPack(); + auto monsterobj = UnpackMonster(buffer); cout << monsterobj->name; // This is now a std::string! monsterobj->name = "Bob"; // Change the name. FlatBufferBuilder fbb; @@ -125,6 +125,15 @@ same string (or hash). When you call `UnPack` (or `Create`), you'll need a function that maps from hash to the object (see `resolver_function_t` for details). +# Using different pointer types. + +By default the object tree is built out of `std::unique_ptr`, but you can +influence this either globally (using the `--cpp-ptr-type` argument to +`flatc`) or per field (using the `cpp_ptr_type` attribute) to by any smart +pointer type (`my_ptr<T>`), or by specifying `naked` as the type to get `T *` +pointers. Unlike the smart pointers, naked pointers do not manage memory for +you, so you'll have to manage their lifecycles manually. + ## Reflection (& Resizing) There is experimental support for reflection in FlatBuffers, allowing you to diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 63788b74..2440a190 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -347,6 +347,7 @@ struct IDLOptions { bool generate_name_strings; bool escape_proto_identifiers; bool generate_object_based_api; + std::string cpp_object_api_pointer_type; bool union_value_namespacing; bool allow_non_utf8; @@ -370,6 +371,7 @@ struct IDLOptions { generate_name_strings(false), escape_proto_identifiers(false), generate_object_based_api(false), + cpp_object_api_pointer_type("std::unique_ptr"), union_value_namespacing(true), allow_non_utf8(false), lang(IDLOptions::kJava) {} @@ -451,6 +453,7 @@ class Parser : public ParserState { known_attributes_["streaming"] = true; known_attributes_["idempotent"] = true; known_attributes_["cpp_type"] = true; + known_attributes_["cpp_ptr_type"] = true; } ~Parser() { diff --git a/include/flatbuffers/reflection_generated.h b/include/flatbuffers/reflection_generated.h index 3bd1590f..e0452c88 100644 --- a/include/flatbuffers/reflection_generated.h +++ b/include/flatbuffers/reflection_generated.h @@ -529,17 +529,27 @@ inline flatbuffers::Offset<Schema> CreateSchemaDirect(flatbuffers::FlatBufferBui return CreateSchema(_fbb, objects ? _fbb.CreateVector<flatbuffers::Offset<Object>>(*objects) : 0, enums ? _fbb.CreateVector<flatbuffers::Offset<Enum>>(*enums) : 0, file_ident ? _fbb.CreateString(file_ident) : 0, file_ext ? _fbb.CreateString(file_ext) : 0, root_table); } -inline const reflection::Schema *GetSchema(const void *buf) { return flatbuffers::GetRoot<reflection::Schema>(buf); } +inline const reflection::Schema *GetSchema(const void *buf) { + return flatbuffers::GetRoot<reflection::Schema>(buf); +} -inline const char *SchemaIdentifier() { return "BFBS"; } +inline const char *SchemaIdentifier() { + return "BFBS"; +} -inline bool SchemaBufferHasIdentifier(const void *buf) { return flatbuffers::BufferHasIdentifier(buf, SchemaIdentifier()); } +inline bool SchemaBufferHasIdentifier(const void *buf) { + return flatbuffers::BufferHasIdentifier(buf, SchemaIdentifier()); +} -inline bool VerifySchemaBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier()); } +inline bool VerifySchemaBuffer(flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier()); +} inline const char *SchemaExtension() { return "bfbs"; } -inline void FinishSchemaBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<reflection::Schema> root) { fbb.Finish(root, SchemaIdentifier()); } +inline void FinishSchemaBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<reflection::Schema> root) { + fbb.Finish(root, SchemaIdentifier()); +} } // namespace reflection diff --git a/samples/monster_generated.h b/samples/monster_generated.h index 71e8b589..fa12e060 100644 --- a/samples/monster_generated.h +++ b/samples/monster_generated.h @@ -150,7 +150,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyEquipment(verifier, equipped(), equipped_type()) && verifier.EndTable(); } - std::unique_ptr<MonsterT> UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; + MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; }; struct MonsterBuilder { @@ -232,7 +232,7 @@ struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField<int16_t>(verifier, VT_DAMAGE) && verifier.EndTable(); } - std::unique_ptr<WeaponT> UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; + WeaponT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; }; struct WeaponBuilder { @@ -265,7 +265,8 @@ inline flatbuffers::Offset<Weapon> CreateWeaponDirect(flatbuffers::FlatBufferBui inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr); -inline std::unique_ptr<MonsterT> Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const { +inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const { + (void)resolver; auto _o = new MonsterT(); { auto _e = pos(); if (_e) _o->pos = std::unique_ptr<Vec3>(new Vec3(*_e)); }; { auto _e = mana(); _o->mana = _e; }; @@ -273,13 +274,14 @@ inline std::unique_ptr<MonsterT> Monster::UnPack(const flatbuffers::resolver_fun { auto _e = name(); if (_e) _o->name = _e->str(); }; { auto _e = inventory(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory.push_back(_e->Get(_i)); } } }; { auto _e = color(); _o->color = _e; }; - { auto _e = weapons(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons.push_back(_e->Get(_i)->UnPack(resolver)); } } }; + { auto _e = weapons(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons.push_back(std::unique_ptr<WeaponT>(_e->Get(_i)->UnPack(resolver))); } } }; { auto _e = equipped_type(); _o->equipped.type = _e; }; { auto _e = equipped(); if (_e) _o->equipped.table = EquipmentUnion::UnPack(_e, equipped_type(), resolver); }; - return std::unique_ptr<MonsterT>(_o); + return _o; } inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher) { + (void)rehasher; return CreateMonster(_fbb, _o->pos ? _o->pos.get() : 0, _o->mana, @@ -292,14 +294,16 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder _o->equipped.Pack(_fbb)); } -inline std::unique_ptr<WeaponT> Weapon::UnPack(const flatbuffers::resolver_function_t *resolver) const { +inline WeaponT *Weapon::UnPack(const flatbuffers::resolver_function_t *resolver) const { + (void)resolver; auto _o = new WeaponT(); { auto _e = name(); if (_e) _o->name = _e->str(); }; { auto _e = damage(); _o->damage = _e; }; - return std::unique_ptr<WeaponT>(_o); + return _o; } inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *rehasher) { + (void)rehasher; return CreateWeapon(_fbb, _o->name.size() ? _fbb.CreateString(_o->name) : 0, _o->damage); @@ -316,7 +320,7 @@ inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *union_o inline flatbuffers::NativeTable *EquipmentUnion::UnPack(const void *union_obj, Equipment type, const flatbuffers::resolver_function_t *resolver) { switch (type) { case Equipment_NONE: return nullptr; - case Equipment_Weapon: return reinterpret_cast<const Weapon *>(union_obj)->UnPack(resolver).release(); + case Equipment_Weapon: return reinterpret_cast<const Weapon *>(union_obj)->UnPack(resolver); default: return nullptr; } } @@ -336,13 +340,25 @@ inline EquipmentUnion::~EquipmentUnion() { } } -inline const MyGame::Sample::Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf); } +inline const MyGame::Sample::Monster *GetMonster(const void *buf) { + return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf); +} + +inline Monster *GetMutableMonster(void *buf) { + return flatbuffers::GetMutableRoot<Monster>(buf); +} -inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot<Monster>(buf); } +inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer<MyGame::Sample::Monster>(nullptr); +} -inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Sample::Monster>(nullptr); } +inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Sample::Monster> root) { + fbb.Finish(root); +} -inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Sample::Monster> root) { fbb.Finish(root); } +inline std::unique_ptr<MonsterT> UnPackMonster(const void *buf, const flatbuffers::resolver_function_t *resolver = nullptr) { + return std::unique_ptr<MonsterT>(GetMonster(buf)->UnPack(resolver)); +} } // namespace Sample } // namespace MyGame diff --git a/src/flatc.cpp b/src/flatc.cpp index bb9f395d..5f8340e0 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -126,7 +126,8 @@ static void Error(const std::string &err, bool usage, bool show_exe_name) { " --gen-onefile Generate single output file for C#.\n" " --gen-name-strings Generate type name functions for C++.\n" " --escape-proto-ids Disable appending '_' in namespaces names.\n" - " --gen-object-api Generate an additional object-based API\n" + " --gen-object-api Generate an additional object-based API.\n" + " --cpp-ptr-type T Set object API pointer type (default std::unique_ptr)\n" " --raw-binary Allow binaries without file_indentifier to be read.\n" " This may crash flatc given a mismatched schema.\n" " --proto Input is a .proto, translate to .fbs.\n" @@ -214,6 +215,9 @@ int main(int argc, const char *argv[]) { opts.generate_name_strings = true; } else if(arg == "--gen-object-api") { opts.generate_object_based_api = true; + } else if (arg == "--cpp-ptr-type") { + if (++argi >= argc) Error("missing type following" + arg, true); + opts.cpp_object_api_pointer_type = argv[argi]; } else if(arg == "--gen-all") { opts.generate_all = true; opts.include_dependence_headers = false; diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index ff32c16e..268ba80a 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -159,40 +159,40 @@ class CppGenerator : public BaseGenerator { // The root datatype accessor: code += "inline const " + cpp_qualified_name + " *Get"; code += name; - code += "(const void *buf) { return flatbuffers::GetRoot<"; - code += cpp_qualified_name + ">(buf); }\n\n"; + code += "(const void *buf) {\n return flatbuffers::GetRoot<"; + code += cpp_qualified_name + ">(buf);\n}\n\n"; if (parser_.opts.mutable_buffer) { code += "inline " + name + " *GetMutable"; code += name; - code += "(void *buf) { return flatbuffers::GetMutableRoot<"; - code += name + ">(buf); }\n\n"; + code += "(void *buf) {\n return flatbuffers::GetMutableRoot<"; + code += name + ">(buf);\n}\n\n"; } if (parser_.file_identifier_.length()) { // Return the identifier code += "inline const char *" + name; - code += "Identifier() { return \"" + parser_.file_identifier_; - code += "\"; }\n\n"; + code += "Identifier() {\n return \"" + parser_.file_identifier_; + code += "\";\n}\n\n"; // Check if a buffer has the identifier. code += "inline bool " + name; - code += "BufferHasIdentifier(const void *buf) { return flatbuffers::"; + code += "BufferHasIdentifier(const void *buf) {\n return flatbuffers::"; code += "BufferHasIdentifier(buf, "; - code += name + "Identifier()); }\n\n"; + code += name + "Identifier());\n}\n\n"; } // The root verifier: code += "inline bool Verify"; code += name; code += - "Buffer(flatbuffers::Verifier &verifier) { " - "return verifier.VerifyBuffer<"; + "Buffer(flatbuffers::Verifier &verifier) {\n" + " return verifier.VerifyBuffer<"; code += cpp_qualified_name + ">("; if (parser_.file_identifier_.length()) code += name + "Identifier()"; else code += "nullptr"; - code += "); }\n\n"; + code += ");\n}\n\n"; if (parser_.file_extension_.length()) { // Return the extension @@ -205,10 +205,22 @@ class CppGenerator : public BaseGenerator { code += "inline void Finish" + name; code += "Buffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<"; - code += cpp_qualified_name + "> root) { fbb.Finish(root"; + code += cpp_qualified_name + "> root) {\n fbb.Finish(root"; if (parser_.file_identifier_.length()) code += ", " + name + "Identifier()"; - code += "); }\n\n"; + code += ");\n}\n\n"; + + if (parser_.opts.generate_object_based_api) { + // A convenient root unpack function. + auto native_name = + NativeName(WrapInNameSpace(*parser_.root_struct_def_)); + code += "inline " + GenTypeNativePtr(native_name, nullptr, false); + code += " UnPack" + name; + code += "(const void *buf, const flatbuffers::resolver_function_t *"; + code += "resolver = nullptr) {\n return "; + code += GenTypeNativePtr(native_name, nullptr, true); + code += "(Get" + name + "(buf)->UnPack(resolver));\n}\n\n"; + } } assert(cur_name_space_); @@ -293,23 +305,42 @@ class CppGenerator : public BaseGenerator { // TODO(wvo): make this configurable. std::string NativeName(const std::string &name) { return name + "T"; } - std::string GenTypeNative(const Type &type, bool invector) { + const std::string &PtrType(const FieldDef *field) { + auto attr = field ? field->attributes.Lookup("cpp_ptr_type") : nullptr; + return attr ? attr->constant : parser_.opts.cpp_object_api_pointer_type; + } + + std::string GenTypeNativePtr(const std::string &type, const FieldDef *field, + bool is_constructor) { + auto &ptr_type = PtrType(field); + if (ptr_type == "naked") return is_constructor ? "" : type + " *"; + return ptr_type + "<" + type + ">"; + } + + std::string GenPtrGet(const FieldDef &field) { + auto &ptr_type = PtrType(&field); + return ptr_type == "naked" ? "" : ".get()"; + } + + std::string GenTypeNative(const Type &type, bool invector, + const FieldDef &field) { switch (type.base_type) { case BASE_TYPE_STRING: return "std::string"; case BASE_TYPE_VECTOR: - return "std::vector<" + GenTypeNative(type.VectorType(), true) + ">"; + return "std::vector<" + GenTypeNative(type.VectorType(), true, field) + + ">"; case BASE_TYPE_STRUCT: if (IsStruct(type)) { if (invector) { return WrapInNameSpace(*type.struct_def); } else { - return "std::unique_ptr<" + - WrapInNameSpace(*type.struct_def) + ">"; + return GenTypeNativePtr(WrapInNameSpace(*type.struct_def), &field, + false); } } else { - return "std::unique_ptr<" + - NativeName(WrapInNameSpace(*type.struct_def)) + ">"; + return GenTypeNativePtr(NativeName(WrapInNameSpace(*type.struct_def)), + &field, false); } case BASE_TYPE_UNION: return type.enum_def->name + "Union"; @@ -383,7 +414,7 @@ class CppGenerator : public BaseGenerator { } std::string TableUnPackSignature(StructDef &struct_def, bool inclass) { - return "std::unique_ptr<" + NativeName(struct_def.name) + "> " + + return NativeName(struct_def.name) + " *" + (inclass ? "" : struct_def.name + "::") + "UnPack(const flatbuffers::resolver_function_t *resolver" + (inclass ? " = nullptr" : "") + ") const"; @@ -490,7 +521,7 @@ class CppGenerator : public BaseGenerator { } code += "]; }\n\n"; } - + // Generate type traits for unions to map from a type to union enum value. if (enum_def.is_union) { for (auto it = enum_def.vals.vec.begin(); @@ -507,7 +538,7 @@ class CppGenerator : public BaseGenerator { code += "};\n\n"; } } - + if (enum_def.is_union) { code += UnionVerifySignature(enum_def) + ";\n\n"; } @@ -548,7 +579,7 @@ class CppGenerator : public BaseGenerator { } else { code += ": return reinterpret_cast<const "; code += WrapInNameSpace(*ev.struct_def); - code += " *>(union_obj)->UnPack(resolver).release();\n"; + code += " *>(union_obj)->UnPack(resolver);\n"; } } code += " default: return nullptr;\n }\n}\n\n"; @@ -662,7 +693,7 @@ class CppGenerator : public BaseGenerator { 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); + 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"; @@ -982,6 +1013,7 @@ class CppGenerator : public BaseGenerator { if (parser_.opts.generate_object_based_api) { // Generate the UnPack() method. code += "inline " + TableUnPackSignature(struct_def, false) + " {\n"; + code += " (void)resolver;\n"; code += " auto _o = new " + NativeName(struct_def.name) + "();\n"; for (auto it = struct_def.fields.vec.begin(); it != struct_def.fields.vec.end(); ++it) { @@ -993,7 +1025,8 @@ class CppGenerator : public BaseGenerator { auto dest = deref + field.name; auto assign = prefix + dest + " = "; auto gen_unpack_val = [&](const Type &type, const std::string &val, - bool invector) -> std::string { + bool invector, const FieldDef &afield) + -> std::string { switch (type.base_type) { case BASE_TYPE_STRING: return val + "->str()"; @@ -1002,13 +1035,15 @@ class CppGenerator : public BaseGenerator { if (invector) { return "*" + val; } else { - return "std::unique_ptr<" + - WrapInNameSpace (*type.struct_def) + - ">(new " + - WrapInNameSpace (*type.struct_def) + "(*" + val + "))"; + return GenTypeNativePtr(WrapInNameSpace(*type.struct_def), + &afield, true) + + "(new " + + WrapInNameSpace(*type.struct_def) + "(*" + val + "))"; } } else { - return val + "->UnPack(resolver)"; + return GenTypeNativePtr(NativeName(WrapInNameSpace( + *type.struct_def)), &afield, true) + + "(" + val + "->UnPack(resolver))"; } default: return val; @@ -1025,7 +1060,7 @@ class CppGenerator : public BaseGenerator { if (field.value.type.element == BASE_TYPE_BOOL) indexing += "!=0"; code += gen_unpack_val(field.value.type.VectorType(), - indexing, true); + indexing, true, field); code += "); } }"; break; } @@ -1052,7 +1087,7 @@ class CppGenerator : public BaseGenerator { code += dest + " = nullptr"; } else { code += assign; - code += gen_unpack_val(field.value.type, "_e", false); + code += gen_unpack_val(field.value.type, "_e", false, field); } code += ";"; break; @@ -1061,11 +1096,11 @@ class CppGenerator : public BaseGenerator { code += " };\n"; } } - code += " return std::unique_ptr<" + NativeName(struct_def.name); - code += ">(_o);\n}\n\n"; + code += " return _o;\n}\n\n"; // Generate a CreateX method that works with an unpacked C++ object. code += TableCreateSignature(struct_def, false) + " {\n"; + code += " (void)rehasher;\n"; auto before_return_statement = code.size(); code += " return Create"; code += struct_def.name + "(_fbb"; @@ -1116,7 +1151,7 @@ class CppGenerator : public BaseGenerator { code += vector_type.struct_def->name + ">>(" + accessor; code += ".size(), [&](size_t i) { return Create"; code += vector_type.struct_def->name + "(_fbb, " + accessor; - code += "[i].get(), rehasher); })"; + code += "[i]" + GenPtrGet(field) + ", rehasher); })"; } break; default: @@ -1131,11 +1166,12 @@ class CppGenerator : public BaseGenerator { break; case BASE_TYPE_STRUCT: if (IsStruct(field.value.type)) { - code += ptrprefix + accessor + ".get()" + postfix; + code += ptrprefix + accessor + GenPtrGet(field) + postfix; } else { code += ptrprefix + "Create"; code += field.value.type.struct_def->name; - code += "(_fbb, " + accessor + ".get(), rehasher)" + postfix; + code += "(_fbb, " + accessor + GenPtrGet(field) + ", rehasher)"; + code += postfix; } break; default: diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h index e4ea3f6b..6e8831e2 100644 --- a/tests/monster_test_generated.h +++ b/tests/monster_test_generated.h @@ -158,7 +158,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { return VerifyTableStart(verifier) && verifier.EndTable(); } - std::unique_ptr<MonsterT> UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; + MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; }; struct MonsterBuilder { @@ -198,7 +198,7 @@ struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Ta VerifyField<int8_t>(verifier, VT_COLOR) && verifier.EndTable(); } - std::unique_ptr<TestSimpleTableWithEnumT> UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; + TestSimpleTableWithEnumT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; }; struct TestSimpleTableWithEnumBuilder { @@ -248,7 +248,7 @@ struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField<uint16_t>(verifier, VT_COUNT) && verifier.EndTable(); } - std::unique_ptr<StatT> UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; + StatT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; }; struct StatBuilder { @@ -454,7 +454,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { verifier.VerifyVectorOfStrings(testarrayofstring2()) && verifier.EndTable(); } - std::unique_ptr<MonsterT> UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; + MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const; }; struct MonsterBuilder { @@ -596,12 +596,14 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder namespace Example2 { -inline std::unique_ptr<MonsterT> Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const { +inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const { + (void)resolver; auto _o = new MonsterT(); - return std::unique_ptr<MonsterT>(_o); + return _o; } inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher) { + (void)rehasher; (void)_o; return CreateMonster(_fbb); } @@ -610,33 +612,38 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder namespace Example { -inline std::unique_ptr<TestSimpleTableWithEnumT> TestSimpleTableWithEnum::UnPack(const flatbuffers::resolver_function_t *resolver) const { +inline TestSimpleTableWithEnumT *TestSimpleTableWithEnum::UnPack(const flatbuffers::resolver_function_t *resolver) const { + (void)resolver; auto _o = new TestSimpleTableWithEnumT(); { auto _e = color(); _o->color = _e; }; - return std::unique_ptr<TestSimpleTableWithEnumT>(_o); + return _o; } inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *rehasher) { + (void)rehasher; return CreateTestSimpleTableWithEnum(_fbb, _o->color); } -inline std::unique_ptr<StatT> Stat::UnPack(const flatbuffers::resolver_function_t *resolver) const { +inline StatT *Stat::UnPack(const flatbuffers::resolver_function_t *resolver) const { + (void)resolver; auto _o = new StatT(); { auto _e = id(); if (_e) _o->id = _e->str(); }; { auto _e = val(); _o->val = _e; }; { auto _e = count(); _o->count = _e; }; - return std::unique_ptr<StatT>(_o); + return _o; } inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *rehasher) { + (void)rehasher; return CreateStat(_fbb, _o->id.size() ? _fbb.CreateString(_o->id) : 0, _o->val, _o->count); } -inline std::unique_ptr<MonsterT> Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const { +inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const { + (void)resolver; auto _o = new MonsterT(); { auto _e = pos(); if (_e) _o->pos = std::unique_ptr<Vec3>(new Vec3(*_e)); }; { auto _e = mana(); _o->mana = _e; }; @@ -648,10 +655,10 @@ inline std::unique_ptr<MonsterT> Monster::UnPack(const flatbuffers::resolver_fun { auto _e = test(); if (_e) _o->test.table = AnyUnion::UnPack(_e, test_type(), resolver); }; { auto _e = test4(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4.push_back(*_e->Get(_i)); } } }; { auto _e = testarrayofstring(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring.push_back(_e->Get(_i)->str()); } } }; - { auto _e = testarrayoftables(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables.push_back(_e->Get(_i)->UnPack(resolver)); } } }; - { auto _e = enemy(); if (_e) _o->enemy = _e->UnPack(resolver); }; + { auto _e = testarrayoftables(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables.push_back(std::unique_ptr<MonsterT>(_e->Get(_i)->UnPack(resolver))); } } }; + { auto _e = enemy(); if (_e) _o->enemy = std::unique_ptr<MonsterT>(_e->UnPack(resolver)); }; { auto _e = testnestedflatbuffer(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer.push_back(_e->Get(_i)); } } }; - { auto _e = testempty(); if (_e) _o->testempty = _e->UnPack(resolver); }; + { auto _e = testempty(); if (_e) _o->testempty = std::unique_ptr<StatT>(_e->UnPack(resolver)); }; { auto _e = testbool(); _o->testbool = _e; }; { auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; }; { auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; }; @@ -666,10 +673,11 @@ inline std::unique_ptr<MonsterT> Monster::UnPack(const flatbuffers::resolver_fun { auto _e = testf2(); _o->testf2 = _e; }; { auto _e = testf3(); _o->testf3 = _e; }; { auto _e = testarrayofstring2(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring2.push_back(_e->Get(_i)->str()); } } }; - return std::unique_ptr<MonsterT>(_o); + return _o; } inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher) { + (void)rehasher; return CreateMonster(_fbb, _o->pos ? _o->pos.get() : 0, _o->mana, @@ -714,9 +722,9 @@ inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, An inline flatbuffers::NativeTable *AnyUnion::UnPack(const void *union_obj, Any type, const flatbuffers::resolver_function_t *resolver) { switch (type) { case Any_NONE: return nullptr; - case Any_Monster: return reinterpret_cast<const Monster *>(union_obj)->UnPack(resolver).release(); - case Any_TestSimpleTableWithEnum: return reinterpret_cast<const TestSimpleTableWithEnum *>(union_obj)->UnPack(resolver).release(); - case Any_MyGame_Example2_Monster: return reinterpret_cast<const MyGame::Example2::Monster *>(union_obj)->UnPack(resolver).release(); + case Any_Monster: return reinterpret_cast<const Monster *>(union_obj)->UnPack(resolver); + case Any_TestSimpleTableWithEnum: return reinterpret_cast<const TestSimpleTableWithEnum *>(union_obj)->UnPack(resolver); + case Any_MyGame_Example2_Monster: return reinterpret_cast<const MyGame::Example2::Monster *>(union_obj)->UnPack(resolver); default: return nullptr; } } @@ -740,19 +748,35 @@ inline AnyUnion::~AnyUnion() { } } -inline const MyGame::Example::Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<MyGame::Example::Monster>(buf); } +inline const MyGame::Example::Monster *GetMonster(const void *buf) { + return flatbuffers::GetRoot<MyGame::Example::Monster>(buf); +} -inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot<Monster>(buf); } +inline Monster *GetMutableMonster(void *buf) { + return flatbuffers::GetMutableRoot<Monster>(buf); +} -inline const char *MonsterIdentifier() { return "MONS"; } +inline const char *MonsterIdentifier() { + return "MONS"; +} -inline bool MonsterBufferHasIdentifier(const void *buf) { return flatbuffers::BufferHasIdentifier(buf, MonsterIdentifier()); } +inline bool MonsterBufferHasIdentifier(const void *buf) { + return flatbuffers::BufferHasIdentifier(buf, MonsterIdentifier()); +} -inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Example::Monster>(MonsterIdentifier()); } +inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer<MyGame::Example::Monster>(MonsterIdentifier()); +} inline const char *MonsterExtension() { return "mon"; } -inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Example::Monster> root) { fbb.Finish(root, MonsterIdentifier()); } +inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Example::Monster> root) { + fbb.Finish(root, MonsterIdentifier()); +} + +inline std::unique_ptr<MonsterT> UnPackMonster(const void *buf, const flatbuffers::resolver_function_t *resolver = nullptr) { + return std::unique_ptr<MonsterT>(GetMonster(buf)->UnPack(resolver)); +} } // namespace Example } // namespace MyGame diff --git a/tests/test.cpp b/tests/test.cpp index d6c709b6..f2854c67 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -326,7 +326,7 @@ void ObjectFlatBuffersTest(uint8_t *flatbuf) { }); // Turn a buffer into C++ objects. - auto monster1 = GetMonster(flatbuf)->UnPack(&resolver); + auto monster1 = UnPackMonster(flatbuf, &resolver); // Re-serialize the data. flatbuffers::FlatBufferBuilder fbb1; @@ -334,7 +334,7 @@ void ObjectFlatBuffersTest(uint8_t *flatbuf) { MonsterIdentifier()); // Unpack again, and re-serialize again. - auto monster2 = GetMonster(fbb1.GetBufferPointer())->UnPack(&resolver); + auto monster2 = UnPackMonster(fbb1.GetBufferPointer(), &resolver); flatbuffers::FlatBufferBuilder fbb2; fbb2.Finish(CreateMonster(fbb2, monster2.get(), &rehasher), MonsterIdentifier()); -- GitLab