// 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 == 24 &&
              FLATBUFFERS_VERSION_MINOR == 3 &&
              FLATBUFFERS_VERSION_REVISION == 25,
             "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;

bool operator==(const AttackerT &lhs, const AttackerT &rhs);
bool operator!=(const AttackerT &lhs, const AttackerT &rhs);
bool operator==(const Rapunzel &lhs, const Rapunzel &rhs);
bool operator!=(const Rapunzel &lhs, const Rapunzel &rhs);
bool operator==(const BookReader &lhs, const BookReader &rhs);
bool operator!=(const BookReader &lhs, const BookReader &rhs);
bool operator==(const FallingTub &lhs, const FallingTub &rhs);
bool operator!=(const FallingTub &lhs, const FallingTub &rhs);
bool operator==(const HandFanT &lhs, const HandFanT &rhs);
bool operator!=(const HandFanT &lhs, const HandFanT &rhs);
bool operator==(const MovieT &lhs, const MovieT &rhs);
bool operator!=(const MovieT &lhs, const MovieT &rhs);

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 Character : uint8_t {
  Character_NONE = 0,
  Character_MuLan = 1,
  Character_Rapunzel = 2,
  Character_Belle = 3,
  Character_BookFan = 4,
  Character_Other = 5,
  Character_Unused = 6,
  Character_MIN = Character_NONE,
  Character_MAX = Character_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;
  }
};


inline bool operator==(const CharacterUnion &lhs, const CharacterUnion &rhs) {
  if (lhs.type != rhs.type) return false;
  switch (lhs.type) {
    case Character_NONE: {
      return true;
    }
    case Character_MuLan: {
      return *(reinterpret_cast<const AttackerT *>(lhs.value)) ==
             *(reinterpret_cast<const AttackerT *>(rhs.value));
    }
    case Character_Rapunzel: {
      return *(reinterpret_cast<const Rapunzel *>(lhs.value)) ==
             *(reinterpret_cast<const Rapunzel *>(rhs.value));
    }
    case Character_Belle: {
      return *(reinterpret_cast<const BookReader *>(lhs.value)) ==
             *(reinterpret_cast<const BookReader *>(rhs.value));
    }
    case Character_BookFan: {
      return *(reinterpret_cast<const BookReader *>(lhs.value)) ==
             *(reinterpret_cast<const BookReader *>(rhs.value));
    }
    case Character_Other: {
      return *(reinterpret_cast<const std::string *>(lhs.value)) ==
             *(reinterpret_cast<const std::string *>(rhs.value));
    }
    case Character_Unused: {
      return *(reinterpret_cast<const std::string *>(lhs.value)) ==
             *(reinterpret_cast<const std::string *>(rhs.value));
    }
    default: {
      return false;
    }
  }
}

inline bool operator!=(const CharacterUnion &lhs, const CharacterUnion &rhs) {
    return !(lhs == rhs);
}

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<uint8_t> *types);

enum Gadget : uint8_t {
  Gadget_NONE = 0,
  Gadget_FallingTub = 1,
  Gadget_HandFan = 2,
  Gadget_MIN = Gadget_NONE,
  Gadget_MAX = Gadget_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;
  }
};


inline bool operator==(const GadgetUnion &lhs, const GadgetUnion &rhs) {
  if (lhs.type != rhs.type) return false;
  switch (lhs.type) {
    case Gadget_NONE: {
      return true;
    }
    case Gadget_FallingTub: {
      return *(reinterpret_cast<const FallingTub *>(lhs.value)) ==
             *(reinterpret_cast<const FallingTub *>(rhs.value));
    }
    case Gadget_HandFan: {
      return *(reinterpret_cast<const HandFanT *>(lhs.value)) ==
             *(reinterpret_cast<const HandFanT *>(rhs.value));
    }
    default: {
      return false;
    }
  }
}

inline bool operator!=(const GadgetUnion &lhs, const GadgetUnion &rhs) {
    return !(lhs == rhs);
}

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<uint8_t> *types);

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

 public:
  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);
  }
};
FLATBUFFERS_STRUCT_END(Rapunzel, 4);

inline bool operator==(const Rapunzel &lhs, const Rapunzel &rhs) {
  return
      (lhs.hair_length() == rhs.hair_length());
}

inline bool operator!=(const Rapunzel &lhs, const Rapunzel &rhs) {
    return !(lhs == rhs);
}


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

 public:
  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);
  }
};
FLATBUFFERS_STRUCT_END(BookReader, 4);

inline bool operator==(const BookReader &lhs, const BookReader &rhs) {
  return
      (lhs.books_read() == rhs.books_read());
}

inline bool operator!=(const BookReader &lhs, const BookReader &rhs) {
    return !(lhs == rhs);
}


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

 public:
  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);
  }
};
FLATBUFFERS_STRUCT_END(FallingTub, 4);

inline bool operator==(const FallingTub &lhs, const FallingTub &rhs) {
  return
      (lhs.weight() == rhs.weight());
}

inline bool operator!=(const FallingTub &lhs, const FallingTub &rhs) {
    return !(lhs == rhs);
}


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;
  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);
  }
  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();
}

::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;
  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);
  }
  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();
}

::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;
  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<uint8_t> *characters_type() const {
    return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_CHARACTERS_TYPE);
  }
  ::flatbuffers::Vector<uint8_t> *mutable_characters_type() {
    return GetPointer<::flatbuffers::Vector<uint8_t> *>(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);
  }
  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<uint8_t>> 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<uint8_t>> 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();
}

inline ::flatbuffers::Offset<Movie> CreateMovieDirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    Character main_character_type = Character_NONE,
    ::flatbuffers::Offset<void> main_character = 0,
    const std::vector<uint8_t> *characters_type = nullptr,
    const std::vector<::flatbuffers::Offset<void>> *characters = nullptr) {
  auto characters_type__ = characters_type ? _fbb.CreateVector<uint8_t>(*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 bool operator==(const AttackerT &lhs, const AttackerT &rhs) {
  return
      (lhs.sword_attack_damage == rhs.sword_attack_damage);
}

inline bool operator!=(const AttackerT &lhs, const AttackerT &rhs) {
    return !(lhs == rhs);
}


inline AttackerT *Attacker::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
  auto _o = std::unique_ptr<AttackerT>(new 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 bool operator==(const HandFanT &lhs, const HandFanT &rhs) {
  return
      (lhs.length == rhs.length);
}

inline bool operator!=(const HandFanT &lhs, const HandFanT &rhs) {
    return !(lhs == rhs);
}


inline HandFanT *HandFan::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
  auto _o = std::unique_ptr<HandFanT>(new 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 bool operator==(const MovieT &lhs, const MovieT &rhs) {
  return
      (lhs.main_character == rhs.main_character) &&
      (lhs.characters == rhs.characters);
}

inline bool operator!=(const MovieT &lhs, const MovieT &rhs) {
    return !(lhs == rhs);
}


inline MovieT *Movie::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
  auto _o = std::unique_ptr<MovieT>(new 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<uint8_t>(_o->characters.size(), [](size_t i, _VectorArgs *__va) { return static_cast<uint8_t>(__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<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 (!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<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 (!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_
