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


#ifndef FLATBUFFERS_GENERATED_UNIONUNDERLYINGTYPETEST_UNIONUNDERLYINGTYPE_H_
#define FLATBUFFERS_GENERATED_UNIONUNDERLYINGTYPETEST_UNIONUNDERLYINGTYPE_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");

namespace UnionUnderlyingType {

struct A;
struct ABuilder;
struct AT;

struct B;
struct BBuilder;
struct BT;

struct C;
struct CBuilder;
struct CT;

struct D;
struct DBuilder;
struct DT;

bool operator==(const AT &lhs, const AT &rhs);
bool operator!=(const AT &lhs, const AT &rhs);
bool operator==(const BT &lhs, const BT &rhs);
bool operator!=(const BT &lhs, const BT &rhs);
bool operator==(const CT &lhs, const CT &rhs);
bool operator!=(const CT &lhs, const CT &rhs);
bool operator==(const DT &lhs, const DT &rhs);
bool operator!=(const DT &lhs, const DT &rhs);

inline const ::flatbuffers::TypeTable *ATypeTable();

inline const ::flatbuffers::TypeTable *BTypeTable();

inline const ::flatbuffers::TypeTable *CTypeTable();

inline const ::flatbuffers::TypeTable *DTypeTable();

enum class ABC : int32_t {
  NONE = 0,
  A = 555,
  B = 666,
  C = 777,
  MIN = NONE,
  MAX = C
};

inline const ABC (&EnumValuesABC())[4] {
  static const ABC values[] = {
    ABC::NONE,
    ABC::A,
    ABC::B,
    ABC::C
  };
  return values;
}

inline const char *EnumNameABC(ABC e) {
  switch (e) {
    case ABC::NONE: return "NONE";
    case ABC::A: return "A";
    case ABC::B: return "B";
    case ABC::C: return "C";
    default: return "";
  }
}

template<typename T> struct ABCTraits {
  static const ABC enum_value = ABC::NONE;
};

template<> struct ABCTraits<UnionUnderlyingType::A> {
  static const ABC enum_value = ABC::A;
};

template<> struct ABCTraits<UnionUnderlyingType::B> {
  static const ABC enum_value = ABC::B;
};

template<> struct ABCTraits<UnionUnderlyingType::C> {
  static const ABC enum_value = ABC::C;
};

template<typename T> struct ABCUnionTraits {
  static const ABC enum_value = ABC::NONE;
};

template<> struct ABCUnionTraits<UnionUnderlyingType::AT> {
  static const ABC enum_value = ABC::A;
};

template<> struct ABCUnionTraits<UnionUnderlyingType::BT> {
  static const ABC enum_value = ABC::B;
};

template<> struct ABCUnionTraits<UnionUnderlyingType::CT> {
  static const ABC enum_value = ABC::C;
};

struct ABCUnion {
  ABC type;
  void *value;

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

  void Reset();

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

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

  UnionUnderlyingType::AT *AsA() {
    return type == ABC::A ?
      reinterpret_cast<UnionUnderlyingType::AT *>(value) : nullptr;
  }
  const UnionUnderlyingType::AT *AsA() const {
    return type == ABC::A ?
      reinterpret_cast<const UnionUnderlyingType::AT *>(value) : nullptr;
  }
  UnionUnderlyingType::BT *AsB() {
    return type == ABC::B ?
      reinterpret_cast<UnionUnderlyingType::BT *>(value) : nullptr;
  }
  const UnionUnderlyingType::BT *AsB() const {
    return type == ABC::B ?
      reinterpret_cast<const UnionUnderlyingType::BT *>(value) : nullptr;
  }
  UnionUnderlyingType::CT *AsC() {
    return type == ABC::C ?
      reinterpret_cast<UnionUnderlyingType::CT *>(value) : nullptr;
  }
  const UnionUnderlyingType::CT *AsC() const {
    return type == ABC::C ?
      reinterpret_cast<const UnionUnderlyingType::CT *>(value) : nullptr;
  }
};


inline bool operator==(const ABCUnion &lhs, const ABCUnion &rhs) {
  if (lhs.type != rhs.type) return false;
  switch (lhs.type) {
    case ABC::NONE: {
      return true;
    }
    case ABC::A: {
      return *(reinterpret_cast<const UnionUnderlyingType::AT *>(lhs.value)) ==
             *(reinterpret_cast<const UnionUnderlyingType::AT *>(rhs.value));
    }
    case ABC::B: {
      return *(reinterpret_cast<const UnionUnderlyingType::BT *>(lhs.value)) ==
             *(reinterpret_cast<const UnionUnderlyingType::BT *>(rhs.value));
    }
    case ABC::C: {
      return *(reinterpret_cast<const UnionUnderlyingType::CT *>(lhs.value)) ==
             *(reinterpret_cast<const UnionUnderlyingType::CT *>(rhs.value));
    }
    default: {
      return false;
    }
  }
}

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

bool VerifyABC(::flatbuffers::Verifier &verifier, const void *obj, ABC type);
bool VerifyABCVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values, const ::flatbuffers::Vector<ABC> *types);

struct AT : public ::flatbuffers::NativeTable {
  typedef A TableType;
  int32_t a = 0;
};

struct A FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef AT NativeTableType;
  typedef ABuilder Builder;
  static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
    return ATypeTable();
  }
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_A = 4
  };
  int32_t a() const {
    return GetField<int32_t>(VT_A, 0);
  }
  bool mutate_a(int32_t _a = 0) {
    return SetField<int32_t>(VT_A, _a, 0);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_A, 4) &&
           verifier.EndTable();
  }
  AT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(AT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static ::flatbuffers::Offset<A> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct ABuilder {
  typedef A Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_a(int32_t a) {
    fbb_.AddElement<int32_t>(A::VT_A, a, 0);
  }
  explicit ABuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<A> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<A>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<A> CreateA(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    int32_t a = 0) {
  ABuilder builder_(_fbb);
  builder_.add_a(a);
  return builder_.Finish();
}

::flatbuffers::Offset<A> CreateA(::flatbuffers::FlatBufferBuilder &_fbb, const AT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct BT : public ::flatbuffers::NativeTable {
  typedef B TableType;
  std::string b{};
};

struct B FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef BT NativeTableType;
  typedef BBuilder Builder;
  static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
    return BTypeTable();
  }
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_B = 4
  };
  const ::flatbuffers::String *b() const {
    return GetPointer<const ::flatbuffers::String *>(VT_B);
  }
  ::flatbuffers::String *mutable_b() {
    return GetPointer<::flatbuffers::String *>(VT_B);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_B) &&
           verifier.VerifyString(b()) &&
           verifier.EndTable();
  }
  BT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(BT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static ::flatbuffers::Offset<B> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const BT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct BBuilder {
  typedef B Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_b(::flatbuffers::Offset<::flatbuffers::String> b) {
    fbb_.AddOffset(B::VT_B, b);
  }
  explicit BBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<B> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<B>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<B> CreateB(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    ::flatbuffers::Offset<::flatbuffers::String> b = 0) {
  BBuilder builder_(_fbb);
  builder_.add_b(b);
  return builder_.Finish();
}

inline ::flatbuffers::Offset<B> CreateBDirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    const char *b = nullptr) {
  auto b__ = b ? _fbb.CreateString(b) : 0;
  return UnionUnderlyingType::CreateB(
      _fbb,
      b__);
}

::flatbuffers::Offset<B> CreateB(::flatbuffers::FlatBufferBuilder &_fbb, const BT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct CT : public ::flatbuffers::NativeTable {
  typedef C TableType;
  bool c = false;
};

struct C FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef CT NativeTableType;
  typedef CBuilder Builder;
  static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
    return CTypeTable();
  }
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_C = 4
  };
  bool c() const {
    return GetField<uint8_t>(VT_C, 0) != 0;
  }
  bool mutate_c(bool _c = 0) {
    return SetField<uint8_t>(VT_C, static_cast<uint8_t>(_c), 0);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_C, 1) &&
           verifier.EndTable();
  }
  CT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(CT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static ::flatbuffers::Offset<C> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const CT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct CBuilder {
  typedef C Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_c(bool c) {
    fbb_.AddElement<uint8_t>(C::VT_C, static_cast<uint8_t>(c), 0);
  }
  explicit CBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<C> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<C>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<C> CreateC(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    bool c = false) {
  CBuilder builder_(_fbb);
  builder_.add_c(c);
  return builder_.Finish();
}

::flatbuffers::Offset<C> CreateC(::flatbuffers::FlatBufferBuilder &_fbb, const CT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct DT : public ::flatbuffers::NativeTable {
  typedef D TableType;
  UnionUnderlyingType::ABCUnion test_union{};
  std::vector<UnionUnderlyingType::ABCUnion> test_vector_of_union{};
};

struct D FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef DT NativeTableType;
  typedef DBuilder Builder;
  static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
    return DTypeTable();
  }
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_TEST_UNION_TYPE = 4,
    VT_TEST_UNION = 6,
    VT_TEST_VECTOR_OF_UNION_TYPE = 8,
    VT_TEST_VECTOR_OF_UNION = 10
  };
  UnionUnderlyingType::ABC test_union_type() const {
    return static_cast<UnionUnderlyingType::ABC>(GetField<int32_t>(VT_TEST_UNION_TYPE, 0));
  }
  const void *test_union() const {
    return GetPointer<const void *>(VT_TEST_UNION);
  }
  template<typename T> const T *test_union_as() const;
  const UnionUnderlyingType::A *test_union_as_A() const {
    return test_union_type() == UnionUnderlyingType::ABC::A ? static_cast<const UnionUnderlyingType::A *>(test_union()) : nullptr;
  }
  const UnionUnderlyingType::B *test_union_as_B() const {
    return test_union_type() == UnionUnderlyingType::ABC::B ? static_cast<const UnionUnderlyingType::B *>(test_union()) : nullptr;
  }
  const UnionUnderlyingType::C *test_union_as_C() const {
    return test_union_type() == UnionUnderlyingType::ABC::C ? static_cast<const UnionUnderlyingType::C *>(test_union()) : nullptr;
  }
  void *mutable_test_union() {
    return GetPointer<void *>(VT_TEST_UNION);
  }
  const ::flatbuffers::Vector<UnionUnderlyingType::ABC> *test_vector_of_union_type() const {
    return GetPointer<const ::flatbuffers::Vector<UnionUnderlyingType::ABC> *>(VT_TEST_VECTOR_OF_UNION_TYPE);
  }
  ::flatbuffers::Vector<UnionUnderlyingType::ABC> *mutable_test_vector_of_union_type() {
    return GetPointer<::flatbuffers::Vector<UnionUnderlyingType::ABC> *>(VT_TEST_VECTOR_OF_UNION_TYPE);
  }
  const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *test_vector_of_union() const {
    return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *>(VT_TEST_VECTOR_OF_UNION);
  }
  ::flatbuffers::Vector<::flatbuffers::Offset<void>> *mutable_test_vector_of_union() {
    return GetPointer<::flatbuffers::Vector<::flatbuffers::Offset<void>> *>(VT_TEST_VECTOR_OF_UNION);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_TEST_UNION_TYPE, 1) &&
           VerifyOffset(verifier, VT_TEST_UNION) &&
           VerifyABC(verifier, test_union(), test_union_type()) &&
           VerifyOffset(verifier, VT_TEST_VECTOR_OF_UNION_TYPE) &&
           verifier.VerifyVector(test_vector_of_union_type()) &&
           VerifyOffset(verifier, VT_TEST_VECTOR_OF_UNION) &&
           verifier.VerifyVector(test_vector_of_union()) &&
           VerifyABCVector(verifier, test_vector_of_union(), test_vector_of_union_type()) &&
           verifier.EndTable();
  }
  DT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(DT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static ::flatbuffers::Offset<D> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const DT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

template<> inline const UnionUnderlyingType::A *D::test_union_as<UnionUnderlyingType::A>() const {
  return test_union_as_A();
}

template<> inline const UnionUnderlyingType::B *D::test_union_as<UnionUnderlyingType::B>() const {
  return test_union_as_B();
}

template<> inline const UnionUnderlyingType::C *D::test_union_as<UnionUnderlyingType::C>() const {
  return test_union_as_C();
}

struct DBuilder {
  typedef D Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_test_union_type(UnionUnderlyingType::ABC test_union_type) {
    fbb_.AddElement<int32_t>(D::VT_TEST_UNION_TYPE, static_cast<int32_t>(test_union_type), 0);
  }
  void add_test_union(::flatbuffers::Offset<void> test_union) {
    fbb_.AddOffset(D::VT_TEST_UNION, test_union);
  }
  void add_test_vector_of_union_type(::flatbuffers::Offset<::flatbuffers::Vector<UnionUnderlyingType::ABC>> test_vector_of_union_type) {
    fbb_.AddOffset(D::VT_TEST_VECTOR_OF_UNION_TYPE, test_vector_of_union_type);
  }
  void add_test_vector_of_union(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> test_vector_of_union) {
    fbb_.AddOffset(D::VT_TEST_VECTOR_OF_UNION, test_vector_of_union);
  }
  explicit DBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<D> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<D>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<D> CreateD(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    UnionUnderlyingType::ABC test_union_type = UnionUnderlyingType::ABC::NONE,
    ::flatbuffers::Offset<void> test_union = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<UnionUnderlyingType::ABC>> test_vector_of_union_type = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> test_vector_of_union = 0) {
  DBuilder builder_(_fbb);
  builder_.add_test_vector_of_union(test_vector_of_union);
  builder_.add_test_vector_of_union_type(test_vector_of_union_type);
  builder_.add_test_union(test_union);
  builder_.add_test_union_type(test_union_type);
  return builder_.Finish();
}

inline ::flatbuffers::Offset<D> CreateDDirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    UnionUnderlyingType::ABC test_union_type = UnionUnderlyingType::ABC::NONE,
    ::flatbuffers::Offset<void> test_union = 0,
    const std::vector<UnionUnderlyingType::ABC> *test_vector_of_union_type = nullptr,
    const std::vector<::flatbuffers::Offset<void>> *test_vector_of_union = nullptr) {
  auto test_vector_of_union_type__ = test_vector_of_union_type ? _fbb.CreateVector<UnionUnderlyingType::ABC>(*test_vector_of_union_type) : 0;
  auto test_vector_of_union__ = test_vector_of_union ? _fbb.CreateVector<::flatbuffers::Offset<void>>(*test_vector_of_union) : 0;
  return UnionUnderlyingType::CreateD(
      _fbb,
      test_union_type,
      test_union,
      test_vector_of_union_type__,
      test_vector_of_union__);
}

::flatbuffers::Offset<D> CreateD(::flatbuffers::FlatBufferBuilder &_fbb, const DT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);


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

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


inline AT *A::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
  auto _o = std::unique_ptr<AT>(new AT());
  UnPackTo(_o.get(), _resolver);
  return _o.release();
}

inline void A::UnPackTo(AT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = a(); _o->a = _e; }
}

inline ::flatbuffers::Offset<A> A::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const AT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
  return CreateA(_fbb, _o, _rehasher);
}

inline ::flatbuffers::Offset<A> CreateA(::flatbuffers::FlatBufferBuilder &_fbb, const AT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const AT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _a = _o->a;
  return UnionUnderlyingType::CreateA(
      _fbb,
      _a);
}


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

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


inline BT *B::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
  auto _o = std::unique_ptr<BT>(new BT());
  UnPackTo(_o.get(), _resolver);
  return _o.release();
}

inline void B::UnPackTo(BT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = b(); if (_e) _o->b = _e->str(); }
}

inline ::flatbuffers::Offset<B> B::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const BT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
  return CreateB(_fbb, _o, _rehasher);
}

inline ::flatbuffers::Offset<B> CreateB(::flatbuffers::FlatBufferBuilder &_fbb, const BT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const BT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _b = _o->b.empty() ? 0 : _fbb.CreateString(_o->b);
  return UnionUnderlyingType::CreateB(
      _fbb,
      _b);
}


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

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


inline CT *C::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
  auto _o = std::unique_ptr<CT>(new CT());
  UnPackTo(_o.get(), _resolver);
  return _o.release();
}

inline void C::UnPackTo(CT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = c(); _o->c = _e; }
}

inline ::flatbuffers::Offset<C> C::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const CT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
  return CreateC(_fbb, _o, _rehasher);
}

inline ::flatbuffers::Offset<C> CreateC(::flatbuffers::FlatBufferBuilder &_fbb, const CT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const CT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _c = _o->c;
  return UnionUnderlyingType::CreateC(
      _fbb,
      _c);
}


inline bool operator==(const DT &lhs, const DT &rhs) {
  return
      (lhs.test_union == rhs.test_union) &&
      (lhs.test_vector_of_union == rhs.test_vector_of_union);
}

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


inline DT *D::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
  auto _o = std::unique_ptr<DT>(new DT());
  UnPackTo(_o.get(), _resolver);
  return _o.release();
}

inline void D::UnPackTo(DT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = test_union_type(); _o->test_union.type = _e; }
  { auto _e = test_union(); if (_e) _o->test_union.value = UnionUnderlyingType::ABCUnion::UnPack(_e, test_union_type(), _resolver); }
  { auto _e = test_vector_of_union_type(); if (_e) { _o->test_vector_of_union.resize(_e->size()); for (::flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test_vector_of_union[_i].type = static_cast<UnionUnderlyingType::ABC>(_e->Get(_i)); } } else { _o->test_vector_of_union.resize(0); } }
  { auto _e = test_vector_of_union(); if (_e) { _o->test_vector_of_union.resize(_e->size()); for (::flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test_vector_of_union[_i].value = UnionUnderlyingType::ABCUnion::UnPack(_e->Get(_i), test_vector_of_union_type()->GetEnum<ABC>(_i), _resolver); } } else { _o->test_vector_of_union.resize(0); } }
}

inline ::flatbuffers::Offset<D> D::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const DT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
  return CreateD(_fbb, _o, _rehasher);
}

inline ::flatbuffers::Offset<D> CreateD(::flatbuffers::FlatBufferBuilder &_fbb, const DT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const DT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _test_union_type = _o->test_union.type;
  auto _test_union = _o->test_union.Pack(_fbb);
  auto _test_vector_of_union_type = _o->test_vector_of_union.size() ? _fbb.CreateVector<ABC>(_o->test_vector_of_union.size(), [](size_t i, _VectorArgs *__va) { return __va->__o->test_vector_of_union[i].type; }, &_va) : 0;
  auto _test_vector_of_union = _o->test_vector_of_union.size() ? _fbb.CreateVector<::flatbuffers::Offset<void>>(_o->test_vector_of_union.size(), [](size_t i, _VectorArgs *__va) { return __va->__o->test_vector_of_union[i].Pack(*__va->__fbb, __va->__rehasher); }, &_va) : 0;
  return UnionUnderlyingType::CreateD(
      _fbb,
      _test_union_type,
      _test_union,
      _test_vector_of_union_type,
      _test_vector_of_union);
}

inline bool VerifyABC(::flatbuffers::Verifier &verifier, const void *obj, ABC type) {
  switch (type) {
    case ABC::NONE: {
      return true;
    }
    case ABC::A: {
      auto ptr = reinterpret_cast<const UnionUnderlyingType::A *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case ABC::B: {
      auto ptr = reinterpret_cast<const UnionUnderlyingType::B *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case ABC::C: {
      auto ptr = reinterpret_cast<const UnionUnderlyingType::C *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

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

inline void *ABCUnion::UnPack(const void *obj, ABC type, const ::flatbuffers::resolver_function_t *resolver) {
  (void)resolver;
  switch (type) {
    case ABC::A: {
      auto ptr = reinterpret_cast<const UnionUnderlyingType::A *>(obj);
      return ptr->UnPack(resolver);
    }
    case ABC::B: {
      auto ptr = reinterpret_cast<const UnionUnderlyingType::B *>(obj);
      return ptr->UnPack(resolver);
    }
    case ABC::C: {
      auto ptr = reinterpret_cast<const UnionUnderlyingType::C *>(obj);
      return ptr->UnPack(resolver);
    }
    default: return nullptr;
  }
}

inline ::flatbuffers::Offset<void> ABCUnion::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const ::flatbuffers::rehasher_function_t *_rehasher) const {
  (void)_rehasher;
  switch (type) {
    case ABC::A: {
      auto ptr = reinterpret_cast<const UnionUnderlyingType::AT *>(value);
      return CreateA(_fbb, ptr, _rehasher).Union();
    }
    case ABC::B: {
      auto ptr = reinterpret_cast<const UnionUnderlyingType::BT *>(value);
      return CreateB(_fbb, ptr, _rehasher).Union();
    }
    case ABC::C: {
      auto ptr = reinterpret_cast<const UnionUnderlyingType::CT *>(value);
      return CreateC(_fbb, ptr, _rehasher).Union();
    }
    default: return 0;
  }
}

inline ABCUnion::ABCUnion(const ABCUnion &u) : type(u.type), value(nullptr) {
  switch (type) {
    case ABC::A: {
      value = new UnionUnderlyingType::AT(*reinterpret_cast<UnionUnderlyingType::AT *>(u.value));
      break;
    }
    case ABC::B: {
      value = new UnionUnderlyingType::BT(*reinterpret_cast<UnionUnderlyingType::BT *>(u.value));
      break;
    }
    case ABC::C: {
      value = new UnionUnderlyingType::CT(*reinterpret_cast<UnionUnderlyingType::CT *>(u.value));
      break;
    }
    default:
      break;
  }
}

inline void ABCUnion::Reset() {
  switch (type) {
    case ABC::A: {
      auto ptr = reinterpret_cast<UnionUnderlyingType::AT *>(value);
      delete ptr;
      break;
    }
    case ABC::B: {
      auto ptr = reinterpret_cast<UnionUnderlyingType::BT *>(value);
      delete ptr;
      break;
    }
    case ABC::C: {
      auto ptr = reinterpret_cast<UnionUnderlyingType::CT *>(value);
      delete ptr;
      break;
    }
    default: break;
  }
  value = nullptr;
  type = ABC::NONE;
}

inline const ::flatbuffers::TypeTable *ABCTypeTable() {
  static const ::flatbuffers::TypeCode type_codes[] = {
    { ::flatbuffers::ET_SEQUENCE, 0, -1 },
    { ::flatbuffers::ET_SEQUENCE, 0, 0 },
    { ::flatbuffers::ET_SEQUENCE, 0, 1 },
    { ::flatbuffers::ET_SEQUENCE, 0, 2 }
  };
  static const ::flatbuffers::TypeFunction type_refs[] = {
    UnionUnderlyingType::ATypeTable,
    UnionUnderlyingType::BTypeTable,
    UnionUnderlyingType::CTypeTable
  };
  static const int64_t values[] = { 0, 555, 666, 777 };
  static const char * const names[] = {
    "NONE",
    "A",
    "B",
    "C"
  };
  static const ::flatbuffers::TypeTable tt = {
    ::flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, values, names
  };
  return &tt;
}

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

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

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

inline const ::flatbuffers::TypeTable *DTypeTable() {
  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[] = {
    UnionUnderlyingType::ABCTypeTable
  };
  static const char * const names[] = {
    "test_union_type",
    "test_union",
    "test_vector_of_union_type",
    "test_vector_of_union"
  };
  static const ::flatbuffers::TypeTable tt = {
    ::flatbuffers::ST_TABLE, 4, type_codes, type_refs, nullptr, nullptr, names
  };
  return &tt;
}

}  // namespace UnionUnderlyingType

#endif  // FLATBUFFERS_GENERATED_UNIONUNDERLYINGTYPETEST_UNIONUNDERLYINGTYPE_H_
