// automatically generated by the FlatBuffers compiler, do not modify


#ifndef FLATBUFFERS_GENERATED_UNIONVECTOR_H_
#define FLATBUFFERS_GENERATED_UNIONVECTOR_H_

#include "flatbuffers/flatbuffers.h"

// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 22 &&
              FLATBUFFERS_VERSION_MINOR == 9 &&
              FLATBUFFERS_VERSION_REVISION == 24,
             "Non-compatible flatbuffers version included");

struct Attacker;
struct AttackerBuilder;
struct AttackerT;

struct Rapunzel;

struct BookReader;

struct FallingTub;

struct HandFan;
struct HandFanBuilder;
struct HandFanT;

struct Movie;
struct MovieBuilder;
struct MovieT;

inline const flatbuffers::TypeTable *AttackerTypeTable();

inline const flatbuffers::TypeTable *RapunzelTypeTable();

inline const flatbuffers::TypeTable *BookReaderTypeTable();

inline const flatbuffers::TypeTable *FallingTubTypeTable();

inline const flatbuffers::TypeTable *HandFanTypeTable();

inline const flatbuffers::TypeTable *MovieTypeTable();

enum class Character : uint8_t {
  NONE = 0,
  MuLan = 1,
  Rapunzel = 2,
  Belle = 3,
  BookFan = 4,
  Other = 5,
  Unused = 6,
  MIN = NONE,
  MAX = Unused
};

inline const Character (&EnumValuesCharacter())[7] {
  static const Character values[] = {
    Character::NONE,
    Character::MuLan,
    Character::Rapunzel,
    Character::Belle,
    Character::BookFan,
    Character::Other,
    Character::Unused
  };
  return values;
}

inline const char * const *EnumNamesCharacter() {
  static const char * const names[8] = {
    "NONE",
    "MuLan",
    "Rapunzel",
    "Belle",
    "BookFan",
    "Other",
    "Unused",
    nullptr
  };
  return names;
}

inline const char *EnumNameCharacter(Character e) {
  if (flatbuffers::IsOutRange(e, Character::NONE, Character::Unused)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesCharacter()[index];
}

struct CharacterUnion {
  Character type;
  void *value;

  CharacterUnion() : type(Character::NONE), value(nullptr) {}
  CharacterUnion(CharacterUnion&& u) FLATBUFFERS_NOEXCEPT :
    type(Character::NONE), value(nullptr)
    { std::swap(type, u.type); std::swap(value, u.value); }
  CharacterUnion(const CharacterUnion &);
  CharacterUnion &operator=(const CharacterUnion &u)
    { CharacterUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
  CharacterUnion &operator=(CharacterUnion &&u) FLATBUFFERS_NOEXCEPT
    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
  ~CharacterUnion() { Reset(); }

  void Reset();

  static void *UnPack(const void *obj, Character type, const flatbuffers::resolver_function_t *resolver);
  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;

  AttackerT *AsMuLan() {
    return type == Character::MuLan ?
      reinterpret_cast<AttackerT *>(value) : nullptr;
  }
  const AttackerT *AsMuLan() const {
    return type == Character::MuLan ?
      reinterpret_cast<const AttackerT *>(value) : nullptr;
  }
  Rapunzel *AsRapunzel() {
    return type == Character::Rapunzel ?
      reinterpret_cast<Rapunzel *>(value) : nullptr;
  }
  const Rapunzel *AsRapunzel() const {
    return type == Character::Rapunzel ?
      reinterpret_cast<const Rapunzel *>(value) : nullptr;
  }
  BookReader *AsBelle() {
    return type == Character::Belle ?
      reinterpret_cast<BookReader *>(value) : nullptr;
  }
  const BookReader *AsBelle() const {
    return type == Character::Belle ?
      reinterpret_cast<const BookReader *>(value) : nullptr;
  }
  BookReader *AsBookFan() {
    return type == Character::BookFan ?
      reinterpret_cast<BookReader *>(value) : nullptr;
  }
  const BookReader *AsBookFan() const {
    return type == Character::BookFan ?
      reinterpret_cast<const BookReader *>(value) : nullptr;
  }
  std::string *AsOther() {
    return type == Character::Other ?
      reinterpret_cast<std::string *>(value) : nullptr;
  }
  const std::string *AsOther() const {
    return type == Character::Other ?
      reinterpret_cast<const std::string *>(value) : nullptr;
  }
  std::string *AsUnused() {
    return type == Character::Unused ?
      reinterpret_cast<std::string *>(value) : nullptr;
  }
  const std::string *AsUnused() const {
    return type == Character::Unused ?
      reinterpret_cast<const std::string *>(value) : nullptr;
  }
};

bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Character type);
bool VerifyCharacterVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<Character> *types);

enum class Gadget : uint8_t {
  NONE = 0,
  FallingTub = 1,
  HandFan = 2,
  MIN = NONE,
  MAX = HandFan
};

inline const Gadget (&EnumValuesGadget())[3] {
  static const Gadget values[] = {
    Gadget::NONE,
    Gadget::FallingTub,
    Gadget::HandFan
  };
  return values;
}

inline const char * const *EnumNamesGadget() {
  static const char * const names[4] = {
    "NONE",
    "FallingTub",
    "HandFan",
    nullptr
  };
  return names;
}

inline const char *EnumNameGadget(Gadget e) {
  if (flatbuffers::IsOutRange(e, Gadget::NONE, Gadget::HandFan)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesGadget()[index];
}

template<typename T> struct GadgetTraits {
  static const Gadget enum_value = Gadget::NONE;
};

template<> struct GadgetTraits<FallingTub> {
  static const Gadget enum_value = Gadget::FallingTub;
};

template<> struct GadgetTraits<HandFan> {
  static const Gadget enum_value = Gadget::HandFan;
};

template<typename T> struct GadgetUnionTraits {
  static const Gadget enum_value = Gadget::NONE;
};

template<> struct GadgetUnionTraits<FallingTub> {
  static const Gadget enum_value = Gadget::FallingTub;
};

template<> struct GadgetUnionTraits<HandFanT> {
  static const Gadget enum_value = Gadget::HandFan;
};

struct GadgetUnion {
  Gadget type;
  void *value;

  GadgetUnion() : type(Gadget::NONE), value(nullptr) {}
  GadgetUnion(GadgetUnion&& u) FLATBUFFERS_NOEXCEPT :
    type(Gadget::NONE), value(nullptr)
    { std::swap(type, u.type); std::swap(value, u.value); }
  GadgetUnion(const GadgetUnion &);
  GadgetUnion &operator=(const GadgetUnion &u)
    { GadgetUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
  GadgetUnion &operator=(GadgetUnion &&u) FLATBUFFERS_NOEXCEPT
    { std::swap(type, u.type); std::swap(value, u.value); return *this; }
  ~GadgetUnion() { Reset(); }

  void Reset();

  template <typename T>
  void Set(T&& val) {
    typedef typename std::remove_reference<T>::type RT;
    Reset();
    type = GadgetUnionTraits<RT>::enum_value;
    if (type != Gadget::NONE) {
      value = new RT(std::forward<T>(val));
    }
  }

  static void *UnPack(const void *obj, Gadget type, const flatbuffers::resolver_function_t *resolver);
  flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;

  FallingTub *AsFallingTub() {
    return type == Gadget::FallingTub ?
      reinterpret_cast<FallingTub *>(value) : nullptr;
  }
  const FallingTub *AsFallingTub() const {
    return type == Gadget::FallingTub ?
      reinterpret_cast<const FallingTub *>(value) : nullptr;
  }
  HandFanT *AsHandFan() {
    return type == Gadget::HandFan ?
      reinterpret_cast<HandFanT *>(value) : nullptr;
  }
  const HandFanT *AsHandFan() const {
    return type == Gadget::HandFan ?
      reinterpret_cast<const HandFanT *>(value) : nullptr;
  }
};

bool VerifyGadget(flatbuffers::Verifier &verifier, const void *obj, Gadget type);
bool VerifyGadgetVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<Gadget> *types);

FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Rapunzel FLATBUFFERS_FINAL_CLASS {
 private:
  int32_t hair_length_;

 public:
  struct Traits;
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return RapunzelTypeTable();
  }
  Rapunzel()
      : hair_length_(0) {
  }
  Rapunzel(int32_t _hair_length)
      : hair_length_(flatbuffers::EndianScalar(_hair_length)) {
  }
  int32_t hair_length() const {
    return flatbuffers::EndianScalar(hair_length_);
  }
  void mutate_hair_length(int32_t _hair_length) {
    flatbuffers::WriteScalar(&hair_length_, _hair_length);
  }
  template<size_t Index>
  auto get_field() const {
         if constexpr (Index == 0) return hair_length();
    else static_assert(Index != Index, "Invalid Field Index");
  }
};
FLATBUFFERS_STRUCT_END(Rapunzel, 4);

struct Rapunzel::Traits {
  using type = Rapunzel;
  static constexpr auto name = "Rapunzel";
  static constexpr auto fully_qualified_name = "Rapunzel";
  static constexpr size_t fields_number = 1;
  static constexpr std::array<const char *, fields_number> field_names = {
    "hair_length"
  };
  template<size_t Index>
  using FieldType = decltype(std::declval<type>().get_field<Index>());
};

FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) BookReader FLATBUFFERS_FINAL_CLASS {
 private:
  int32_t books_read_;

 public:
  struct Traits;
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return BookReaderTypeTable();
  }
  BookReader()
      : books_read_(0) {
  }
  BookReader(int32_t _books_read)
      : books_read_(flatbuffers::EndianScalar(_books_read)) {
  }
  int32_t books_read() const {
    return flatbuffers::EndianScalar(books_read_);
  }
  void mutate_books_read(int32_t _books_read) {
    flatbuffers::WriteScalar(&books_read_, _books_read);
  }
  template<size_t Index>
  auto get_field() const {
         if constexpr (Index == 0) return books_read();
    else static_assert(Index != Index, "Invalid Field Index");
  }
};
FLATBUFFERS_STRUCT_END(BookReader, 4);

struct BookReader::Traits {
  using type = BookReader;
  static constexpr auto name = "BookReader";
  static constexpr auto fully_qualified_name = "BookReader";
  static constexpr size_t fields_number = 1;
  static constexpr std::array<const char *, fields_number> field_names = {
    "books_read"
  };
  template<size_t Index>
  using FieldType = decltype(std::declval<type>().get_field<Index>());
};

FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) FallingTub FLATBUFFERS_FINAL_CLASS {
 private:
  int32_t weight_;

 public:
  struct Traits;
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return FallingTubTypeTable();
  }
  FallingTub()
      : weight_(0) {
  }
  FallingTub(int32_t _weight)
      : weight_(flatbuffers::EndianScalar(_weight)) {
  }
  int32_t weight() const {
    return flatbuffers::EndianScalar(weight_);
  }
  void mutate_weight(int32_t _weight) {
    flatbuffers::WriteScalar(&weight_, _weight);
  }
  template<size_t Index>
  auto get_field() const {
         if constexpr (Index == 0) return weight();
    else static_assert(Index != Index, "Invalid Field Index");
  }
};
FLATBUFFERS_STRUCT_END(FallingTub, 4);

struct FallingTub::Traits {
  using type = FallingTub;
  static constexpr auto name = "FallingTub";
  static constexpr auto fully_qualified_name = "FallingTub";
  static constexpr size_t fields_number = 1;
  static constexpr std::array<const char *, fields_number> field_names = {
    "weight"
  };
  template<size_t Index>
  using FieldType = decltype(std::declval<type>().get_field<Index>());
};

struct AttackerT : public flatbuffers::NativeTable {
  typedef Attacker TableType;
  int32_t sword_attack_damage = 0;
};

struct Attacker FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef AttackerT NativeTableType;
  typedef AttackerBuilder Builder;
  struct Traits;
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return AttackerTypeTable();
  }
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_SWORD_ATTACK_DAMAGE = 4
  };
  int32_t sword_attack_damage() const {
    return GetField<int32_t>(VT_SWORD_ATTACK_DAMAGE, 0);
  }
  bool mutate_sword_attack_damage(int32_t _sword_attack_damage = 0) {
    return SetField<int32_t>(VT_SWORD_ATTACK_DAMAGE, _sword_attack_damage, 0);
  }
  template<size_t Index>
  auto get_field() const {
         if constexpr (Index == 0) return sword_attack_damage();
    else static_assert(Index != Index, "Invalid Field Index");
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_SWORD_ATTACK_DAMAGE, 4) &&
           verifier.EndTable();
  }
  AttackerT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(AttackerT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<Attacker> Pack(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct AttackerBuilder {
  typedef Attacker Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_sword_attack_damage(int32_t sword_attack_damage) {
    fbb_.AddElement<int32_t>(Attacker::VT_SWORD_ATTACK_DAMAGE, sword_attack_damage, 0);
  }
  explicit AttackerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  flatbuffers::Offset<Attacker> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Attacker>(end);
    return o;
  }
};

inline flatbuffers::Offset<Attacker> CreateAttacker(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t sword_attack_damage = 0) {
  AttackerBuilder builder_(_fbb);
  builder_.add_sword_attack_damage(sword_attack_damage);
  return builder_.Finish();
}

struct Attacker::Traits {
  using type = Attacker;
  static auto constexpr Create = CreateAttacker;
  static constexpr auto name = "Attacker";
  static constexpr auto fully_qualified_name = "Attacker";
  static constexpr size_t fields_number = 1;
  static constexpr std::array<const char *, fields_number> field_names = {
    "sword_attack_damage"
  };
  template<size_t Index>
  using FieldType = decltype(std::declval<type>().get_field<Index>());
};

flatbuffers::Offset<Attacker> CreateAttacker(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct HandFanT : public flatbuffers::NativeTable {
  typedef HandFan TableType;
  int32_t length = 0;
};

struct HandFan FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef HandFanT NativeTableType;
  typedef HandFanBuilder Builder;
  struct Traits;
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return HandFanTypeTable();
  }
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_LENGTH = 4
  };
  int32_t length() const {
    return GetField<int32_t>(VT_LENGTH, 0);
  }
  bool mutate_length(int32_t _length = 0) {
    return SetField<int32_t>(VT_LENGTH, _length, 0);
  }
  template<size_t Index>
  auto get_field() const {
         if constexpr (Index == 0) return length();
    else static_assert(Index != Index, "Invalid Field Index");
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_LENGTH, 4) &&
           verifier.EndTable();
  }
  HandFanT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(HandFanT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<HandFan> Pack(flatbuffers::FlatBufferBuilder &_fbb, const HandFanT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct HandFanBuilder {
  typedef HandFan Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_length(int32_t length) {
    fbb_.AddElement<int32_t>(HandFan::VT_LENGTH, length, 0);
  }
  explicit HandFanBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  flatbuffers::Offset<HandFan> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<HandFan>(end);
    return o;
  }
};

inline flatbuffers::Offset<HandFan> CreateHandFan(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t length = 0) {
  HandFanBuilder builder_(_fbb);
  builder_.add_length(length);
  return builder_.Finish();
}

struct HandFan::Traits {
  using type = HandFan;
  static auto constexpr Create = CreateHandFan;
  static constexpr auto name = "HandFan";
  static constexpr auto fully_qualified_name = "HandFan";
  static constexpr size_t fields_number = 1;
  static constexpr std::array<const char *, fields_number> field_names = {
    "length"
  };
  template<size_t Index>
  using FieldType = decltype(std::declval<type>().get_field<Index>());
};

flatbuffers::Offset<HandFan> CreateHandFan(flatbuffers::FlatBufferBuilder &_fbb, const HandFanT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct MovieT : public flatbuffers::NativeTable {
  typedef Movie TableType;
  CharacterUnion main_character{};
  std::vector<CharacterUnion> characters{};
};

struct Movie FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MovieT NativeTableType;
  typedef MovieBuilder Builder;
  struct Traits;
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return MovieTypeTable();
  }
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_MAIN_CHARACTER_TYPE = 4,
    VT_MAIN_CHARACTER = 6,
    VT_CHARACTERS_TYPE = 8,
    VT_CHARACTERS = 10
  };
  Character main_character_type() const {
    return static_cast<Character>(GetField<uint8_t>(VT_MAIN_CHARACTER_TYPE, 0));
  }
  const void *main_character() const {
    return GetPointer<const void *>(VT_MAIN_CHARACTER);
  }
  const Attacker *main_character_as_MuLan() const {
    return main_character_type() == Character::MuLan ? static_cast<const Attacker *>(main_character()) : nullptr;
  }
  const Rapunzel *main_character_as_Rapunzel() const {
    return main_character_type() == Character::Rapunzel ? static_cast<const Rapunzel *>(main_character()) : nullptr;
  }
  const BookReader *main_character_as_Belle() const {
    return main_character_type() == Character::Belle ? static_cast<const BookReader *>(main_character()) : nullptr;
  }
  const BookReader *main_character_as_BookFan() const {
    return main_character_type() == Character::BookFan ? static_cast<const BookReader *>(main_character()) : nullptr;
  }
  const flatbuffers::String *main_character_as_Other() const {
    return main_character_type() == Character::Other ? static_cast<const flatbuffers::String *>(main_character()) : nullptr;
  }
  const flatbuffers::String *main_character_as_Unused() const {
    return main_character_type() == Character::Unused ? static_cast<const flatbuffers::String *>(main_character()) : nullptr;
  }
  void *mutable_main_character() {
    return GetPointer<void *>(VT_MAIN_CHARACTER);
  }
  const flatbuffers::Vector<Character> *characters_type() const {
    return GetPointer<const flatbuffers::Vector<Character> *>(VT_CHARACTERS_TYPE);
  }
  flatbuffers::Vector<Character> *mutable_characters_type() {
    return GetPointer<flatbuffers::Vector<Character> *>(VT_CHARACTERS_TYPE);
  }
  const flatbuffers::Vector<flatbuffers::Offset<void>> *characters() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<void>> *>(VT_CHARACTERS);
  }
  flatbuffers::Vector<flatbuffers::Offset<void>> *mutable_characters() {
    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<void>> *>(VT_CHARACTERS);
  }
  template<size_t Index>
  auto get_field() const {
         if constexpr (Index == 0) return main_character_type();
    else if constexpr (Index == 1) return main_character();
    else if constexpr (Index == 2) return characters_type();
    else if constexpr (Index == 3) return characters();
    else static_assert(Index != Index, "Invalid Field Index");
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_MAIN_CHARACTER_TYPE, 1) &&
           VerifyOffset(verifier, VT_MAIN_CHARACTER) &&
           VerifyCharacter(verifier, main_character(), main_character_type()) &&
           VerifyOffset(verifier, VT_CHARACTERS_TYPE) &&
           verifier.VerifyVector(characters_type()) &&
           VerifyOffset(verifier, VT_CHARACTERS) &&
           verifier.VerifyVector(characters()) &&
           VerifyCharacterVector(verifier, characters(), characters_type()) &&
           verifier.EndTable();
  }
  MovieT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(MovieT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<Movie> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MovieT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct MovieBuilder {
  typedef Movie Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_main_character_type(Character main_character_type) {
    fbb_.AddElement<uint8_t>(Movie::VT_MAIN_CHARACTER_TYPE, static_cast<uint8_t>(main_character_type), 0);
  }
  void add_main_character(flatbuffers::Offset<void> main_character) {
    fbb_.AddOffset(Movie::VT_MAIN_CHARACTER, main_character);
  }
  void add_characters_type(flatbuffers::Offset<flatbuffers::Vector<Character>> characters_type) {
    fbb_.AddOffset(Movie::VT_CHARACTERS_TYPE, characters_type);
  }
  void add_characters(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<void>>> characters) {
    fbb_.AddOffset(Movie::VT_CHARACTERS, characters);
  }
  explicit MovieBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  flatbuffers::Offset<Movie> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Movie>(end);
    return o;
  }
};

inline flatbuffers::Offset<Movie> CreateMovie(
    flatbuffers::FlatBufferBuilder &_fbb,
    Character main_character_type = Character::NONE,
    flatbuffers::Offset<void> main_character = 0,
    flatbuffers::Offset<flatbuffers::Vector<Character>> characters_type = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<void>>> characters = 0) {
  MovieBuilder builder_(_fbb);
  builder_.add_characters(characters);
  builder_.add_characters_type(characters_type);
  builder_.add_main_character(main_character);
  builder_.add_main_character_type(main_character_type);
  return builder_.Finish();
}

struct Movie::Traits {
  using type = Movie;
  static auto constexpr Create = CreateMovie;
  static constexpr auto name = "Movie";
  static constexpr auto fully_qualified_name = "Movie";
  static constexpr size_t fields_number = 4;
  static constexpr std::array<const char *, fields_number> field_names = {
    "main_character_type",
    "main_character",
    "characters_type",
    "characters"
  };
  template<size_t Index>
  using FieldType = decltype(std::declval<type>().get_field<Index>());
};

inline flatbuffers::Offset<Movie> CreateMovieDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    Character main_character_type = Character::NONE,
    flatbuffers::Offset<void> main_character = 0,
    const std::vector<Character> *characters_type = nullptr,
    const std::vector<flatbuffers::Offset<void>> *characters = nullptr) {
  auto characters_type__ = characters_type ? _fbb.CreateVector<Character>(*characters_type) : 0;
  auto characters__ = characters ? _fbb.CreateVector<flatbuffers::Offset<void>>(*characters) : 0;
  return CreateMovie(
      _fbb,
      main_character_type,
      main_character,
      characters_type__,
      characters__);
}

flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

inline AttackerT *Attacker::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = std::make_unique<AttackerT>();
  UnPackTo(_o.get(), _resolver);
  return _o.release();
}

inline void Attacker::UnPackTo(AttackerT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = sword_attack_damage(); _o->sword_attack_damage = _e; }
}

inline flatbuffers::Offset<Attacker> Attacker::Pack(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateAttacker(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<Attacker> CreateAttacker(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const AttackerT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _sword_attack_damage = _o->sword_attack_damage;
  return CreateAttacker(
      _fbb,
      _sword_attack_damage);
}

inline HandFanT *HandFan::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = std::make_unique<HandFanT>();
  UnPackTo(_o.get(), _resolver);
  return _o.release();
}

inline void HandFan::UnPackTo(HandFanT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = length(); _o->length = _e; }
}

inline flatbuffers::Offset<HandFan> HandFan::Pack(flatbuffers::FlatBufferBuilder &_fbb, const HandFanT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateHandFan(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<HandFan> CreateHandFan(flatbuffers::FlatBufferBuilder &_fbb, const HandFanT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const HandFanT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _length = _o->length;
  return CreateHandFan(
      _fbb,
      _length);
}

inline MovieT *Movie::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = std::make_unique<MovieT>();
  UnPackTo(_o.get(), _resolver);
  return _o.release();
}

inline void Movie::UnPackTo(MovieT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = main_character_type(); _o->main_character.type = _e; }
  { auto _e = main_character(); if (_e) _o->main_character.value = CharacterUnion::UnPack(_e, main_character_type(), _resolver); }
  { auto _e = characters_type(); if (_e) { _o->characters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->characters[_i].type = static_cast<Character>(_e->Get(_i)); } } else { _o->characters.resize(0); } }
  { auto _e = characters(); if (_e) { _o->characters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->characters[_i].value = CharacterUnion::UnPack(_e->Get(_i), characters_type()->GetEnum<Character>(_i), _resolver); } } else { _o->characters.resize(0); } }
}

inline flatbuffers::Offset<Movie> Movie::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MovieT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateMovie(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MovieT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _main_character_type = _o->main_character.type;
  auto _main_character = _o->main_character.Pack(_fbb);
  auto _characters_type = _o->characters.size() ? _fbb.CreateVector<Character>(_o->characters.size(), [](size_t i, _VectorArgs *__va) { return __va->__o->characters[i].type; }, &_va) : 0;
  auto _characters = _o->characters.size() ? _fbb.CreateVector<flatbuffers::Offset<void>>(_o->characters.size(), [](size_t i, _VectorArgs *__va) { return __va->__o->characters[i].Pack(*__va->__fbb, __va->__rehasher); }, &_va) : 0;
  return CreateMovie(
      _fbb,
      _main_character_type,
      _main_character,
      _characters_type,
      _characters);
}

inline bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Character type) {
  switch (type) {
    case Character::NONE: {
      return true;
    }
    case Character::MuLan: {
      auto ptr = reinterpret_cast<const Attacker *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Character::Rapunzel: {
      return verifier.VerifyField<Rapunzel>(static_cast<const uint8_t *>(obj), 0, 4);
    }
    case Character::Belle: {
      return verifier.VerifyField<BookReader>(static_cast<const uint8_t *>(obj), 0, 4);
    }
    case Character::BookFan: {
      return verifier.VerifyField<BookReader>(static_cast<const uint8_t *>(obj), 0, 4);
    }
    case Character::Other: {
      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
      return verifier.VerifyString(ptr);
    }
    case Character::Unused: {
      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
      return verifier.VerifyString(ptr);
    }
    default: return true;
  }
}

inline bool VerifyCharacterVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<Character> *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 (!VerifyCharacter(
        verifier,  values->Get(i), types->GetEnum<Character>(i))) {
      return false;
    }
  }
  return true;
}

inline void *CharacterUnion::UnPack(const void *obj, Character type, const flatbuffers::resolver_function_t *resolver) {
  (void)resolver;
  switch (type) {
    case Character::MuLan: {
      auto ptr = reinterpret_cast<const Attacker *>(obj);
      return ptr->UnPack(resolver);
    }
    case Character::Rapunzel: {
      auto ptr = reinterpret_cast<const Rapunzel *>(obj);
      return new Rapunzel(*ptr);
    }
    case Character::Belle: {
      auto ptr = reinterpret_cast<const BookReader *>(obj);
      return new BookReader(*ptr);
    }
    case Character::BookFan: {
      auto ptr = reinterpret_cast<const BookReader *>(obj);
      return new BookReader(*ptr);
    }
    case Character::Other: {
      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
      return new std::string(ptr->c_str(), ptr->size());
    }
    case Character::Unused: {
      auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
      return new std::string(ptr->c_str(), ptr->size());
    }
    default: return nullptr;
  }
}

inline flatbuffers::Offset<void> CharacterUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
  (void)_rehasher;
  switch (type) {
    case Character::MuLan: {
      auto ptr = reinterpret_cast<const AttackerT *>(value);
      return CreateAttacker(_fbb, ptr, _rehasher).Union();
    }
    case Character::Rapunzel: {
      auto ptr = reinterpret_cast<const Rapunzel *>(value);
      return _fbb.CreateStruct(*ptr).Union();
    }
    case Character::Belle: {
      auto ptr = reinterpret_cast<const BookReader *>(value);
      return _fbb.CreateStruct(*ptr).Union();
    }
    case Character::BookFan: {
      auto ptr = reinterpret_cast<const BookReader *>(value);
      return _fbb.CreateStruct(*ptr).Union();
    }
    case Character::Other: {
      auto ptr = reinterpret_cast<const std::string *>(value);
      return _fbb.CreateString(*ptr).Union();
    }
    case Character::Unused: {
      auto ptr = reinterpret_cast<const std::string *>(value);
      return _fbb.CreateString(*ptr).Union();
    }
    default: return 0;
  }
}

inline CharacterUnion::CharacterUnion(const CharacterUnion &u) : type(u.type), value(nullptr) {
  switch (type) {
    case Character::MuLan: {
      value = new AttackerT(*reinterpret_cast<AttackerT *>(u.value));
      break;
    }
    case Character::Rapunzel: {
      value = new Rapunzel(*reinterpret_cast<Rapunzel *>(u.value));
      break;
    }
    case Character::Belle: {
      value = new BookReader(*reinterpret_cast<BookReader *>(u.value));
      break;
    }
    case Character::BookFan: {
      value = new BookReader(*reinterpret_cast<BookReader *>(u.value));
      break;
    }
    case Character::Other: {
      value = new std::string(*reinterpret_cast<std::string *>(u.value));
      break;
    }
    case Character::Unused: {
      value = new std::string(*reinterpret_cast<std::string *>(u.value));
      break;
    }
    default:
      break;
  }
}

inline void CharacterUnion::Reset() {
  switch (type) {
    case Character::MuLan: {
      auto ptr = reinterpret_cast<AttackerT *>(value);
      delete ptr;
      break;
    }
    case Character::Rapunzel: {
      auto ptr = reinterpret_cast<Rapunzel *>(value);
      delete ptr;
      break;
    }
    case Character::Belle: {
      auto ptr = reinterpret_cast<BookReader *>(value);
      delete ptr;
      break;
    }
    case Character::BookFan: {
      auto ptr = reinterpret_cast<BookReader *>(value);
      delete ptr;
      break;
    }
    case Character::Other: {
      auto ptr = reinterpret_cast<std::string *>(value);
      delete ptr;
      break;
    }
    case Character::Unused: {
      auto ptr = reinterpret_cast<std::string *>(value);
      delete ptr;
      break;
    }
    default: break;
  }
  value = nullptr;
  type = Character::NONE;
}

inline bool VerifyGadget(flatbuffers::Verifier &verifier, const void *obj, Gadget type) {
  switch (type) {
    case Gadget::NONE: {
      return true;
    }
    case Gadget::FallingTub: {
      return verifier.VerifyField<FallingTub>(static_cast<const uint8_t *>(obj), 0, 4);
    }
    case Gadget::HandFan: {
      auto ptr = reinterpret_cast<const HandFan *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

inline bool VerifyGadgetVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<Gadget> *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 (!VerifyGadget(
        verifier,  values->Get(i), types->GetEnum<Gadget>(i))) {
      return false;
    }
  }
  return true;
}

inline void *GadgetUnion::UnPack(const void *obj, Gadget type, const flatbuffers::resolver_function_t *resolver) {
  (void)resolver;
  switch (type) {
    case Gadget::FallingTub: {
      auto ptr = reinterpret_cast<const FallingTub *>(obj);
      return new FallingTub(*ptr);
    }
    case Gadget::HandFan: {
      auto ptr = reinterpret_cast<const HandFan *>(obj);
      return ptr->UnPack(resolver);
    }
    default: return nullptr;
  }
}

inline flatbuffers::Offset<void> GadgetUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
  (void)_rehasher;
  switch (type) {
    case Gadget::FallingTub: {
      auto ptr = reinterpret_cast<const FallingTub *>(value);
      return _fbb.CreateStruct(*ptr).Union();
    }
    case Gadget::HandFan: {
      auto ptr = reinterpret_cast<const HandFanT *>(value);
      return CreateHandFan(_fbb, ptr, _rehasher).Union();
    }
    default: return 0;
  }
}

inline GadgetUnion::GadgetUnion(const GadgetUnion &u) : type(u.type), value(nullptr) {
  switch (type) {
    case Gadget::FallingTub: {
      value = new FallingTub(*reinterpret_cast<FallingTub *>(u.value));
      break;
    }
    case Gadget::HandFan: {
      value = new HandFanT(*reinterpret_cast<HandFanT *>(u.value));
      break;
    }
    default:
      break;
  }
}

inline void GadgetUnion::Reset() {
  switch (type) {
    case Gadget::FallingTub: {
      auto ptr = reinterpret_cast<FallingTub *>(value);
      delete ptr;
      break;
    }
    case Gadget::HandFan: {
      auto ptr = reinterpret_cast<HandFanT *>(value);
      delete ptr;
      break;
    }
    default: break;
  }
  value = nullptr;
  type = Gadget::NONE;
}

inline const flatbuffers::TypeTable *CharacterTypeTable() {
  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 },
    { flatbuffers::ET_SEQUENCE, 0, 2 },
    { flatbuffers::ET_STRING, 0, -1 },
    { flatbuffers::ET_STRING, 0, -1 }
  };
  static const flatbuffers::TypeFunction type_refs[] = {
    AttackerTypeTable,
    RapunzelTypeTable,
    BookReaderTypeTable
  };
  static const char * const names[] = {
    "NONE",
    "MuLan",
    "Rapunzel",
    "Belle",
    "BookFan",
    "Other",
    "Unused"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_UNION, 7, type_codes, type_refs, nullptr, nullptr, names
  };
  return &tt;
}

inline const flatbuffers::TypeTable *GadgetTypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_SEQUENCE, 0, -1 },
    { flatbuffers::ET_SEQUENCE, 0, 0 },
    { flatbuffers::ET_SEQUENCE, 0, 1 }
  };
  static const flatbuffers::TypeFunction type_refs[] = {
    FallingTubTypeTable,
    HandFanTypeTable
  };
  static const char * const names[] = {
    "NONE",
    "FallingTub",
    "HandFan"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_UNION, 3, type_codes, type_refs, nullptr, nullptr, names
  };
  return &tt;
}

inline const flatbuffers::TypeTable *AttackerTypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_INT, 0, -1 }
  };
  static const char * const names[] = {
    "sword_attack_damage"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, nullptr, names
  };
  return &tt;
}

inline const flatbuffers::TypeTable *RapunzelTypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_INT, 0, -1 }
  };
  static const int64_t values[] = { 0, 4 };
  static const char * const names[] = {
    "hair_length"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_STRUCT, 1, type_codes, nullptr, nullptr, values, names
  };
  return &tt;
}

inline const flatbuffers::TypeTable *BookReaderTypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_INT, 0, -1 }
  };
  static const int64_t values[] = { 0, 4 };
  static const char * const names[] = {
    "books_read"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_STRUCT, 1, type_codes, nullptr, nullptr, values, names
  };
  return &tt;
}

inline const flatbuffers::TypeTable *FallingTubTypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_INT, 0, -1 }
  };
  static const int64_t values[] = { 0, 4 };
  static const char * const names[] = {
    "weight"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_STRUCT, 1, type_codes, nullptr, nullptr, values, names
  };
  return &tt;
}

inline const flatbuffers::TypeTable *HandFanTypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_INT, 0, -1 }
  };
  static const char * const names[] = {
    "length"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, nullptr, names
  };
  return &tt;
}

inline const flatbuffers::TypeTable *MovieTypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_UTYPE, 0, 0 },
    { flatbuffers::ET_SEQUENCE, 0, 0 },
    { flatbuffers::ET_UTYPE, 1, 0 },
    { flatbuffers::ET_SEQUENCE, 1, 0 }
  };
  static const flatbuffers::TypeFunction type_refs[] = {
    CharacterTypeTable
  };
  static const char * const names[] = {
    "main_character_type",
    "main_character",
    "characters_type",
    "characters"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_TABLE, 4, type_codes, type_refs, nullptr, nullptr, names
  };
  return &tt;
}

inline const Movie *GetMovie(const void *buf) {
  return flatbuffers::GetRoot<Movie>(buf);
}

inline const Movie *GetSizePrefixedMovie(const void *buf) {
  return flatbuffers::GetSizePrefixedRoot<Movie>(buf);
}

inline Movie *GetMutableMovie(void *buf) {
  return flatbuffers::GetMutableRoot<Movie>(buf);
}

inline Movie *GetMutableSizePrefixedMovie(void *buf) {
  return flatbuffers::GetMutableSizePrefixedRoot<Movie>(buf);
}

inline const char *MovieIdentifier() {
  return "MOVI";
}

inline bool MovieBufferHasIdentifier(const void *buf) {
  return flatbuffers::BufferHasIdentifier(
      buf, MovieIdentifier());
}

inline bool SizePrefixedMovieBufferHasIdentifier(const void *buf) {
  return flatbuffers::BufferHasIdentifier(
      buf, MovieIdentifier(), true);
}

inline bool VerifyMovieBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifyBuffer<Movie>(MovieIdentifier());
}

inline bool VerifySizePrefixedMovieBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifySizePrefixedBuffer<Movie>(MovieIdentifier());
}

inline void FinishMovieBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<Movie> root) {
  fbb.Finish(root, MovieIdentifier());
}

inline void FinishSizePrefixedMovieBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<Movie> root) {
  fbb.FinishSizePrefixed(root, MovieIdentifier());
}

inline std::unique_ptr<MovieT> UnPackMovie(
    const void *buf,
    const flatbuffers::resolver_function_t *res = nullptr) {
  return std::unique_ptr<MovieT>(GetMovie(buf)->UnPack(res));
}

inline std::unique_ptr<MovieT> UnPackSizePrefixedMovie(
    const void *buf,
    const flatbuffers::resolver_function_t *res = nullptr) {
  return std::unique_ptr<MovieT>(GetSizePrefixedMovie(buf)->UnPack(res));
}

#endif  // FLATBUFFERS_GENERATED_UNIONVECTOR_H_
