diff --git a/tests/cpp17/generated_cpp17/monster_test_generated.h b/tests/cpp17/generated_cpp17/monster_test_generated.h
new file mode 100644
index 0000000..77bc011
--- /dev/null
+++ b/tests/cpp17/generated_cpp17/monster_test_generated.h
@@ -0,0 +1,3346 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
+#define FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
+
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/flexbuffers.h"
+
+namespace MyGame {
+
+struct InParentNamespace;
+struct InParentNamespaceBuilder;
+struct InParentNamespaceT;
+
+namespace Example2 {
+
+struct Monster;
+struct MonsterBuilder;
+struct MonsterT;
+
+}  // namespace Example2
+
+namespace Example {
+
+struct Test;
+
+struct TestSimpleTableWithEnum;
+struct TestSimpleTableWithEnumBuilder;
+struct TestSimpleTableWithEnumT;
+
+struct Vec3;
+
+struct Ability;
+
+struct Stat;
+struct StatBuilder;
+struct StatT;
+
+struct Referrable;
+struct ReferrableBuilder;
+struct ReferrableT;
+
+struct Monster;
+struct MonsterBuilder;
+struct MonsterT;
+
+struct TypeAliases;
+struct TypeAliasesBuilder;
+struct TypeAliasesT;
+
+}  // namespace Example
+
+inline const flatbuffers::TypeTable *InParentNamespaceTypeTable();
+
+namespace Example2 {
+
+inline const flatbuffers::TypeTable *MonsterTypeTable();
+
+}  // namespace Example2
+
+namespace Example {
+
+inline const flatbuffers::TypeTable *TestTypeTable();
+
+inline const flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable();
+
+inline const flatbuffers::TypeTable *Vec3TypeTable();
+
+inline const flatbuffers::TypeTable *AbilityTypeTable();
+
+inline const flatbuffers::TypeTable *StatTypeTable();
+
+inline const flatbuffers::TypeTable *ReferrableTypeTable();
+
+inline const flatbuffers::TypeTable *MonsterTypeTable();
+
+inline const flatbuffers::TypeTable *TypeAliasesTypeTable();
+
+/// Composite components of Monster color.
+enum class Color : uint8_t {
+  Red = 1,
+  /// \brief color Green
+  /// Green is bit_flag with value (1u << 1)
+  Green = 2,
+  /// \brief color Blue (1u << 3)
+  Blue = 8,
+  NONE = 0,
+  ANY = 11
+};
+FLATBUFFERS_DEFINE_BITMASK_OPERATORS(Color, uint8_t)
+
+inline const Color (&EnumValuesColor())[3] {
+  static const Color values[] = {
+    Color::Red,
+    Color::Green,
+    Color::Blue
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesColor() {
+  static const char * const names[9] = {
+    "Red",
+    "Green",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "Blue",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameColor(Color e) {
+  if (flatbuffers::IsOutRange(e, Color::Red, Color::Blue)) return "";
+  const size_t index = static_cast<size_t>(e) - static_cast<size_t>(Color::Red);
+  return EnumNamesColor()[index];
+}
+
+enum class Race : int8_t {
+  None = -1,
+  Human = 0,
+  Dwarf = 1,
+  Elf = 2,
+  MIN = None,
+  MAX = Elf
+};
+
+inline const Race (&EnumValuesRace())[4] {
+  static const Race values[] = {
+    Race::None,
+    Race::Human,
+    Race::Dwarf,
+    Race::Elf
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesRace() {
+  static const char * const names[5] = {
+    "None",
+    "Human",
+    "Dwarf",
+    "Elf",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameRace(Race e) {
+  if (flatbuffers::IsOutRange(e, Race::None, Race::Elf)) return "";
+  const size_t index = static_cast<size_t>(e) - static_cast<size_t>(Race::None);
+  return EnumNamesRace()[index];
+}
+
+enum class Any : uint8_t {
+  NONE = 0,
+  Monster = 1,
+  TestSimpleTableWithEnum = 2,
+  MyGame_Example2_Monster = 3,
+  MIN = NONE,
+  MAX = MyGame_Example2_Monster
+};
+
+inline const Any (&EnumValuesAny())[4] {
+  static const Any values[] = {
+    Any::NONE,
+    Any::Monster,
+    Any::TestSimpleTableWithEnum,
+    Any::MyGame_Example2_Monster
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesAny() {
+  static const char * const names[5] = {
+    "NONE",
+    "Monster",
+    "TestSimpleTableWithEnum",
+    "MyGame_Example2_Monster",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameAny(Any e) {
+  if (flatbuffers::IsOutRange(e, Any::NONE, Any::MyGame_Example2_Monster)) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesAny()[index];
+}
+
+template<typename T> struct AnyTraits {
+  static const Any enum_value = Any::NONE;
+};
+
+template<> struct AnyTraits<MyGame::Example::Monster> {
+  static const Any enum_value = Any::Monster;
+};
+
+template<> struct AnyTraits<MyGame::Example::TestSimpleTableWithEnum> {
+  static const Any enum_value = Any::TestSimpleTableWithEnum;
+};
+
+template<> struct AnyTraits<MyGame::Example2::Monster> {
+  static const Any enum_value = Any::MyGame_Example2_Monster;
+};
+
+struct AnyUnion {
+  Any type;
+  void *value;
+
+  AnyUnion() : type(Any::NONE), value(nullptr) {}
+  AnyUnion(AnyUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(Any::NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  AnyUnion(const AnyUnion &);
+  AnyUnion &operator=(const AnyUnion &u)
+    { AnyUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  AnyUnion &operator=(AnyUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~AnyUnion() { Reset(); }
+
+  void Reset();
+
+#ifndef FLATBUFFERS_CPP98_STL
+  template <typename T>
+  void Set(T&& val) {
+    using RT = typename std::remove_reference<T>::type;
+    Reset();
+    type = AnyTraits<typename RT::TableType>::enum_value;
+    if (type != Any::NONE) {
+      value = new RT(std::forward<T>(val));
+    }
+  }
+#endif  // FLATBUFFERS_CPP98_STL
+
+  static void *UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  MyGame::Example::MonsterT *AsMonster() {
+    return type == Any::Monster ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsMonster() const {
+    return type == Any::Monster ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() {
+    return type == Any::TestSimpleTableWithEnum ?
+      reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() const {
+    return type == Any::TestSimpleTableWithEnum ?
+      reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  MyGame::Example2::MonsterT *AsMyGame_Example2_Monster() {
+    return type == Any::MyGame_Example2_Monster ?
+      reinterpret_cast<MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example2::MonsterT *AsMyGame_Example2_Monster() const {
+    return type == Any::MyGame_Example2_Monster ?
+      reinterpret_cast<const MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+};
+
+bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type);
+bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+enum class AnyUniqueAliases : uint8_t {
+  NONE = 0,
+  M = 1,
+  TS = 2,
+  M2 = 3,
+  MIN = NONE,
+  MAX = M2
+};
+
+inline const AnyUniqueAliases (&EnumValuesAnyUniqueAliases())[4] {
+  static const AnyUniqueAliases values[] = {
+    AnyUniqueAliases::NONE,
+    AnyUniqueAliases::M,
+    AnyUniqueAliases::TS,
+    AnyUniqueAliases::M2
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesAnyUniqueAliases() {
+  static const char * const names[5] = {
+    "NONE",
+    "M",
+    "TS",
+    "M2",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameAnyUniqueAliases(AnyUniqueAliases e) {
+  if (flatbuffers::IsOutRange(e, AnyUniqueAliases::NONE, AnyUniqueAliases::M2)) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesAnyUniqueAliases()[index];
+}
+
+template<typename T> struct AnyUniqueAliasesTraits {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases::NONE;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example::Monster> {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases::M;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example::TestSimpleTableWithEnum> {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases::TS;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example2::Monster> {
+  static const AnyUniqueAliases enum_value = AnyUniqueAliases::M2;
+};
+
+struct AnyUniqueAliasesUnion {
+  AnyUniqueAliases type;
+  void *value;
+
+  AnyUniqueAliasesUnion() : type(AnyUniqueAliases::NONE), value(nullptr) {}
+  AnyUniqueAliasesUnion(AnyUniqueAliasesUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(AnyUniqueAliases::NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &);
+  AnyUniqueAliasesUnion &operator=(const AnyUniqueAliasesUnion &u)
+    { AnyUniqueAliasesUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  AnyUniqueAliasesUnion &operator=(AnyUniqueAliasesUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~AnyUniqueAliasesUnion() { Reset(); }
+
+  void Reset();
+
+#ifndef FLATBUFFERS_CPP98_STL
+  template <typename T>
+  void Set(T&& val) {
+    using RT = typename std::remove_reference<T>::type;
+    Reset();
+    type = AnyUniqueAliasesTraits<typename RT::TableType>::enum_value;
+    if (type != AnyUniqueAliases::NONE) {
+      value = new RT(std::forward<T>(val));
+    }
+  }
+#endif  // FLATBUFFERS_CPP98_STL
+
+  static void *UnPack(const void *obj, AnyUniqueAliases type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  MyGame::Example::MonsterT *AsM() {
+    return type == AnyUniqueAliases::M ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM() const {
+    return type == AnyUniqueAliases::M ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::TestSimpleTableWithEnumT *AsTS() {
+    return type == AnyUniqueAliases::TS ?
+      reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnumT *AsTS() const {
+    return type == AnyUniqueAliases::TS ?
+      reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+  }
+  MyGame::Example2::MonsterT *AsM2() {
+    return type == AnyUniqueAliases::M2 ?
+      reinterpret_cast<MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example2::MonsterT *AsM2() const {
+    return type == AnyUniqueAliases::M2 ?
+      reinterpret_cast<const MyGame::Example2::MonsterT *>(value) : nullptr;
+  }
+};
+
+bool VerifyAnyUniqueAliases(flatbuffers::Verifier &verifier, const void *obj, AnyUniqueAliases type);
+bool VerifyAnyUniqueAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+enum class AnyAmbiguousAliases : uint8_t {
+  NONE = 0,
+  M1 = 1,
+  M2 = 2,
+  M3 = 3,
+  MIN = NONE,
+  MAX = M3
+};
+
+inline const AnyAmbiguousAliases (&EnumValuesAnyAmbiguousAliases())[4] {
+  static const AnyAmbiguousAliases values[] = {
+    AnyAmbiguousAliases::NONE,
+    AnyAmbiguousAliases::M1,
+    AnyAmbiguousAliases::M2,
+    AnyAmbiguousAliases::M3
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesAnyAmbiguousAliases() {
+  static const char * const names[5] = {
+    "NONE",
+    "M1",
+    "M2",
+    "M3",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameAnyAmbiguousAliases(AnyAmbiguousAliases e) {
+  if (flatbuffers::IsOutRange(e, AnyAmbiguousAliases::NONE, AnyAmbiguousAliases::M3)) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesAnyAmbiguousAliases()[index];
+}
+
+struct AnyAmbiguousAliasesUnion {
+  AnyAmbiguousAliases type;
+  void *value;
+
+  AnyAmbiguousAliasesUnion() : type(AnyAmbiguousAliases::NONE), value(nullptr) {}
+  AnyAmbiguousAliasesUnion(AnyAmbiguousAliasesUnion&& u) FLATBUFFERS_NOEXCEPT :
+    type(AnyAmbiguousAliases::NONE), value(nullptr)
+    { std::swap(type, u.type); std::swap(value, u.value); }
+  AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &);
+  AnyAmbiguousAliasesUnion &operator=(const AnyAmbiguousAliasesUnion &u)
+    { AnyAmbiguousAliasesUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+  AnyAmbiguousAliasesUnion &operator=(AnyAmbiguousAliasesUnion &&u) FLATBUFFERS_NOEXCEPT
+    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+  ~AnyAmbiguousAliasesUnion() { Reset(); }
+
+  void Reset();
+
+  static void *UnPack(const void *obj, AnyAmbiguousAliases type, const flatbuffers::resolver_function_t *resolver);
+  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+  MyGame::Example::MonsterT *AsM1() {
+    return type == AnyAmbiguousAliases::M1 ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM1() const {
+    return type == AnyAmbiguousAliases::M1 ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::MonsterT *AsM2() {
+    return type == AnyAmbiguousAliases::M2 ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM2() const {
+    return type == AnyAmbiguousAliases::M2 ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  MyGame::Example::MonsterT *AsM3() {
+    return type == AnyAmbiguousAliases::M3 ?
+      reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+  const MyGame::Example::MonsterT *AsM3() const {
+    return type == AnyAmbiguousAliases::M3 ?
+      reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+  }
+};
+
+bool VerifyAnyAmbiguousAliases(flatbuffers::Verifier &verifier, const void *obj, AnyAmbiguousAliases type);
+bool VerifyAnyAmbiguousAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(2) Test FLATBUFFERS_FINAL_CLASS {
+ private:
+  int16_t a_;
+  int8_t b_;
+  int8_t padding0__;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TestTypeTable();
+  }
+  Test()
+      : a_(0),
+        b_(0),
+        padding0__(0) {
+    (void)padding0__;
+  }
+  Test(int16_t _a, int8_t _b)
+      : a_(flatbuffers::EndianScalar(_a)),
+        b_(flatbuffers::EndianScalar(_b)),
+        padding0__(0) {
+    (void)padding0__;
+  }
+  int16_t a() const {
+    return flatbuffers::EndianScalar(a_);
+  }
+  void mutate_a(int16_t _a) {
+    flatbuffers::WriteScalar(&a_, _a);
+  }
+  int8_t b() const {
+    return flatbuffers::EndianScalar(b_);
+  }
+  void mutate_b(int8_t _b) {
+    flatbuffers::WriteScalar(&b_, _b);
+  }
+};
+FLATBUFFERS_STRUCT_END(Test, 4);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Vec3 FLATBUFFERS_FINAL_CLASS {
+ private:
+  float x_;
+  float y_;
+  float z_;
+  int32_t padding0__;
+  double test1_;
+  uint8_t test2_;
+  int8_t padding1__;
+  MyGame::Example::Test test3_;
+  int16_t padding2__;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return Vec3TypeTable();
+  }
+  Vec3()
+      : x_(0),
+        y_(0),
+        z_(0),
+        padding0__(0),
+        test1_(0),
+        test2_(0),
+        padding1__(0),
+        test3_(),
+        padding2__(0) {
+    (void)padding0__;
+    (void)padding1__;
+    (void)padding2__;
+  }
+  Vec3(float _x, float _y, float _z, double _test1, MyGame::Example::Color _test2, const MyGame::Example::Test &_test3)
+      : x_(flatbuffers::EndianScalar(_x)),
+        y_(flatbuffers::EndianScalar(_y)),
+        z_(flatbuffers::EndianScalar(_z)),
+        padding0__(0),
+        test1_(flatbuffers::EndianScalar(_test1)),
+        test2_(flatbuffers::EndianScalar(static_cast<uint8_t>(_test2))),
+        padding1__(0),
+        test3_(_test3),
+        padding2__(0) {
+    (void)padding0__;
+    (void)padding1__;
+    (void)padding2__;
+  }
+  float x() const {
+    return flatbuffers::EndianScalar(x_);
+  }
+  void mutate_x(float _x) {
+    flatbuffers::WriteScalar(&x_, _x);
+  }
+  float y() const {
+    return flatbuffers::EndianScalar(y_);
+  }
+  void mutate_y(float _y) {
+    flatbuffers::WriteScalar(&y_, _y);
+  }
+  float z() const {
+    return flatbuffers::EndianScalar(z_);
+  }
+  void mutate_z(float _z) {
+    flatbuffers::WriteScalar(&z_, _z);
+  }
+  double test1() const {
+    return flatbuffers::EndianScalar(test1_);
+  }
+  void mutate_test1(double _test1) {
+    flatbuffers::WriteScalar(&test1_, _test1);
+  }
+  MyGame::Example::Color test2() const {
+    return static_cast<MyGame::Example::Color>(flatbuffers::EndianScalar(test2_));
+  }
+  void mutate_test2(MyGame::Example::Color _test2) {
+    flatbuffers::WriteScalar(&test2_, static_cast<uint8_t>(_test2));
+  }
+  const MyGame::Example::Test &test3() const {
+    return test3_;
+  }
+  MyGame::Example::Test &mutable_test3() {
+    return test3_;
+  }
+};
+FLATBUFFERS_STRUCT_END(Vec3, 32);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Ability FLATBUFFERS_FINAL_CLASS {
+ private:
+  uint32_t id_;
+  uint32_t distance_;
+
+ public:
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return AbilityTypeTable();
+  }
+  Ability()
+      : id_(0),
+        distance_(0) {
+  }
+  Ability(uint32_t _id, uint32_t _distance)
+      : id_(flatbuffers::EndianScalar(_id)),
+        distance_(flatbuffers::EndianScalar(_distance)) {
+  }
+  uint32_t id() const {
+    return flatbuffers::EndianScalar(id_);
+  }
+  void mutate_id(uint32_t _id) {
+    flatbuffers::WriteScalar(&id_, _id);
+  }
+  bool KeyCompareLessThan(const Ability *o) const {
+    return id() < o->id();
+  }
+  int KeyCompareWithValue(uint32_t val) const {
+    return static_cast<int>(id() > val) - static_cast<int>(id() < val);
+  }
+  uint32_t distance() const {
+    return flatbuffers::EndianScalar(distance_);
+  }
+  void mutate_distance(uint32_t _distance) {
+    flatbuffers::WriteScalar(&distance_, _distance);
+  }
+};
+FLATBUFFERS_STRUCT_END(Ability, 8);
+
+}  // namespace Example
+
+struct InParentNamespaceT : public flatbuffers::NativeTable {
+  typedef InParentNamespace TableType;
+};
+
+struct InParentNamespace FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef InParentNamespaceT NativeTableType;
+  typedef InParentNamespaceBuilder Builder;
+  struct Traits;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return InParentNamespaceTypeTable();
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           verifier.EndTable();
+  }
+  InParentNamespaceT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(InParentNamespaceT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<InParentNamespace> Pack(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct InParentNamespaceBuilder {
+  typedef InParentNamespace Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  explicit InParentNamespaceBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  flatbuffers::Offset<InParentNamespace> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<InParentNamespace>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(
+    flatbuffers::FlatBufferBuilder &_fbb) {
+  InParentNamespaceBuilder builder_(_fbb);
+  return builder_.Finish();
+}
+
+struct InParentNamespace::Traits {
+  using type = InParentNamespace;
+  static auto constexpr Create = CreateInParentNamespace;
+};
+
+flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+namespace Example2 {
+
+struct MonsterT : public flatbuffers::NativeTable {
+  typedef Monster TableType;
+};
+
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
+  typedef MonsterBuilder Builder;
+  struct Traits;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MonsterTypeTable();
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           verifier.EndTable();
+  }
+  MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct MonsterBuilder {
+  typedef Monster Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  flatbuffers::Offset<Monster> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Monster>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Monster> CreateMonster(
+    flatbuffers::FlatBufferBuilder &_fbb) {
+  MonsterBuilder builder_(_fbb);
+  return builder_.Finish();
+}
+
+struct Monster::Traits {
+  using type = Monster;
+  static auto constexpr Create = CreateMonster;
+};
+
+flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+}  // namespace Example2
+
+namespace Example {
+
+struct TestSimpleTableWithEnumT : public flatbuffers::NativeTable {
+  typedef TestSimpleTableWithEnum TableType;
+  MyGame::Example::Color color = MyGame::Example::Color::Green;
+};
+
+struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TestSimpleTableWithEnumT NativeTableType;
+  typedef TestSimpleTableWithEnumBuilder Builder;
+  struct Traits;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TestSimpleTableWithEnumTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_COLOR = 4
+  };
+  MyGame::Example::Color color() const {
+    return static_cast<MyGame::Example::Color>(GetField<uint8_t>(VT_COLOR, 2));
+  }
+  bool mutate_color(MyGame::Example::Color _color) {
+    return SetField<uint8_t>(VT_COLOR, static_cast<uint8_t>(_color), 2);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<uint8_t>(verifier, VT_COLOR) &&
+           verifier.EndTable();
+  }
+  TestSimpleTableWithEnumT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<TestSimpleTableWithEnum> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct TestSimpleTableWithEnumBuilder {
+  typedef TestSimpleTableWithEnum Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_color(MyGame::Example::Color color) {
+    fbb_.AddElement<uint8_t>(TestSimpleTableWithEnum::VT_COLOR, static_cast<uint8_t>(color), 2);
+  }
+  explicit TestSimpleTableWithEnumBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  flatbuffers::Offset<TestSimpleTableWithEnum> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TestSimpleTableWithEnum>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    MyGame::Example::Color color = MyGame::Example::Color::Green) {
+  TestSimpleTableWithEnumBuilder builder_(_fbb);
+  builder_.add_color(color);
+  return builder_.Finish();
+}
+
+struct TestSimpleTableWithEnum::Traits {
+  using type = TestSimpleTableWithEnum;
+  static auto constexpr Create = CreateTestSimpleTableWithEnum;
+};
+
+flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct StatT : public flatbuffers::NativeTable {
+  typedef Stat TableType;
+  std::string id{};
+  int64_t val = 0;
+  uint16_t count = 0;
+};
+
+struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef StatT NativeTableType;
+  typedef StatBuilder Builder;
+  struct Traits;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return StatTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_ID = 4,
+    VT_VAL = 6,
+    VT_COUNT = 8
+  };
+  const flatbuffers::String *id() const {
+    return GetPointer<const flatbuffers::String *>(VT_ID);
+  }
+  flatbuffers::String *mutable_id() {
+    return GetPointer<flatbuffers::String *>(VT_ID);
+  }
+  int64_t val() const {
+    return GetField<int64_t>(VT_VAL, 0);
+  }
+  bool mutate_val(int64_t _val) {
+    return SetField<int64_t>(VT_VAL, _val, 0);
+  }
+  uint16_t count() const {
+    return GetField<uint16_t>(VT_COUNT, 0);
+  }
+  bool mutate_count(uint16_t _count) {
+    return SetField<uint16_t>(VT_COUNT, _count, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_ID) &&
+           verifier.VerifyString(id()) &&
+           VerifyField<int64_t>(verifier, VT_VAL) &&
+           VerifyField<uint16_t>(verifier, VT_COUNT) &&
+           verifier.EndTable();
+  }
+  StatT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Stat> Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct StatBuilder {
+  typedef Stat Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_id(flatbuffers::Offset<flatbuffers::String> id) {
+    fbb_.AddOffset(Stat::VT_ID, id);
+  }
+  void add_val(int64_t val) {
+    fbb_.AddElement<int64_t>(Stat::VT_VAL, val, 0);
+  }
+  void add_count(uint16_t count) {
+    fbb_.AddElement<uint16_t>(Stat::VT_COUNT, count, 0);
+  }
+  explicit StatBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  flatbuffers::Offset<Stat> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Stat>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Stat> CreateStat(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> id = 0,
+    int64_t val = 0,
+    uint16_t count = 0) {
+  StatBuilder builder_(_fbb);
+  builder_.add_val(val);
+  builder_.add_id(id);
+  builder_.add_count(count);
+  return builder_.Finish();
+}
+
+struct Stat::Traits {
+  using type = Stat;
+  static auto constexpr Create = CreateStat;
+};
+
+inline flatbuffers::Offset<Stat> CreateStatDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *id = nullptr,
+    int64_t val = 0,
+    uint16_t count = 0) {
+  auto id__ = id ? _fbb.CreateString(id) : 0;
+  return MyGame::Example::CreateStat(
+      _fbb,
+      id__,
+      val,
+      count);
+}
+
+flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct ReferrableT : public flatbuffers::NativeTable {
+  typedef Referrable TableType;
+  uint64_t id = 0;
+};
+
+struct Referrable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ReferrableT NativeTableType;
+  typedef ReferrableBuilder Builder;
+  struct Traits;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ReferrableTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_ID = 4
+  };
+  uint64_t id() const {
+    return GetField<uint64_t>(VT_ID, 0);
+  }
+  bool mutate_id(uint64_t _id) {
+    return SetField<uint64_t>(VT_ID, _id, 0);
+  }
+  bool KeyCompareLessThan(const Referrable *o) const {
+    return id() < o->id();
+  }
+  int KeyCompareWithValue(uint64_t val) const {
+    return static_cast<int>(id() > val) - static_cast<int>(id() < val);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<uint64_t>(verifier, VT_ID) &&
+           verifier.EndTable();
+  }
+  ReferrableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(ReferrableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Referrable> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ReferrableBuilder {
+  typedef Referrable Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_id(uint64_t id) {
+    fbb_.AddElement<uint64_t>(Referrable::VT_ID, id, 0);
+  }
+  explicit ReferrableBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  flatbuffers::Offset<Referrable> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Referrable>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Referrable> CreateReferrable(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    uint64_t id = 0) {
+  ReferrableBuilder builder_(_fbb);
+  builder_.add_id(id);
+  return builder_.Finish();
+}
+
+struct Referrable::Traits {
+  using type = Referrable;
+  static auto constexpr Create = CreateReferrable;
+};
+
+flatbuffers::Offset<Referrable> CreateReferrable(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct MonsterT : public flatbuffers::NativeTable {
+  typedef Monster TableType;
+  std::unique_ptr<MyGame::Example::Vec3> pos{};
+  int16_t mana = 150;
+  int16_t hp = 100;
+  std::string name{};
+  std::vector<uint8_t> inventory{};
+  MyGame::Example::Color color = MyGame::Example::Color::Blue;
+  MyGame::Example::AnyUnion test{};
+  std::vector<MyGame::Example::Test> test4{};
+  std::vector<std::string> testarrayofstring{};
+  std::vector<std::unique_ptr<MyGame::Example::MonsterT>> testarrayoftables{};
+  std::unique_ptr<MyGame::Example::MonsterT> enemy{};
+  std::vector<uint8_t> testnestedflatbuffer{};
+  std::unique_ptr<MyGame::Example::StatT> testempty{};
+  bool testbool = false;
+  int32_t testhashs32_fnv1 = 0;
+  uint32_t testhashu32_fnv1 = 0;
+  int64_t testhashs64_fnv1 = 0;
+  uint64_t testhashu64_fnv1 = 0;
+  int32_t testhashs32_fnv1a = 0;
+  Stat *testhashu32_fnv1a = nullptr;
+  int64_t testhashs64_fnv1a = 0;
+  uint64_t testhashu64_fnv1a = 0;
+  std::vector<bool> testarrayofbools{};
+  float testf = 3.14159f;
+  float testf2 = 3.0f;
+  float testf3 = 0.0f;
+  std::vector<std::string> testarrayofstring2{};
+  std::vector<MyGame::Example::Ability> testarrayofsortedstruct{};
+  std::vector<uint8_t> flex{};
+  std::vector<MyGame::Example::Test> test5{};
+  std::vector<int64_t> vector_of_longs{};
+  std::vector<double> vector_of_doubles{};
+  std::unique_ptr<MyGame::InParentNamespaceT> parent_namespace_test{};
+  std::vector<std::unique_ptr<MyGame::Example::ReferrableT>> vector_of_referrables{};
+  ReferrableT *single_weak_reference = nullptr;
+  std::vector<ReferrableT *> vector_of_weak_references{};
+  std::vector<std::unique_ptr<MyGame::Example::ReferrableT>> vector_of_strong_referrables{};
+  ReferrableT *co_owning_reference = nullptr;
+  std::vector<std::unique_ptr<ReferrableT>> vector_of_co_owning_references{};
+  ReferrableT *non_owning_reference = nullptr;
+  std::vector<ReferrableT *> vector_of_non_owning_references{};
+  MyGame::Example::AnyUniqueAliasesUnion any_unique{};
+  MyGame::Example::AnyAmbiguousAliasesUnion any_ambiguous{};
+  std::vector<MyGame::Example::Color> vector_of_enums{};
+  MyGame::Example::Race signed_enum = MyGame::Example::Race::None;
+  std::vector<uint8_t> testrequirednestedflatbuffer{};
+};
+
+/// an example documentation comment: "monster object"
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
+  typedef MonsterBuilder Builder;
+  struct Traits;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return MonsterTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_POS = 4,
+    VT_MANA = 6,
+    VT_HP = 8,
+    VT_NAME = 10,
+    VT_INVENTORY = 14,
+    VT_COLOR = 16,
+    VT_TEST_TYPE = 18,
+    VT_TEST = 20,
+    VT_TEST4 = 22,
+    VT_TESTARRAYOFSTRING = 24,
+    VT_TESTARRAYOFTABLES = 26,
+    VT_ENEMY = 28,
+    VT_TESTNESTEDFLATBUFFER = 30,
+    VT_TESTEMPTY = 32,
+    VT_TESTBOOL = 34,
+    VT_TESTHASHS32_FNV1 = 36,
+    VT_TESTHASHU32_FNV1 = 38,
+    VT_TESTHASHS64_FNV1 = 40,
+    VT_TESTHASHU64_FNV1 = 42,
+    VT_TESTHASHS32_FNV1A = 44,
+    VT_TESTHASHU32_FNV1A = 46,
+    VT_TESTHASHS64_FNV1A = 48,
+    VT_TESTHASHU64_FNV1A = 50,
+    VT_TESTARRAYOFBOOLS = 52,
+    VT_TESTF = 54,
+    VT_TESTF2 = 56,
+    VT_TESTF3 = 58,
+    VT_TESTARRAYOFSTRING2 = 60,
+    VT_TESTARRAYOFSORTEDSTRUCT = 62,
+    VT_FLEX = 64,
+    VT_TEST5 = 66,
+    VT_VECTOR_OF_LONGS = 68,
+    VT_VECTOR_OF_DOUBLES = 70,
+    VT_PARENT_NAMESPACE_TEST = 72,
+    VT_VECTOR_OF_REFERRABLES = 74,
+    VT_SINGLE_WEAK_REFERENCE = 76,
+    VT_VECTOR_OF_WEAK_REFERENCES = 78,
+    VT_VECTOR_OF_STRONG_REFERRABLES = 80,
+    VT_CO_OWNING_REFERENCE = 82,
+    VT_VECTOR_OF_CO_OWNING_REFERENCES = 84,
+    VT_NON_OWNING_REFERENCE = 86,
+    VT_VECTOR_OF_NON_OWNING_REFERENCES = 88,
+    VT_ANY_UNIQUE_TYPE = 90,
+    VT_ANY_UNIQUE = 92,
+    VT_ANY_AMBIGUOUS_TYPE = 94,
+    VT_ANY_AMBIGUOUS = 96,
+    VT_VECTOR_OF_ENUMS = 98,
+    VT_SIGNED_ENUM = 100,
+    VT_TESTREQUIREDNESTEDFLATBUFFER = 102
+  };
+  const MyGame::Example::Vec3 *pos() const {
+    return GetStruct<const MyGame::Example::Vec3 *>(VT_POS);
+  }
+  MyGame::Example::Vec3 *mutable_pos() {
+    return GetStruct<MyGame::Example::Vec3 *>(VT_POS);
+  }
+  int16_t mana() const {
+    return GetField<int16_t>(VT_MANA, 150);
+  }
+  bool mutate_mana(int16_t _mana) {
+    return SetField<int16_t>(VT_MANA, _mana, 150);
+  }
+  int16_t hp() const {
+    return GetField<int16_t>(VT_HP, 100);
+  }
+  bool mutate_hp(int16_t _hp) {
+    return SetField<int16_t>(VT_HP, _hp, 100);
+  }
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  flatbuffers::String *mutable_name() {
+    return GetPointer<flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Monster *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const flatbuffers::Vector<uint8_t> *inventory() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_inventory() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
+  }
+  MyGame::Example::Color color() const {
+    return static_cast<MyGame::Example::Color>(GetField<uint8_t>(VT_COLOR, 8));
+  }
+  bool mutate_color(MyGame::Example::Color _color) {
+    return SetField<uint8_t>(VT_COLOR, static_cast<uint8_t>(_color), 8);
+  }
+  MyGame::Example::Any test_type() const {
+    return static_cast<MyGame::Example::Any>(GetField<uint8_t>(VT_TEST_TYPE, 0));
+  }
+  const void *test() const {
+    return GetPointer<const void *>(VT_TEST);
+  }
+  template<typename T> const T *test_as() const;
+  const MyGame::Example::Monster *test_as_Monster() const {
+    return test_type() == MyGame::Example::Any::Monster ? static_cast<const MyGame::Example::Monster *>(test()) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnum *test_as_TestSimpleTableWithEnum() const {
+    return test_type() == MyGame::Example::Any::TestSimpleTableWithEnum ? static_cast<const MyGame::Example::TestSimpleTableWithEnum *>(test()) : nullptr;
+  }
+  const MyGame::Example2::Monster *test_as_MyGame_Example2_Monster() const {
+    return test_type() == MyGame::Example::Any::MyGame_Example2_Monster ? static_cast<const MyGame::Example2::Monster *>(test()) : nullptr;
+  }
+  void *mutable_test() {
+    return GetPointer<void *>(VT_TEST);
+  }
+  const flatbuffers::Vector<const MyGame::Example::Test *> *test4() const {
+    return GetPointer<const flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST4);
+  }
+  flatbuffers::Vector<const MyGame::Example::Test *> *mutable_test4() {
+    return GetPointer<flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST4);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *mutable_testarrayofstring() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING);
+  }
+  /// an example documentation comment: this will end up in the generated code
+  /// multiline too
+  const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *testarrayoftables() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *>(VT_TESTARRAYOFTABLES);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *mutable_testarrayoftables() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *>(VT_TESTARRAYOFTABLES);
+  }
+  const MyGame::Example::Monster *enemy() const {
+    return GetPointer<const MyGame::Example::Monster *>(VT_ENEMY);
+  }
+  MyGame::Example::Monster *mutable_enemy() {
+    return GetPointer<MyGame::Example::Monster *>(VT_ENEMY);
+  }
+  const flatbuffers::Vector<uint8_t> *testnestedflatbuffer() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_testnestedflatbuffer() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER);
+  }
+  const MyGame::Example::Monster *testnestedflatbuffer_nested_root() const {
+    return flatbuffers::GetRoot<MyGame::Example::Monster>(testnestedflatbuffer()->Data());
+  }
+  const MyGame::Example::Stat *testempty() const {
+    return GetPointer<const MyGame::Example::Stat *>(VT_TESTEMPTY);
+  }
+  MyGame::Example::Stat *mutable_testempty() {
+    return GetPointer<MyGame::Example::Stat *>(VT_TESTEMPTY);
+  }
+  bool testbool() const {
+    return GetField<uint8_t>(VT_TESTBOOL, 0) != 0;
+  }
+  bool mutate_testbool(bool _testbool) {
+    return SetField<uint8_t>(VT_TESTBOOL, static_cast<uint8_t>(_testbool), 0);
+  }
+  int32_t testhashs32_fnv1() const {
+    return GetField<int32_t>(VT_TESTHASHS32_FNV1, 0);
+  }
+  bool mutate_testhashs32_fnv1(int32_t _testhashs32_fnv1) {
+    return SetField<int32_t>(VT_TESTHASHS32_FNV1, _testhashs32_fnv1, 0);
+  }
+  uint32_t testhashu32_fnv1() const {
+    return GetField<uint32_t>(VT_TESTHASHU32_FNV1, 0);
+  }
+  bool mutate_testhashu32_fnv1(uint32_t _testhashu32_fnv1) {
+    return SetField<uint32_t>(VT_TESTHASHU32_FNV1, _testhashu32_fnv1, 0);
+  }
+  int64_t testhashs64_fnv1() const {
+    return GetField<int64_t>(VT_TESTHASHS64_FNV1, 0);
+  }
+  bool mutate_testhashs64_fnv1(int64_t _testhashs64_fnv1) {
+    return SetField<int64_t>(VT_TESTHASHS64_FNV1, _testhashs64_fnv1, 0);
+  }
+  uint64_t testhashu64_fnv1() const {
+    return GetField<uint64_t>(VT_TESTHASHU64_FNV1, 0);
+  }
+  bool mutate_testhashu64_fnv1(uint64_t _testhashu64_fnv1) {
+    return SetField<uint64_t>(VT_TESTHASHU64_FNV1, _testhashu64_fnv1, 0);
+  }
+  int32_t testhashs32_fnv1a() const {
+    return GetField<int32_t>(VT_TESTHASHS32_FNV1A, 0);
+  }
+  bool mutate_testhashs32_fnv1a(int32_t _testhashs32_fnv1a) {
+    return SetField<int32_t>(VT_TESTHASHS32_FNV1A, _testhashs32_fnv1a, 0);
+  }
+  uint32_t testhashu32_fnv1a() const {
+    return GetField<uint32_t>(VT_TESTHASHU32_FNV1A, 0);
+  }
+  bool mutate_testhashu32_fnv1a(uint32_t _testhashu32_fnv1a) {
+    return SetField<uint32_t>(VT_TESTHASHU32_FNV1A, _testhashu32_fnv1a, 0);
+  }
+  int64_t testhashs64_fnv1a() const {
+    return GetField<int64_t>(VT_TESTHASHS64_FNV1A, 0);
+  }
+  bool mutate_testhashs64_fnv1a(int64_t _testhashs64_fnv1a) {
+    return SetField<int64_t>(VT_TESTHASHS64_FNV1A, _testhashs64_fnv1a, 0);
+  }
+  uint64_t testhashu64_fnv1a() const {
+    return GetField<uint64_t>(VT_TESTHASHU64_FNV1A, 0);
+  }
+  bool mutate_testhashu64_fnv1a(uint64_t _testhashu64_fnv1a) {
+    return SetField<uint64_t>(VT_TESTHASHU64_FNV1A, _testhashu64_fnv1a, 0);
+  }
+  const flatbuffers::Vector<uint8_t> *testarrayofbools() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_TESTARRAYOFBOOLS);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_testarrayofbools() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_TESTARRAYOFBOOLS);
+  }
+  float testf() const {
+    return GetField<float>(VT_TESTF, 3.14159f);
+  }
+  bool mutate_testf(float _testf) {
+    return SetField<float>(VT_TESTF, _testf, 3.14159f);
+  }
+  float testf2() const {
+    return GetField<float>(VT_TESTF2, 3.0f);
+  }
+  bool mutate_testf2(float _testf2) {
+    return SetField<float>(VT_TESTF2, _testf2, 3.0f);
+  }
+  float testf3() const {
+    return GetField<float>(VT_TESTF3, 0.0f);
+  }
+  bool mutate_testf3(float _testf3) {
+    return SetField<float>(VT_TESTF3, _testf3, 0.0f);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING2);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *mutable_testarrayofstring2() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING2);
+  }
+  const flatbuffers::Vector<const MyGame::Example::Ability *> *testarrayofsortedstruct() const {
+    return GetPointer<const flatbuffers::Vector<const MyGame::Example::Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
+  }
+  flatbuffers::Vector<const MyGame::Example::Ability *> *mutable_testarrayofsortedstruct() {
+    return GetPointer<flatbuffers::Vector<const MyGame::Example::Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
+  }
+  const flatbuffers::Vector<uint8_t> *flex() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_FLEX);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_flex() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_FLEX);
+  }
+  flexbuffers::Reference flex_flexbuffer_root() const {
+    return flexbuffers::GetRoot(flex()->Data(), flex()->size());
+  }
+  const flatbuffers::Vector<const MyGame::Example::Test *> *test5() const {
+    return GetPointer<const flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5);
+  }
+  flatbuffers::Vector<const MyGame::Example::Test *> *mutable_test5() {
+    return GetPointer<flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5);
+  }
+  const flatbuffers::Vector<int64_t> *vector_of_longs() const {
+    return GetPointer<const flatbuffers::Vector<int64_t> *>(VT_VECTOR_OF_LONGS);
+  }
+  flatbuffers::Vector<int64_t> *mutable_vector_of_longs() {
+    return GetPointer<flatbuffers::Vector<int64_t> *>(VT_VECTOR_OF_LONGS);
+  }
+  const flatbuffers::Vector<double> *vector_of_doubles() const {
+    return GetPointer<const flatbuffers::Vector<double> *>(VT_VECTOR_OF_DOUBLES);
+  }
+  flatbuffers::Vector<double> *mutable_vector_of_doubles() {
+    return GetPointer<flatbuffers::Vector<double> *>(VT_VECTOR_OF_DOUBLES);
+  }
+  const MyGame::InParentNamespace *parent_namespace_test() const {
+    return GetPointer<const MyGame::InParentNamespace *>(VT_PARENT_NAMESPACE_TEST);
+  }
+  MyGame::InParentNamespace *mutable_parent_namespace_test() {
+    return GetPointer<MyGame::InParentNamespace *>(VT_PARENT_NAMESPACE_TEST);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_referrables() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *mutable_vector_of_referrables() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
+  }
+  uint64_t single_weak_reference() const {
+    return GetField<uint64_t>(VT_SINGLE_WEAK_REFERENCE, 0);
+  }
+  bool mutate_single_weak_reference(uint64_t _single_weak_reference) {
+    return SetField<uint64_t>(VT_SINGLE_WEAK_REFERENCE, _single_weak_reference, 0);
+  }
+  const flatbuffers::Vector<uint64_t> *vector_of_weak_references() const {
+    return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_WEAK_REFERENCES);
+  }
+  flatbuffers::Vector<uint64_t> *mutable_vector_of_weak_references() {
+    return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_WEAK_REFERENCES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_strong_referrables() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
+  }
+  flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *mutable_vector_of_strong_referrables() {
+    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
+  }
+  uint64_t co_owning_reference() const {
+    return GetField<uint64_t>(VT_CO_OWNING_REFERENCE, 0);
+  }
+  bool mutate_co_owning_reference(uint64_t _co_owning_reference) {
+    return SetField<uint64_t>(VT_CO_OWNING_REFERENCE, _co_owning_reference, 0);
+  }
+  const flatbuffers::Vector<uint64_t> *vector_of_co_owning_references() const {
+    return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_CO_OWNING_REFERENCES);
+  }
+  flatbuffers::Vector<uint64_t> *mutable_vector_of_co_owning_references() {
+    return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_CO_OWNING_REFERENCES);
+  }
+  uint64_t non_owning_reference() const {
+    return GetField<uint64_t>(VT_NON_OWNING_REFERENCE, 0);
+  }
+  bool mutate_non_owning_reference(uint64_t _non_owning_reference) {
+    return SetField<uint64_t>(VT_NON_OWNING_REFERENCE, _non_owning_reference, 0);
+  }
+  const flatbuffers::Vector<uint64_t> *vector_of_non_owning_references() const {
+    return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_NON_OWNING_REFERENCES);
+  }
+  flatbuffers::Vector<uint64_t> *mutable_vector_of_non_owning_references() {
+    return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_NON_OWNING_REFERENCES);
+  }
+  MyGame::Example::AnyUniqueAliases any_unique_type() const {
+    return static_cast<MyGame::Example::AnyUniqueAliases>(GetField<uint8_t>(VT_ANY_UNIQUE_TYPE, 0));
+  }
+  const void *any_unique() const {
+    return GetPointer<const void *>(VT_ANY_UNIQUE);
+  }
+  template<typename T> const T *any_unique_as() const;
+  const MyGame::Example::Monster *any_unique_as_M() const {
+    return any_unique_type() == MyGame::Example::AnyUniqueAliases::M ? static_cast<const MyGame::Example::Monster *>(any_unique()) : nullptr;
+  }
+  const MyGame::Example::TestSimpleTableWithEnum *any_unique_as_TS() const {
+    return any_unique_type() == MyGame::Example::AnyUniqueAliases::TS ? static_cast<const MyGame::Example::TestSimpleTableWithEnum *>(any_unique()) : nullptr;
+  }
+  const MyGame::Example2::Monster *any_unique_as_M2() const {
+    return any_unique_type() == MyGame::Example::AnyUniqueAliases::M2 ? static_cast<const MyGame::Example2::Monster *>(any_unique()) : nullptr;
+  }
+  void *mutable_any_unique() {
+    return GetPointer<void *>(VT_ANY_UNIQUE);
+  }
+  MyGame::Example::AnyAmbiguousAliases any_ambiguous_type() const {
+    return static_cast<MyGame::Example::AnyAmbiguousAliases>(GetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, 0));
+  }
+  const void *any_ambiguous() const {
+    return GetPointer<const void *>(VT_ANY_AMBIGUOUS);
+  }
+  const MyGame::Example::Monster *any_ambiguous_as_M1() const {
+    return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases::M1 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+  }
+  const MyGame::Example::Monster *any_ambiguous_as_M2() const {
+    return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases::M2 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+  }
+  const MyGame::Example::Monster *any_ambiguous_as_M3() const {
+    return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases::M3 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+  }
+  void *mutable_any_ambiguous() {
+    return GetPointer<void *>(VT_ANY_AMBIGUOUS);
+  }
+  const flatbuffers::Vector<MyGame::Example::Color> *vector_of_enums() const {
+    return GetPointer<const flatbuffers::Vector<MyGame::Example::Color> *>(VT_VECTOR_OF_ENUMS);
+  }
+  flatbuffers::Vector<MyGame::Example::Color> *mutable_vector_of_enums() {
+    return GetPointer<flatbuffers::Vector<MyGame::Example::Color> *>(VT_VECTOR_OF_ENUMS);
+  }
+  MyGame::Example::Race signed_enum() const {
+    return static_cast<MyGame::Example::Race>(GetField<int8_t>(VT_SIGNED_ENUM, -1));
+  }
+  bool mutate_signed_enum(MyGame::Example::Race _signed_enum) {
+    return SetField<int8_t>(VT_SIGNED_ENUM, static_cast<int8_t>(_signed_enum), -1);
+  }
+  const flatbuffers::Vector<uint8_t> *testrequirednestedflatbuffer() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_TESTREQUIREDNESTEDFLATBUFFER);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_testrequirednestedflatbuffer() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_TESTREQUIREDNESTEDFLATBUFFER);
+  }
+  const MyGame::Example::Monster *testrequirednestedflatbuffer_nested_root() const {
+    return flatbuffers::GetRoot<MyGame::Example::Monster>(testrequirednestedflatbuffer()->Data());
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<MyGame::Example::Vec3>(verifier, VT_POS) &&
+           VerifyField<int16_t>(verifier, VT_MANA) &&
+           VerifyField<int16_t>(verifier, VT_HP) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffset(verifier, VT_INVENTORY) &&
+           verifier.VerifyVector(inventory()) &&
+           VerifyField<uint8_t>(verifier, VT_COLOR) &&
+           VerifyField<uint8_t>(verifier, VT_TEST_TYPE) &&
+           VerifyOffset(verifier, VT_TEST) &&
+           VerifyAny(verifier, test(), test_type()) &&
+           VerifyOffset(verifier, VT_TEST4) &&
+           verifier.VerifyVector(test4()) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFSTRING) &&
+           verifier.VerifyVector(testarrayofstring()) &&
+           verifier.VerifyVectorOfStrings(testarrayofstring()) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFTABLES) &&
+           verifier.VerifyVector(testarrayoftables()) &&
+           verifier.VerifyVectorOfTables(testarrayoftables()) &&
+           VerifyOffset(verifier, VT_ENEMY) &&
+           verifier.VerifyTable(enemy()) &&
+           VerifyOffset(verifier, VT_TESTNESTEDFLATBUFFER) &&
+           verifier.VerifyVector(testnestedflatbuffer()) &&
+           VerifyOffset(verifier, VT_TESTEMPTY) &&
+           verifier.VerifyTable(testempty()) &&
+           VerifyField<uint8_t>(verifier, VT_TESTBOOL) &&
+           VerifyField<int32_t>(verifier, VT_TESTHASHS32_FNV1) &&
+           VerifyField<uint32_t>(verifier, VT_TESTHASHU32_FNV1) &&
+           VerifyField<int64_t>(verifier, VT_TESTHASHS64_FNV1) &&
+           VerifyField<uint64_t>(verifier, VT_TESTHASHU64_FNV1) &&
+           VerifyField<int32_t>(verifier, VT_TESTHASHS32_FNV1A) &&
+           VerifyField<uint32_t>(verifier, VT_TESTHASHU32_FNV1A) &&
+           VerifyField<int64_t>(verifier, VT_TESTHASHS64_FNV1A) &&
+           VerifyField<uint64_t>(verifier, VT_TESTHASHU64_FNV1A) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFBOOLS) &&
+           verifier.VerifyVector(testarrayofbools()) &&
+           VerifyField<float>(verifier, VT_TESTF) &&
+           VerifyField<float>(verifier, VT_TESTF2) &&
+           VerifyField<float>(verifier, VT_TESTF3) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFSTRING2) &&
+           verifier.VerifyVector(testarrayofstring2()) &&
+           verifier.VerifyVectorOfStrings(testarrayofstring2()) &&
+           VerifyOffset(verifier, VT_TESTARRAYOFSORTEDSTRUCT) &&
+           verifier.VerifyVector(testarrayofsortedstruct()) &&
+           VerifyOffset(verifier, VT_FLEX) &&
+           verifier.VerifyVector(flex()) &&
+           VerifyOffset(verifier, VT_TEST5) &&
+           verifier.VerifyVector(test5()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_LONGS) &&
+           verifier.VerifyVector(vector_of_longs()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_DOUBLES) &&
+           verifier.VerifyVector(vector_of_doubles()) &&
+           VerifyOffset(verifier, VT_PARENT_NAMESPACE_TEST) &&
+           verifier.VerifyTable(parent_namespace_test()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_REFERRABLES) &&
+           verifier.VerifyVector(vector_of_referrables()) &&
+           verifier.VerifyVectorOfTables(vector_of_referrables()) &&
+           VerifyField<uint64_t>(verifier, VT_SINGLE_WEAK_REFERENCE) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_WEAK_REFERENCES) &&
+           verifier.VerifyVector(vector_of_weak_references()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_STRONG_REFERRABLES) &&
+           verifier.VerifyVector(vector_of_strong_referrables()) &&
+           verifier.VerifyVectorOfTables(vector_of_strong_referrables()) &&
+           VerifyField<uint64_t>(verifier, VT_CO_OWNING_REFERENCE) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_CO_OWNING_REFERENCES) &&
+           verifier.VerifyVector(vector_of_co_owning_references()) &&
+           VerifyField<uint64_t>(verifier, VT_NON_OWNING_REFERENCE) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_NON_OWNING_REFERENCES) &&
+           verifier.VerifyVector(vector_of_non_owning_references()) &&
+           VerifyField<uint8_t>(verifier, VT_ANY_UNIQUE_TYPE) &&
+           VerifyOffset(verifier, VT_ANY_UNIQUE) &&
+           VerifyAnyUniqueAliases(verifier, any_unique(), any_unique_type()) &&
+           VerifyField<uint8_t>(verifier, VT_ANY_AMBIGUOUS_TYPE) &&
+           VerifyOffset(verifier, VT_ANY_AMBIGUOUS) &&
+           VerifyAnyAmbiguousAliases(verifier, any_ambiguous(), any_ambiguous_type()) &&
+           VerifyOffset(verifier, VT_VECTOR_OF_ENUMS) &&
+           verifier.VerifyVector(vector_of_enums()) &&
+           VerifyField<int8_t>(verifier, VT_SIGNED_ENUM) &&
+           VerifyOffset(verifier, VT_TESTREQUIREDNESTEDFLATBUFFER) &&
+           verifier.VerifyVector(testrequirednestedflatbuffer()) &&
+           verifier.EndTable();
+  }
+  MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+template<> inline const MyGame::Example::Monster *Monster::test_as<MyGame::Example::Monster>() const {
+  return test_as_Monster();
+}
+
+template<> inline const MyGame::Example::TestSimpleTableWithEnum *Monster::test_as<MyGame::Example::TestSimpleTableWithEnum>() const {
+  return test_as_TestSimpleTableWithEnum();
+}
+
+template<> inline const MyGame::Example2::Monster *Monster::test_as<MyGame::Example2::Monster>() const {
+  return test_as_MyGame_Example2_Monster();
+}
+
+template<> inline const MyGame::Example::Monster *Monster::any_unique_as<MyGame::Example::Monster>() const {
+  return any_unique_as_M();
+}
+
+template<> inline const MyGame::Example::TestSimpleTableWithEnum *Monster::any_unique_as<MyGame::Example::TestSimpleTableWithEnum>() const {
+  return any_unique_as_TS();
+}
+
+template<> inline const MyGame::Example2::Monster *Monster::any_unique_as<MyGame::Example2::Monster>() const {
+  return any_unique_as_M2();
+}
+
+struct MonsterBuilder {
+  typedef Monster Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_pos(const MyGame::Example::Vec3 *pos) {
+    fbb_.AddStruct(Monster::VT_POS, pos);
+  }
+  void add_mana(int16_t mana) {
+    fbb_.AddElement<int16_t>(Monster::VT_MANA, mana, 150);
+  }
+  void add_hp(int16_t hp) {
+    fbb_.AddElement<int16_t>(Monster::VT_HP, hp, 100);
+  }
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Monster::VT_NAME, name);
+  }
+  void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) {
+    fbb_.AddOffset(Monster::VT_INVENTORY, inventory);
+  }
+  void add_color(MyGame::Example::Color color) {
+    fbb_.AddElement<uint8_t>(Monster::VT_COLOR, static_cast<uint8_t>(color), 8);
+  }
+  void add_test_type(MyGame::Example::Any test_type) {
+    fbb_.AddElement<uint8_t>(Monster::VT_TEST_TYPE, static_cast<uint8_t>(test_type), 0);
+  }
+  void add_test(flatbuffers::Offset<void> test) {
+    fbb_.AddOffset(Monster::VT_TEST, test);
+  }
+  void add_test4(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test4) {
+    fbb_.AddOffset(Monster::VT_TEST4, test4);
+  }
+  void add_testarrayofstring(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING, testarrayofstring);
+  }
+  void add_testarrayoftables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>>> testarrayoftables) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFTABLES, testarrayoftables);
+  }
+  void add_enemy(flatbuffers::Offset<MyGame::Example::Monster> enemy) {
+    fbb_.AddOffset(Monster::VT_ENEMY, enemy);
+  }
+  void add_testnestedflatbuffer(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer) {
+    fbb_.AddOffset(Monster::VT_TESTNESTEDFLATBUFFER, testnestedflatbuffer);
+  }
+  void add_testempty(flatbuffers::Offset<MyGame::Example::Stat> testempty) {
+    fbb_.AddOffset(Monster::VT_TESTEMPTY, testempty);
+  }
+  void add_testbool(bool testbool) {
+    fbb_.AddElement<uint8_t>(Monster::VT_TESTBOOL, static_cast<uint8_t>(testbool), 0);
+  }
+  void add_testhashs32_fnv1(int32_t testhashs32_fnv1) {
+    fbb_.AddElement<int32_t>(Monster::VT_TESTHASHS32_FNV1, testhashs32_fnv1, 0);
+  }
+  void add_testhashu32_fnv1(uint32_t testhashu32_fnv1) {
+    fbb_.AddElement<uint32_t>(Monster::VT_TESTHASHU32_FNV1, testhashu32_fnv1, 0);
+  }
+  void add_testhashs64_fnv1(int64_t testhashs64_fnv1) {
+    fbb_.AddElement<int64_t>(Monster::VT_TESTHASHS64_FNV1, testhashs64_fnv1, 0);
+  }
+  void add_testhashu64_fnv1(uint64_t testhashu64_fnv1) {
+    fbb_.AddElement<uint64_t>(Monster::VT_TESTHASHU64_FNV1, testhashu64_fnv1, 0);
+  }
+  void add_testhashs32_fnv1a(int32_t testhashs32_fnv1a) {
+    fbb_.AddElement<int32_t>(Monster::VT_TESTHASHS32_FNV1A, testhashs32_fnv1a, 0);
+  }
+  void add_testhashu32_fnv1a(uint32_t testhashu32_fnv1a) {
+    fbb_.AddElement<uint32_t>(Monster::VT_TESTHASHU32_FNV1A, testhashu32_fnv1a, 0);
+  }
+  void add_testhashs64_fnv1a(int64_t testhashs64_fnv1a) {
+    fbb_.AddElement<int64_t>(Monster::VT_TESTHASHS64_FNV1A, testhashs64_fnv1a, 0);
+  }
+  void add_testhashu64_fnv1a(uint64_t testhashu64_fnv1a) {
+    fbb_.AddElement<uint64_t>(Monster::VT_TESTHASHU64_FNV1A, testhashu64_fnv1a, 0);
+  }
+  void add_testarrayofbools(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testarrayofbools) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFBOOLS, testarrayofbools);
+  }
+  void add_testf(float testf) {
+    fbb_.AddElement<float>(Monster::VT_TESTF, testf, 3.14159f);
+  }
+  void add_testf2(float testf2) {
+    fbb_.AddElement<float>(Monster::VT_TESTF2, testf2, 3.0f);
+  }
+  void add_testf3(float testf3) {
+    fbb_.AddElement<float>(Monster::VT_TESTF3, testf3, 0.0f);
+  }
+  void add_testarrayofstring2(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING2, testarrayofstring2);
+  }
+  void add_testarrayofsortedstruct(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Ability *>> testarrayofsortedstruct) {
+    fbb_.AddOffset(Monster::VT_TESTARRAYOFSORTEDSTRUCT, testarrayofsortedstruct);
+  }
+  void add_flex(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex) {
+    fbb_.AddOffset(Monster::VT_FLEX, flex);
+  }
+  void add_test5(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test5) {
+    fbb_.AddOffset(Monster::VT_TEST5, test5);
+  }
+  void add_vector_of_longs(flatbuffers::Offset<flatbuffers::Vector<int64_t>> vector_of_longs) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_LONGS, vector_of_longs);
+  }
+  void add_vector_of_doubles(flatbuffers::Offset<flatbuffers::Vector<double>> vector_of_doubles) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_DOUBLES, vector_of_doubles);
+  }
+  void add_parent_namespace_test(flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test) {
+    fbb_.AddOffset(Monster::VT_PARENT_NAMESPACE_TEST, parent_namespace_test);
+  }
+  void add_vector_of_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_referrables) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_REFERRABLES, vector_of_referrables);
+  }
+  void add_single_weak_reference(uint64_t single_weak_reference) {
+    fbb_.AddElement<uint64_t>(Monster::VT_SINGLE_WEAK_REFERENCE, single_weak_reference, 0);
+  }
+  void add_vector_of_weak_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_weak_references) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_WEAK_REFERENCES, vector_of_weak_references);
+  }
+  void add_vector_of_strong_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_strong_referrables) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, vector_of_strong_referrables);
+  }
+  void add_co_owning_reference(uint64_t co_owning_reference) {
+    fbb_.AddElement<uint64_t>(Monster::VT_CO_OWNING_REFERENCE, co_owning_reference, 0);
+  }
+  void add_vector_of_co_owning_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_co_owning_references) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_CO_OWNING_REFERENCES, vector_of_co_owning_references);
+  }
+  void add_non_owning_reference(uint64_t non_owning_reference) {
+    fbb_.AddElement<uint64_t>(Monster::VT_NON_OWNING_REFERENCE, non_owning_reference, 0);
+  }
+  void add_vector_of_non_owning_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_non_owning_references) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_NON_OWNING_REFERENCES, vector_of_non_owning_references);
+  }
+  void add_any_unique_type(MyGame::Example::AnyUniqueAliases any_unique_type) {
+    fbb_.AddElement<uint8_t>(Monster::VT_ANY_UNIQUE_TYPE, static_cast<uint8_t>(any_unique_type), 0);
+  }
+  void add_any_unique(flatbuffers::Offset<void> any_unique) {
+    fbb_.AddOffset(Monster::VT_ANY_UNIQUE, any_unique);
+  }
+  void add_any_ambiguous_type(MyGame::Example::AnyAmbiguousAliases any_ambiguous_type) {
+    fbb_.AddElement<uint8_t>(Monster::VT_ANY_AMBIGUOUS_TYPE, static_cast<uint8_t>(any_ambiguous_type), 0);
+  }
+  void add_any_ambiguous(flatbuffers::Offset<void> any_ambiguous) {
+    fbb_.AddOffset(Monster::VT_ANY_AMBIGUOUS, any_ambiguous);
+  }
+  void add_vector_of_enums(flatbuffers::Offset<flatbuffers::Vector<MyGame::Example::Color>> vector_of_enums) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_ENUMS, vector_of_enums);
+  }
+  void add_signed_enum(MyGame::Example::Race signed_enum) {
+    fbb_.AddElement<int8_t>(Monster::VT_SIGNED_ENUM, static_cast<int8_t>(signed_enum), -1);
+  }
+  void add_testrequirednestedflatbuffer(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testrequirednestedflatbuffer) {
+    fbb_.AddOffset(Monster::VT_TESTREQUIREDNESTEDFLATBUFFER, testrequirednestedflatbuffer);
+  }
+  explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  flatbuffers::Offset<Monster> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Monster>(end);
+    fbb_.Required(o, Monster::VT_NAME);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Monster> CreateMonster(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const MyGame::Example::Vec3 *pos = 0,
+    int16_t mana = 150,
+    int16_t hp = 100,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
+    MyGame::Example::Color color = MyGame::Example::Color::Blue,
+    MyGame::Example::Any test_type = MyGame::Example::Any::NONE,
+    flatbuffers::Offset<void> test = 0,
+    flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test4 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>>> testarrayoftables = 0,
+    flatbuffers::Offset<MyGame::Example::Monster> enemy = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer = 0,
+    flatbuffers::Offset<MyGame::Example::Stat> testempty = 0,
+    bool testbool = false,
+    int32_t testhashs32_fnv1 = 0,
+    uint32_t testhashu32_fnv1 = 0,
+    int64_t testhashs64_fnv1 = 0,
+    uint64_t testhashu64_fnv1 = 0,
+    int32_t testhashs32_fnv1a = 0,
+    uint32_t testhashu32_fnv1a = 0,
+    int64_t testhashs64_fnv1a = 0,
+    uint64_t testhashu64_fnv1a = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testarrayofbools = 0,
+    float testf = 3.14159f,
+    float testf2 = 3.0f,
+    float testf3 = 0.0f,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Ability *>> testarrayofsortedstruct = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex = 0,
+    flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test5 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int64_t>> vector_of_longs = 0,
+    flatbuffers::Offset<flatbuffers::Vector<double>> vector_of_doubles = 0,
+    flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_referrables = 0,
+    uint64_t single_weak_reference = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_weak_references = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_strong_referrables = 0,
+    uint64_t co_owning_reference = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_co_owning_references = 0,
+    uint64_t non_owning_reference = 0,
+    flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_non_owning_references = 0,
+    MyGame::Example::AnyUniqueAliases any_unique_type = MyGame::Example::AnyUniqueAliases::NONE,
+    flatbuffers::Offset<void> any_unique = 0,
+    MyGame::Example::AnyAmbiguousAliases any_ambiguous_type = MyGame::Example::AnyAmbiguousAliases::NONE,
+    flatbuffers::Offset<void> any_ambiguous = 0,
+    flatbuffers::Offset<flatbuffers::Vector<MyGame::Example::Color>> vector_of_enums = 0,
+    MyGame::Example::Race signed_enum = MyGame::Example::Race::None,
+    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testrequirednestedflatbuffer = 0) {
+  MonsterBuilder builder_(_fbb);
+  builder_.add_non_owning_reference(non_owning_reference);
+  builder_.add_co_owning_reference(co_owning_reference);
+  builder_.add_single_weak_reference(single_weak_reference);
+  builder_.add_testhashu64_fnv1a(testhashu64_fnv1a);
+  builder_.add_testhashs64_fnv1a(testhashs64_fnv1a);
+  builder_.add_testhashu64_fnv1(testhashu64_fnv1);
+  builder_.add_testhashs64_fnv1(testhashs64_fnv1);
+  builder_.add_testrequirednestedflatbuffer(testrequirednestedflatbuffer);
+  builder_.add_vector_of_enums(vector_of_enums);
+  builder_.add_any_ambiguous(any_ambiguous);
+  builder_.add_any_unique(any_unique);
+  builder_.add_vector_of_non_owning_references(vector_of_non_owning_references);
+  builder_.add_vector_of_co_owning_references(vector_of_co_owning_references);
+  builder_.add_vector_of_strong_referrables(vector_of_strong_referrables);
+  builder_.add_vector_of_weak_references(vector_of_weak_references);
+  builder_.add_vector_of_referrables(vector_of_referrables);
+  builder_.add_parent_namespace_test(parent_namespace_test);
+  builder_.add_vector_of_doubles(vector_of_doubles);
+  builder_.add_vector_of_longs(vector_of_longs);
+  builder_.add_test5(test5);
+  builder_.add_flex(flex);
+  builder_.add_testarrayofsortedstruct(testarrayofsortedstruct);
+  builder_.add_testarrayofstring2(testarrayofstring2);
+  builder_.add_testf3(testf3);
+  builder_.add_testf2(testf2);
+  builder_.add_testf(testf);
+  builder_.add_testarrayofbools(testarrayofbools);
+  builder_.add_testhashu32_fnv1a(testhashu32_fnv1a);
+  builder_.add_testhashs32_fnv1a(testhashs32_fnv1a);
+  builder_.add_testhashu32_fnv1(testhashu32_fnv1);
+  builder_.add_testhashs32_fnv1(testhashs32_fnv1);
+  builder_.add_testempty(testempty);
+  builder_.add_testnestedflatbuffer(testnestedflatbuffer);
+  builder_.add_enemy(enemy);
+  builder_.add_testarrayoftables(testarrayoftables);
+  builder_.add_testarrayofstring(testarrayofstring);
+  builder_.add_test4(test4);
+  builder_.add_test(test);
+  builder_.add_inventory(inventory);
+  builder_.add_name(name);
+  builder_.add_pos(pos);
+  builder_.add_hp(hp);
+  builder_.add_mana(mana);
+  builder_.add_signed_enum(signed_enum);
+  builder_.add_any_ambiguous_type(any_ambiguous_type);
+  builder_.add_any_unique_type(any_unique_type);
+  builder_.add_testbool(testbool);
+  builder_.add_test_type(test_type);
+  builder_.add_color(color);
+  return builder_.Finish();
+}
+
+struct Monster::Traits {
+  using type = Monster;
+  static auto constexpr Create = CreateMonster;
+};
+
+inline flatbuffers::Offset<Monster> CreateMonsterDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const MyGame::Example::Vec3 *pos = 0,
+    int16_t mana = 150,
+    int16_t hp = 100,
+    const char *name = nullptr,
+    const std::vector<uint8_t> *inventory = nullptr,
+    MyGame::Example::Color color = MyGame::Example::Color::Blue,
+    MyGame::Example::Any test_type = MyGame::Example::Any::NONE,
+    flatbuffers::Offset<void> test = 0,
+    const std::vector<MyGame::Example::Test> *test4 = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring = nullptr,
+    std::vector<flatbuffers::Offset<MyGame::Example::Monster>> *testarrayoftables = nullptr,
+    flatbuffers::Offset<MyGame::Example::Monster> enemy = 0,
+    const std::vector<uint8_t> *testnestedflatbuffer = nullptr,
+    flatbuffers::Offset<MyGame::Example::Stat> testempty = 0,
+    bool testbool = false,
+    int32_t testhashs32_fnv1 = 0,
+    uint32_t testhashu32_fnv1 = 0,
+    int64_t testhashs64_fnv1 = 0,
+    uint64_t testhashu64_fnv1 = 0,
+    int32_t testhashs32_fnv1a = 0,
+    uint32_t testhashu32_fnv1a = 0,
+    int64_t testhashs64_fnv1a = 0,
+    uint64_t testhashu64_fnv1a = 0,
+    const std::vector<uint8_t> *testarrayofbools = nullptr,
+    float testf = 3.14159f,
+    float testf2 = 3.0f,
+    float testf3 = 0.0f,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2 = nullptr,
+    std::vector<MyGame::Example::Ability> *testarrayofsortedstruct = nullptr,
+    const std::vector<uint8_t> *flex = nullptr,
+    const std::vector<MyGame::Example::Test> *test5 = nullptr,
+    const std::vector<int64_t> *vector_of_longs = nullptr,
+    const std::vector<double> *vector_of_doubles = nullptr,
+    flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test = 0,
+    std::vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_referrables = nullptr,
+    uint64_t single_weak_reference = 0,
+    const std::vector<uint64_t> *vector_of_weak_references = nullptr,
+    std::vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_strong_referrables = nullptr,
+    uint64_t co_owning_reference = 0,
+    const std::vector<uint64_t> *vector_of_co_owning_references = nullptr,
+    uint64_t non_owning_reference = 0,
+    const std::vector<uint64_t> *vector_of_non_owning_references = nullptr,
+    MyGame::Example::AnyUniqueAliases any_unique_type = MyGame::Example::AnyUniqueAliases::NONE,
+    flatbuffers::Offset<void> any_unique = 0,
+    MyGame::Example::AnyAmbiguousAliases any_ambiguous_type = MyGame::Example::AnyAmbiguousAliases::NONE,
+    flatbuffers::Offset<void> any_ambiguous = 0,
+    const std::vector<MyGame::Example::Color> *vector_of_enums = nullptr,
+    MyGame::Example::Race signed_enum = MyGame::Example::Race::None,
+    const std::vector<uint8_t> *testrequirednestedflatbuffer = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto inventory__ = inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0;
+  auto test4__ = test4 ? _fbb.CreateVectorOfStructs<MyGame::Example::Test>(*test4) : 0;
+  auto testarrayofstring__ = testarrayofstring ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring) : 0;
+  auto testarrayoftables__ = testarrayoftables ? _fbb.CreateVectorOfSortedTables<MyGame::Example::Monster>(testarrayoftables) : 0;
+  auto testnestedflatbuffer__ = testnestedflatbuffer ? _fbb.CreateVector<uint8_t>(*testnestedflatbuffer) : 0;
+  auto testarrayofbools__ = testarrayofbools ? _fbb.CreateVector<uint8_t>(*testarrayofbools) : 0;
+  auto testarrayofstring2__ = testarrayofstring2 ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring2) : 0;
+  auto testarrayofsortedstruct__ = testarrayofsortedstruct ? _fbb.CreateVectorOfSortedStructs<MyGame::Example::Ability>(testarrayofsortedstruct) : 0;
+  auto flex__ = flex ? _fbb.CreateVector<uint8_t>(*flex) : 0;
+  auto test5__ = test5 ? _fbb.CreateVectorOfStructs<MyGame::Example::Test>(*test5) : 0;
+  auto vector_of_longs__ = vector_of_longs ? _fbb.CreateVector<int64_t>(*vector_of_longs) : 0;
+  auto vector_of_doubles__ = vector_of_doubles ? _fbb.CreateVector<double>(*vector_of_doubles) : 0;
+  auto vector_of_referrables__ = vector_of_referrables ? _fbb.CreateVectorOfSortedTables<MyGame::Example::Referrable>(vector_of_referrables) : 0;
+  auto vector_of_weak_references__ = vector_of_weak_references ? _fbb.CreateVector<uint64_t>(*vector_of_weak_references) : 0;
+  auto vector_of_strong_referrables__ = vector_of_strong_referrables ? _fbb.CreateVectorOfSortedTables<MyGame::Example::Referrable>(vector_of_strong_referrables) : 0;
+  auto vector_of_co_owning_references__ = vector_of_co_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_co_owning_references) : 0;
+  auto vector_of_non_owning_references__ = vector_of_non_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_non_owning_references) : 0;
+  auto vector_of_enums__ = vector_of_enums ? _fbb.CreateVector<MyGame::Example::Color>(*vector_of_enums) : 0;
+  auto testrequirednestedflatbuffer__ = testrequirednestedflatbuffer ? _fbb.CreateVector<uint8_t>(*testrequirednestedflatbuffer) : 0;
+  return MyGame::Example::CreateMonster(
+      _fbb,
+      pos,
+      mana,
+      hp,
+      name__,
+      inventory__,
+      color,
+      test_type,
+      test,
+      test4__,
+      testarrayofstring__,
+      testarrayoftables__,
+      enemy,
+      testnestedflatbuffer__,
+      testempty,
+      testbool,
+      testhashs32_fnv1,
+      testhashu32_fnv1,
+      testhashs64_fnv1,
+      testhashu64_fnv1,
+      testhashs32_fnv1a,
+      testhashu32_fnv1a,
+      testhashs64_fnv1a,
+      testhashu64_fnv1a,
+      testarrayofbools__,
+      testf,
+      testf2,
+      testf3,
+      testarrayofstring2__,
+      testarrayofsortedstruct__,
+      flex__,
+      test5__,
+      vector_of_longs__,
+      vector_of_doubles__,
+      parent_namespace_test,
+      vector_of_referrables__,
+      single_weak_reference,
+      vector_of_weak_references__,
+      vector_of_strong_referrables__,
+      co_owning_reference,
+      vector_of_co_owning_references__,
+      non_owning_reference,
+      vector_of_non_owning_references__,
+      any_unique_type,
+      any_unique,
+      any_ambiguous_type,
+      any_ambiguous,
+      vector_of_enums__,
+      signed_enum,
+      testrequirednestedflatbuffer__);
+}
+
+flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct TypeAliasesT : public flatbuffers::NativeTable {
+  typedef TypeAliases TableType;
+  int8_t i8 = 0;
+  uint8_t u8 = 0;
+  int16_t i16 = 0;
+  uint16_t u16 = 0;
+  int32_t i32 = 0;
+  uint32_t u32 = 0;
+  int64_t i64 = 0;
+  uint64_t u64 = 0;
+  float f32 = 0.0f;
+  double f64 = 0.0;
+  std::vector<int8_t> v8{};
+  std::vector<double> vf64{};
+};
+
+struct TypeAliases FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TypeAliasesT NativeTableType;
+  typedef TypeAliasesBuilder Builder;
+  struct Traits;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return TypeAliasesTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_I8 = 4,
+    VT_U8 = 6,
+    VT_I16 = 8,
+    VT_U16 = 10,
+    VT_I32 = 12,
+    VT_U32 = 14,
+    VT_I64 = 16,
+    VT_U64 = 18,
+    VT_F32 = 20,
+    VT_F64 = 22,
+    VT_V8 = 24,
+    VT_VF64 = 26
+  };
+  int8_t i8() const {
+    return GetField<int8_t>(VT_I8, 0);
+  }
+  bool mutate_i8(int8_t _i8) {
+    return SetField<int8_t>(VT_I8, _i8, 0);
+  }
+  uint8_t u8() const {
+    return GetField<uint8_t>(VT_U8, 0);
+  }
+  bool mutate_u8(uint8_t _u8) {
+    return SetField<uint8_t>(VT_U8, _u8, 0);
+  }
+  int16_t i16() const {
+    return GetField<int16_t>(VT_I16, 0);
+  }
+  bool mutate_i16(int16_t _i16) {
+    return SetField<int16_t>(VT_I16, _i16, 0);
+  }
+  uint16_t u16() const {
+    return GetField<uint16_t>(VT_U16, 0);
+  }
+  bool mutate_u16(uint16_t _u16) {
+    return SetField<uint16_t>(VT_U16, _u16, 0);
+  }
+  int32_t i32() const {
+    return GetField<int32_t>(VT_I32, 0);
+  }
+  bool mutate_i32(int32_t _i32) {
+    return SetField<int32_t>(VT_I32, _i32, 0);
+  }
+  uint32_t u32() const {
+    return GetField<uint32_t>(VT_U32, 0);
+  }
+  bool mutate_u32(uint32_t _u32) {
+    return SetField<uint32_t>(VT_U32, _u32, 0);
+  }
+  int64_t i64() const {
+    return GetField<int64_t>(VT_I64, 0);
+  }
+  bool mutate_i64(int64_t _i64) {
+    return SetField<int64_t>(VT_I64, _i64, 0);
+  }
+  uint64_t u64() const {
+    return GetField<uint64_t>(VT_U64, 0);
+  }
+  bool mutate_u64(uint64_t _u64) {
+    return SetField<uint64_t>(VT_U64, _u64, 0);
+  }
+  float f32() const {
+    return GetField<float>(VT_F32, 0.0f);
+  }
+  bool mutate_f32(float _f32) {
+    return SetField<float>(VT_F32, _f32, 0.0f);
+  }
+  double f64() const {
+    return GetField<double>(VT_F64, 0.0);
+  }
+  bool mutate_f64(double _f64) {
+    return SetField<double>(VT_F64, _f64, 0.0);
+  }
+  const flatbuffers::Vector<int8_t> *v8() const {
+    return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_V8);
+  }
+  flatbuffers::Vector<int8_t> *mutable_v8() {
+    return GetPointer<flatbuffers::Vector<int8_t> *>(VT_V8);
+  }
+  const flatbuffers::Vector<double> *vf64() const {
+    return GetPointer<const flatbuffers::Vector<double> *>(VT_VF64);
+  }
+  flatbuffers::Vector<double> *mutable_vf64() {
+    return GetPointer<flatbuffers::Vector<double> *>(VT_VF64);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int8_t>(verifier, VT_I8) &&
+           VerifyField<uint8_t>(verifier, VT_U8) &&
+           VerifyField<int16_t>(verifier, VT_I16) &&
+           VerifyField<uint16_t>(verifier, VT_U16) &&
+           VerifyField<int32_t>(verifier, VT_I32) &&
+           VerifyField<uint32_t>(verifier, VT_U32) &&
+           VerifyField<int64_t>(verifier, VT_I64) &&
+           VerifyField<uint64_t>(verifier, VT_U64) &&
+           VerifyField<float>(verifier, VT_F32) &&
+           VerifyField<double>(verifier, VT_F64) &&
+           VerifyOffset(verifier, VT_V8) &&
+           verifier.VerifyVector(v8()) &&
+           VerifyOffset(verifier, VT_VF64) &&
+           verifier.VerifyVector(vf64()) &&
+           verifier.EndTable();
+  }
+  TypeAliasesT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(TypeAliasesT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<TypeAliases> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct TypeAliasesBuilder {
+  typedef TypeAliases Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_i8(int8_t i8) {
+    fbb_.AddElement<int8_t>(TypeAliases::VT_I8, i8, 0);
+  }
+  void add_u8(uint8_t u8) {
+    fbb_.AddElement<uint8_t>(TypeAliases::VT_U8, u8, 0);
+  }
+  void add_i16(int16_t i16) {
+    fbb_.AddElement<int16_t>(TypeAliases::VT_I16, i16, 0);
+  }
+  void add_u16(uint16_t u16) {
+    fbb_.AddElement<uint16_t>(TypeAliases::VT_U16, u16, 0);
+  }
+  void add_i32(int32_t i32) {
+    fbb_.AddElement<int32_t>(TypeAliases::VT_I32, i32, 0);
+  }
+  void add_u32(uint32_t u32) {
+    fbb_.AddElement<uint32_t>(TypeAliases::VT_U32, u32, 0);
+  }
+  void add_i64(int64_t i64) {
+    fbb_.AddElement<int64_t>(TypeAliases::VT_I64, i64, 0);
+  }
+  void add_u64(uint64_t u64) {
+    fbb_.AddElement<uint64_t>(TypeAliases::VT_U64, u64, 0);
+  }
+  void add_f32(float f32) {
+    fbb_.AddElement<float>(TypeAliases::VT_F32, f32, 0.0f);
+  }
+  void add_f64(double f64) {
+    fbb_.AddElement<double>(TypeAliases::VT_F64, f64, 0.0);
+  }
+  void add_v8(flatbuffers::Offset<flatbuffers::Vector<int8_t>> v8) {
+    fbb_.AddOffset(TypeAliases::VT_V8, v8);
+  }
+  void add_vf64(flatbuffers::Offset<flatbuffers::Vector<double>> vf64) {
+    fbb_.AddOffset(TypeAliases::VT_VF64, vf64);
+  }
+  explicit TypeAliasesBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  flatbuffers::Offset<TypeAliases> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TypeAliases>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliases(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int8_t i8 = 0,
+    uint8_t u8 = 0,
+    int16_t i16 = 0,
+    uint16_t u16 = 0,
+    int32_t i32 = 0,
+    uint32_t u32 = 0,
+    int64_t i64 = 0,
+    uint64_t u64 = 0,
+    float f32 = 0.0f,
+    double f64 = 0.0,
+    flatbuffers::Offset<flatbuffers::Vector<int8_t>> v8 = 0,
+    flatbuffers::Offset<flatbuffers::Vector<double>> vf64 = 0) {
+  TypeAliasesBuilder builder_(_fbb);
+  builder_.add_f64(f64);
+  builder_.add_u64(u64);
+  builder_.add_i64(i64);
+  builder_.add_vf64(vf64);
+  builder_.add_v8(v8);
+  builder_.add_f32(f32);
+  builder_.add_u32(u32);
+  builder_.add_i32(i32);
+  builder_.add_u16(u16);
+  builder_.add_i16(i16);
+  builder_.add_u8(u8);
+  builder_.add_i8(i8);
+  return builder_.Finish();
+}
+
+struct TypeAliases::Traits {
+  using type = TypeAliases;
+  static auto constexpr Create = CreateTypeAliases;
+};
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliasesDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int8_t i8 = 0,
+    uint8_t u8 = 0,
+    int16_t i16 = 0,
+    uint16_t u16 = 0,
+    int32_t i32 = 0,
+    uint32_t u32 = 0,
+    int64_t i64 = 0,
+    uint64_t u64 = 0,
+    float f32 = 0.0f,
+    double f64 = 0.0,
+    const std::vector<int8_t> *v8 = nullptr,
+    const std::vector<double> *vf64 = nullptr) {
+  auto v8__ = v8 ? _fbb.CreateVector<int8_t>(*v8) : 0;
+  auto vf64__ = vf64 ? _fbb.CreateVector<double>(*vf64) : 0;
+  return MyGame::Example::CreateTypeAliases(
+      _fbb,
+      i8,
+      u8,
+      i16,
+      u16,
+      i32,
+      u32,
+      i64,
+      u64,
+      f32,
+      f64,
+      v8__,
+      vf64__);
+}
+
+flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+}  // namespace Example
+
+inline InParentNamespaceT *InParentNamespace::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = std::make_unique<InParentNamespaceT>();
+  UnPackTo(_o.get(), _resolver);
+  return _o.release();
+}
+
+inline void InParentNamespace::UnPackTo(InParentNamespaceT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+}
+
+inline flatbuffers::Offset<InParentNamespace> InParentNamespace::Pack(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateInParentNamespace(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const InParentNamespaceT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  return MyGame::CreateInParentNamespace(
+      _fbb);
+}
+
+namespace Example2 {
+
+inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = std::make_unique<MonsterT>();
+  UnPackTo(_o.get(), _resolver);
+  return _o.release();
+}
+
+inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+}
+
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonster(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  return MyGame::Example2::CreateMonster(
+      _fbb);
+}
+
+}  // namespace Example2
+
+namespace Example {
+
+inline TestSimpleTableWithEnumT *TestSimpleTableWithEnum::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = std::make_unique<TestSimpleTableWithEnumT>();
+  UnPackTo(_o.get(), _resolver);
+  return _o.release();
+}
+
+inline void TestSimpleTableWithEnum::UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = color(); _o->color = _e; }
+}
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> TestSimpleTableWithEnum::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateTestSimpleTableWithEnum(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TestSimpleTableWithEnumT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _color = _o->color;
+  return MyGame::Example::CreateTestSimpleTableWithEnum(
+      _fbb,
+      _color);
+}
+
+inline StatT *Stat::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = std::make_unique<StatT>();
+  UnPackTo(_o.get(), _resolver);
+  return _o.release();
+}
+
+inline void Stat::UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = id(); if (_e) _o->id = _e->str(); }
+  { auto _e = val(); _o->val = _e; }
+  { auto _e = count(); _o->count = _e; }
+}
+
+inline flatbuffers::Offset<Stat> Stat::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateStat(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StatT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _id = _o->id.empty() ? 0 : _fbb.CreateString(_o->id);
+  auto _val = _o->val;
+  auto _count = _o->count;
+  return MyGame::Example::CreateStat(
+      _fbb,
+      _id,
+      _val,
+      _count);
+}
+
+inline ReferrableT *Referrable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = std::make_unique<ReferrableT>();
+  UnPackTo(_o.get(), _resolver);
+  return _o.release();
+}
+
+inline void Referrable::UnPackTo(ReferrableT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = id(); _o->id = _e; }
+}
+
+inline flatbuffers::Offset<Referrable> Referrable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateReferrable(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Referrable> CreateReferrable(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ReferrableT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _id = _o->id;
+  return MyGame::Example::CreateReferrable(
+      _fbb,
+      _id);
+}
+
+inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = std::make_unique<MonsterT>();
+  UnPackTo(_o.get(), _resolver);
+  return _o.release();
+}
+
+inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = pos(); if (_e) _o->pos = std::unique_ptr<MyGame::Example::Vec3>(new MyGame::Example::Vec3(*_e)); }
+  { auto _e = mana(); _o->mana = _e; }
+  { auto _e = hp(); _o->hp = _e; }
+  { auto _e = name(); if (_e) _o->name = _e->str(); }
+  { auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->inventory.begin()); } }
+  { auto _e = color(); _o->color = _e; }
+  { auto _e = test_type(); _o->test.type = _e; }
+  { auto _e = test(); if (_e) _o->test.value = MyGame::Example::AnyUnion::UnPack(_e, test_type(), _resolver); }
+  { auto _e = test4(); if (_e) { _o->test4.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4[_i] = *_e->Get(_i); } } }
+  { auto _e = testarrayofstring(); if (_e) { _o->testarrayofstring.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring[_i] = _e->Get(_i)->str(); } } }
+  { auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables[_i] = std::unique_ptr<MyGame::Example::MonsterT>(_e->Get(_i)->UnPack(_resolver)); } } }
+  { auto _e = enemy(); if (_e) _o->enemy = std::unique_ptr<MyGame::Example::MonsterT>(_e->UnPack(_resolver)); }
+  { auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->testnestedflatbuffer.begin()); } }
+  { auto _e = testempty(); if (_e) _o->testempty = std::unique_ptr<MyGame::Example::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; }
+  { auto _e = testhashs64_fnv1(); _o->testhashs64_fnv1 = _e; }
+  { auto _e = testhashu64_fnv1(); _o->testhashu64_fnv1 = _e; }
+  { auto _e = testhashs32_fnv1a(); _o->testhashs32_fnv1a = _e; }
+  { auto _e = testhashu32_fnv1a(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->testhashu32_fnv1a), static_cast<flatbuffers::hash_value_t>(_e)); else _o->testhashu32_fnv1a = nullptr; }
+  { auto _e = testhashs64_fnv1a(); _o->testhashs64_fnv1a = _e; }
+  { auto _e = testhashu64_fnv1a(); _o->testhashu64_fnv1a = _e; }
+  { auto _e = testarrayofbools(); if (_e) { _o->testarrayofbools.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofbools[_i] = _e->Get(_i) != 0; } } }
+  { auto _e = testf(); _o->testf = _e; }
+  { auto _e = testf2(); _o->testf2 = _e; }
+  { auto _e = testf3(); _o->testf3 = _e; }
+  { auto _e = testarrayofstring2(); if (_e) { _o->testarrayofstring2.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring2[_i] = _e->Get(_i)->str(); } } }
+  { auto _e = testarrayofsortedstruct(); if (_e) { _o->testarrayofsortedstruct.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofsortedstruct[_i] = *_e->Get(_i); } } }
+  { auto _e = flex(); if (_e) { _o->flex.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->flex.begin()); } }
+  { auto _e = test5(); if (_e) { _o->test5.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test5[_i] = *_e->Get(_i); } } }
+  { auto _e = vector_of_longs(); if (_e) { _o->vector_of_longs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_longs[_i] = _e->Get(_i); } } }
+  { auto _e = vector_of_doubles(); if (_e) { _o->vector_of_doubles.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_doubles[_i] = _e->Get(_i); } } }
+  { auto _e = parent_namespace_test(); if (_e) _o->parent_namespace_test = std::unique_ptr<MyGame::InParentNamespaceT>(_e->UnPack(_resolver)); }
+  { auto _e = vector_of_referrables(); if (_e) { _o->vector_of_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_referrables[_i] = std::unique_ptr<MyGame::Example::ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } }
+  { auto _e = single_weak_reference(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->single_weak_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->single_weak_reference = nullptr; }
+  { auto _e = vector_of_weak_references(); if (_e) { _o->vector_of_weak_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_weak_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_weak_references[_i] = nullptr; } } }
+  { auto _e = vector_of_strong_referrables(); if (_e) { _o->vector_of_strong_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_strong_referrables[_i] = std::unique_ptr<MyGame::Example::ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } }
+  { auto _e = co_owning_reference(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->co_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->co_owning_reference = nullptr; }
+  { auto _e = vector_of_co_owning_references(); if (_e) { _o->vector_of_co_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, default_ptr_type
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_co_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i)));/* else do nothing */; } } }
+  { auto _e = non_owning_reference(); //scalar resolver, naked 
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->non_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->non_owning_reference = nullptr; }
+  { auto _e = vector_of_non_owning_references(); if (_e) { _o->vector_of_non_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_non_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_non_owning_references[_i] = nullptr; } } }
+  { auto _e = any_unique_type(); _o->any_unique.type = _e; }
+  { auto _e = any_unique(); if (_e) _o->any_unique.value = MyGame::Example::AnyUniqueAliasesUnion::UnPack(_e, any_unique_type(), _resolver); }
+  { auto _e = any_ambiguous_type(); _o->any_ambiguous.type = _e; }
+  { auto _e = any_ambiguous(); if (_e) _o->any_ambiguous.value = MyGame::Example::AnyAmbiguousAliasesUnion::UnPack(_e, any_ambiguous_type(), _resolver); }
+  { auto _e = vector_of_enums(); if (_e) { _o->vector_of_enums.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_enums[_i] = static_cast<MyGame::Example::Color>(_e->Get(_i)); } } }
+  { auto _e = signed_enum(); _o->signed_enum = _e; }
+  { auto _e = testrequirednestedflatbuffer(); if (_e) { _o->testrequirednestedflatbuffer.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->testrequirednestedflatbuffer.begin()); } }
+}
+
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonster(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _pos = _o->pos ? _o->pos.get() : 0;
+  auto _mana = _o->mana;
+  auto _hp = _o->hp;
+  auto _name = _fbb.CreateString(_o->name);
+  auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
+  auto _color = _o->color;
+  auto _test_type = _o->test.type;
+  auto _test = _o->test.Pack(_fbb);
+  auto _test4 = _o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 0;
+  auto _testarrayofstring = _o->testarrayofstring.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring) : 0;
+  auto _testarrayoftables = _o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Monster>> (_o->testarrayoftables.size(), [](size_t i, _VectorArgs *__va) { return CreateMonster(*__va->__fbb, __va->__o->testarrayoftables[i].get(), __va->__rehasher); }, &_va ) : 0;
+  auto _enemy = _o->enemy ? CreateMonster(_fbb, _o->enemy.get(), _rehasher) : 0;
+  auto _testnestedflatbuffer = _o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0;
+  auto _testempty = _o->testempty ? CreateStat(_fbb, _o->testempty.get(), _rehasher) : 0;
+  auto _testbool = _o->testbool;
+  auto _testhashs32_fnv1 = _o->testhashs32_fnv1;
+  auto _testhashu32_fnv1 = _o->testhashu32_fnv1;
+  auto _testhashs64_fnv1 = _o->testhashs64_fnv1;
+  auto _testhashu64_fnv1 = _o->testhashu64_fnv1;
+  auto _testhashs32_fnv1a = _o->testhashs32_fnv1a;
+  auto _testhashu32_fnv1a = _rehasher ? static_cast<uint32_t>((*_rehasher)(_o->testhashu32_fnv1a)) : 0;
+  auto _testhashs64_fnv1a = _o->testhashs64_fnv1a;
+  auto _testhashu64_fnv1a = _o->testhashu64_fnv1a;
+  auto _testarrayofbools = _o->testarrayofbools.size() ? _fbb.CreateVector(_o->testarrayofbools) : 0;
+  auto _testf = _o->testf;
+  auto _testf2 = _o->testf2;
+  auto _testf3 = _o->testf3;
+  auto _testarrayofstring2 = _o->testarrayofstring2.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring2) : 0;
+  auto _testarrayofsortedstruct = _o->testarrayofsortedstruct.size() ? _fbb.CreateVectorOfStructs(_o->testarrayofsortedstruct) : 0;
+  auto _flex = _o->flex.size() ? _fbb.CreateVector(_o->flex) : 0;
+  auto _test5 = _o->test5.size() ? _fbb.CreateVectorOfStructs(_o->test5) : 0;
+  auto _vector_of_longs = _o->vector_of_longs.size() ? _fbb.CreateVector(_o->vector_of_longs) : 0;
+  auto _vector_of_doubles = _o->vector_of_doubles.size() ? _fbb.CreateVector(_o->vector_of_doubles) : 0;
+  auto _parent_namespace_test = _o->parent_namespace_test ? CreateInParentNamespace(_fbb, _o->parent_namespace_test.get(), _rehasher) : 0;
+  auto _vector_of_referrables = _o->vector_of_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>> (_o->vector_of_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
+  auto _single_weak_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->single_weak_reference)) : 0;
+  auto _vector_of_weak_references = _o->vector_of_weak_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_weak_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_weak_references[i])) : 0; }, &_va ) : 0;
+  auto _vector_of_strong_referrables = _o->vector_of_strong_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>> (_o->vector_of_strong_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_strong_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
+  auto _co_owning_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->co_owning_reference)) : 0;
+  auto _vector_of_co_owning_references = _o->vector_of_co_owning_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_co_owning_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_co_owning_references[i].get())) : 0; }, &_va ) : 0;
+  auto _non_owning_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->non_owning_reference)) : 0;
+  auto _vector_of_non_owning_references = _o->vector_of_non_owning_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_non_owning_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_non_owning_references[i])) : 0; }, &_va ) : 0;
+  auto _any_unique_type = _o->any_unique.type;
+  auto _any_unique = _o->any_unique.Pack(_fbb);
+  auto _any_ambiguous_type = _o->any_ambiguous.type;
+  auto _any_ambiguous = _o->any_ambiguous.Pack(_fbb);
+  auto _vector_of_enums = _o->vector_of_enums.size() ? _fbb.CreateVector(_o->vector_of_enums) : 0;
+  auto _signed_enum = _o->signed_enum;
+  auto _testrequirednestedflatbuffer = _o->testrequirednestedflatbuffer.size() ? _fbb.CreateVector(_o->testrequirednestedflatbuffer) : 0;
+  return MyGame::Example::CreateMonster(
+      _fbb,
+      _pos,
+      _mana,
+      _hp,
+      _name,
+      _inventory,
+      _color,
+      _test_type,
+      _test,
+      _test4,
+      _testarrayofstring,
+      _testarrayoftables,
+      _enemy,
+      _testnestedflatbuffer,
+      _testempty,
+      _testbool,
+      _testhashs32_fnv1,
+      _testhashu32_fnv1,
+      _testhashs64_fnv1,
+      _testhashu64_fnv1,
+      _testhashs32_fnv1a,
+      _testhashu32_fnv1a,
+      _testhashs64_fnv1a,
+      _testhashu64_fnv1a,
+      _testarrayofbools,
+      _testf,
+      _testf2,
+      _testf3,
+      _testarrayofstring2,
+      _testarrayofsortedstruct,
+      _flex,
+      _test5,
+      _vector_of_longs,
+      _vector_of_doubles,
+      _parent_namespace_test,
+      _vector_of_referrables,
+      _single_weak_reference,
+      _vector_of_weak_references,
+      _vector_of_strong_referrables,
+      _co_owning_reference,
+      _vector_of_co_owning_references,
+      _non_owning_reference,
+      _vector_of_non_owning_references,
+      _any_unique_type,
+      _any_unique,
+      _any_ambiguous_type,
+      _any_ambiguous,
+      _vector_of_enums,
+      _signed_enum,
+      _testrequirednestedflatbuffer);
+}
+
+inline TypeAliasesT *TypeAliases::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = std::make_unique<TypeAliasesT>();
+  UnPackTo(_o.get(), _resolver);
+  return _o.release();
+}
+
+inline void TypeAliases::UnPackTo(TypeAliasesT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = i8(); _o->i8 = _e; }
+  { auto _e = u8(); _o->u8 = _e; }
+  { auto _e = i16(); _o->i16 = _e; }
+  { auto _e = u16(); _o->u16 = _e; }
+  { auto _e = i32(); _o->i32 = _e; }
+  { auto _e = u32(); _o->u32 = _e; }
+  { auto _e = i64(); _o->i64 = _e; }
+  { auto _e = u64(); _o->u64 = _e; }
+  { auto _e = f32(); _o->f32 = _e; }
+  { auto _e = f64(); _o->f64 = _e; }
+  { auto _e = v8(); if (_e) { _o->v8.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->v8.begin()); } }
+  { auto _e = vf64(); if (_e) { _o->vf64.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vf64[_i] = _e->Get(_i); } } }
+}
+
+inline flatbuffers::Offset<TypeAliases> TypeAliases::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateTypeAliases(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TypeAliasesT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _i8 = _o->i8;
+  auto _u8 = _o->u8;
+  auto _i16 = _o->i16;
+  auto _u16 = _o->u16;
+  auto _i32 = _o->i32;
+  auto _u32 = _o->u32;
+  auto _i64 = _o->i64;
+  auto _u64 = _o->u64;
+  auto _f32 = _o->f32;
+  auto _f64 = _o->f64;
+  auto _v8 = _o->v8.size() ? _fbb.CreateVector(_o->v8) : 0;
+  auto _vf64 = _o->vf64.size() ? _fbb.CreateVector(_o->vf64) : 0;
+  return MyGame::Example::CreateTypeAliases(
+      _fbb,
+      _i8,
+      _u8,
+      _i16,
+      _u16,
+      _i32,
+      _u32,
+      _i64,
+      _u64,
+      _f32,
+      _f64,
+      _v8,
+      _vf64);
+}
+
+inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type) {
+  switch (type) {
+    case Any::NONE: {
+      return true;
+    }
+    case Any::Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Any::TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Any::MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return true;
+  }
+}
+
+inline bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyAny(
+        verifier,  values->Get(i), types->GetEnum<Any>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *AnyUnion::UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case Any::Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case Any::TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case Any::MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> AnyUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case Any::Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case Any::TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      return CreateTestSimpleTableWithEnum(_fbb, ptr, _rehasher).Union();
+    }
+    case Any::MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline AnyUnion::AnyUnion(const AnyUnion &u) : type(u.type), value(nullptr) {
+  switch (type) {
+    case Any::Monster: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case Any::TestSimpleTableWithEnum: {
+      value = new MyGame::Example::TestSimpleTableWithEnumT(*reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(u.value));
+      break;
+    }
+    case Any::MyGame_Example2_Monster: {
+      value = new MyGame::Example2::MonsterT(*reinterpret_cast<MyGame::Example2::MonsterT *>(u.value));
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void AnyUnion::Reset() {
+  switch (type) {
+    case Any::Monster: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case Any::TestSimpleTableWithEnum: {
+      auto ptr = reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      delete ptr;
+      break;
+    }
+    case Any::MyGame_Example2_Monster: {
+      auto ptr = reinterpret_cast<MyGame::Example2::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = Any::NONE;
+}
+
+inline bool VerifyAnyUniqueAliases(flatbuffers::Verifier &verifier, const void *obj, AnyUniqueAliases type) {
+  switch (type) {
+    case AnyUniqueAliases::NONE: {
+      return true;
+    }
+    case AnyUniqueAliases::M: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyUniqueAliases::TS: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyUniqueAliases::M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return true;
+  }
+}
+
+inline bool VerifyAnyUniqueAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyAnyUniqueAliases(
+        verifier,  values->Get(i), types->GetEnum<AnyUniqueAliases>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *AnyUniqueAliasesUnion::UnPack(const void *obj, AnyUniqueAliases type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case AnyUniqueAliases::M: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyUniqueAliases::TS: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyUniqueAliases::M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> AnyUniqueAliasesUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case AnyUniqueAliases::M: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyUniqueAliases::TS: {
+      auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      return CreateTestSimpleTableWithEnum(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyUniqueAliases::M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example2::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline AnyUniqueAliasesUnion::AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &u) : type(u.type), value(nullptr) {
+  switch (type) {
+    case AnyUniqueAliases::M: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case AnyUniqueAliases::TS: {
+      value = new MyGame::Example::TestSimpleTableWithEnumT(*reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(u.value));
+      break;
+    }
+    case AnyUniqueAliases::M2: {
+      value = new MyGame::Example2::MonsterT(*reinterpret_cast<MyGame::Example2::MonsterT *>(u.value));
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void AnyUniqueAliasesUnion::Reset() {
+  switch (type) {
+    case AnyUniqueAliases::M: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyUniqueAliases::TS: {
+      auto ptr = reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyUniqueAliases::M2: {
+      auto ptr = reinterpret_cast<MyGame::Example2::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = AnyUniqueAliases::NONE;
+}
+
+inline bool VerifyAnyAmbiguousAliases(flatbuffers::Verifier &verifier, const void *obj, AnyAmbiguousAliases type) {
+  switch (type) {
+    case AnyAmbiguousAliases::NONE: {
+      return true;
+    }
+    case AnyAmbiguousAliases::M1: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyAmbiguousAliases::M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case AnyAmbiguousAliases::M3: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return true;
+  }
+}
+
+inline bool VerifyAnyAmbiguousAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+  if (!values || !types) return !values && !types;
+  if (values->size() != types->size()) return false;
+  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+    if (!VerifyAnyAmbiguousAliases(
+        verifier,  values->Get(i), types->GetEnum<AnyAmbiguousAliases>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline void *AnyAmbiguousAliasesUnion::UnPack(const void *obj, AnyAmbiguousAliases type, const flatbuffers::resolver_function_t *resolver) {
+  switch (type) {
+    case AnyAmbiguousAliases::M1: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyAmbiguousAliases::M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    case AnyAmbiguousAliases::M3: {
+      auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+      return ptr->UnPack(resolver);
+    }
+    default: return nullptr;
+  }
+}
+
+inline flatbuffers::Offset<void> AnyAmbiguousAliasesUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+  switch (type) {
+    case AnyAmbiguousAliases::M1: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyAmbiguousAliases::M2: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    case AnyAmbiguousAliases::M3: {
+      auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+      return CreateMonster(_fbb, ptr, _rehasher).Union();
+    }
+    default: return 0;
+  }
+}
+
+inline AnyAmbiguousAliasesUnion::AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &u) : type(u.type), value(nullptr) {
+  switch (type) {
+    case AnyAmbiguousAliases::M1: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case AnyAmbiguousAliases::M2: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    case AnyAmbiguousAliases::M3: {
+      FLATBUFFERS_ASSERT(false);  // MyGame::Example::MonsterT not copyable.
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+inline void AnyAmbiguousAliasesUnion::Reset() {
+  switch (type) {
+    case AnyAmbiguousAliases::M1: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyAmbiguousAliases::M2: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    case AnyAmbiguousAliases::M3: {
+      auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+      delete ptr;
+      break;
+    }
+    default: break;
+  }
+  value = nullptr;
+  type = AnyAmbiguousAliases::NONE;
+}
+
+inline const flatbuffers::TypeTable *ColorTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UCHAR, 0, 0 },
+    { flatbuffers::ET_UCHAR, 0, 0 },
+    { flatbuffers::ET_UCHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ColorTypeTable
+  };
+  static const int64_t values[] = { 1, 2, 8 };
+  static const char * const names[] = {
+    "Red",
+    "Green",
+    "Blue"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *RaceTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::RaceTypeTable
+  };
+  static const int64_t values[] = { -1, 0, 1, 2 };
+  static const char * const names[] = {
+    "None",
+    "Human",
+    "Dwarf",
+    "Elf"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 4, type_codes, type_refs, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::MonsterTypeTable,
+    MyGame::Example::TestSimpleTableWithEnumTypeTable,
+    MyGame::Example2::MonsterTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "Monster",
+    "TestSimpleTableWithEnum",
+    "MyGame_Example2_Monster"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyUniqueAliasesTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::MonsterTypeTable,
+    MyGame::Example::TestSimpleTableWithEnumTypeTable,
+    MyGame::Example2::MonsterTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "M",
+    "TS",
+    "M2"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyAmbiguousAliasesTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::MonsterTypeTable
+  };
+  static const char * const names[] = {
+    "NONE",
+    "M1",
+    "M2",
+    "M3"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+}  // namespace Example
+
+inline const flatbuffers::TypeTable *InParentNamespaceTypeTable() {
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr, nullptr
+  };
+  return &tt;
+}
+
+namespace Example2 {
+
+inline const flatbuffers::TypeTable *MonsterTypeTable() {
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr, nullptr
+  };
+  return &tt;
+}
+
+}  // namespace Example2
+
+namespace Example {
+
+inline const flatbuffers::TypeTable *TestTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 2, 4 };
+  static const char * const names[] = {
+    "a",
+    "b"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 2, type_codes, nullptr, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UCHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ColorTypeTable
+  };
+  static const char * const names[] = {
+    "color"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *Vec3TypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, 0 },
+    { flatbuffers::ET_SEQUENCE, 0, 1 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::ColorTypeTable,
+    MyGame::Example::TestTypeTable
+  };
+  static const int64_t values[] = { 0, 4, 8, 16, 24, 26, 32 };
+  static const char * const names[] = {
+    "x",
+    "y",
+    "z",
+    "test1",
+    "test2",
+    "test3"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 6, type_codes, type_refs, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *AbilityTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 }
+  };
+  static const int64_t values[] = { 0, 4, 8 };
+  static const char * const names[] = {
+    "id",
+    "distance"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_STRUCT, 2, type_codes, nullptr, nullptr, values, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *StatTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_STRING, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 }
+  };
+  static const char * const names[] = {
+    "id",
+    "val",
+    "count"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 3, type_codes, nullptr, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ReferrableTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_ULONG, 0, -1 }
+  };
+  static const char * const names[] = {
+    "id"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *MonsterTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_SEQUENCE, 0, 0 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_STRING, 0, -1 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_UCHAR, 1, -1 },
+    { flatbuffers::ET_UCHAR, 0, 1 },
+    { flatbuffers::ET_UTYPE, 0, 2 },
+    { flatbuffers::ET_SEQUENCE, 0, 2 },
+    { flatbuffers::ET_SEQUENCE, 1, 3 },
+    { flatbuffers::ET_STRING, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 4 },
+    { flatbuffers::ET_SEQUENCE, 0, 4 },
+    { flatbuffers::ET_UCHAR, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 5 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_BOOL, 1, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_STRING, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 6 },
+    { flatbuffers::ET_UCHAR, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 3 },
+    { flatbuffers::ET_LONG, 1, -1 },
+    { flatbuffers::ET_DOUBLE, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 0, 7 },
+    { flatbuffers::ET_SEQUENCE, 1, 8 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 1, -1 },
+    { flatbuffers::ET_SEQUENCE, 1, 8 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 1, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 1, -1 },
+    { flatbuffers::ET_UTYPE, 0, 9 },
+    { flatbuffers::ET_SEQUENCE, 0, 9 },
+    { flatbuffers::ET_UTYPE, 0, 10 },
+    { flatbuffers::ET_SEQUENCE, 0, 10 },
+    { flatbuffers::ET_UCHAR, 1, 1 },
+    { flatbuffers::ET_CHAR, 0, 11 },
+    { flatbuffers::ET_UCHAR, 1, -1 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    MyGame::Example::Vec3TypeTable,
+    MyGame::Example::ColorTypeTable,
+    MyGame::Example::AnyTypeTable,
+    MyGame::Example::TestTypeTable,
+    MyGame::Example::MonsterTypeTable,
+    MyGame::Example::StatTypeTable,
+    MyGame::Example::AbilityTypeTable,
+    MyGame::InParentNamespaceTypeTable,
+    MyGame::Example::ReferrableTypeTable,
+    MyGame::Example::AnyUniqueAliasesTypeTable,
+    MyGame::Example::AnyAmbiguousAliasesTypeTable,
+    MyGame::Example::RaceTypeTable
+  };
+  static const char * const names[] = {
+    "pos",
+    "mana",
+    "hp",
+    "name",
+    "friendly",
+    "inventory",
+    "color",
+    "test_type",
+    "test",
+    "test4",
+    "testarrayofstring",
+    "testarrayoftables",
+    "enemy",
+    "testnestedflatbuffer",
+    "testempty",
+    "testbool",
+    "testhashs32_fnv1",
+    "testhashu32_fnv1",
+    "testhashs64_fnv1",
+    "testhashu64_fnv1",
+    "testhashs32_fnv1a",
+    "testhashu32_fnv1a",
+    "testhashs64_fnv1a",
+    "testhashu64_fnv1a",
+    "testarrayofbools",
+    "testf",
+    "testf2",
+    "testf3",
+    "testarrayofstring2",
+    "testarrayofsortedstruct",
+    "flex",
+    "test5",
+    "vector_of_longs",
+    "vector_of_doubles",
+    "parent_namespace_test",
+    "vector_of_referrables",
+    "single_weak_reference",
+    "vector_of_weak_references",
+    "vector_of_strong_referrables",
+    "co_owning_reference",
+    "vector_of_co_owning_references",
+    "non_owning_reference",
+    "vector_of_non_owning_references",
+    "any_unique_type",
+    "any_unique",
+    "any_ambiguous_type",
+    "any_ambiguous",
+    "vector_of_enums",
+    "signed_enum",
+    "testrequirednestedflatbuffer"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 50, type_codes, type_refs, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *TypeAliasesTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_CHAR, 1, -1 },
+    { flatbuffers::ET_DOUBLE, 1, -1 }
+  };
+  static const char * const names[] = {
+    "i8",
+    "u8",
+    "i16",
+    "u16",
+    "i32",
+    "u32",
+    "i64",
+    "u64",
+    "f32",
+    "f64",
+    "v8",
+    "vf64"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 12, type_codes, nullptr, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const MyGame::Example::Monster *GetMonster(const void *buf) {
+  return flatbuffers::GetRoot<MyGame::Example::Monster>(buf);
+}
+
+inline const MyGame::Example::Monster *GetSizePrefixedMonster(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<MyGame::Example::Monster>(buf);
+}
+
+inline Monster *GetMutableMonster(void *buf) {
+  return flatbuffers::GetMutableRoot<Monster>(buf);
+}
+
+inline const char *MonsterIdentifier() {
+  return "MONS";
+}
+
+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 VerifySizePrefixedMonsterBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<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 FinishSizePrefixedMonsterBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<MyGame::Example::Monster> root) {
+  fbb.FinishSizePrefixed(root, MonsterIdentifier());
+}
+
+inline std::unique_ptr<MyGame::Example::MonsterT> UnPackMonster(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return std::unique_ptr<MyGame::Example::MonsterT>(GetMonster(buf)->UnPack(res));
+}
+
+inline std::unique_ptr<MyGame::Example::MonsterT> UnPackSizePrefixedMonster(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return std::unique_ptr<MyGame::Example::MonsterT>(GetSizePrefixedMonster(buf)->UnPack(res));
+}
+
+}  // namespace Example
+}  // namespace MyGame
+
+#endif  // FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
diff --git a/tests/cpp17/generated_cpp17/optional_scalars2_generated.h b/tests/cpp17/generated_cpp17/optional_scalars2_generated.h
new file mode 100644
index 0000000..1aba093
--- /dev/null
+++ b/tests/cpp17/generated_cpp17/optional_scalars2_generated.h
@@ -0,0 +1,902 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_OPTIONALSCALARS2_OPTIONAL_SCALARS_H_
+#define FLATBUFFERS_GENERATED_OPTIONALSCALARS2_OPTIONAL_SCALARS_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace optional_scalars {
+
+struct ScalarStuff;
+struct ScalarStuffBuilder;
+struct ScalarStuffT;
+
+inline const flatbuffers::TypeTable *ScalarStuffTypeTable();
+
+enum class OptionalByte : int8_t {
+  None = 0,
+  One = 1,
+  Two = 2,
+  MIN = None,
+  MAX = Two
+};
+
+inline const OptionalByte (&EnumValuesOptionalByte())[3] {
+  static const OptionalByte values[] = {
+    OptionalByte::None,
+    OptionalByte::One,
+    OptionalByte::Two
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesOptionalByte() {
+  static const char * const names[4] = {
+    "None",
+    "One",
+    "Two",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameOptionalByte(OptionalByte e) {
+  if (flatbuffers::IsOutRange(e, OptionalByte::None, OptionalByte::Two)) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesOptionalByte()[index];
+}
+
+struct ScalarStuffT : public flatbuffers::NativeTable {
+  typedef ScalarStuff TableType;
+  int8_t just_i8 = 0;
+  flatbuffers::Optional<int8_t> maybe_i8 = flatbuffers::nullopt;
+  int8_t default_i8 = 42;
+  uint8_t just_u8 = 0;
+  flatbuffers::Optional<uint8_t> maybe_u8 = flatbuffers::nullopt;
+  uint8_t default_u8 = 42;
+  int16_t just_i16 = 0;
+  flatbuffers::Optional<int16_t> maybe_i16 = flatbuffers::nullopt;
+  int16_t default_i16 = 42;
+  uint16_t just_u16 = 0;
+  flatbuffers::Optional<uint16_t> maybe_u16 = flatbuffers::nullopt;
+  uint16_t default_u16 = 42;
+  int32_t just_i32 = 0;
+  flatbuffers::Optional<int32_t> maybe_i32 = flatbuffers::nullopt;
+  int32_t default_i32 = 42;
+  uint32_t just_u32 = 0;
+  flatbuffers::Optional<uint32_t> maybe_u32 = flatbuffers::nullopt;
+  uint32_t default_u32 = 42;
+  int64_t just_i64 = 0;
+  flatbuffers::Optional<int64_t> maybe_i64 = flatbuffers::nullopt;
+  int64_t default_i64 = 42LL;
+  uint64_t just_u64 = 0;
+  flatbuffers::Optional<uint64_t> maybe_u64 = flatbuffers::nullopt;
+  uint64_t default_u64 = 42ULL;
+  float just_f32 = 0.0f;
+  flatbuffers::Optional<float> maybe_f32 = flatbuffers::nullopt;
+  float default_f32 = 42.0f;
+  double just_f64 = 0.0;
+  flatbuffers::Optional<double> maybe_f64 = flatbuffers::nullopt;
+  double default_f64 = 42.0;
+  bool just_bool = false;
+  flatbuffers::Optional<bool> maybe_bool = flatbuffers::nullopt;
+  bool default_bool = true;
+  optional_scalars::OptionalByte just_enum = optional_scalars::OptionalByte::None;
+  flatbuffers::Optional<optional_scalars::OptionalByte> maybe_enum = flatbuffers::nullopt;
+  optional_scalars::OptionalByte default_enum = optional_scalars::OptionalByte::One;
+};
+
+struct ScalarStuff FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ScalarStuffT NativeTableType;
+  typedef ScalarStuffBuilder Builder;
+  struct Traits;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ScalarStuffTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_JUST_I8 = 4,
+    VT_MAYBE_I8 = 6,
+    VT_DEFAULT_I8 = 8,
+    VT_JUST_U8 = 10,
+    VT_MAYBE_U8 = 12,
+    VT_DEFAULT_U8 = 14,
+    VT_JUST_I16 = 16,
+    VT_MAYBE_I16 = 18,
+    VT_DEFAULT_I16 = 20,
+    VT_JUST_U16 = 22,
+    VT_MAYBE_U16 = 24,
+    VT_DEFAULT_U16 = 26,
+    VT_JUST_I32 = 28,
+    VT_MAYBE_I32 = 30,
+    VT_DEFAULT_I32 = 32,
+    VT_JUST_U32 = 34,
+    VT_MAYBE_U32 = 36,
+    VT_DEFAULT_U32 = 38,
+    VT_JUST_I64 = 40,
+    VT_MAYBE_I64 = 42,
+    VT_DEFAULT_I64 = 44,
+    VT_JUST_U64 = 46,
+    VT_MAYBE_U64 = 48,
+    VT_DEFAULT_U64 = 50,
+    VT_JUST_F32 = 52,
+    VT_MAYBE_F32 = 54,
+    VT_DEFAULT_F32 = 56,
+    VT_JUST_F64 = 58,
+    VT_MAYBE_F64 = 60,
+    VT_DEFAULT_F64 = 62,
+    VT_JUST_BOOL = 64,
+    VT_MAYBE_BOOL = 66,
+    VT_DEFAULT_BOOL = 68,
+    VT_JUST_ENUM = 70,
+    VT_MAYBE_ENUM = 72,
+    VT_DEFAULT_ENUM = 74
+  };
+  int8_t just_i8() const {
+    return GetField<int8_t>(VT_JUST_I8, 0);
+  }
+  bool mutate_just_i8(int8_t _just_i8) {
+    return SetField<int8_t>(VT_JUST_I8, _just_i8, 0);
+  }
+  flatbuffers::Optional<int8_t> maybe_i8() const {
+    return GetOptional<int8_t, int8_t>(VT_MAYBE_I8);
+  }
+  bool mutate_maybe_i8(int8_t _maybe_i8) {
+    return SetField<int8_t>(VT_MAYBE_I8, _maybe_i8);
+  }
+  int8_t default_i8() const {
+    return GetField<int8_t>(VT_DEFAULT_I8, 42);
+  }
+  bool mutate_default_i8(int8_t _default_i8) {
+    return SetField<int8_t>(VT_DEFAULT_I8, _default_i8, 42);
+  }
+  uint8_t just_u8() const {
+    return GetField<uint8_t>(VT_JUST_U8, 0);
+  }
+  bool mutate_just_u8(uint8_t _just_u8) {
+    return SetField<uint8_t>(VT_JUST_U8, _just_u8, 0);
+  }
+  flatbuffers::Optional<uint8_t> maybe_u8() const {
+    return GetOptional<uint8_t, uint8_t>(VT_MAYBE_U8);
+  }
+  bool mutate_maybe_u8(uint8_t _maybe_u8) {
+    return SetField<uint8_t>(VT_MAYBE_U8, _maybe_u8);
+  }
+  uint8_t default_u8() const {
+    return GetField<uint8_t>(VT_DEFAULT_U8, 42);
+  }
+  bool mutate_default_u8(uint8_t _default_u8) {
+    return SetField<uint8_t>(VT_DEFAULT_U8, _default_u8, 42);
+  }
+  int16_t just_i16() const {
+    return GetField<int16_t>(VT_JUST_I16, 0);
+  }
+  bool mutate_just_i16(int16_t _just_i16) {
+    return SetField<int16_t>(VT_JUST_I16, _just_i16, 0);
+  }
+  flatbuffers::Optional<int16_t> maybe_i16() const {
+    return GetOptional<int16_t, int16_t>(VT_MAYBE_I16);
+  }
+  bool mutate_maybe_i16(int16_t _maybe_i16) {
+    return SetField<int16_t>(VT_MAYBE_I16, _maybe_i16);
+  }
+  int16_t default_i16() const {
+    return GetField<int16_t>(VT_DEFAULT_I16, 42);
+  }
+  bool mutate_default_i16(int16_t _default_i16) {
+    return SetField<int16_t>(VT_DEFAULT_I16, _default_i16, 42);
+  }
+  uint16_t just_u16() const {
+    return GetField<uint16_t>(VT_JUST_U16, 0);
+  }
+  bool mutate_just_u16(uint16_t _just_u16) {
+    return SetField<uint16_t>(VT_JUST_U16, _just_u16, 0);
+  }
+  flatbuffers::Optional<uint16_t> maybe_u16() const {
+    return GetOptional<uint16_t, uint16_t>(VT_MAYBE_U16);
+  }
+  bool mutate_maybe_u16(uint16_t _maybe_u16) {
+    return SetField<uint16_t>(VT_MAYBE_U16, _maybe_u16);
+  }
+  uint16_t default_u16() const {
+    return GetField<uint16_t>(VT_DEFAULT_U16, 42);
+  }
+  bool mutate_default_u16(uint16_t _default_u16) {
+    return SetField<uint16_t>(VT_DEFAULT_U16, _default_u16, 42);
+  }
+  int32_t just_i32() const {
+    return GetField<int32_t>(VT_JUST_I32, 0);
+  }
+  bool mutate_just_i32(int32_t _just_i32) {
+    return SetField<int32_t>(VT_JUST_I32, _just_i32, 0);
+  }
+  flatbuffers::Optional<int32_t> maybe_i32() const {
+    return GetOptional<int32_t, int32_t>(VT_MAYBE_I32);
+  }
+  bool mutate_maybe_i32(int32_t _maybe_i32) {
+    return SetField<int32_t>(VT_MAYBE_I32, _maybe_i32);
+  }
+  int32_t default_i32() const {
+    return GetField<int32_t>(VT_DEFAULT_I32, 42);
+  }
+  bool mutate_default_i32(int32_t _default_i32) {
+    return SetField<int32_t>(VT_DEFAULT_I32, _default_i32, 42);
+  }
+  uint32_t just_u32() const {
+    return GetField<uint32_t>(VT_JUST_U32, 0);
+  }
+  bool mutate_just_u32(uint32_t _just_u32) {
+    return SetField<uint32_t>(VT_JUST_U32, _just_u32, 0);
+  }
+  flatbuffers::Optional<uint32_t> maybe_u32() const {
+    return GetOptional<uint32_t, uint32_t>(VT_MAYBE_U32);
+  }
+  bool mutate_maybe_u32(uint32_t _maybe_u32) {
+    return SetField<uint32_t>(VT_MAYBE_U32, _maybe_u32);
+  }
+  uint32_t default_u32() const {
+    return GetField<uint32_t>(VT_DEFAULT_U32, 42);
+  }
+  bool mutate_default_u32(uint32_t _default_u32) {
+    return SetField<uint32_t>(VT_DEFAULT_U32, _default_u32, 42);
+  }
+  int64_t just_i64() const {
+    return GetField<int64_t>(VT_JUST_I64, 0);
+  }
+  bool mutate_just_i64(int64_t _just_i64) {
+    return SetField<int64_t>(VT_JUST_I64, _just_i64, 0);
+  }
+  flatbuffers::Optional<int64_t> maybe_i64() const {
+    return GetOptional<int64_t, int64_t>(VT_MAYBE_I64);
+  }
+  bool mutate_maybe_i64(int64_t _maybe_i64) {
+    return SetField<int64_t>(VT_MAYBE_I64, _maybe_i64);
+  }
+  int64_t default_i64() const {
+    return GetField<int64_t>(VT_DEFAULT_I64, 42LL);
+  }
+  bool mutate_default_i64(int64_t _default_i64) {
+    return SetField<int64_t>(VT_DEFAULT_I64, _default_i64, 42LL);
+  }
+  uint64_t just_u64() const {
+    return GetField<uint64_t>(VT_JUST_U64, 0);
+  }
+  bool mutate_just_u64(uint64_t _just_u64) {
+    return SetField<uint64_t>(VT_JUST_U64, _just_u64, 0);
+  }
+  flatbuffers::Optional<uint64_t> maybe_u64() const {
+    return GetOptional<uint64_t, uint64_t>(VT_MAYBE_U64);
+  }
+  bool mutate_maybe_u64(uint64_t _maybe_u64) {
+    return SetField<uint64_t>(VT_MAYBE_U64, _maybe_u64);
+  }
+  uint64_t default_u64() const {
+    return GetField<uint64_t>(VT_DEFAULT_U64, 42ULL);
+  }
+  bool mutate_default_u64(uint64_t _default_u64) {
+    return SetField<uint64_t>(VT_DEFAULT_U64, _default_u64, 42ULL);
+  }
+  float just_f32() const {
+    return GetField<float>(VT_JUST_F32, 0.0f);
+  }
+  bool mutate_just_f32(float _just_f32) {
+    return SetField<float>(VT_JUST_F32, _just_f32, 0.0f);
+  }
+  flatbuffers::Optional<float> maybe_f32() const {
+    return GetOptional<float, float>(VT_MAYBE_F32);
+  }
+  bool mutate_maybe_f32(float _maybe_f32) {
+    return SetField<float>(VT_MAYBE_F32, _maybe_f32);
+  }
+  float default_f32() const {
+    return GetField<float>(VT_DEFAULT_F32, 42.0f);
+  }
+  bool mutate_default_f32(float _default_f32) {
+    return SetField<float>(VT_DEFAULT_F32, _default_f32, 42.0f);
+  }
+  double just_f64() const {
+    return GetField<double>(VT_JUST_F64, 0.0);
+  }
+  bool mutate_just_f64(double _just_f64) {
+    return SetField<double>(VT_JUST_F64, _just_f64, 0.0);
+  }
+  flatbuffers::Optional<double> maybe_f64() const {
+    return GetOptional<double, double>(VT_MAYBE_F64);
+  }
+  bool mutate_maybe_f64(double _maybe_f64) {
+    return SetField<double>(VT_MAYBE_F64, _maybe_f64);
+  }
+  double default_f64() const {
+    return GetField<double>(VT_DEFAULT_F64, 42.0);
+  }
+  bool mutate_default_f64(double _default_f64) {
+    return SetField<double>(VT_DEFAULT_F64, _default_f64, 42.0);
+  }
+  bool just_bool() const {
+    return GetField<uint8_t>(VT_JUST_BOOL, 0) != 0;
+  }
+  bool mutate_just_bool(bool _just_bool) {
+    return SetField<uint8_t>(VT_JUST_BOOL, static_cast<uint8_t>(_just_bool), 0);
+  }
+  flatbuffers::Optional<bool> maybe_bool() const {
+    return GetOptional<uint8_t, bool>(VT_MAYBE_BOOL);
+  }
+  bool mutate_maybe_bool(bool _maybe_bool) {
+    return SetField<uint8_t>(VT_MAYBE_BOOL, static_cast<uint8_t>(_maybe_bool));
+  }
+  bool default_bool() const {
+    return GetField<uint8_t>(VT_DEFAULT_BOOL, 1) != 0;
+  }
+  bool mutate_default_bool(bool _default_bool) {
+    return SetField<uint8_t>(VT_DEFAULT_BOOL, static_cast<uint8_t>(_default_bool), 1);
+  }
+  optional_scalars::OptionalByte just_enum() const {
+    return static_cast<optional_scalars::OptionalByte>(GetField<int8_t>(VT_JUST_ENUM, 0));
+  }
+  bool mutate_just_enum(optional_scalars::OptionalByte _just_enum) {
+    return SetField<int8_t>(VT_JUST_ENUM, static_cast<int8_t>(_just_enum), 0);
+  }
+  flatbuffers::Optional<optional_scalars::OptionalByte> maybe_enum() const {
+    return GetOptional<int8_t, optional_scalars::OptionalByte>(VT_MAYBE_ENUM);
+  }
+  bool mutate_maybe_enum(optional_scalars::OptionalByte _maybe_enum) {
+    return SetField<int8_t>(VT_MAYBE_ENUM, static_cast<int8_t>(_maybe_enum));
+  }
+  optional_scalars::OptionalByte default_enum() const {
+    return static_cast<optional_scalars::OptionalByte>(GetField<int8_t>(VT_DEFAULT_ENUM, 1));
+  }
+  bool mutate_default_enum(optional_scalars::OptionalByte _default_enum) {
+    return SetField<int8_t>(VT_DEFAULT_ENUM, static_cast<int8_t>(_default_enum), 1);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int8_t>(verifier, VT_JUST_I8) &&
+           VerifyField<int8_t>(verifier, VT_MAYBE_I8) &&
+           VerifyField<int8_t>(verifier, VT_DEFAULT_I8) &&
+           VerifyField<uint8_t>(verifier, VT_JUST_U8) &&
+           VerifyField<uint8_t>(verifier, VT_MAYBE_U8) &&
+           VerifyField<uint8_t>(verifier, VT_DEFAULT_U8) &&
+           VerifyField<int16_t>(verifier, VT_JUST_I16) &&
+           VerifyField<int16_t>(verifier, VT_MAYBE_I16) &&
+           VerifyField<int16_t>(verifier, VT_DEFAULT_I16) &&
+           VerifyField<uint16_t>(verifier, VT_JUST_U16) &&
+           VerifyField<uint16_t>(verifier, VT_MAYBE_U16) &&
+           VerifyField<uint16_t>(verifier, VT_DEFAULT_U16) &&
+           VerifyField<int32_t>(verifier, VT_JUST_I32) &&
+           VerifyField<int32_t>(verifier, VT_MAYBE_I32) &&
+           VerifyField<int32_t>(verifier, VT_DEFAULT_I32) &&
+           VerifyField<uint32_t>(verifier, VT_JUST_U32) &&
+           VerifyField<uint32_t>(verifier, VT_MAYBE_U32) &&
+           VerifyField<uint32_t>(verifier, VT_DEFAULT_U32) &&
+           VerifyField<int64_t>(verifier, VT_JUST_I64) &&
+           VerifyField<int64_t>(verifier, VT_MAYBE_I64) &&
+           VerifyField<int64_t>(verifier, VT_DEFAULT_I64) &&
+           VerifyField<uint64_t>(verifier, VT_JUST_U64) &&
+           VerifyField<uint64_t>(verifier, VT_MAYBE_U64) &&
+           VerifyField<uint64_t>(verifier, VT_DEFAULT_U64) &&
+           VerifyField<float>(verifier, VT_JUST_F32) &&
+           VerifyField<float>(verifier, VT_MAYBE_F32) &&
+           VerifyField<float>(verifier, VT_DEFAULT_F32) &&
+           VerifyField<double>(verifier, VT_JUST_F64) &&
+           VerifyField<double>(verifier, VT_MAYBE_F64) &&
+           VerifyField<double>(verifier, VT_DEFAULT_F64) &&
+           VerifyField<uint8_t>(verifier, VT_JUST_BOOL) &&
+           VerifyField<uint8_t>(verifier, VT_MAYBE_BOOL) &&
+           VerifyField<uint8_t>(verifier, VT_DEFAULT_BOOL) &&
+           VerifyField<int8_t>(verifier, VT_JUST_ENUM) &&
+           VerifyField<int8_t>(verifier, VT_MAYBE_ENUM) &&
+           VerifyField<int8_t>(verifier, VT_DEFAULT_ENUM) &&
+           verifier.EndTable();
+  }
+  ScalarStuffT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(ScalarStuffT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<ScalarStuff> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ScalarStuffT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ScalarStuffBuilder {
+  typedef ScalarStuff Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_just_i8(int8_t just_i8) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_JUST_I8, just_i8, 0);
+  }
+  void add_maybe_i8(int8_t maybe_i8) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_MAYBE_I8, maybe_i8);
+  }
+  void add_default_i8(int8_t default_i8) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_DEFAULT_I8, default_i8, 42);
+  }
+  void add_just_u8(uint8_t just_u8) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_JUST_U8, just_u8, 0);
+  }
+  void add_maybe_u8(uint8_t maybe_u8) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_MAYBE_U8, maybe_u8);
+  }
+  void add_default_u8(uint8_t default_u8) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_DEFAULT_U8, default_u8, 42);
+  }
+  void add_just_i16(int16_t just_i16) {
+    fbb_.AddElement<int16_t>(ScalarStuff::VT_JUST_I16, just_i16, 0);
+  }
+  void add_maybe_i16(int16_t maybe_i16) {
+    fbb_.AddElement<int16_t>(ScalarStuff::VT_MAYBE_I16, maybe_i16);
+  }
+  void add_default_i16(int16_t default_i16) {
+    fbb_.AddElement<int16_t>(ScalarStuff::VT_DEFAULT_I16, default_i16, 42);
+  }
+  void add_just_u16(uint16_t just_u16) {
+    fbb_.AddElement<uint16_t>(ScalarStuff::VT_JUST_U16, just_u16, 0);
+  }
+  void add_maybe_u16(uint16_t maybe_u16) {
+    fbb_.AddElement<uint16_t>(ScalarStuff::VT_MAYBE_U16, maybe_u16);
+  }
+  void add_default_u16(uint16_t default_u16) {
+    fbb_.AddElement<uint16_t>(ScalarStuff::VT_DEFAULT_U16, default_u16, 42);
+  }
+  void add_just_i32(int32_t just_i32) {
+    fbb_.AddElement<int32_t>(ScalarStuff::VT_JUST_I32, just_i32, 0);
+  }
+  void add_maybe_i32(int32_t maybe_i32) {
+    fbb_.AddElement<int32_t>(ScalarStuff::VT_MAYBE_I32, maybe_i32);
+  }
+  void add_default_i32(int32_t default_i32) {
+    fbb_.AddElement<int32_t>(ScalarStuff::VT_DEFAULT_I32, default_i32, 42);
+  }
+  void add_just_u32(uint32_t just_u32) {
+    fbb_.AddElement<uint32_t>(ScalarStuff::VT_JUST_U32, just_u32, 0);
+  }
+  void add_maybe_u32(uint32_t maybe_u32) {
+    fbb_.AddElement<uint32_t>(ScalarStuff::VT_MAYBE_U32, maybe_u32);
+  }
+  void add_default_u32(uint32_t default_u32) {
+    fbb_.AddElement<uint32_t>(ScalarStuff::VT_DEFAULT_U32, default_u32, 42);
+  }
+  void add_just_i64(int64_t just_i64) {
+    fbb_.AddElement<int64_t>(ScalarStuff::VT_JUST_I64, just_i64, 0);
+  }
+  void add_maybe_i64(int64_t maybe_i64) {
+    fbb_.AddElement<int64_t>(ScalarStuff::VT_MAYBE_I64, maybe_i64);
+  }
+  void add_default_i64(int64_t default_i64) {
+    fbb_.AddElement<int64_t>(ScalarStuff::VT_DEFAULT_I64, default_i64, 42LL);
+  }
+  void add_just_u64(uint64_t just_u64) {
+    fbb_.AddElement<uint64_t>(ScalarStuff::VT_JUST_U64, just_u64, 0);
+  }
+  void add_maybe_u64(uint64_t maybe_u64) {
+    fbb_.AddElement<uint64_t>(ScalarStuff::VT_MAYBE_U64, maybe_u64);
+  }
+  void add_default_u64(uint64_t default_u64) {
+    fbb_.AddElement<uint64_t>(ScalarStuff::VT_DEFAULT_U64, default_u64, 42ULL);
+  }
+  void add_just_f32(float just_f32) {
+    fbb_.AddElement<float>(ScalarStuff::VT_JUST_F32, just_f32, 0.0f);
+  }
+  void add_maybe_f32(float maybe_f32) {
+    fbb_.AddElement<float>(ScalarStuff::VT_MAYBE_F32, maybe_f32);
+  }
+  void add_default_f32(float default_f32) {
+    fbb_.AddElement<float>(ScalarStuff::VT_DEFAULT_F32, default_f32, 42.0f);
+  }
+  void add_just_f64(double just_f64) {
+    fbb_.AddElement<double>(ScalarStuff::VT_JUST_F64, just_f64, 0.0);
+  }
+  void add_maybe_f64(double maybe_f64) {
+    fbb_.AddElement<double>(ScalarStuff::VT_MAYBE_F64, maybe_f64);
+  }
+  void add_default_f64(double default_f64) {
+    fbb_.AddElement<double>(ScalarStuff::VT_DEFAULT_F64, default_f64, 42.0);
+  }
+  void add_just_bool(bool just_bool) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_JUST_BOOL, static_cast<uint8_t>(just_bool), 0);
+  }
+  void add_maybe_bool(bool maybe_bool) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_MAYBE_BOOL, static_cast<uint8_t>(maybe_bool));
+  }
+  void add_default_bool(bool default_bool) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_DEFAULT_BOOL, static_cast<uint8_t>(default_bool), 1);
+  }
+  void add_just_enum(optional_scalars::OptionalByte just_enum) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_JUST_ENUM, static_cast<int8_t>(just_enum), 0);
+  }
+  void add_maybe_enum(optional_scalars::OptionalByte maybe_enum) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_MAYBE_ENUM, static_cast<int8_t>(maybe_enum));
+  }
+  void add_default_enum(optional_scalars::OptionalByte default_enum) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_DEFAULT_ENUM, static_cast<int8_t>(default_enum), 1);
+  }
+  explicit ScalarStuffBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  flatbuffers::Offset<ScalarStuff> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<ScalarStuff>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<ScalarStuff> CreateScalarStuff(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int8_t just_i8 = 0,
+    flatbuffers::Optional<int8_t> maybe_i8 = flatbuffers::nullopt,
+    int8_t default_i8 = 42,
+    uint8_t just_u8 = 0,
+    flatbuffers::Optional<uint8_t> maybe_u8 = flatbuffers::nullopt,
+    uint8_t default_u8 = 42,
+    int16_t just_i16 = 0,
+    flatbuffers::Optional<int16_t> maybe_i16 = flatbuffers::nullopt,
+    int16_t default_i16 = 42,
+    uint16_t just_u16 = 0,
+    flatbuffers::Optional<uint16_t> maybe_u16 = flatbuffers::nullopt,
+    uint16_t default_u16 = 42,
+    int32_t just_i32 = 0,
+    flatbuffers::Optional<int32_t> maybe_i32 = flatbuffers::nullopt,
+    int32_t default_i32 = 42,
+    uint32_t just_u32 = 0,
+    flatbuffers::Optional<uint32_t> maybe_u32 = flatbuffers::nullopt,
+    uint32_t default_u32 = 42,
+    int64_t just_i64 = 0,
+    flatbuffers::Optional<int64_t> maybe_i64 = flatbuffers::nullopt,
+    int64_t default_i64 = 42LL,
+    uint64_t just_u64 = 0,
+    flatbuffers::Optional<uint64_t> maybe_u64 = flatbuffers::nullopt,
+    uint64_t default_u64 = 42ULL,
+    float just_f32 = 0.0f,
+    flatbuffers::Optional<float> maybe_f32 = flatbuffers::nullopt,
+    float default_f32 = 42.0f,
+    double just_f64 = 0.0,
+    flatbuffers::Optional<double> maybe_f64 = flatbuffers::nullopt,
+    double default_f64 = 42.0,
+    bool just_bool = false,
+    flatbuffers::Optional<bool> maybe_bool = flatbuffers::nullopt,
+    bool default_bool = true,
+    optional_scalars::OptionalByte just_enum = optional_scalars::OptionalByte::None,
+    flatbuffers::Optional<optional_scalars::OptionalByte> maybe_enum = flatbuffers::nullopt,
+    optional_scalars::OptionalByte default_enum = optional_scalars::OptionalByte::One) {
+  ScalarStuffBuilder builder_(_fbb);
+  builder_.add_default_f64(default_f64);
+  if(maybe_f64) { builder_.add_maybe_f64(*maybe_f64); }
+  builder_.add_just_f64(just_f64);
+  builder_.add_default_u64(default_u64);
+  if(maybe_u64) { builder_.add_maybe_u64(*maybe_u64); }
+  builder_.add_just_u64(just_u64);
+  builder_.add_default_i64(default_i64);
+  if(maybe_i64) { builder_.add_maybe_i64(*maybe_i64); }
+  builder_.add_just_i64(just_i64);
+  builder_.add_default_f32(default_f32);
+  if(maybe_f32) { builder_.add_maybe_f32(*maybe_f32); }
+  builder_.add_just_f32(just_f32);
+  builder_.add_default_u32(default_u32);
+  if(maybe_u32) { builder_.add_maybe_u32(*maybe_u32); }
+  builder_.add_just_u32(just_u32);
+  builder_.add_default_i32(default_i32);
+  if(maybe_i32) { builder_.add_maybe_i32(*maybe_i32); }
+  builder_.add_just_i32(just_i32);
+  builder_.add_default_u16(default_u16);
+  if(maybe_u16) { builder_.add_maybe_u16(*maybe_u16); }
+  builder_.add_just_u16(just_u16);
+  builder_.add_default_i16(default_i16);
+  if(maybe_i16) { builder_.add_maybe_i16(*maybe_i16); }
+  builder_.add_just_i16(just_i16);
+  builder_.add_default_enum(default_enum);
+  if(maybe_enum) { builder_.add_maybe_enum(*maybe_enum); }
+  builder_.add_just_enum(just_enum);
+  builder_.add_default_bool(default_bool);
+  if(maybe_bool) { builder_.add_maybe_bool(*maybe_bool); }
+  builder_.add_just_bool(just_bool);
+  builder_.add_default_u8(default_u8);
+  if(maybe_u8) { builder_.add_maybe_u8(*maybe_u8); }
+  builder_.add_just_u8(just_u8);
+  builder_.add_default_i8(default_i8);
+  if(maybe_i8) { builder_.add_maybe_i8(*maybe_i8); }
+  builder_.add_just_i8(just_i8);
+  return builder_.Finish();
+}
+
+struct ScalarStuff::Traits {
+  using type = ScalarStuff;
+  static auto constexpr Create = CreateScalarStuff;
+};
+
+flatbuffers::Offset<ScalarStuff> CreateScalarStuff(flatbuffers::FlatBufferBuilder &_fbb, const ScalarStuffT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline ScalarStuffT *ScalarStuff::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = std::make_unique<ScalarStuffT>();
+  UnPackTo(_o.get(), _resolver);
+  return _o.release();
+}
+
+inline void ScalarStuff::UnPackTo(ScalarStuffT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = just_i8(); _o->just_i8 = _e; }
+  { auto _e = maybe_i8(); _o->maybe_i8 = _e; }
+  { auto _e = default_i8(); _o->default_i8 = _e; }
+  { auto _e = just_u8(); _o->just_u8 = _e; }
+  { auto _e = maybe_u8(); _o->maybe_u8 = _e; }
+  { auto _e = default_u8(); _o->default_u8 = _e; }
+  { auto _e = just_i16(); _o->just_i16 = _e; }
+  { auto _e = maybe_i16(); _o->maybe_i16 = _e; }
+  { auto _e = default_i16(); _o->default_i16 = _e; }
+  { auto _e = just_u16(); _o->just_u16 = _e; }
+  { auto _e = maybe_u16(); _o->maybe_u16 = _e; }
+  { auto _e = default_u16(); _o->default_u16 = _e; }
+  { auto _e = just_i32(); _o->just_i32 = _e; }
+  { auto _e = maybe_i32(); _o->maybe_i32 = _e; }
+  { auto _e = default_i32(); _o->default_i32 = _e; }
+  { auto _e = just_u32(); _o->just_u32 = _e; }
+  { auto _e = maybe_u32(); _o->maybe_u32 = _e; }
+  { auto _e = default_u32(); _o->default_u32 = _e; }
+  { auto _e = just_i64(); _o->just_i64 = _e; }
+  { auto _e = maybe_i64(); _o->maybe_i64 = _e; }
+  { auto _e = default_i64(); _o->default_i64 = _e; }
+  { auto _e = just_u64(); _o->just_u64 = _e; }
+  { auto _e = maybe_u64(); _o->maybe_u64 = _e; }
+  { auto _e = default_u64(); _o->default_u64 = _e; }
+  { auto _e = just_f32(); _o->just_f32 = _e; }
+  { auto _e = maybe_f32(); _o->maybe_f32 = _e; }
+  { auto _e = default_f32(); _o->default_f32 = _e; }
+  { auto _e = just_f64(); _o->just_f64 = _e; }
+  { auto _e = maybe_f64(); _o->maybe_f64 = _e; }
+  { auto _e = default_f64(); _o->default_f64 = _e; }
+  { auto _e = just_bool(); _o->just_bool = _e; }
+  { auto _e = maybe_bool(); _o->maybe_bool = _e; }
+  { auto _e = default_bool(); _o->default_bool = _e; }
+  { auto _e = just_enum(); _o->just_enum = _e; }
+  { auto _e = maybe_enum(); _o->maybe_enum = _e; }
+  { auto _e = default_enum(); _o->default_enum = _e; }
+}
+
+inline flatbuffers::Offset<ScalarStuff> ScalarStuff::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ScalarStuffT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateScalarStuff(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<ScalarStuff> CreateScalarStuff(flatbuffers::FlatBufferBuilder &_fbb, const ScalarStuffT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ScalarStuffT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _just_i8 = _o->just_i8;
+  auto _maybe_i8 = _o->maybe_i8;
+  auto _default_i8 = _o->default_i8;
+  auto _just_u8 = _o->just_u8;
+  auto _maybe_u8 = _o->maybe_u8;
+  auto _default_u8 = _o->default_u8;
+  auto _just_i16 = _o->just_i16;
+  auto _maybe_i16 = _o->maybe_i16;
+  auto _default_i16 = _o->default_i16;
+  auto _just_u16 = _o->just_u16;
+  auto _maybe_u16 = _o->maybe_u16;
+  auto _default_u16 = _o->default_u16;
+  auto _just_i32 = _o->just_i32;
+  auto _maybe_i32 = _o->maybe_i32;
+  auto _default_i32 = _o->default_i32;
+  auto _just_u32 = _o->just_u32;
+  auto _maybe_u32 = _o->maybe_u32;
+  auto _default_u32 = _o->default_u32;
+  auto _just_i64 = _o->just_i64;
+  auto _maybe_i64 = _o->maybe_i64;
+  auto _default_i64 = _o->default_i64;
+  auto _just_u64 = _o->just_u64;
+  auto _maybe_u64 = _o->maybe_u64;
+  auto _default_u64 = _o->default_u64;
+  auto _just_f32 = _o->just_f32;
+  auto _maybe_f32 = _o->maybe_f32;
+  auto _default_f32 = _o->default_f32;
+  auto _just_f64 = _o->just_f64;
+  auto _maybe_f64 = _o->maybe_f64;
+  auto _default_f64 = _o->default_f64;
+  auto _just_bool = _o->just_bool;
+  auto _maybe_bool = _o->maybe_bool;
+  auto _default_bool = _o->default_bool;
+  auto _just_enum = _o->just_enum;
+  auto _maybe_enum = _o->maybe_enum;
+  auto _default_enum = _o->default_enum;
+  return optional_scalars::CreateScalarStuff(
+      _fbb,
+      _just_i8,
+      _maybe_i8,
+      _default_i8,
+      _just_u8,
+      _maybe_u8,
+      _default_u8,
+      _just_i16,
+      _maybe_i16,
+      _default_i16,
+      _just_u16,
+      _maybe_u16,
+      _default_u16,
+      _just_i32,
+      _maybe_i32,
+      _default_i32,
+      _just_u32,
+      _maybe_u32,
+      _default_u32,
+      _just_i64,
+      _maybe_i64,
+      _default_i64,
+      _just_u64,
+      _maybe_u64,
+      _default_u64,
+      _just_f32,
+      _maybe_f32,
+      _default_f32,
+      _just_f64,
+      _maybe_f64,
+      _default_f64,
+      _just_bool,
+      _maybe_bool,
+      _default_bool,
+      _just_enum,
+      _maybe_enum,
+      _default_enum);
+}
+
+inline const flatbuffers::TypeTable *OptionalByteTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    optional_scalars::OptionalByteTypeTable
+  };
+  static const char * const names[] = {
+    "None",
+    "One",
+    "Two"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ScalarStuffTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    optional_scalars::OptionalByteTypeTable
+  };
+  static const char * const names[] = {
+    "just_i8",
+    "maybe_i8",
+    "default_i8",
+    "just_u8",
+    "maybe_u8",
+    "default_u8",
+    "just_i16",
+    "maybe_i16",
+    "default_i16",
+    "just_u16",
+    "maybe_u16",
+    "default_u16",
+    "just_i32",
+    "maybe_i32",
+    "default_i32",
+    "just_u32",
+    "maybe_u32",
+    "default_u32",
+    "just_i64",
+    "maybe_i64",
+    "default_i64",
+    "just_u64",
+    "maybe_u64",
+    "default_u64",
+    "just_f32",
+    "maybe_f32",
+    "default_f32",
+    "just_f64",
+    "maybe_f64",
+    "default_f64",
+    "just_bool",
+    "maybe_bool",
+    "default_bool",
+    "just_enum",
+    "maybe_enum",
+    "default_enum"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 36, type_codes, type_refs, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const optional_scalars::ScalarStuff *GetScalarStuff(const void *buf) {
+  return flatbuffers::GetRoot<optional_scalars::ScalarStuff>(buf);
+}
+
+inline const optional_scalars::ScalarStuff *GetSizePrefixedScalarStuff(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<optional_scalars::ScalarStuff>(buf);
+}
+
+inline ScalarStuff *GetMutableScalarStuff(void *buf) {
+  return flatbuffers::GetMutableRoot<ScalarStuff>(buf);
+}
+
+inline const char *ScalarStuffIdentifier() {
+  return "NULL";
+}
+
+inline bool ScalarStuffBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, ScalarStuffIdentifier());
+}
+
+inline bool VerifyScalarStuffBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<optional_scalars::ScalarStuff>(ScalarStuffIdentifier());
+}
+
+inline bool VerifySizePrefixedScalarStuffBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<optional_scalars::ScalarStuff>(ScalarStuffIdentifier());
+}
+
+inline const char *ScalarStuffExtension() {
+  return "mon";
+}
+
+inline void FinishScalarStuffBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<optional_scalars::ScalarStuff> root) {
+  fbb.Finish(root, ScalarStuffIdentifier());
+}
+
+inline void FinishSizePrefixedScalarStuffBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<optional_scalars::ScalarStuff> root) {
+  fbb.FinishSizePrefixed(root, ScalarStuffIdentifier());
+}
+
+inline std::unique_ptr<optional_scalars::ScalarStuffT> UnPackScalarStuff(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return std::unique_ptr<optional_scalars::ScalarStuffT>(GetScalarStuff(buf)->UnPack(res));
+}
+
+inline std::unique_ptr<optional_scalars::ScalarStuffT> UnPackSizePrefixedScalarStuff(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return std::unique_ptr<optional_scalars::ScalarStuffT>(GetSizePrefixedScalarStuff(buf)->UnPack(res));
+}
+
+}  // namespace optional_scalars
+
+#endif  // FLATBUFFERS_GENERATED_OPTIONALSCALARS2_OPTIONAL_SCALARS_H_
diff --git a/tests/cpp17/generated_cpp17/optional_scalars_generated.h b/tests/cpp17/generated_cpp17/optional_scalars_generated.h
new file mode 100644
index 0000000..7581e38
--- /dev/null
+++ b/tests/cpp17/generated_cpp17/optional_scalars_generated.h
@@ -0,0 +1,902 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_OPTIONALSCALARS_OPTIONAL_SCALARS_H_
+#define FLATBUFFERS_GENERATED_OPTIONALSCALARS_OPTIONAL_SCALARS_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace optional_scalars {
+
+struct ScalarStuff;
+struct ScalarStuffBuilder;
+struct ScalarStuffT;
+
+inline const flatbuffers::TypeTable *ScalarStuffTypeTable();
+
+enum class OptionalByte : int8_t {
+  None = 0,
+  One = 1,
+  Two = 2,
+  MIN = None,
+  MAX = Two
+};
+
+inline const OptionalByte (&EnumValuesOptionalByte())[3] {
+  static const OptionalByte values[] = {
+    OptionalByte::None,
+    OptionalByte::One,
+    OptionalByte::Two
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesOptionalByte() {
+  static const char * const names[4] = {
+    "None",
+    "One",
+    "Two",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameOptionalByte(OptionalByte e) {
+  if (flatbuffers::IsOutRange(e, OptionalByte::None, OptionalByte::Two)) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesOptionalByte()[index];
+}
+
+struct ScalarStuffT : public flatbuffers::NativeTable {
+  typedef ScalarStuff TableType;
+  int8_t just_i8 = 0;
+  flatbuffers::Optional<int8_t> maybe_i8 = flatbuffers::nullopt;
+  int8_t default_i8 = 42;
+  uint8_t just_u8 = 0;
+  flatbuffers::Optional<uint8_t> maybe_u8 = flatbuffers::nullopt;
+  uint8_t default_u8 = 42;
+  int16_t just_i16 = 0;
+  flatbuffers::Optional<int16_t> maybe_i16 = flatbuffers::nullopt;
+  int16_t default_i16 = 42;
+  uint16_t just_u16 = 0;
+  flatbuffers::Optional<uint16_t> maybe_u16 = flatbuffers::nullopt;
+  uint16_t default_u16 = 42;
+  int32_t just_i32 = 0;
+  flatbuffers::Optional<int32_t> maybe_i32 = flatbuffers::nullopt;
+  int32_t default_i32 = 42;
+  uint32_t just_u32 = 0;
+  flatbuffers::Optional<uint32_t> maybe_u32 = flatbuffers::nullopt;
+  uint32_t default_u32 = 42;
+  int64_t just_i64 = 0;
+  flatbuffers::Optional<int64_t> maybe_i64 = flatbuffers::nullopt;
+  int64_t default_i64 = 42LL;
+  uint64_t just_u64 = 0;
+  flatbuffers::Optional<uint64_t> maybe_u64 = flatbuffers::nullopt;
+  uint64_t default_u64 = 42ULL;
+  float just_f32 = 0.0f;
+  flatbuffers::Optional<float> maybe_f32 = flatbuffers::nullopt;
+  float default_f32 = 42.0f;
+  double just_f64 = 0.0;
+  flatbuffers::Optional<double> maybe_f64 = flatbuffers::nullopt;
+  double default_f64 = 42.0;
+  bool just_bool = false;
+  flatbuffers::Optional<bool> maybe_bool = flatbuffers::nullopt;
+  bool default_bool = true;
+  optional_scalars::OptionalByte just_enum = optional_scalars::OptionalByte::None;
+  flatbuffers::Optional<optional_scalars::OptionalByte> maybe_enum = flatbuffers::nullopt;
+  optional_scalars::OptionalByte default_enum = optional_scalars::OptionalByte::One;
+};
+
+struct ScalarStuff FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ScalarStuffT NativeTableType;
+  typedef ScalarStuffBuilder Builder;
+  struct Traits;
+  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+    return ScalarStuffTypeTable();
+  }
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_JUST_I8 = 4,
+    VT_MAYBE_I8 = 6,
+    VT_DEFAULT_I8 = 8,
+    VT_JUST_U8 = 10,
+    VT_MAYBE_U8 = 12,
+    VT_DEFAULT_U8 = 14,
+    VT_JUST_I16 = 16,
+    VT_MAYBE_I16 = 18,
+    VT_DEFAULT_I16 = 20,
+    VT_JUST_U16 = 22,
+    VT_MAYBE_U16 = 24,
+    VT_DEFAULT_U16 = 26,
+    VT_JUST_I32 = 28,
+    VT_MAYBE_I32 = 30,
+    VT_DEFAULT_I32 = 32,
+    VT_JUST_U32 = 34,
+    VT_MAYBE_U32 = 36,
+    VT_DEFAULT_U32 = 38,
+    VT_JUST_I64 = 40,
+    VT_MAYBE_I64 = 42,
+    VT_DEFAULT_I64 = 44,
+    VT_JUST_U64 = 46,
+    VT_MAYBE_U64 = 48,
+    VT_DEFAULT_U64 = 50,
+    VT_JUST_F32 = 52,
+    VT_MAYBE_F32 = 54,
+    VT_DEFAULT_F32 = 56,
+    VT_JUST_F64 = 58,
+    VT_MAYBE_F64 = 60,
+    VT_DEFAULT_F64 = 62,
+    VT_JUST_BOOL = 64,
+    VT_MAYBE_BOOL = 66,
+    VT_DEFAULT_BOOL = 68,
+    VT_JUST_ENUM = 70,
+    VT_MAYBE_ENUM = 72,
+    VT_DEFAULT_ENUM = 74
+  };
+  int8_t just_i8() const {
+    return GetField<int8_t>(VT_JUST_I8, 0);
+  }
+  bool mutate_just_i8(int8_t _just_i8) {
+    return SetField<int8_t>(VT_JUST_I8, _just_i8, 0);
+  }
+  flatbuffers::Optional<int8_t> maybe_i8() const {
+    return GetOptional<int8_t, int8_t>(VT_MAYBE_I8);
+  }
+  bool mutate_maybe_i8(int8_t _maybe_i8) {
+    return SetField<int8_t>(VT_MAYBE_I8, _maybe_i8);
+  }
+  int8_t default_i8() const {
+    return GetField<int8_t>(VT_DEFAULT_I8, 42);
+  }
+  bool mutate_default_i8(int8_t _default_i8) {
+    return SetField<int8_t>(VT_DEFAULT_I8, _default_i8, 42);
+  }
+  uint8_t just_u8() const {
+    return GetField<uint8_t>(VT_JUST_U8, 0);
+  }
+  bool mutate_just_u8(uint8_t _just_u8) {
+    return SetField<uint8_t>(VT_JUST_U8, _just_u8, 0);
+  }
+  flatbuffers::Optional<uint8_t> maybe_u8() const {
+    return GetOptional<uint8_t, uint8_t>(VT_MAYBE_U8);
+  }
+  bool mutate_maybe_u8(uint8_t _maybe_u8) {
+    return SetField<uint8_t>(VT_MAYBE_U8, _maybe_u8);
+  }
+  uint8_t default_u8() const {
+    return GetField<uint8_t>(VT_DEFAULT_U8, 42);
+  }
+  bool mutate_default_u8(uint8_t _default_u8) {
+    return SetField<uint8_t>(VT_DEFAULT_U8, _default_u8, 42);
+  }
+  int16_t just_i16() const {
+    return GetField<int16_t>(VT_JUST_I16, 0);
+  }
+  bool mutate_just_i16(int16_t _just_i16) {
+    return SetField<int16_t>(VT_JUST_I16, _just_i16, 0);
+  }
+  flatbuffers::Optional<int16_t> maybe_i16() const {
+    return GetOptional<int16_t, int16_t>(VT_MAYBE_I16);
+  }
+  bool mutate_maybe_i16(int16_t _maybe_i16) {
+    return SetField<int16_t>(VT_MAYBE_I16, _maybe_i16);
+  }
+  int16_t default_i16() const {
+    return GetField<int16_t>(VT_DEFAULT_I16, 42);
+  }
+  bool mutate_default_i16(int16_t _default_i16) {
+    return SetField<int16_t>(VT_DEFAULT_I16, _default_i16, 42);
+  }
+  uint16_t just_u16() const {
+    return GetField<uint16_t>(VT_JUST_U16, 0);
+  }
+  bool mutate_just_u16(uint16_t _just_u16) {
+    return SetField<uint16_t>(VT_JUST_U16, _just_u16, 0);
+  }
+  flatbuffers::Optional<uint16_t> maybe_u16() const {
+    return GetOptional<uint16_t, uint16_t>(VT_MAYBE_U16);
+  }
+  bool mutate_maybe_u16(uint16_t _maybe_u16) {
+    return SetField<uint16_t>(VT_MAYBE_U16, _maybe_u16);
+  }
+  uint16_t default_u16() const {
+    return GetField<uint16_t>(VT_DEFAULT_U16, 42);
+  }
+  bool mutate_default_u16(uint16_t _default_u16) {
+    return SetField<uint16_t>(VT_DEFAULT_U16, _default_u16, 42);
+  }
+  int32_t just_i32() const {
+    return GetField<int32_t>(VT_JUST_I32, 0);
+  }
+  bool mutate_just_i32(int32_t _just_i32) {
+    return SetField<int32_t>(VT_JUST_I32, _just_i32, 0);
+  }
+  flatbuffers::Optional<int32_t> maybe_i32() const {
+    return GetOptional<int32_t, int32_t>(VT_MAYBE_I32);
+  }
+  bool mutate_maybe_i32(int32_t _maybe_i32) {
+    return SetField<int32_t>(VT_MAYBE_I32, _maybe_i32);
+  }
+  int32_t default_i32() const {
+    return GetField<int32_t>(VT_DEFAULT_I32, 42);
+  }
+  bool mutate_default_i32(int32_t _default_i32) {
+    return SetField<int32_t>(VT_DEFAULT_I32, _default_i32, 42);
+  }
+  uint32_t just_u32() const {
+    return GetField<uint32_t>(VT_JUST_U32, 0);
+  }
+  bool mutate_just_u32(uint32_t _just_u32) {
+    return SetField<uint32_t>(VT_JUST_U32, _just_u32, 0);
+  }
+  flatbuffers::Optional<uint32_t> maybe_u32() const {
+    return GetOptional<uint32_t, uint32_t>(VT_MAYBE_U32);
+  }
+  bool mutate_maybe_u32(uint32_t _maybe_u32) {
+    return SetField<uint32_t>(VT_MAYBE_U32, _maybe_u32);
+  }
+  uint32_t default_u32() const {
+    return GetField<uint32_t>(VT_DEFAULT_U32, 42);
+  }
+  bool mutate_default_u32(uint32_t _default_u32) {
+    return SetField<uint32_t>(VT_DEFAULT_U32, _default_u32, 42);
+  }
+  int64_t just_i64() const {
+    return GetField<int64_t>(VT_JUST_I64, 0);
+  }
+  bool mutate_just_i64(int64_t _just_i64) {
+    return SetField<int64_t>(VT_JUST_I64, _just_i64, 0);
+  }
+  flatbuffers::Optional<int64_t> maybe_i64() const {
+    return GetOptional<int64_t, int64_t>(VT_MAYBE_I64);
+  }
+  bool mutate_maybe_i64(int64_t _maybe_i64) {
+    return SetField<int64_t>(VT_MAYBE_I64, _maybe_i64);
+  }
+  int64_t default_i64() const {
+    return GetField<int64_t>(VT_DEFAULT_I64, 42LL);
+  }
+  bool mutate_default_i64(int64_t _default_i64) {
+    return SetField<int64_t>(VT_DEFAULT_I64, _default_i64, 42LL);
+  }
+  uint64_t just_u64() const {
+    return GetField<uint64_t>(VT_JUST_U64, 0);
+  }
+  bool mutate_just_u64(uint64_t _just_u64) {
+    return SetField<uint64_t>(VT_JUST_U64, _just_u64, 0);
+  }
+  flatbuffers::Optional<uint64_t> maybe_u64() const {
+    return GetOptional<uint64_t, uint64_t>(VT_MAYBE_U64);
+  }
+  bool mutate_maybe_u64(uint64_t _maybe_u64) {
+    return SetField<uint64_t>(VT_MAYBE_U64, _maybe_u64);
+  }
+  uint64_t default_u64() const {
+    return GetField<uint64_t>(VT_DEFAULT_U64, 42ULL);
+  }
+  bool mutate_default_u64(uint64_t _default_u64) {
+    return SetField<uint64_t>(VT_DEFAULT_U64, _default_u64, 42ULL);
+  }
+  float just_f32() const {
+    return GetField<float>(VT_JUST_F32, 0.0f);
+  }
+  bool mutate_just_f32(float _just_f32) {
+    return SetField<float>(VT_JUST_F32, _just_f32, 0.0f);
+  }
+  flatbuffers::Optional<float> maybe_f32() const {
+    return GetOptional<float, float>(VT_MAYBE_F32);
+  }
+  bool mutate_maybe_f32(float _maybe_f32) {
+    return SetField<float>(VT_MAYBE_F32, _maybe_f32);
+  }
+  float default_f32() const {
+    return GetField<float>(VT_DEFAULT_F32, 42.0f);
+  }
+  bool mutate_default_f32(float _default_f32) {
+    return SetField<float>(VT_DEFAULT_F32, _default_f32, 42.0f);
+  }
+  double just_f64() const {
+    return GetField<double>(VT_JUST_F64, 0.0);
+  }
+  bool mutate_just_f64(double _just_f64) {
+    return SetField<double>(VT_JUST_F64, _just_f64, 0.0);
+  }
+  flatbuffers::Optional<double> maybe_f64() const {
+    return GetOptional<double, double>(VT_MAYBE_F64);
+  }
+  bool mutate_maybe_f64(double _maybe_f64) {
+    return SetField<double>(VT_MAYBE_F64, _maybe_f64);
+  }
+  double default_f64() const {
+    return GetField<double>(VT_DEFAULT_F64, 42.0);
+  }
+  bool mutate_default_f64(double _default_f64) {
+    return SetField<double>(VT_DEFAULT_F64, _default_f64, 42.0);
+  }
+  bool just_bool() const {
+    return GetField<uint8_t>(VT_JUST_BOOL, 0) != 0;
+  }
+  bool mutate_just_bool(bool _just_bool) {
+    return SetField<uint8_t>(VT_JUST_BOOL, static_cast<uint8_t>(_just_bool), 0);
+  }
+  flatbuffers::Optional<bool> maybe_bool() const {
+    return GetOptional<uint8_t, bool>(VT_MAYBE_BOOL);
+  }
+  bool mutate_maybe_bool(bool _maybe_bool) {
+    return SetField<uint8_t>(VT_MAYBE_BOOL, static_cast<uint8_t>(_maybe_bool));
+  }
+  bool default_bool() const {
+    return GetField<uint8_t>(VT_DEFAULT_BOOL, 1) != 0;
+  }
+  bool mutate_default_bool(bool _default_bool) {
+    return SetField<uint8_t>(VT_DEFAULT_BOOL, static_cast<uint8_t>(_default_bool), 1);
+  }
+  optional_scalars::OptionalByte just_enum() const {
+    return static_cast<optional_scalars::OptionalByte>(GetField<int8_t>(VT_JUST_ENUM, 0));
+  }
+  bool mutate_just_enum(optional_scalars::OptionalByte _just_enum) {
+    return SetField<int8_t>(VT_JUST_ENUM, static_cast<int8_t>(_just_enum), 0);
+  }
+  flatbuffers::Optional<optional_scalars::OptionalByte> maybe_enum() const {
+    return GetOptional<int8_t, optional_scalars::OptionalByte>(VT_MAYBE_ENUM);
+  }
+  bool mutate_maybe_enum(optional_scalars::OptionalByte _maybe_enum) {
+    return SetField<int8_t>(VT_MAYBE_ENUM, static_cast<int8_t>(_maybe_enum));
+  }
+  optional_scalars::OptionalByte default_enum() const {
+    return static_cast<optional_scalars::OptionalByte>(GetField<int8_t>(VT_DEFAULT_ENUM, 1));
+  }
+  bool mutate_default_enum(optional_scalars::OptionalByte _default_enum) {
+    return SetField<int8_t>(VT_DEFAULT_ENUM, static_cast<int8_t>(_default_enum), 1);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int8_t>(verifier, VT_JUST_I8) &&
+           VerifyField<int8_t>(verifier, VT_MAYBE_I8) &&
+           VerifyField<int8_t>(verifier, VT_DEFAULT_I8) &&
+           VerifyField<uint8_t>(verifier, VT_JUST_U8) &&
+           VerifyField<uint8_t>(verifier, VT_MAYBE_U8) &&
+           VerifyField<uint8_t>(verifier, VT_DEFAULT_U8) &&
+           VerifyField<int16_t>(verifier, VT_JUST_I16) &&
+           VerifyField<int16_t>(verifier, VT_MAYBE_I16) &&
+           VerifyField<int16_t>(verifier, VT_DEFAULT_I16) &&
+           VerifyField<uint16_t>(verifier, VT_JUST_U16) &&
+           VerifyField<uint16_t>(verifier, VT_MAYBE_U16) &&
+           VerifyField<uint16_t>(verifier, VT_DEFAULT_U16) &&
+           VerifyField<int32_t>(verifier, VT_JUST_I32) &&
+           VerifyField<int32_t>(verifier, VT_MAYBE_I32) &&
+           VerifyField<int32_t>(verifier, VT_DEFAULT_I32) &&
+           VerifyField<uint32_t>(verifier, VT_JUST_U32) &&
+           VerifyField<uint32_t>(verifier, VT_MAYBE_U32) &&
+           VerifyField<uint32_t>(verifier, VT_DEFAULT_U32) &&
+           VerifyField<int64_t>(verifier, VT_JUST_I64) &&
+           VerifyField<int64_t>(verifier, VT_MAYBE_I64) &&
+           VerifyField<int64_t>(verifier, VT_DEFAULT_I64) &&
+           VerifyField<uint64_t>(verifier, VT_JUST_U64) &&
+           VerifyField<uint64_t>(verifier, VT_MAYBE_U64) &&
+           VerifyField<uint64_t>(verifier, VT_DEFAULT_U64) &&
+           VerifyField<float>(verifier, VT_JUST_F32) &&
+           VerifyField<float>(verifier, VT_MAYBE_F32) &&
+           VerifyField<float>(verifier, VT_DEFAULT_F32) &&
+           VerifyField<double>(verifier, VT_JUST_F64) &&
+           VerifyField<double>(verifier, VT_MAYBE_F64) &&
+           VerifyField<double>(verifier, VT_DEFAULT_F64) &&
+           VerifyField<uint8_t>(verifier, VT_JUST_BOOL) &&
+           VerifyField<uint8_t>(verifier, VT_MAYBE_BOOL) &&
+           VerifyField<uint8_t>(verifier, VT_DEFAULT_BOOL) &&
+           VerifyField<int8_t>(verifier, VT_JUST_ENUM) &&
+           VerifyField<int8_t>(verifier, VT_MAYBE_ENUM) &&
+           VerifyField<int8_t>(verifier, VT_DEFAULT_ENUM) &&
+           verifier.EndTable();
+  }
+  ScalarStuffT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  void UnPackTo(ScalarStuffT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+  static flatbuffers::Offset<ScalarStuff> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ScalarStuffT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ScalarStuffBuilder {
+  typedef ScalarStuff Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_just_i8(int8_t just_i8) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_JUST_I8, just_i8, 0);
+  }
+  void add_maybe_i8(int8_t maybe_i8) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_MAYBE_I8, maybe_i8);
+  }
+  void add_default_i8(int8_t default_i8) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_DEFAULT_I8, default_i8, 42);
+  }
+  void add_just_u8(uint8_t just_u8) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_JUST_U8, just_u8, 0);
+  }
+  void add_maybe_u8(uint8_t maybe_u8) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_MAYBE_U8, maybe_u8);
+  }
+  void add_default_u8(uint8_t default_u8) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_DEFAULT_U8, default_u8, 42);
+  }
+  void add_just_i16(int16_t just_i16) {
+    fbb_.AddElement<int16_t>(ScalarStuff::VT_JUST_I16, just_i16, 0);
+  }
+  void add_maybe_i16(int16_t maybe_i16) {
+    fbb_.AddElement<int16_t>(ScalarStuff::VT_MAYBE_I16, maybe_i16);
+  }
+  void add_default_i16(int16_t default_i16) {
+    fbb_.AddElement<int16_t>(ScalarStuff::VT_DEFAULT_I16, default_i16, 42);
+  }
+  void add_just_u16(uint16_t just_u16) {
+    fbb_.AddElement<uint16_t>(ScalarStuff::VT_JUST_U16, just_u16, 0);
+  }
+  void add_maybe_u16(uint16_t maybe_u16) {
+    fbb_.AddElement<uint16_t>(ScalarStuff::VT_MAYBE_U16, maybe_u16);
+  }
+  void add_default_u16(uint16_t default_u16) {
+    fbb_.AddElement<uint16_t>(ScalarStuff::VT_DEFAULT_U16, default_u16, 42);
+  }
+  void add_just_i32(int32_t just_i32) {
+    fbb_.AddElement<int32_t>(ScalarStuff::VT_JUST_I32, just_i32, 0);
+  }
+  void add_maybe_i32(int32_t maybe_i32) {
+    fbb_.AddElement<int32_t>(ScalarStuff::VT_MAYBE_I32, maybe_i32);
+  }
+  void add_default_i32(int32_t default_i32) {
+    fbb_.AddElement<int32_t>(ScalarStuff::VT_DEFAULT_I32, default_i32, 42);
+  }
+  void add_just_u32(uint32_t just_u32) {
+    fbb_.AddElement<uint32_t>(ScalarStuff::VT_JUST_U32, just_u32, 0);
+  }
+  void add_maybe_u32(uint32_t maybe_u32) {
+    fbb_.AddElement<uint32_t>(ScalarStuff::VT_MAYBE_U32, maybe_u32);
+  }
+  void add_default_u32(uint32_t default_u32) {
+    fbb_.AddElement<uint32_t>(ScalarStuff::VT_DEFAULT_U32, default_u32, 42);
+  }
+  void add_just_i64(int64_t just_i64) {
+    fbb_.AddElement<int64_t>(ScalarStuff::VT_JUST_I64, just_i64, 0);
+  }
+  void add_maybe_i64(int64_t maybe_i64) {
+    fbb_.AddElement<int64_t>(ScalarStuff::VT_MAYBE_I64, maybe_i64);
+  }
+  void add_default_i64(int64_t default_i64) {
+    fbb_.AddElement<int64_t>(ScalarStuff::VT_DEFAULT_I64, default_i64, 42LL);
+  }
+  void add_just_u64(uint64_t just_u64) {
+    fbb_.AddElement<uint64_t>(ScalarStuff::VT_JUST_U64, just_u64, 0);
+  }
+  void add_maybe_u64(uint64_t maybe_u64) {
+    fbb_.AddElement<uint64_t>(ScalarStuff::VT_MAYBE_U64, maybe_u64);
+  }
+  void add_default_u64(uint64_t default_u64) {
+    fbb_.AddElement<uint64_t>(ScalarStuff::VT_DEFAULT_U64, default_u64, 42ULL);
+  }
+  void add_just_f32(float just_f32) {
+    fbb_.AddElement<float>(ScalarStuff::VT_JUST_F32, just_f32, 0.0f);
+  }
+  void add_maybe_f32(float maybe_f32) {
+    fbb_.AddElement<float>(ScalarStuff::VT_MAYBE_F32, maybe_f32);
+  }
+  void add_default_f32(float default_f32) {
+    fbb_.AddElement<float>(ScalarStuff::VT_DEFAULT_F32, default_f32, 42.0f);
+  }
+  void add_just_f64(double just_f64) {
+    fbb_.AddElement<double>(ScalarStuff::VT_JUST_F64, just_f64, 0.0);
+  }
+  void add_maybe_f64(double maybe_f64) {
+    fbb_.AddElement<double>(ScalarStuff::VT_MAYBE_F64, maybe_f64);
+  }
+  void add_default_f64(double default_f64) {
+    fbb_.AddElement<double>(ScalarStuff::VT_DEFAULT_F64, default_f64, 42.0);
+  }
+  void add_just_bool(bool just_bool) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_JUST_BOOL, static_cast<uint8_t>(just_bool), 0);
+  }
+  void add_maybe_bool(bool maybe_bool) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_MAYBE_BOOL, static_cast<uint8_t>(maybe_bool));
+  }
+  void add_default_bool(bool default_bool) {
+    fbb_.AddElement<uint8_t>(ScalarStuff::VT_DEFAULT_BOOL, static_cast<uint8_t>(default_bool), 1);
+  }
+  void add_just_enum(optional_scalars::OptionalByte just_enum) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_JUST_ENUM, static_cast<int8_t>(just_enum), 0);
+  }
+  void add_maybe_enum(optional_scalars::OptionalByte maybe_enum) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_MAYBE_ENUM, static_cast<int8_t>(maybe_enum));
+  }
+  void add_default_enum(optional_scalars::OptionalByte default_enum) {
+    fbb_.AddElement<int8_t>(ScalarStuff::VT_DEFAULT_ENUM, static_cast<int8_t>(default_enum), 1);
+  }
+  explicit ScalarStuffBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  flatbuffers::Offset<ScalarStuff> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<ScalarStuff>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<ScalarStuff> CreateScalarStuff(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int8_t just_i8 = 0,
+    flatbuffers::Optional<int8_t> maybe_i8 = flatbuffers::nullopt,
+    int8_t default_i8 = 42,
+    uint8_t just_u8 = 0,
+    flatbuffers::Optional<uint8_t> maybe_u8 = flatbuffers::nullopt,
+    uint8_t default_u8 = 42,
+    int16_t just_i16 = 0,
+    flatbuffers::Optional<int16_t> maybe_i16 = flatbuffers::nullopt,
+    int16_t default_i16 = 42,
+    uint16_t just_u16 = 0,
+    flatbuffers::Optional<uint16_t> maybe_u16 = flatbuffers::nullopt,
+    uint16_t default_u16 = 42,
+    int32_t just_i32 = 0,
+    flatbuffers::Optional<int32_t> maybe_i32 = flatbuffers::nullopt,
+    int32_t default_i32 = 42,
+    uint32_t just_u32 = 0,
+    flatbuffers::Optional<uint32_t> maybe_u32 = flatbuffers::nullopt,
+    uint32_t default_u32 = 42,
+    int64_t just_i64 = 0,
+    flatbuffers::Optional<int64_t> maybe_i64 = flatbuffers::nullopt,
+    int64_t default_i64 = 42LL,
+    uint64_t just_u64 = 0,
+    flatbuffers::Optional<uint64_t> maybe_u64 = flatbuffers::nullopt,
+    uint64_t default_u64 = 42ULL,
+    float just_f32 = 0.0f,
+    flatbuffers::Optional<float> maybe_f32 = flatbuffers::nullopt,
+    float default_f32 = 42.0f,
+    double just_f64 = 0.0,
+    flatbuffers::Optional<double> maybe_f64 = flatbuffers::nullopt,
+    double default_f64 = 42.0,
+    bool just_bool = false,
+    flatbuffers::Optional<bool> maybe_bool = flatbuffers::nullopt,
+    bool default_bool = true,
+    optional_scalars::OptionalByte just_enum = optional_scalars::OptionalByte::None,
+    flatbuffers::Optional<optional_scalars::OptionalByte> maybe_enum = flatbuffers::nullopt,
+    optional_scalars::OptionalByte default_enum = optional_scalars::OptionalByte::One) {
+  ScalarStuffBuilder builder_(_fbb);
+  builder_.add_default_f64(default_f64);
+  if(maybe_f64) { builder_.add_maybe_f64(*maybe_f64); }
+  builder_.add_just_f64(just_f64);
+  builder_.add_default_u64(default_u64);
+  if(maybe_u64) { builder_.add_maybe_u64(*maybe_u64); }
+  builder_.add_just_u64(just_u64);
+  builder_.add_default_i64(default_i64);
+  if(maybe_i64) { builder_.add_maybe_i64(*maybe_i64); }
+  builder_.add_just_i64(just_i64);
+  builder_.add_default_f32(default_f32);
+  if(maybe_f32) { builder_.add_maybe_f32(*maybe_f32); }
+  builder_.add_just_f32(just_f32);
+  builder_.add_default_u32(default_u32);
+  if(maybe_u32) { builder_.add_maybe_u32(*maybe_u32); }
+  builder_.add_just_u32(just_u32);
+  builder_.add_default_i32(default_i32);
+  if(maybe_i32) { builder_.add_maybe_i32(*maybe_i32); }
+  builder_.add_just_i32(just_i32);
+  builder_.add_default_u16(default_u16);
+  if(maybe_u16) { builder_.add_maybe_u16(*maybe_u16); }
+  builder_.add_just_u16(just_u16);
+  builder_.add_default_i16(default_i16);
+  if(maybe_i16) { builder_.add_maybe_i16(*maybe_i16); }
+  builder_.add_just_i16(just_i16);
+  builder_.add_default_enum(default_enum);
+  if(maybe_enum) { builder_.add_maybe_enum(*maybe_enum); }
+  builder_.add_just_enum(just_enum);
+  builder_.add_default_bool(default_bool);
+  if(maybe_bool) { builder_.add_maybe_bool(*maybe_bool); }
+  builder_.add_just_bool(just_bool);
+  builder_.add_default_u8(default_u8);
+  if(maybe_u8) { builder_.add_maybe_u8(*maybe_u8); }
+  builder_.add_just_u8(just_u8);
+  builder_.add_default_i8(default_i8);
+  if(maybe_i8) { builder_.add_maybe_i8(*maybe_i8); }
+  builder_.add_just_i8(just_i8);
+  return builder_.Finish();
+}
+
+struct ScalarStuff::Traits {
+  using type = ScalarStuff;
+  static auto constexpr Create = CreateScalarStuff;
+};
+
+flatbuffers::Offset<ScalarStuff> CreateScalarStuff(flatbuffers::FlatBufferBuilder &_fbb, const ScalarStuffT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline ScalarStuffT *ScalarStuff::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = std::make_unique<ScalarStuffT>();
+  UnPackTo(_o.get(), _resolver);
+  return _o.release();
+}
+
+inline void ScalarStuff::UnPackTo(ScalarStuffT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = just_i8(); _o->just_i8 = _e; }
+  { auto _e = maybe_i8(); _o->maybe_i8 = _e; }
+  { auto _e = default_i8(); _o->default_i8 = _e; }
+  { auto _e = just_u8(); _o->just_u8 = _e; }
+  { auto _e = maybe_u8(); _o->maybe_u8 = _e; }
+  { auto _e = default_u8(); _o->default_u8 = _e; }
+  { auto _e = just_i16(); _o->just_i16 = _e; }
+  { auto _e = maybe_i16(); _o->maybe_i16 = _e; }
+  { auto _e = default_i16(); _o->default_i16 = _e; }
+  { auto _e = just_u16(); _o->just_u16 = _e; }
+  { auto _e = maybe_u16(); _o->maybe_u16 = _e; }
+  { auto _e = default_u16(); _o->default_u16 = _e; }
+  { auto _e = just_i32(); _o->just_i32 = _e; }
+  { auto _e = maybe_i32(); _o->maybe_i32 = _e; }
+  { auto _e = default_i32(); _o->default_i32 = _e; }
+  { auto _e = just_u32(); _o->just_u32 = _e; }
+  { auto _e = maybe_u32(); _o->maybe_u32 = _e; }
+  { auto _e = default_u32(); _o->default_u32 = _e; }
+  { auto _e = just_i64(); _o->just_i64 = _e; }
+  { auto _e = maybe_i64(); _o->maybe_i64 = _e; }
+  { auto _e = default_i64(); _o->default_i64 = _e; }
+  { auto _e = just_u64(); _o->just_u64 = _e; }
+  { auto _e = maybe_u64(); _o->maybe_u64 = _e; }
+  { auto _e = default_u64(); _o->default_u64 = _e; }
+  { auto _e = just_f32(); _o->just_f32 = _e; }
+  { auto _e = maybe_f32(); _o->maybe_f32 = _e; }
+  { auto _e = default_f32(); _o->default_f32 = _e; }
+  { auto _e = just_f64(); _o->just_f64 = _e; }
+  { auto _e = maybe_f64(); _o->maybe_f64 = _e; }
+  { auto _e = default_f64(); _o->default_f64 = _e; }
+  { auto _e = just_bool(); _o->just_bool = _e; }
+  { auto _e = maybe_bool(); _o->maybe_bool = _e; }
+  { auto _e = default_bool(); _o->default_bool = _e; }
+  { auto _e = just_enum(); _o->just_enum = _e; }
+  { auto _e = maybe_enum(); _o->maybe_enum = _e; }
+  { auto _e = default_enum(); _o->default_enum = _e; }
+}
+
+inline flatbuffers::Offset<ScalarStuff> ScalarStuff::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ScalarStuffT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateScalarStuff(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<ScalarStuff> CreateScalarStuff(flatbuffers::FlatBufferBuilder &_fbb, const ScalarStuffT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+  (void)_rehasher;
+  (void)_o;
+  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ScalarStuffT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+  auto _just_i8 = _o->just_i8;
+  auto _maybe_i8 = _o->maybe_i8;
+  auto _default_i8 = _o->default_i8;
+  auto _just_u8 = _o->just_u8;
+  auto _maybe_u8 = _o->maybe_u8;
+  auto _default_u8 = _o->default_u8;
+  auto _just_i16 = _o->just_i16;
+  auto _maybe_i16 = _o->maybe_i16;
+  auto _default_i16 = _o->default_i16;
+  auto _just_u16 = _o->just_u16;
+  auto _maybe_u16 = _o->maybe_u16;
+  auto _default_u16 = _o->default_u16;
+  auto _just_i32 = _o->just_i32;
+  auto _maybe_i32 = _o->maybe_i32;
+  auto _default_i32 = _o->default_i32;
+  auto _just_u32 = _o->just_u32;
+  auto _maybe_u32 = _o->maybe_u32;
+  auto _default_u32 = _o->default_u32;
+  auto _just_i64 = _o->just_i64;
+  auto _maybe_i64 = _o->maybe_i64;
+  auto _default_i64 = _o->default_i64;
+  auto _just_u64 = _o->just_u64;
+  auto _maybe_u64 = _o->maybe_u64;
+  auto _default_u64 = _o->default_u64;
+  auto _just_f32 = _o->just_f32;
+  auto _maybe_f32 = _o->maybe_f32;
+  auto _default_f32 = _o->default_f32;
+  auto _just_f64 = _o->just_f64;
+  auto _maybe_f64 = _o->maybe_f64;
+  auto _default_f64 = _o->default_f64;
+  auto _just_bool = _o->just_bool;
+  auto _maybe_bool = _o->maybe_bool;
+  auto _default_bool = _o->default_bool;
+  auto _just_enum = _o->just_enum;
+  auto _maybe_enum = _o->maybe_enum;
+  auto _default_enum = _o->default_enum;
+  return optional_scalars::CreateScalarStuff(
+      _fbb,
+      _just_i8,
+      _maybe_i8,
+      _default_i8,
+      _just_u8,
+      _maybe_u8,
+      _default_u8,
+      _just_i16,
+      _maybe_i16,
+      _default_i16,
+      _just_u16,
+      _maybe_u16,
+      _default_u16,
+      _just_i32,
+      _maybe_i32,
+      _default_i32,
+      _just_u32,
+      _maybe_u32,
+      _default_u32,
+      _just_i64,
+      _maybe_i64,
+      _default_i64,
+      _just_u64,
+      _maybe_u64,
+      _default_u64,
+      _just_f32,
+      _maybe_f32,
+      _default_f32,
+      _just_f64,
+      _maybe_f64,
+      _default_f64,
+      _just_bool,
+      _maybe_bool,
+      _default_bool,
+      _just_enum,
+      _maybe_enum,
+      _default_enum);
+}
+
+inline const flatbuffers::TypeTable *OptionalByteTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    optional_scalars::OptionalByteTypeTable
+  };
+  static const char * const names[] = {
+    "None",
+    "One",
+    "Two"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const flatbuffers::TypeTable *ScalarStuffTypeTable() {
+  static const flatbuffers::TypeCode type_codes[] = {
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, -1 },
+    { flatbuffers::ET_UCHAR, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_SHORT, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 },
+    { flatbuffers::ET_USHORT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_INT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_UINT, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_LONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_ULONG, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_FLOAT, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_DOUBLE, 0, -1 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_BOOL, 0, -1 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 },
+    { flatbuffers::ET_CHAR, 0, 0 }
+  };
+  static const flatbuffers::TypeFunction type_refs[] = {
+    optional_scalars::OptionalByteTypeTable
+  };
+  static const char * const names[] = {
+    "just_i8",
+    "maybe_i8",
+    "default_i8",
+    "just_u8",
+    "maybe_u8",
+    "default_u8",
+    "just_i16",
+    "maybe_i16",
+    "default_i16",
+    "just_u16",
+    "maybe_u16",
+    "default_u16",
+    "just_i32",
+    "maybe_i32",
+    "default_i32",
+    "just_u32",
+    "maybe_u32",
+    "default_u32",
+    "just_i64",
+    "maybe_i64",
+    "default_i64",
+    "just_u64",
+    "maybe_u64",
+    "default_u64",
+    "just_f32",
+    "maybe_f32",
+    "default_f32",
+    "just_f64",
+    "maybe_f64",
+    "default_f64",
+    "just_bool",
+    "maybe_bool",
+    "default_bool",
+    "just_enum",
+    "maybe_enum",
+    "default_enum"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 36, type_codes, type_refs, nullptr, nullptr, names
+  };
+  return &tt;
+}
+
+inline const optional_scalars::ScalarStuff *GetScalarStuff(const void *buf) {
+  return flatbuffers::GetRoot<optional_scalars::ScalarStuff>(buf);
+}
+
+inline const optional_scalars::ScalarStuff *GetSizePrefixedScalarStuff(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<optional_scalars::ScalarStuff>(buf);
+}
+
+inline ScalarStuff *GetMutableScalarStuff(void *buf) {
+  return flatbuffers::GetMutableRoot<ScalarStuff>(buf);
+}
+
+inline const char *ScalarStuffIdentifier() {
+  return "NULL";
+}
+
+inline bool ScalarStuffBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, ScalarStuffIdentifier());
+}
+
+inline bool VerifyScalarStuffBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<optional_scalars::ScalarStuff>(ScalarStuffIdentifier());
+}
+
+inline bool VerifySizePrefixedScalarStuffBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<optional_scalars::ScalarStuff>(ScalarStuffIdentifier());
+}
+
+inline const char *ScalarStuffExtension() {
+  return "mon";
+}
+
+inline void FinishScalarStuffBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<optional_scalars::ScalarStuff> root) {
+  fbb.Finish(root, ScalarStuffIdentifier());
+}
+
+inline void FinishSizePrefixedScalarStuffBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<optional_scalars::ScalarStuff> root) {
+  fbb.FinishSizePrefixed(root, ScalarStuffIdentifier());
+}
+
+inline std::unique_ptr<optional_scalars::ScalarStuffT> UnPackScalarStuff(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return std::unique_ptr<optional_scalars::ScalarStuffT>(GetScalarStuff(buf)->UnPack(res));
+}
+
+inline std::unique_ptr<optional_scalars::ScalarStuffT> UnPackSizePrefixedScalarStuff(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return std::unique_ptr<optional_scalars::ScalarStuffT>(GetSizePrefixedScalarStuff(buf)->UnPack(res));
+}
+
+}  // namespace optional_scalars
+
+#endif  // FLATBUFFERS_GENERATED_OPTIONALSCALARS_OPTIONAL_SCALARS_H_
diff --git a/tests/cpp17/test_cpp17.cpp b/tests/cpp17/test_cpp17.cpp
new file mode 100644
index 0000000..9b47c10
--- /dev/null
+++ b/tests/cpp17/test_cpp17.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This is a sandbox for modeling C++17 code generator.
+// C++17 code generator: "flatc --cpp_std c++17".
+// Warning:
+// This is an experimental feature and could change at any time.
+
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/flexbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/minireflect.h"
+#include "flatbuffers/registry.h"
+#include "flatbuffers/util.h"
+#include "test_assert.h"
+
+// Embed generated code into an isolated namespace.
+namespace cpp17 {
+#include "generated_cpp17/monster_test_generated.h"
+#include "generated_cpp17/optional_scalars_generated.h"
+}  // namespace cpp17
+
+namespace cpp11 {
+#include "../monster_test_generated.h"
+#include "../optional_scalars_generated.h"
+}  // namespace cpp11
+
+void CreateTableByTypeTest() {
+  flatbuffers::FlatBufferBuilder builder;
+
+  // We will create an object of this type using only the type.
+  using type_to_create_t = cpp17::MyGame::Example::Stat;
+
+  [&builder] {
+    auto id_str = builder.CreateString("my_id");
+    auto table = type_to_create_t::Traits::Create(builder, id_str, 42, 7);
+    // Be sure that the correct return type was inferred.
+    static_assert(
+        std::is_same_v<decltype(table), flatbuffers::Offset<type_to_create_t>>);
+    builder.Finish(table);
+  }();
+
+  // Access it.
+  auto stat =
+      flatbuffers::GetRoot<type_to_create_t>(builder.GetBufferPointer());
+  TEST_EQ_STR(stat->id()->c_str(), "my_id");
+  TEST_EQ(stat->val(), 42);
+  TEST_EQ(stat->count(), 7);
+}
+
+void OptionalScalarsTest() {
+  static_assert(std::is_same<flatbuffers::Optional<float>, std::optional<float>>::value);
+  static_assert(std::is_same<flatbuffers::nullopt_t, std::nullopt_t>::value);
+
+  // test C++ nullable
+  flatbuffers::FlatBufferBuilder fbb;
+  FinishScalarStuffBuffer(fbb, cpp17::optional_scalars::CreateScalarStuff(
+                                   fbb, 1, static_cast<int8_t>(2)));
+  auto opts =
+      cpp17::optional_scalars::GetMutableScalarStuff(fbb.GetBufferPointer());
+  TEST_ASSERT(!opts->maybe_bool());
+  TEST_ASSERT(!opts->maybe_f32().has_value());
+  TEST_ASSERT(opts->maybe_i8().has_value());
+  TEST_EQ(opts->maybe_i8().value(), 2);
+  TEST_ASSERT(opts->mutate_maybe_i8(3));
+  TEST_ASSERT(opts->maybe_i8().has_value());
+  TEST_EQ(opts->maybe_i8().value(), 3);
+  TEST_ASSERT(!opts->mutate_maybe_i16(-10));
+
+  cpp17::optional_scalars::ScalarStuffT obj;
+  opts->UnPackTo(&obj);
+  TEST_ASSERT(!obj.maybe_bool);
+  TEST_ASSERT(!obj.maybe_f32.has_value());
+  TEST_ASSERT(obj.maybe_i8.has_value() && obj.maybe_i8.value() == 3);
+  TEST_ASSERT(obj.maybe_i8 && *obj.maybe_i8 == 3);
+  obj.maybe_i32 = -1;
+
+  fbb.Clear();
+  FinishScalarStuffBuffer(
+      fbb, cpp17::optional_scalars::ScalarStuff::Pack(fbb, &obj));
+  opts = cpp17::optional_scalars::GetMutableScalarStuff(fbb.GetBufferPointer());
+  TEST_ASSERT(opts->maybe_i8().has_value());
+  TEST_EQ(opts->maybe_i8().value(), 3);
+  TEST_ASSERT(opts->maybe_i32().has_value());
+  TEST_EQ(opts->maybe_i32().value(), -1);
+
+  TEST_EQ(std::optional<int32_t>(opts->maybe_i32()).value(), -1);
+  TEST_EQ(std::optional<int64_t>(opts->maybe_i32()).value(), -1);
+  TEST_ASSERT(opts->maybe_i32() == std::optional<int64_t>(-1));
+}
+
+int FlatBufferCpp17Tests() {
+  CreateTableByTypeTest();
+  OptionalScalarsTest();
+  return 0;
+}
+
+int main(int /*argc*/, const char * /*argv*/[]) {
+  InitTestEngine();
+
+  FlatBufferCpp17Tests();
+
+  if (!testing_fails) {
+    TEST_OUTPUT_LINE("C++17: ALL TESTS PASSED");
+  } else {
+    TEST_OUTPUT_LINE("C++17: %d FAILED TESTS", testing_fails);
+  }
+  return CloseTestEngine();
+}
