Allow other pointer types than unique_ptr for object API.

Change-Id: I945890ce667a2f5a6c0495e78fd5326ed33b9914
Tested: on Linux.
Bug: 30135763
parent 424fc0c3
......@@ -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
......
......@@ -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() {
......
......@@ -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
......
......@@ -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
......
......@@ -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;
......
This diff is collapsed.
......@@ -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
......
......@@ -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());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment