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


#ifndef FLATBUFFERS_GENERATED_EVOLUTIONV2_EVOLUTION_V2_H_
#define FLATBUFFERS_GENERATED_EVOLUTIONV2_EVOLUTION_V2_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 Evolution {
namespace V2 {

struct TableA;
struct TableABuilder;

struct TableB;
struct TableBBuilder;

struct TableC;
struct TableCBuilder;

struct Struct;

struct Root;
struct RootBuilder;

enum class Enum : int8_t {
  King = 0,
  Queen = 1,
  Rook = 2,
  Bishop = 3,
  MIN = King,
  MAX = Bishop
};

inline const Enum (&EnumValuesEnum())[4] {
  static const Enum values[] = {
    Enum::King,
    Enum::Queen,
    Enum::Rook,
    Enum::Bishop
  };
  return values;
}

inline const char * const *EnumNamesEnum() {
  static const char * const names[5] = {
    "King",
    "Queen",
    "Rook",
    "Bishop",
    nullptr
  };
  return names;
}

inline const char *EnumNameEnum(Enum e) {
  if (::flatbuffers::IsOutRange(e, Enum::King, Enum::Bishop)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesEnum()[index];
}

enum class Union : uint8_t {
  NONE = 0,
  TableA = 1,
  TableB = 2,
  TableC = 3,
  MIN = NONE,
  MAX = TableC
};

inline const Union (&EnumValuesUnion())[4] {
  static const Union values[] = {
    Union::NONE,
    Union::TableA,
    Union::TableB,
    Union::TableC
  };
  return values;
}

inline const char * const *EnumNamesUnion() {
  static const char * const names[5] = {
    "NONE",
    "TableA",
    "TableB",
    "TableC",
    nullptr
  };
  return names;
}

inline const char *EnumNameUnion(Union e) {
  if (::flatbuffers::IsOutRange(e, Union::NONE, Union::TableC)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesUnion()[index];
}

template<typename T> struct UnionTraits {
  static const Union enum_value = Union::NONE;
};

template<> struct UnionTraits<Evolution::V2::TableA> {
  static const Union enum_value = Union::TableA;
};

template<> struct UnionTraits<Evolution::V2::TableB> {
  static const Union enum_value = Union::TableB;
};

template<> struct UnionTraits<Evolution::V2::TableC> {
  static const Union enum_value = Union::TableC;
};

bool VerifyUnion(::flatbuffers::Verifier &verifier, const void *obj, Union type);
bool VerifyUnionVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values, const ::flatbuffers::Vector<Union> *types);

FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Struct FLATBUFFERS_FINAL_CLASS {
 private:
  int32_t a_;
  int32_t padding0__;
  double b_;

 public:
  Struct()
      : a_(0),
        padding0__(0),
        b_(0) {
    (void)padding0__;
  }
  Struct(int32_t _a, double _b)
      : a_(::flatbuffers::EndianScalar(_a)),
        padding0__(0),
        b_(::flatbuffers::EndianScalar(_b)) {
    (void)padding0__;
  }
  int32_t a() const {
    return ::flatbuffers::EndianScalar(a_);
  }
  double b() const {
    return ::flatbuffers::EndianScalar(b_);
  }
};
FLATBUFFERS_STRUCT_END(Struct, 16);

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

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


struct TableA FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef TableABuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_A = 4,
    VT_B = 6,
    VT_C = 8
  };
  float a() const {
    return GetField<float>(VT_A, 0.0f);
  }
  int32_t b() const {
    return GetField<int32_t>(VT_B, 0);
  }
  const ::flatbuffers::String *c() const {
    return GetPointer<const ::flatbuffers::String *>(VT_C);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_A, 4) &&
           VerifyField<int32_t>(verifier, VT_B, 4) &&
           VerifyOffset(verifier, VT_C) &&
           verifier.VerifyString(c()) &&
           verifier.EndTable();
  }
};

struct TableABuilder {
  typedef TableA Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_a(float a) {
    fbb_.AddElement<float>(TableA::VT_A, a, 0.0f);
  }
  void add_b(int32_t b) {
    fbb_.AddElement<int32_t>(TableA::VT_B, b, 0);
  }
  void add_c(::flatbuffers::Offset<::flatbuffers::String> c) {
    fbb_.AddOffset(TableA::VT_C, c);
  }
  explicit TableABuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<TableA> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<TableA>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<TableA> CreateTableA(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    float a = 0.0f,
    int32_t b = 0,
    ::flatbuffers::Offset<::flatbuffers::String> c = 0) {
  TableABuilder builder_(_fbb);
  builder_.add_c(c);
  builder_.add_b(b);
  builder_.add_a(a);
  return builder_.Finish();
}

inline ::flatbuffers::Offset<TableA> CreateTableADirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    float a = 0.0f,
    int32_t b = 0,
    const char *c = nullptr) {
  auto c__ = c ? _fbb.CreateString(c) : 0;
  return Evolution::V2::CreateTableA(
      _fbb,
      a,
      b,
      c__);
}

struct TableB FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef TableBBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_A = 4
  };
  int32_t a() const {
    return GetField<int32_t>(VT_A, 0);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_A, 4) &&
           verifier.EndTable();
  }
};

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

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

struct TableC FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef TableCBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_A = 4,
    VT_B = 6
  };
  double a() const {
    return GetField<double>(VT_A, 0.0);
  }
  const ::flatbuffers::String *b() const {
    return GetPointer<const ::flatbuffers::String *>(VT_B);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<double>(verifier, VT_A, 8) &&
           VerifyOffset(verifier, VT_B) &&
           verifier.VerifyString(b()) &&
           verifier.EndTable();
  }
};

struct TableCBuilder {
  typedef TableC Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_a(double a) {
    fbb_.AddElement<double>(TableC::VT_A, a, 0.0);
  }
  void add_b(::flatbuffers::Offset<::flatbuffers::String> b) {
    fbb_.AddOffset(TableC::VT_B, b);
  }
  explicit TableCBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<TableC> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<TableC>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<TableC> CreateTableC(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    double a = 0.0,
    ::flatbuffers::Offset<::flatbuffers::String> b = 0) {
  TableCBuilder builder_(_fbb);
  builder_.add_a(a);
  builder_.add_b(b);
  return builder_.Finish();
}

inline ::flatbuffers::Offset<TableC> CreateTableCDirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    double a = 0.0,
    const char *b = nullptr) {
  auto b__ = b ? _fbb.CreateString(b) : 0;
  return Evolution::V2::CreateTableC(
      _fbb,
      a,
      b__);
}

struct Root FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef RootBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_B = 6,
    VT_C_TYPE = 8,
    VT_C = 10,
    VT_D = 12,
    VT_E = 14,
    VT_FF = 16,
    VT_G = 18,
    VT_H = 20,
    VT_I = 22,
    VT_K = 28,
    VT_L = 30
  };
  bool b() const {
    return GetField<uint8_t>(VT_B, 0) != 0;
  }
  Evolution::V2::Union c_type() const {
    return static_cast<Evolution::V2::Union>(GetField<uint8_t>(VT_C_TYPE, 0));
  }
  const void *c() const {
    return GetPointer<const void *>(VT_C);
  }
  template<typename T> const T *c_as() const;
  const Evolution::V2::TableA *c_as_TableA() const {
    return c_type() == Evolution::V2::Union::TableA ? static_cast<const Evolution::V2::TableA *>(c()) : nullptr;
  }
  const Evolution::V2::TableB *c_as_TableB() const {
    return c_type() == Evolution::V2::Union::TableB ? static_cast<const Evolution::V2::TableB *>(c()) : nullptr;
  }
  const Evolution::V2::TableC *c_as_TableC() const {
    return c_type() == Evolution::V2::Union::TableC ? static_cast<const Evolution::V2::TableC *>(c()) : nullptr;
  }
  Evolution::V2::Enum d() const {
    return static_cast<Evolution::V2::Enum>(GetField<int8_t>(VT_D, 0));
  }
  const Evolution::V2::TableA *e() const {
    return GetPointer<const Evolution::V2::TableA *>(VT_E);
  }
  const Evolution::V2::Struct *ff() const {
    return GetStruct<const Evolution::V2::Struct *>(VT_FF);
  }
  const ::flatbuffers::Vector<int32_t> *g() const {
    return GetPointer<const ::flatbuffers::Vector<int32_t> *>(VT_G);
  }
  const ::flatbuffers::Vector<::flatbuffers::Offset<Evolution::V2::TableB>> *h() const {
    return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<Evolution::V2::TableB>> *>(VT_H);
  }
  uint32_t i() const {
    return GetField<uint32_t>(VT_I, 1234);
  }
  const Evolution::V2::TableC *k() const {
    return GetPointer<const Evolution::V2::TableC *>(VT_K);
  }
  uint8_t l() const {
    return GetField<uint8_t>(VT_L, 56);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_B, 1) &&
           VerifyField<uint8_t>(verifier, VT_C_TYPE, 1) &&
           VerifyOffset(verifier, VT_C) &&
           VerifyUnion(verifier, c(), c_type()) &&
           VerifyField<int8_t>(verifier, VT_D, 1) &&
           VerifyOffset(verifier, VT_E) &&
           verifier.VerifyTable(e()) &&
           VerifyField<Evolution::V2::Struct>(verifier, VT_FF, 8) &&
           VerifyOffset(verifier, VT_G) &&
           verifier.VerifyVector(g()) &&
           VerifyOffset(verifier, VT_H) &&
           verifier.VerifyVector(h()) &&
           verifier.VerifyVectorOfTables(h()) &&
           VerifyField<uint32_t>(verifier, VT_I, 4) &&
           VerifyOffset(verifier, VT_K) &&
           verifier.VerifyTable(k()) &&
           VerifyField<uint8_t>(verifier, VT_L, 1) &&
           verifier.EndTable();
  }
};

template<> inline const Evolution::V2::TableA *Root::c_as<Evolution::V2::TableA>() const {
  return c_as_TableA();
}

template<> inline const Evolution::V2::TableB *Root::c_as<Evolution::V2::TableB>() const {
  return c_as_TableB();
}

template<> inline const Evolution::V2::TableC *Root::c_as<Evolution::V2::TableC>() const {
  return c_as_TableC();
}

struct RootBuilder {
  typedef Root Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_b(bool b) {
    fbb_.AddElement<uint8_t>(Root::VT_B, static_cast<uint8_t>(b), 0);
  }
  void add_c_type(Evolution::V2::Union c_type) {
    fbb_.AddElement<uint8_t>(Root::VT_C_TYPE, static_cast<uint8_t>(c_type), 0);
  }
  void add_c(::flatbuffers::Offset<void> c) {
    fbb_.AddOffset(Root::VT_C, c);
  }
  void add_d(Evolution::V2::Enum d) {
    fbb_.AddElement<int8_t>(Root::VT_D, static_cast<int8_t>(d), 0);
  }
  void add_e(::flatbuffers::Offset<Evolution::V2::TableA> e) {
    fbb_.AddOffset(Root::VT_E, e);
  }
  void add_ff(const Evolution::V2::Struct *ff) {
    fbb_.AddStruct(Root::VT_FF, ff);
  }
  void add_g(::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> g) {
    fbb_.AddOffset(Root::VT_G, g);
  }
  void add_h(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<Evolution::V2::TableB>>> h) {
    fbb_.AddOffset(Root::VT_H, h);
  }
  void add_i(uint32_t i) {
    fbb_.AddElement<uint32_t>(Root::VT_I, i, 1234);
  }
  void add_k(::flatbuffers::Offset<Evolution::V2::TableC> k) {
    fbb_.AddOffset(Root::VT_K, k);
  }
  void add_l(uint8_t l) {
    fbb_.AddElement<uint8_t>(Root::VT_L, l, 56);
  }
  explicit RootBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<Root> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<Root>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<Root> CreateRoot(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    bool b = false,
    Evolution::V2::Union c_type = Evolution::V2::Union::NONE,
    ::flatbuffers::Offset<void> c = 0,
    Evolution::V2::Enum d = Evolution::V2::Enum::King,
    ::flatbuffers::Offset<Evolution::V2::TableA> e = 0,
    const Evolution::V2::Struct *ff = nullptr,
    ::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> g = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<Evolution::V2::TableB>>> h = 0,
    uint32_t i = 1234,
    ::flatbuffers::Offset<Evolution::V2::TableC> k = 0,
    uint8_t l = 56) {
  RootBuilder builder_(_fbb);
  builder_.add_k(k);
  builder_.add_i(i);
  builder_.add_h(h);
  builder_.add_g(g);
  builder_.add_ff(ff);
  builder_.add_e(e);
  builder_.add_c(c);
  builder_.add_l(l);
  builder_.add_d(d);
  builder_.add_c_type(c_type);
  builder_.add_b(b);
  return builder_.Finish();
}

inline ::flatbuffers::Offset<Root> CreateRootDirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    bool b = false,
    Evolution::V2::Union c_type = Evolution::V2::Union::NONE,
    ::flatbuffers::Offset<void> c = 0,
    Evolution::V2::Enum d = Evolution::V2::Enum::King,
    ::flatbuffers::Offset<Evolution::V2::TableA> e = 0,
    const Evolution::V2::Struct *ff = nullptr,
    const std::vector<int32_t> *g = nullptr,
    const std::vector<::flatbuffers::Offset<Evolution::V2::TableB>> *h = nullptr,
    uint32_t i = 1234,
    ::flatbuffers::Offset<Evolution::V2::TableC> k = 0,
    uint8_t l = 56) {
  auto g__ = g ? _fbb.CreateVector<int32_t>(*g) : 0;
  auto h__ = h ? _fbb.CreateVector<::flatbuffers::Offset<Evolution::V2::TableB>>(*h) : 0;
  return Evolution::V2::CreateRoot(
      _fbb,
      b,
      c_type,
      c,
      d,
      e,
      ff,
      g__,
      h__,
      i,
      k,
      l);
}

inline bool VerifyUnion(::flatbuffers::Verifier &verifier, const void *obj, Union type) {
  switch (type) {
    case Union::NONE: {
      return true;
    }
    case Union::TableA: {
      auto ptr = reinterpret_cast<const Evolution::V2::TableA *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Union::TableB: {
      auto ptr = reinterpret_cast<const Evolution::V2::TableB *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Union::TableC: {
      auto ptr = reinterpret_cast<const Evolution::V2::TableC *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

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

inline const Evolution::V2::Root *GetRoot(const void *buf) {
  return ::flatbuffers::GetRoot<Evolution::V2::Root>(buf);
}

inline const Evolution::V2::Root *GetSizePrefixedRoot(const void *buf) {
  return ::flatbuffers::GetSizePrefixedRoot<Evolution::V2::Root>(buf);
}

inline bool VerifyRootBuffer(
    ::flatbuffers::Verifier &verifier) {
  return verifier.VerifyBuffer<Evolution::V2::Root>(nullptr);
}

inline bool VerifySizePrefixedRootBuffer(
    ::flatbuffers::Verifier &verifier) {
  return verifier.VerifySizePrefixedBuffer<Evolution::V2::Root>(nullptr);
}

inline void FinishRootBuffer(
    ::flatbuffers::FlatBufferBuilder &fbb,
    ::flatbuffers::Offset<Evolution::V2::Root> root) {
  fbb.Finish(root);
}

inline void FinishSizePrefixedRootBuffer(
    ::flatbuffers::FlatBufferBuilder &fbb,
    ::flatbuffers::Offset<Evolution::V2::Root> root) {
  fbb.FinishSizePrefixed(root);
}

}  // namespace V2
}  // namespace Evolution

#endif  // FLATBUFFERS_GENERATED_EVOLUTIONV2_EVOLUTION_V2_H_
