// 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 == 2 &&
              FLATBUFFERS_VERSION_MINOR == 0 &&
              FLATBUFFERS_VERSION_REVISION == 7,
             "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)); } } }
  { 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); } } }
}

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_
