From 4ebe824087e8ccd7407454dca2f72d0524dca2b9 Mon Sep 17 00:00:00 2001 From: Alexander Gallego Date: Thu, 15 Feb 2018 17:58:06 -0500 Subject: [PATCH] C++: mini_reflect: Add DefaultTypeTable (#4614) * mini_reflect: Add DefaultTypeTable Currently it's very easy to make a mistake when it comes to instantiating the TypeTable to print a buffer because it is not type safe. This will allow us to write safer cpp code: flatbuffers::FlatBufferToString(reinterpret_cast(&t), decltype(t)::DefaultTypeTable()); * c++: mini_reflect: update generated code * Ensure types and names are set for mini_reflect * c++: mini_refelct: update unit tests with new typed TypeTable * Adding PR feedback of sylte and naming convention --- samples/monster_generated.h | 18 +++-- src/idl_gen_cpp.cpp | 27 ++++--- tests/monster_test_generated.h | 70 ++++++++++++------- .../namespace_test1_generated.h | 11 +-- .../namespace_test2_generated.h | 37 ++++++---- tests/test.cpp | 2 +- tests/union_vector/union_vector_generated.h | 22 +++--- 7 files changed, 119 insertions(+), 68 deletions(-) diff --git a/samples/monster_generated.h b/samples/monster_generated.h index baf3fe74ca2..32d44d00284 100644 --- a/samples/monster_generated.h +++ b/samples/monster_generated.h @@ -17,6 +17,12 @@ struct MonsterT; struct Weapon; struct WeaponT; +inline flatbuffers::TypeTable *Vec3TypeTable(); + +inline flatbuffers::TypeTable *MonsterTypeTable(); + +inline flatbuffers::TypeTable *WeaponTypeTable(); + enum Color { Color_Red = 0, Color_Green = 1, @@ -185,6 +191,9 @@ struct MonsterT : public flatbuffers::NativeTable { struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef MonsterT NativeTableType; + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return MonsterTypeTable(); + } enum { VT_POS = 4, VT_MANA = 6, @@ -384,6 +393,9 @@ struct WeaponT : public flatbuffers::NativeTable { struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef WeaponT NativeTableType; + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return WeaponTypeTable(); + } enum { VT_NAME = 4, VT_DAMAGE = 6 @@ -603,12 +615,6 @@ inline void EquipmentUnion::Reset() { type = Equipment_NONE; } -inline flatbuffers::TypeTable *Vec3TypeTable(); - -inline flatbuffers::TypeTable *MonsterTypeTable(); - -inline flatbuffers::TypeTable *WeaponTypeTable(); - inline flatbuffers::TypeTable *ColorTypeTable() { static flatbuffers::TypeCode type_codes[] = { { flatbuffers::ET_CHAR, 0, 0 }, diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 15f2f38c25c..ea01bf1c212 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -231,6 +231,18 @@ class CppGenerator : public BaseGenerator { code_ += ""; } } + // Generate preablmle code for mini reflection. + if (parser_.opts.mini_reflect != IDLOptions::kNone) { + // To break cyclic dependencies, first pre-declare all tables/structs. + for (auto it = parser_.structs_.vec.begin(); + it != parser_.structs_.vec.end(); ++it) { + const auto &struct_def = **it; + if (!struct_def.generated) { + SetNameSpace(struct_def.defined_namespace); + GenMiniReflectPre(&struct_def); + } + } + } // Generate code for all the enum declarations. for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); @@ -280,15 +292,6 @@ class CppGenerator : public BaseGenerator { // Generate code for mini reflection. if (parser_.opts.mini_reflect != IDLOptions::kNone) { - // To break cyclic dependencies, first pre-declare all tables/structs. - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (!struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - GenMiniReflectPre(&struct_def); - } - } // Then the unions/enums that may refer to them. for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); ++it) { @@ -1503,6 +1506,12 @@ class CppGenerator : public BaseGenerator { if (parser_.opts.generate_object_based_api) { code_ += " typedef {{NATIVE_NAME}} NativeTableType;"; } + if (parser_.opts.mini_reflect != IDLOptions::kNone) { + code_ += " static flatbuffers::TypeTable *MiniReflectTypeTable() {"; + code_ += " return {{STRUCT_NAME}}TypeTable();"; + code_ += " }"; + } + GenFullyQualifiedNameGetter(struct_def, Name(struct_def)); diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h index d2a0d505038..07813839e62 100644 --- a/tests/monster_test_generated.h +++ b/tests/monster_test_generated.h @@ -39,6 +39,32 @@ struct MonsterT; struct TypeAliases; struct TypeAliasesT; +} // namespace Example + +inline flatbuffers::TypeTable *InParentNamespaceTypeTable(); + +namespace Example2 { + +inline flatbuffers::TypeTable *MonsterTypeTable(); + +} // namespace Example2 + +namespace Example { + +inline flatbuffers::TypeTable *TestTypeTable(); + +inline flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable(); + +inline flatbuffers::TypeTable *Vec3TypeTable(); + +inline flatbuffers::TypeTable *AbilityTypeTable(); + +inline flatbuffers::TypeTable *StatTypeTable(); + +inline flatbuffers::TypeTable *MonsterTypeTable(); + +inline flatbuffers::TypeTable *TypeAliasesTypeTable(); + enum Color { Color_Red = 1, Color_Green = 2, @@ -332,6 +358,9 @@ struct InParentNamespaceT : public flatbuffers::NativeTable { struct InParentNamespace FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef InParentNamespaceT NativeTableType; + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return InParentNamespaceTypeTable(); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && verifier.EndTable(); @@ -374,6 +403,9 @@ struct MonsterT : public flatbuffers::NativeTable { struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef MonsterT NativeTableType; + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return MonsterTypeTable(); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && verifier.EndTable(); @@ -420,6 +452,9 @@ struct TestSimpleTableWithEnumT : public flatbuffers::NativeTable { struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef TestSimpleTableWithEnumT NativeTableType; + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return TestSimpleTableWithEnumTypeTable(); + } enum { VT_COLOR = 4 }; @@ -480,6 +515,9 @@ struct StatT : public flatbuffers::NativeTable { struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef StatT NativeTableType; + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return StatTypeTable(); + } enum { VT_ID = 4, VT_VAL = 6, @@ -623,6 +661,9 @@ struct MonsterT : public flatbuffers::NativeTable { /// an example documentation comment: monster object struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef MonsterT NativeTableType; + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return MonsterTypeTable(); + } enum { VT_POS = 4, VT_MANA = 6, @@ -1261,6 +1302,9 @@ struct TypeAliasesT : public flatbuffers::NativeTable { struct TypeAliases FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef TypeAliasesT NativeTableType; + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return TypeAliasesTypeTable(); + } enum { VT_I8 = 4, VT_U8 = 6, @@ -1890,32 +1934,6 @@ inline void AnyUnion::Reset() { type = Any_NONE; } -} // namespace Example - -inline flatbuffers::TypeTable *InParentNamespaceTypeTable(); - -namespace Example2 { - -inline flatbuffers::TypeTable *MonsterTypeTable(); - -} // namespace Example2 - -namespace Example { - -inline flatbuffers::TypeTable *TestTypeTable(); - -inline flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable(); - -inline flatbuffers::TypeTable *Vec3TypeTable(); - -inline flatbuffers::TypeTable *AbilityTypeTable(); - -inline flatbuffers::TypeTable *StatTypeTable(); - -inline flatbuffers::TypeTable *MonsterTypeTable(); - -inline flatbuffers::TypeTable *TypeAliasesTypeTable(); - inline flatbuffers::TypeTable *ColorTypeTable() { static flatbuffers::TypeCode type_codes[] = { { flatbuffers::ET_CHAR, 0, 0 }, diff --git a/tests/namespace_test/namespace_test1_generated.h b/tests/namespace_test/namespace_test1_generated.h index 47e6a2628c8..4b85249aecf 100644 --- a/tests/namespace_test/namespace_test1_generated.h +++ b/tests/namespace_test/namespace_test1_generated.h @@ -13,6 +13,10 @@ struct TableInNestedNS; struct StructInNestedNS; +inline flatbuffers::TypeTable *TableInNestedNSTypeTable(); + +inline flatbuffers::TypeTable *StructInNestedNSTypeTable(); + enum EnumInNestedNS { EnumInNestedNS_A = 0, EnumInNestedNS_B = 1, @@ -74,6 +78,9 @@ MANUALLY_ALIGNED_STRUCT(4) StructInNestedNS FLATBUFFERS_FINAL_CLASS { STRUCT_END(StructInNestedNS, 8); struct TableInNestedNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return TableInNestedNSTypeTable(); + } enum { VT_FOO = 4 }; @@ -116,10 +123,6 @@ inline flatbuffers::Offset CreateTableInNestedNS( return builder_.Finish(); } -inline flatbuffers::TypeTable *TableInNestedNSTypeTable(); - -inline flatbuffers::TypeTable *StructInNestedNSTypeTable(); - inline flatbuffers::TypeTable *EnumInNestedNSTypeTable() { static flatbuffers::TypeCode type_codes[] = { { flatbuffers::ET_CHAR, 0, 0 }, diff --git a/tests/namespace_test/namespace_test2_generated.h b/tests/namespace_test/namespace_test2_generated.h index a8818146998..510e1de3b1e 100644 --- a/tests/namespace_test/namespace_test2_generated.h +++ b/tests/namespace_test/namespace_test2_generated.h @@ -24,7 +24,24 @@ namespace NamespaceA { struct SecondTableInA; +inline flatbuffers::TypeTable *TableInFirstNSTypeTable(); + +} // namespace NamespaceA + +namespace NamespaceC { + +inline flatbuffers::TypeTable *TableInCTypeTable(); + +} // namespace NamespaceC + +namespace NamespaceA { + +inline flatbuffers::TypeTable *SecondTableInATypeTable(); + struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return TableInFirstNSTypeTable(); + } enum { VT_FOO_TABLE = 4, VT_FOO_ENUM = 6, @@ -99,6 +116,9 @@ inline flatbuffers::Offset CreateTableInFirstNS( namespace NamespaceC { struct TableInC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return TableInCTypeTable(); + } enum { VT_REFER_TO_A1 = 4, VT_REFER_TO_A2 = 6 @@ -161,6 +181,9 @@ inline flatbuffers::Offset CreateTableInC( namespace NamespaceA { struct SecondTableInA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return SecondTableInATypeTable(); + } enum { VT_REFER_TO_C = 4 }; @@ -212,20 +235,6 @@ namespace NamespaceC { namespace NamespaceA { -inline flatbuffers::TypeTable *TableInFirstNSTypeTable(); - -} // namespace NamespaceA - -namespace NamespaceC { - -inline flatbuffers::TypeTable *TableInCTypeTable(); - -} // namespace NamespaceC - -namespace NamespaceA { - -inline flatbuffers::TypeTable *SecondTableInATypeTable(); - inline flatbuffers::TypeTable *TableInFirstNSTypeTable() { static flatbuffers::TypeCode type_codes[] = { { flatbuffers::ET_SEQUENCE, 0, 0 }, diff --git a/tests/test.cpp b/tests/test.cpp index 0dea810c944..a89e56ddb46 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -819,7 +819,7 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) { } void MiniReflectFlatBuffersTest(uint8_t *flatbuf) { - auto s = flatbuffers::FlatBufferToString(flatbuf, MonsterTypeTable()); + auto s = flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable()); TEST_EQ_STR( s.c_str(), "{ " diff --git a/tests/union_vector/union_vector_generated.h b/tests/union_vector/union_vector_generated.h index 14c3cc91fe3..77de579edf5 100644 --- a/tests/union_vector/union_vector_generated.h +++ b/tests/union_vector/union_vector_generated.h @@ -16,6 +16,14 @@ struct BookReader; struct Movie; struct MovieT; +inline flatbuffers::TypeTable *AttackerTypeTable(); + +inline flatbuffers::TypeTable *RapunzelTypeTable(); + +inline flatbuffers::TypeTable *BookReaderTypeTable(); + +inline flatbuffers::TypeTable *MovieTypeTable(); + enum Character { Character_NONE = 0, Character_MuLan = 1, @@ -183,6 +191,9 @@ struct AttackerT : public flatbuffers::NativeTable { struct Attacker FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef AttackerT NativeTableType; + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return AttackerTypeTable(); + } enum { VT_SWORD_ATTACK_DAMAGE = 4 }; @@ -240,6 +251,9 @@ struct MovieT : public flatbuffers::NativeTable { struct Movie FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef MovieT NativeTableType; + static flatbuffers::TypeTable *MiniReflectTypeTable() { + return MovieTypeTable(); + } enum { VT_MAIN_CHARACTER_TYPE = 4, VT_MAIN_CHARACTER = 6, @@ -595,14 +609,6 @@ inline void CharacterUnion::Reset() { type = Character_NONE; } -inline flatbuffers::TypeTable *AttackerTypeTable(); - -inline flatbuffers::TypeTable *RapunzelTypeTable(); - -inline flatbuffers::TypeTable *BookReaderTypeTable(); - -inline flatbuffers::TypeTable *MovieTypeTable(); - inline flatbuffers::TypeTable *CharacterTypeTable() { static flatbuffers::TypeCode type_codes[] = { { flatbuffers::ET_SEQUENCE, 0, -1 },