diff --git a/tests/evolution_test/evolution_v1.fbs b/tests/evolution_test/evolution_v1.fbs
new file mode 100644
index 0000000..e9d3b8d
--- /dev/null
+++ b/tests/evolution_test/evolution_v1.fbs
@@ -0,0 +1,40 @@
+namespace Evolution.V1;
+
+table TableA {
+    a:float;
+    b:int;
+}
+
+table TableB {
+    a:int;
+}
+
+enum Enum : byte {
+    King,
+    Queen
+}
+
+union Union {
+    TableA,
+    TableB
+}
+
+struct Struct {
+    a:int;
+    b:double;
+}
+
+table Root {
+    a:int;
+    b:bool;
+    c:Union;
+    d:Enum;
+    e:TableA;
+    f:Struct;
+    g:[int];
+    h:[TableB];
+    i:int = 1234;
+    j:Union;
+}
+
+root_type Root;
diff --git a/tests/evolution_test/evolution_v1.json b/tests/evolution_test/evolution_v1.json
new file mode 100644
index 0000000..c90fdb9
--- /dev/null
+++ b/tests/evolution_test/evolution_v1.json
@@ -0,0 +1,29 @@
+{
+  "a": 42,
+  "b": true,
+  "c_type": "TableB",
+  "c": {
+    "a": 15
+  },
+  "d": "King",
+  "e": {
+    "a": 3.1452,
+    "b": 325
+  },
+  "f":{
+    "a": 16,
+    "b": 243.980943
+  },
+  "g": [ 7, 8, 9],
+  "h": [
+    {
+      "a": 212
+    },
+    {
+      "a": 459
+    }
+  ],
+  "j": {
+    "a": 984
+  }
+}
diff --git a/tests/evolution_test/evolution_v1_generated.h b/tests/evolution_test/evolution_v1_generated.h
new file mode 100644
index 0000000..a9c2b7f
--- /dev/null
+++ b/tests/evolution_test/evolution_v1_generated.h
@@ -0,0 +1,513 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_EVOLUTIONV1_EVOLUTION_V1_H_
+#define FLATBUFFERS_GENERATED_EVOLUTIONV1_EVOLUTION_V1_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace Evolution {
+namespace V1 {
+
+struct TableA;
+struct TableABuilder;
+
+struct TableB;
+struct TableBBuilder;
+
+struct Struct;
+
+struct Root;
+struct RootBuilder;
+
+enum class Enum : int8_t {
+  King = 0,
+  Queen = 1,
+  MIN = King,
+  MAX = Queen
+};
+
+inline const Enum (&EnumValuesEnum())[2] {
+  static const Enum values[] = {
+    Enum::King,
+    Enum::Queen
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesEnum() {
+  static const char * const names[3] = {
+    "King",
+    "Queen",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameEnum(Enum e) {
+  if (flatbuffers::IsOutRange(e, Enum::King, Enum::Queen)) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesEnum()[index];
+}
+
+enum class Union : uint8_t {
+  NONE = 0,
+  TableA = 1,
+  TableB = 2,
+  MIN = NONE,
+  MAX = TableB
+};
+
+inline const Union (&EnumValuesUnion())[3] {
+  static const Union values[] = {
+    Union::NONE,
+    Union::TableA,
+    Union::TableB
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesUnion() {
+  static const char * const names[4] = {
+    "NONE",
+    "TableA",
+    "TableB",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameUnion(Union e) {
+  if (flatbuffers::IsOutRange(e, Union::NONE, Union::TableB)) 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::V1::TableA> {
+  static const Union enum_value = Union::TableA;
+};
+
+template<> struct UnionTraits<Evolution::V1::TableB> {
+  static const Union enum_value = Union::TableB;
+};
+
+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<uint8_t> *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
+  };
+  float a() const {
+    return GetField<float>(VT_A, 0.0f);
+  }
+  int32_t b() const {
+    return GetField<int32_t>(VT_B, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<float>(verifier, VT_A) &&
+           VerifyField<int32_t>(verifier, VT_B) &&
+           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);
+  }
+  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) {
+  TableABuilder builder_(_fbb);
+  builder_.add_b(b);
+  builder_.add_a(a);
+  return builder_.Finish();
+}
+
+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) &&
+           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 Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef RootBuilder Builder;
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_A = 4,
+    VT_B = 6,
+    VT_C_TYPE = 8,
+    VT_C = 10,
+    VT_D = 12,
+    VT_E = 14,
+    VT_F = 16,
+    VT_G = 18,
+    VT_H = 20,
+    VT_I = 22,
+    VT_J_TYPE = 24,
+    VT_J = 26
+  };
+  int32_t a() const {
+    return GetField<int32_t>(VT_A, 0);
+  }
+  bool b() const {
+    return GetField<uint8_t>(VT_B, 0) != 0;
+  }
+  Evolution::V1::Union c_type() const {
+    return static_cast<Evolution::V1::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::V1::TableA *c_as_TableA() const {
+    return c_type() == Evolution::V1::Union::TableA ? static_cast<const Evolution::V1::TableA *>(c()) : nullptr;
+  }
+  const Evolution::V1::TableB *c_as_TableB() const {
+    return c_type() == Evolution::V1::Union::TableB ? static_cast<const Evolution::V1::TableB *>(c()) : nullptr;
+  }
+  Evolution::V1::Enum d() const {
+    return static_cast<Evolution::V1::Enum>(GetField<int8_t>(VT_D, 0));
+  }
+  const Evolution::V1::TableA *e() const {
+    return GetPointer<const Evolution::V1::TableA *>(VT_E);
+  }
+  const Evolution::V1::Struct *f() const {
+    return GetStruct<const Evolution::V1::Struct *>(VT_F);
+  }
+  const flatbuffers::Vector<int32_t> *g() const {
+    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_G);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>> *h() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>> *>(VT_H);
+  }
+  int32_t i() const {
+    return GetField<int32_t>(VT_I, 1234);
+  }
+  Evolution::V1::Union j_type() const {
+    return static_cast<Evolution::V1::Union>(GetField<uint8_t>(VT_J_TYPE, 0));
+  }
+  const void *j() const {
+    return GetPointer<const void *>(VT_J);
+  }
+  template<typename T> const T *j_as() const;
+  const Evolution::V1::TableA *j_as_TableA() const {
+    return j_type() == Evolution::V1::Union::TableA ? static_cast<const Evolution::V1::TableA *>(j()) : nullptr;
+  }
+  const Evolution::V1::TableB *j_as_TableB() const {
+    return j_type() == Evolution::V1::Union::TableB ? static_cast<const Evolution::V1::TableB *>(j()) : nullptr;
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, VT_A) &&
+           VerifyField<uint8_t>(verifier, VT_B) &&
+           VerifyField<uint8_t>(verifier, VT_C_TYPE) &&
+           VerifyOffset(verifier, VT_C) &&
+           VerifyUnion(verifier, c(), c_type()) &&
+           VerifyField<int8_t>(verifier, VT_D) &&
+           VerifyOffset(verifier, VT_E) &&
+           verifier.VerifyTable(e()) &&
+           VerifyField<Evolution::V1::Struct>(verifier, VT_F) &&
+           VerifyOffset(verifier, VT_G) &&
+           verifier.VerifyVector(g()) &&
+           VerifyOffset(verifier, VT_H) &&
+           verifier.VerifyVector(h()) &&
+           verifier.VerifyVectorOfTables(h()) &&
+           VerifyField<int32_t>(verifier, VT_I) &&
+           VerifyField<uint8_t>(verifier, VT_J_TYPE) &&
+           VerifyOffset(verifier, VT_J) &&
+           VerifyUnion(verifier, j(), j_type()) &&
+           verifier.EndTable();
+  }
+};
+
+template<> inline const Evolution::V1::TableA *Root::c_as<Evolution::V1::TableA>() const {
+  return c_as_TableA();
+}
+
+template<> inline const Evolution::V1::TableB *Root::c_as<Evolution::V1::TableB>() const {
+  return c_as_TableB();
+}
+
+template<> inline const Evolution::V1::TableA *Root::j_as<Evolution::V1::TableA>() const {
+  return j_as_TableA();
+}
+
+template<> inline const Evolution::V1::TableB *Root::j_as<Evolution::V1::TableB>() const {
+  return j_as_TableB();
+}
+
+struct RootBuilder {
+  typedef Root Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_a(int32_t a) {
+    fbb_.AddElement<int32_t>(Root::VT_A, a, 0);
+  }
+  void add_b(bool b) {
+    fbb_.AddElement<uint8_t>(Root::VT_B, static_cast<uint8_t>(b), 0);
+  }
+  void add_c_type(Evolution::V1::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::V1::Enum d) {
+    fbb_.AddElement<int8_t>(Root::VT_D, static_cast<int8_t>(d), 0);
+  }
+  void add_e(flatbuffers::Offset<Evolution::V1::TableA> e) {
+    fbb_.AddOffset(Root::VT_E, e);
+  }
+  void add_f(const Evolution::V1::Struct *f) {
+    fbb_.AddStruct(Root::VT_F, f);
+  }
+  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::V1::TableB>>> h) {
+    fbb_.AddOffset(Root::VT_H, h);
+  }
+  void add_i(int32_t i) {
+    fbb_.AddElement<int32_t>(Root::VT_I, i, 1234);
+  }
+  void add_j_type(Evolution::V1::Union j_type) {
+    fbb_.AddElement<uint8_t>(Root::VT_J_TYPE, static_cast<uint8_t>(j_type), 0);
+  }
+  void add_j(flatbuffers::Offset<void> j) {
+    fbb_.AddOffset(Root::VT_J, j);
+  }
+  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,
+    int32_t a = 0,
+    bool b = false,
+    Evolution::V1::Union c_type = Evolution::V1::Union::NONE,
+    flatbuffers::Offset<void> c = 0,
+    Evolution::V1::Enum d = Evolution::V1::Enum::King,
+    flatbuffers::Offset<Evolution::V1::TableA> e = 0,
+    const Evolution::V1::Struct *f = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> g = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>>> h = 0,
+    int32_t i = 1234,
+    Evolution::V1::Union j_type = Evolution::V1::Union::NONE,
+    flatbuffers::Offset<void> j = 0) {
+  RootBuilder builder_(_fbb);
+  builder_.add_j(j);
+  builder_.add_i(i);
+  builder_.add_h(h);
+  builder_.add_g(g);
+  builder_.add_f(f);
+  builder_.add_e(e);
+  builder_.add_c(c);
+  builder_.add_a(a);
+  builder_.add_j_type(j_type);
+  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,
+    int32_t a = 0,
+    bool b = false,
+    Evolution::V1::Union c_type = Evolution::V1::Union::NONE,
+    flatbuffers::Offset<void> c = 0,
+    Evolution::V1::Enum d = Evolution::V1::Enum::King,
+    flatbuffers::Offset<Evolution::V1::TableA> e = 0,
+    const Evolution::V1::Struct *f = 0,
+    const std::vector<int32_t> *g = nullptr,
+    const std::vector<flatbuffers::Offset<Evolution::V1::TableB>> *h = nullptr,
+    int32_t i = 1234,
+    Evolution::V1::Union j_type = Evolution::V1::Union::NONE,
+    flatbuffers::Offset<void> j = 0) {
+  auto g__ = g ? _fbb.CreateVector<int32_t>(*g) : 0;
+  auto h__ = h ? _fbb.CreateVector<flatbuffers::Offset<Evolution::V1::TableB>>(*h) : 0;
+  return Evolution::V1::CreateRoot(
+      _fbb,
+      a,
+      b,
+      c_type,
+      c,
+      d,
+      e,
+      f,
+      g__,
+      h__,
+      i,
+      j_type,
+      j);
+}
+
+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::V1::TableA *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Union::TableB: {
+      auto ptr = reinterpret_cast<const Evolution::V1::TableB *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    default: return true;
+  }
+}
+
+inline bool VerifyUnionVector(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 (!VerifyUnion(
+        verifier,  values->Get(i), types->GetEnum<Union>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+inline const Evolution::V1::Root *GetRoot(const void *buf) {
+  return flatbuffers::GetRoot<Evolution::V1::Root>(buf);
+}
+
+inline const Evolution::V1::Root *GetSizePrefixedRoot(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<Evolution::V1::Root>(buf);
+}
+
+inline bool VerifyRootBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<Evolution::V1::Root>(nullptr);
+}
+
+inline bool VerifySizePrefixedRootBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<Evolution::V1::Root>(nullptr);
+}
+
+inline void FinishRootBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Evolution::V1::Root> root) {
+  fbb.Finish(root);
+}
+
+inline void FinishSizePrefixedRootBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<Evolution::V1::Root> root) {
+  fbb.FinishSizePrefixed(root);
+}
+
+}  // namespace V1
+}  // namespace Evolution
+
+#endif  // FLATBUFFERS_GENERATED_EVOLUTIONV1_EVOLUTION_V1_H_
diff --git a/tests/evolution_test/evolution_v2.fbs b/tests/evolution_test/evolution_v2.fbs
new file mode 100644
index 0000000..c7e1ef9
--- /dev/null
+++ b/tests/evolution_test/evolution_v2.fbs
@@ -0,0 +1,51 @@
+namespace Evolution.V2;
+
+table TableA {
+    b:int (id: 1);      // swapped with 'a'
+    a:float (id: 0);    // swapped with 'b'
+    c:string (id: 2);   // new in v2
+}
+
+table TableB {
+    a:int;
+}
+
+table TableC {          // new in v2
+    a:double;
+    b:string;
+}
+
+enum Enum : byte {
+    King,
+    Queen,
+    Rook,               // new in v2
+    Bishop              // new in v2
+}
+
+union Union {
+    TableA,
+    TableB,
+    TableC
+}
+
+struct Struct {
+    a:int;
+    b:double;
+}
+
+table Root {
+    a:int (deprecated); // deprecated in v2
+    b:bool;
+    c:Union;
+    d:Enum;
+    e:TableA;
+    ff:Struct;          // renamed from 'f' in v1
+    g:[int];
+    h:[TableB];
+    i:uint = 1234;
+    j:Union (deprecated); // deprecated in v2
+    k:TableC;           // new in v2
+    l:uint8 = 56;       // new in v2
+}
+
+root_type Root;
diff --git a/tests/evolution_test/evolution_v2.json b/tests/evolution_test/evolution_v2.json
new file mode 100644
index 0000000..b170eb2
--- /dev/null
+++ b/tests/evolution_test/evolution_v2.json
@@ -0,0 +1,34 @@
+{
+  "b": false,
+  "c_type": "TableC",
+  "c": {
+    "a": 984.2494
+  },
+  "d": "Bishop",
+  "e": {
+    "a": 3.1452,
+    "b": 435,
+    "c": "yummy yummy fig bar bar"
+  },
+  "ff":{
+    "a": 35,
+    "b": 243.980943
+  },
+  "g": [ 7, 8, 10],
+  "h": [
+    {
+      "a": 212
+    },
+    {
+      "a": 459
+    },
+    {
+      "a": 333
+    }
+  ],
+  "i": 4321,
+  "k": {
+    "a": 9874.342,
+    "b": "more please"
+  }
+}
diff --git a/tests/evolution_test/evolution_v2_generated.h b/tests/evolution_test/evolution_v2_generated.h
new file mode 100644
index 0000000..303d94d
--- /dev/null
+++ b/tests/evolution_test/evolution_v2_generated.h
@@ -0,0 +1,600 @@
+// 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"
+
+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<uint8_t> *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) &&
+           VerifyField<int32_t>(verifier, VT_B) &&
+           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) &&
+           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) &&
+           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) &&
+           VerifyField<uint8_t>(verifier, VT_C_TYPE) &&
+           VerifyOffset(verifier, VT_C) &&
+           VerifyUnion(verifier, c(), c_type()) &&
+           VerifyField<int8_t>(verifier, VT_D) &&
+           VerifyOffset(verifier, VT_E) &&
+           verifier.VerifyTable(e()) &&
+           VerifyField<Evolution::V2::Struct>(verifier, VT_FF) &&
+           VerifyOffset(verifier, VT_G) &&
+           verifier.VerifyVector(g()) &&
+           VerifyOffset(verifier, VT_H) &&
+           verifier.VerifyVector(h()) &&
+           verifier.VerifyVectorOfTables(h()) &&
+           VerifyField<uint32_t>(verifier, VT_I) &&
+           VerifyOffset(verifier, VT_K) &&
+           verifier.VerifyTable(k()) &&
+           VerifyField<uint8_t>(verifier, VT_L) &&
+           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 = 0,
+    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 = 0,
+    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<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 (!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_
