diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h
new file mode 100644
index 0000000..4016ce9
--- /dev/null
+++ b/tests/monster_test_generated.h
@@ -0,0 +1,3499 @@
+// 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 InParentNamespaceT;
+
+namespace Example2 {
+
+struct Monster;
+struct MonsterT;
+
+}  // namespace Example2
+
+namespace Example {
+
+struct Test;
+
+struct TestSimpleTableWithEnum;
+struct TestSimpleTableWithEnumT;
+
+struct Vec3;
+
+struct Ability;
+
+struct Stat;
+struct StatT;
+
+struct Referrable;
+struct ReferrableT;
+
+struct Monster;
+struct MonsterT;
+
+struct TypeAliases;
+struct TypeAliasesT;
+
+}  // namespace Example
+
+bool operator==(const InParentNamespaceT &lhs, const InParentNamespaceT &rhs);
+bool operator!=(const InParentNamespaceT &lhs, const InParentNamespaceT &rhs);
+namespace Example2 {
+
+bool operator==(const MonsterT &lhs, const MonsterT &rhs);
+bool operator!=(const MonsterT &lhs, const MonsterT &rhs);
+}  // namespace Example2
+
+namespace Example {
+
+bool operator==(const Test &lhs, const Test &rhs);
+bool operator!=(const Test &lhs, const Test &rhs);
+bool operator==(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs);
+bool operator!=(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs);
+bool operator==(const Vec3 &lhs, const Vec3 &rhs);
+bool operator!=(const Vec3 &lhs, const Vec3 &rhs);
+bool operator==(const Ability &lhs, const Ability &rhs);
+bool operator!=(const Ability &lhs, const Ability &rhs);
+bool operator==(const StatT &lhs, const StatT &rhs);
+bool operator!=(const StatT &lhs, const StatT &rhs);
+bool operator==(const ReferrableT &lhs, const ReferrableT &rhs);
+bool operator!=(const ReferrableT &lhs, const ReferrableT &rhs);
+bool operator==(const MonsterT &lhs, const MonsterT &rhs);
+bool operator!=(const MonsterT &lhs, const MonsterT &rhs);
+bool operator==(const TypeAliasesT &lhs, const TypeAliasesT &rhs);
+bool operator!=(const TypeAliasesT &lhs, const TypeAliasesT &rhs);
+
+}  // 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 Color {
+  Color_Red = 1,
+  /// \brief color Green
+  /// Green is bit_flag with value (1u << 1)
+  Color_Green = 2,
+  /// \brief color Blue (1u << 3)
+  Color_Blue = 8,
+  Color_NONE = 0,
+  Color_ANY = 11
+};
+
+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 (e < Color_Red || e > Color_Blue) return "";
+  const size_t index = static_cast<size_t>(e) - static_cast<size_t>(Color_Red);
+  return EnumNamesColor()[index];
+}
+
+enum Any {
+  Any_NONE = 0,
+  Any_Monster = 1,
+  Any_TestSimpleTableWithEnum = 2,
+  Any_MyGame_Example2_Monster = 3,
+  Any_MIN = Any_NONE,
+  Any_MAX = Any_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 (e < Any_NONE || e > 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 &) FLATBUFFERS_NOEXCEPT;
+  AnyUnion &operator=(const AnyUnion &u) FLATBUFFERS_NOEXCEPT
+    { 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;
+  }
+};
+
+
+inline bool operator==(const AnyUnion &lhs, const AnyUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case Any_NONE: {
+      return true;
+    }
+    case Any_Monster: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case Any_TestSimpleTableWithEnum: {
+      return *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(rhs.value));
+    }
+    case Any_MyGame_Example2_Monster: {
+      return *(reinterpret_cast<const MyGame::Example2::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example2::MonsterT *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const AnyUnion &lhs, const AnyUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+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 AnyUniqueAliases {
+  AnyUniqueAliases_NONE = 0,
+  AnyUniqueAliases_M = 1,
+  AnyUniqueAliases_TS = 2,
+  AnyUniqueAliases_M2 = 3,
+  AnyUniqueAliases_MIN = AnyUniqueAliases_NONE,
+  AnyUniqueAliases_MAX = AnyUniqueAliases_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 (e < AnyUniqueAliases_NONE || e > 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 &) FLATBUFFERS_NOEXCEPT;
+  AnyUniqueAliasesUnion &operator=(const AnyUniqueAliasesUnion &u) FLATBUFFERS_NOEXCEPT
+    { 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;
+  }
+};
+
+
+inline bool operator==(const AnyUniqueAliasesUnion &lhs, const AnyUniqueAliasesUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case AnyUniqueAliases_NONE: {
+      return true;
+    }
+    case AnyUniqueAliases_M: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case AnyUniqueAliases_TS: {
+      return *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(rhs.value));
+    }
+    case AnyUniqueAliases_M2: {
+      return *(reinterpret_cast<const MyGame::Example2::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example2::MonsterT *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const AnyUniqueAliasesUnion &lhs, const AnyUniqueAliasesUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+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 AnyAmbiguousAliases {
+  AnyAmbiguousAliases_NONE = 0,
+  AnyAmbiguousAliases_M1 = 1,
+  AnyAmbiguousAliases_M2 = 2,
+  AnyAmbiguousAliases_M3 = 3,
+  AnyAmbiguousAliases_MIN = AnyAmbiguousAliases_NONE,
+  AnyAmbiguousAliases_MAX = AnyAmbiguousAliases_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 (e < AnyAmbiguousAliases_NONE || e > 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 &) FLATBUFFERS_NOEXCEPT;
+  AnyAmbiguousAliasesUnion &operator=(const AnyAmbiguousAliasesUnion &u) FLATBUFFERS_NOEXCEPT
+    { 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;
+  }
+};
+
+
+inline bool operator==(const AnyAmbiguousAliasesUnion &lhs, const AnyAmbiguousAliasesUnion &rhs) {
+  if (lhs.type != rhs.type) return false;
+  switch (lhs.type) {
+    case AnyAmbiguousAliases_NONE: {
+      return true;
+    }
+    case AnyAmbiguousAliases_M1: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case AnyAmbiguousAliases_M2: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    case AnyAmbiguousAliases_M3: {
+      return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+             *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+inline bool operator!=(const AnyAmbiguousAliasesUnion &lhs, const AnyAmbiguousAliasesUnion &rhs) {
+    return !(lhs == rhs);
+}
+
+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() {
+    memset(static_cast<void *>(this), 0, sizeof(Test));
+  }
+  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);
+
+inline bool operator==(const Test &lhs, const Test &rhs) {
+  return
+      (lhs.a() == rhs.a()) &&
+      (lhs.b() == rhs.b());
+}
+
+inline bool operator!=(const Test &lhs, const Test &rhs) {
+    return !(lhs == rhs);
+}
+
+
+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() {
+    memset(static_cast<void *>(this), 0, sizeof(Vec3));
+  }
+  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);
+
+inline bool operator==(const Vec3 &lhs, const Vec3 &rhs) {
+  return
+      (lhs.x() == rhs.x()) &&
+      (lhs.y() == rhs.y()) &&
+      (lhs.z() == rhs.z()) &&
+      (lhs.test1() == rhs.test1()) &&
+      (lhs.test2() == rhs.test2()) &&
+      (lhs.test3() == rhs.test3());
+}
+
+inline bool operator!=(const Vec3 &lhs, const Vec3 &rhs) {
+    return !(lhs == rhs);
+}
+
+
+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() {
+    memset(static_cast<void *>(this), 0, sizeof(Ability));
+  }
+  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);
+
+inline bool operator==(const Ability &lhs, const Ability &rhs) {
+  return
+      (lhs.id() == rhs.id()) &&
+      (lhs.distance() == rhs.distance());
+}
+
+inline bool operator!=(const Ability &lhs, const Ability &rhs) {
+    return !(lhs == rhs);
+}
+
+
+}  // namespace Example
+
+struct InParentNamespaceT : public flatbuffers::NativeTable {
+  typedef InParentNamespace TableType;
+  InParentNamespaceT() {
+  }
+};
+
+inline bool operator==(const InParentNamespaceT &, const InParentNamespaceT &) {
+  return true;
+}
+
+inline bool operator!=(const InParentNamespaceT &lhs, const InParentNamespaceT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct InParentNamespace FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef InParentNamespaceT NativeTableType;
+  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 {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  explicit InParentNamespaceBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  InParentNamespaceBuilder &operator=(const InParentNamespaceBuilder &);
+  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();
+}
+
+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;
+  MonsterT() {
+  }
+};
+
+inline bool operator==(const MonsterT &, const MonsterT &) {
+  return true;
+}
+
+inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
+  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 {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MonsterBuilder &operator=(const MonsterBuilder &);
+  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();
+}
+
+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;
+  TestSimpleTableWithEnumT()
+      : color(MyGame::Example::Color_Green) {
+  }
+};
+
+inline bool operator==(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs) {
+  return
+      (lhs.color == rhs.color);
+}
+
+inline bool operator!=(const TestSimpleTableWithEnumT &lhs, const TestSimpleTableWithEnumT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TestSimpleTableWithEnumT NativeTableType;
+  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 {
+  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();
+  }
+  TestSimpleTableWithEnumBuilder &operator=(const TestSimpleTableWithEnumBuilder &);
+  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();
+}
+
+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;
+  uint16_t count;
+  StatT()
+      : val(0),
+        count(0) {
+  }
+};
+
+inline bool operator==(const StatT &lhs, const StatT &rhs) {
+  return
+      (lhs.id == rhs.id) &&
+      (lhs.val == rhs.val) &&
+      (lhs.count == rhs.count);
+}
+
+inline bool operator!=(const StatT &lhs, const StatT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef StatT NativeTableType;
+  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 {
+  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();
+  }
+  StatBuilder &operator=(const StatBuilder &);
+  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();
+}
+
+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;
+  ReferrableT()
+      : id(0) {
+  }
+};
+
+inline bool operator==(const ReferrableT &lhs, const ReferrableT &rhs) {
+  return
+      (lhs.id == rhs.id);
+}
+
+inline bool operator!=(const ReferrableT &lhs, const ReferrableT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct Referrable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ReferrableT NativeTableType;
+  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 {
+  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();
+  }
+  ReferrableBuilder &operator=(const ReferrableBuilder &);
+  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();
+}
+
+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;
+  flatbuffers::unique_ptr<MyGame::Example::Vec3> pos;
+  int16_t mana;
+  int16_t hp;
+  std::string name;
+  std::vector<uint8_t> inventory;
+  MyGame::Example::Color color;
+  AnyUnion test;
+  std::vector<MyGame::Example::Test> test4;
+  std::vector<std::string> testarrayofstring;
+  std::vector<flatbuffers::unique_ptr<MyGame::Example::MonsterT>> testarrayoftables;
+  flatbuffers::unique_ptr<MyGame::Example::MonsterT> enemy;
+  std::vector<uint8_t> testnestedflatbuffer;
+  flatbuffers::unique_ptr<MyGame::Example::StatT> testempty;
+  bool testbool;
+  int32_t testhashs32_fnv1;
+  uint32_t testhashu32_fnv1;
+  int64_t testhashs64_fnv1;
+  uint64_t testhashu64_fnv1;
+  int32_t testhashs32_fnv1a;
+  Stat *testhashu32_fnv1a;
+  int64_t testhashs64_fnv1a;
+  uint64_t testhashu64_fnv1a;
+  std::vector<bool> testarrayofbools;
+  float testf;
+  float testf2;
+  float testf3;
+  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;
+  flatbuffers::unique_ptr<MyGame::InParentNamespaceT> parent_namespace_test;
+  std::vector<flatbuffers::unique_ptr<MyGame::Example::ReferrableT>> vector_of_referrables;
+  ReferrableT *single_weak_reference;
+  std::vector<ReferrableT *> vector_of_weak_references;
+  std::vector<flatbuffers::unique_ptr<MyGame::Example::ReferrableT>> vector_of_strong_referrables;
+  ReferrableT *co_owning_reference;
+  std::vector<flatbuffers::unique_ptr<ReferrableT>> vector_of_co_owning_references;
+  ReferrableT *non_owning_reference;
+  std::vector<ReferrableT *> vector_of_non_owning_references;
+  AnyUniqueAliasesUnion any_unique;
+  AnyAmbiguousAliasesUnion any_ambiguous;
+  std::vector<MyGame::Example::Color> vector_of_enums;
+  MonsterT()
+      : mana(150),
+        hp(100),
+        color(MyGame::Example::Color_Blue),
+        testbool(false),
+        testhashs32_fnv1(0),
+        testhashu32_fnv1(0),
+        testhashs64_fnv1(0),
+        testhashu64_fnv1(0),
+        testhashs32_fnv1a(0),
+        testhashu32_fnv1a(nullptr),
+        testhashs64_fnv1a(0),
+        testhashu64_fnv1a(0),
+        testf(3.14159f),
+        testf2(3.0f),
+        testf3(0.0f),
+        single_weak_reference(nullptr),
+        co_owning_reference(nullptr),
+        non_owning_reference(nullptr) {
+  }
+};
+
+inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
+  return
+      (lhs.pos == rhs.pos) &&
+      (lhs.mana == rhs.mana) &&
+      (lhs.hp == rhs.hp) &&
+      (lhs.name == rhs.name) &&
+      (lhs.inventory == rhs.inventory) &&
+      (lhs.color == rhs.color) &&
+      (lhs.test == rhs.test) &&
+      (lhs.test4 == rhs.test4) &&
+      (lhs.testarrayofstring == rhs.testarrayofstring) &&
+      (lhs.testarrayoftables == rhs.testarrayoftables) &&
+      (lhs.enemy == rhs.enemy) &&
+      (lhs.testnestedflatbuffer == rhs.testnestedflatbuffer) &&
+      (lhs.testempty == rhs.testempty) &&
+      (lhs.testbool == rhs.testbool) &&
+      (lhs.testhashs32_fnv1 == rhs.testhashs32_fnv1) &&
+      (lhs.testhashu32_fnv1 == rhs.testhashu32_fnv1) &&
+      (lhs.testhashs64_fnv1 == rhs.testhashs64_fnv1) &&
+      (lhs.testhashu64_fnv1 == rhs.testhashu64_fnv1) &&
+      (lhs.testhashs32_fnv1a == rhs.testhashs32_fnv1a) &&
+      (lhs.testhashu32_fnv1a == rhs.testhashu32_fnv1a) &&
+      (lhs.testhashs64_fnv1a == rhs.testhashs64_fnv1a) &&
+      (lhs.testhashu64_fnv1a == rhs.testhashu64_fnv1a) &&
+      (lhs.testarrayofbools == rhs.testarrayofbools) &&
+      (lhs.testf == rhs.testf) &&
+      (lhs.testf2 == rhs.testf2) &&
+      (lhs.testf3 == rhs.testf3) &&
+      (lhs.testarrayofstring2 == rhs.testarrayofstring2) &&
+      (lhs.testarrayofsortedstruct == rhs.testarrayofsortedstruct) &&
+      (lhs.flex == rhs.flex) &&
+      (lhs.test5 == rhs.test5) &&
+      (lhs.vector_of_longs == rhs.vector_of_longs) &&
+      (lhs.vector_of_doubles == rhs.vector_of_doubles) &&
+      (lhs.parent_namespace_test == rhs.parent_namespace_test) &&
+      (lhs.vector_of_referrables == rhs.vector_of_referrables) &&
+      (lhs.single_weak_reference == rhs.single_weak_reference) &&
+      (lhs.vector_of_weak_references == rhs.vector_of_weak_references) &&
+      (lhs.vector_of_strong_referrables == rhs.vector_of_strong_referrables) &&
+      (lhs.co_owning_reference == rhs.co_owning_reference) &&
+      (lhs.vector_of_co_owning_references == rhs.vector_of_co_owning_references) &&
+      (lhs.non_owning_reference == rhs.non_owning_reference) &&
+      (lhs.vector_of_non_owning_references == rhs.vector_of_non_owning_references) &&
+      (lhs.any_unique == rhs.any_unique) &&
+      (lhs.any_ambiguous == rhs.any_ambiguous) &&
+      (lhs.vector_of_enums == rhs.vector_of_enums);
+}
+
+inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+/// an example documentation comment: monster object
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
+  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
+  };
+  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));
+  }
+  bool mutate_test_type(MyGame::Example::Any _test_type) {
+    return SetField<uint8_t>(VT_TEST_TYPE, static_cast<uint8_t>(_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));
+  }
+  bool mutate_any_unique_type(MyGame::Example::AnyUniqueAliases _any_unique_type) {
+    return SetField<uint8_t>(VT_ANY_UNIQUE_TYPE, static_cast<uint8_t>(_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));
+  }
+  bool mutate_any_ambiguous_type(MyGame::Example::AnyAmbiguousAliases _any_ambiguous_type) {
+    return SetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, static_cast<uint8_t>(_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<uint8_t> *vector_of_enums() const {
+    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_VECTOR_OF_ENUMS);
+  }
+  flatbuffers::Vector<uint8_t> *mutable_vector_of_enums() {
+    return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_VECTOR_OF_ENUMS);
+  }
+  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()) &&
+           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 {
+  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<uint8_t>> vector_of_enums) {
+    fbb_.AddOffset(Monster::VT_VECTOR_OF_ENUMS, vector_of_enums);
+  }
+  explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  MonsterBuilder &operator=(const MonsterBuilder &);
+  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<uint8_t>> vector_of_enums = 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_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_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();
+}
+
+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,
+    const 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,
+    const 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,
+    const 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,
+    const 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<uint8_t> *vector_of_enums = 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.CreateVector<flatbuffers::Offset<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.CreateVectorOfStructs<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.CreateVector<flatbuffers::Offset<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.CreateVector<flatbuffers::Offset<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<uint8_t>(*vector_of_enums) : 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__);
+}
+
+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;
+  uint8_t u8;
+  int16_t i16;
+  uint16_t u16;
+  int32_t i32;
+  uint32_t u32;
+  int64_t i64;
+  uint64_t u64;
+  float f32;
+  double f64;
+  std::vector<int8_t> v8;
+  std::vector<double> vf64;
+  TypeAliasesT()
+      : i8(0),
+        u8(0),
+        i16(0),
+        u16(0),
+        i32(0),
+        u32(0),
+        i64(0),
+        u64(0),
+        f32(0.0f),
+        f64(0.0) {
+  }
+};
+
+inline bool operator==(const TypeAliasesT &lhs, const TypeAliasesT &rhs) {
+  return
+      (lhs.i8 == rhs.i8) &&
+      (lhs.u8 == rhs.u8) &&
+      (lhs.i16 == rhs.i16) &&
+      (lhs.u16 == rhs.u16) &&
+      (lhs.i32 == rhs.i32) &&
+      (lhs.u32 == rhs.u32) &&
+      (lhs.i64 == rhs.i64) &&
+      (lhs.u64 == rhs.u64) &&
+      (lhs.f32 == rhs.f32) &&
+      (lhs.f64 == rhs.f64) &&
+      (lhs.v8 == rhs.v8) &&
+      (lhs.vf64 == rhs.vf64);
+}
+
+inline bool operator!=(const TypeAliasesT &lhs, const TypeAliasesT &rhs) {
+    return !(lhs == rhs);
+}
+
+
+struct TypeAliases FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TypeAliasesT NativeTableType;
+  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 {
+  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();
+  }
+  TypeAliasesBuilder &operator=(const TypeAliasesBuilder &);
+  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();
+}
+
+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 = new InParentNamespaceT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+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 = new MonsterT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+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 = new TestSimpleTableWithEnumT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+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 = new StatT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+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 = new ReferrableT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+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 = new MonsterT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+  (void)_o;
+  (void)_resolver;
+  { auto _e = pos(); if (_e) _o->pos = flatbuffers::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()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } };
+  { auto _e = color(); _o->color = _e; };
+  { auto _e = test_type(); _o->test.type = _e; };
+  { auto _e = test(); if (_e) _o->test.value = 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] = flatbuffers::unique_ptr<MyGame::Example::MonsterT>(_e->Get(_i)->UnPack(_resolver)); } } };
+  { auto _e = enemy(); if (_e) _o->enemy = flatbuffers::unique_ptr<MyGame::Example::MonsterT>(_e->UnPack(_resolver)); };
+  { auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer[_i] = _e->Get(_i); } } };
+  { auto _e = testempty(); if (_e) _o->testempty = flatbuffers::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()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->flex[_i] = _e->Get(_i); } } };
+  { 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 = flatbuffers::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] = flatbuffers::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] = flatbuffers::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 = 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 = 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)); } } };
+}
+
+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.CreateVectorScalarCast<uint8_t>(flatbuffers::data(_o->vector_of_enums), _o->vector_of_enums.size()) : 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);
+}
+
+inline TypeAliasesT *TypeAliases::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+  auto _o = new TypeAliasesT();
+  UnPackTo(_o, _resolver);
+  return _o;
+}
+
+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()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->v8[_i] = _e->Get(_i); } } };
+  { 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 false;
+  }
+}
+
+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) FLATBUFFERS_NOEXCEPT : 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 false;
+  }
+}
+
+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) FLATBUFFERS_NOEXCEPT : 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 false;
+  }
+}
+
+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) FLATBUFFERS_NOEXCEPT : 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, 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, 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, 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, names
+  };
+  return &tt;
+}
+
+}  // namespace Example
+
+inline const flatbuffers::TypeTable *InParentNamespaceTypeTable() {
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 0, 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
+  };
+  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, 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, 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, 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, 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, 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, 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 }
+  };
+  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
+  };
+  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"
+  };
+  static const flatbuffers::TypeTable tt = {
+    flatbuffers::ST_TABLE, 48, type_codes, type_refs, 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, 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 flatbuffers::unique_ptr<MyGame::Example::MonsterT> UnPackMonster(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Example::MonsterT>(GetMonster(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::MonsterT> UnPackSizePrefixedMonster(
+    const void *buf,
+    const flatbuffers::resolver_function_t *res = nullptr) {
+  return flatbuffers::unique_ptr<MyGame::Example::MonsterT>(GetSizePrefixedMonster(buf)->UnPack(res));
+}
+
+}  // namespace Example
+}  // namespace MyGame
+
+#endif  // FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
