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


#ifndef FLATBUFFERS_GENERATED_NATIVEINLINETABLETEST_H_
#define FLATBUFFERS_GENERATED_NATIVEINLINETABLETEST_H_

#include "flatbuffers/flatbuffers.h"

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

struct NativeInlineTable;
struct NativeInlineTableBuilder;
struct NativeInlineTableT;

struct TestNativeInlineTable;
struct TestNativeInlineTableBuilder;
struct TestNativeInlineTableT;

bool operator==(const NativeInlineTableT &lhs, const NativeInlineTableT &rhs);
bool operator!=(const NativeInlineTableT &lhs, const NativeInlineTableT &rhs);
bool operator==(const TestNativeInlineTableT &lhs, const TestNativeInlineTableT &rhs);
bool operator!=(const TestNativeInlineTableT &lhs, const TestNativeInlineTableT &rhs);

inline const flatbuffers::TypeTable *NativeInlineTableTypeTable();

inline const flatbuffers::TypeTable *TestNativeInlineTableTypeTable();

struct NativeInlineTableT : public flatbuffers::NativeTable {
  typedef NativeInlineTable TableType;
  int32_t a = 0;
};

struct NativeInlineTable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef NativeInlineTableT NativeTableType;
  typedef NativeInlineTableBuilder Builder;
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return NativeInlineTableTypeTable();
  }
  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();
  }
  NativeInlineTableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(NativeInlineTableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<NativeInlineTable> Pack(flatbuffers::FlatBufferBuilder &_fbb, const NativeInlineTableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

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

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

flatbuffers::Offset<NativeInlineTable> CreateNativeInlineTable(flatbuffers::FlatBufferBuilder &_fbb, const NativeInlineTableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct TestNativeInlineTableT : public flatbuffers::NativeTable {
  typedef TestNativeInlineTable TableType;
  std::vector<NativeInlineTableT> t{};
};

struct TestNativeInlineTable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TestNativeInlineTableT NativeTableType;
  typedef TestNativeInlineTableBuilder Builder;
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return TestNativeInlineTableTypeTable();
  }
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_T = 4
  };
  const flatbuffers::Vector<flatbuffers::Offset<NativeInlineTable>> *t() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<NativeInlineTable>> *>(VT_T);
  }
  flatbuffers::Vector<flatbuffers::Offset<NativeInlineTable>> *mutable_t() {
    return GetPointer<flatbuffers::Vector<flatbuffers::Offset<NativeInlineTable>> *>(VT_T);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_T) &&
           verifier.VerifyVector(t()) &&
           verifier.VerifyVectorOfTables(t()) &&
           verifier.EndTable();
  }
  TestNativeInlineTableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(TestNativeInlineTableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<TestNativeInlineTable> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestNativeInlineTableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct TestNativeInlineTableBuilder {
  typedef TestNativeInlineTable Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_t(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<NativeInlineTable>>> t) {
    fbb_.AddOffset(TestNativeInlineTable::VT_T, t);
  }
  explicit TestNativeInlineTableBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  flatbuffers::Offset<TestNativeInlineTable> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TestNativeInlineTable>(end);
    return o;
  }
};

inline flatbuffers::Offset<TestNativeInlineTable> CreateTestNativeInlineTable(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<NativeInlineTable>>> t = 0) {
  TestNativeInlineTableBuilder builder_(_fbb);
  builder_.add_t(t);
  return builder_.Finish();
}

inline flatbuffers::Offset<TestNativeInlineTable> CreateTestNativeInlineTableDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<NativeInlineTable>> *t = nullptr) {
  auto t__ = t ? _fbb.CreateVector<flatbuffers::Offset<NativeInlineTable>>(*t) : 0;
  return CreateTestNativeInlineTable(
      _fbb,
      t__);
}

flatbuffers::Offset<TestNativeInlineTable> CreateTestNativeInlineTable(flatbuffers::FlatBufferBuilder &_fbb, const TestNativeInlineTableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);


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

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


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

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

inline flatbuffers::Offset<NativeInlineTable> NativeInlineTable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const NativeInlineTableT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateNativeInlineTable(_fbb, _o, _rehasher);
}

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


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

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


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

inline void TestNativeInlineTable::UnPackTo(TestNativeInlineTableT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = t(); if (_e) { _o->t.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->t[_i] = *flatbuffers::unique_ptr<NativeInlineTableT>(_e->Get(_i)->UnPack(_resolver)); } } else { _o->t.resize(0); } }
}

inline flatbuffers::Offset<TestNativeInlineTable> TestNativeInlineTable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestNativeInlineTableT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateTestNativeInlineTable(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<TestNativeInlineTable> CreateTestNativeInlineTable(flatbuffers::FlatBufferBuilder &_fbb, const TestNativeInlineTableT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TestNativeInlineTableT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _t = _o->t.size() ? _fbb.CreateVector<flatbuffers::Offset<NativeInlineTable>> (_o->t.size(), [](size_t i, _VectorArgs *__va) { return CreateNativeInlineTable(*__va->__fbb, &(__va->__o->t[i]), __va->__rehasher); }, &_va ) : 0;
  return CreateTestNativeInlineTable(
      _fbb,
      _t);
}

inline const flatbuffers::TypeTable *NativeInlineTableTypeTable() {
  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 *TestNativeInlineTableTypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_SEQUENCE, 1, 0 }
  };
  static const flatbuffers::TypeFunction type_refs[] = {
    NativeInlineTableTypeTable
  };
  static const char * const names[] = {
    "t"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, nullptr, names
  };
  return &tt;
}

#endif  // FLATBUFFERS_GENERATED_NATIVEINLINETABLETEST_H_
