Adds typedefs and functions to help write generic code.

The following changes have been made to the C++ codegen to enable writing generic code
that uses the Table and NativeTable types.

- Adds TableType and NativeTableType typedefs to NativeTable and Table structs.
- Adds GetFullyQualifiedName() to NativeTables if --gen-name-strings is set.
- Adds a static Pack function to Tables that simply calls the global CreateX functions.

See cr/140391505 as an example of improved usage.

From cl/140529288.

Change-Id: Idec137c16129e15c1783f94fabdcea24aeeaaef6
diff --git a/samples/monster_generated.h b/samples/monster_generated.h
index fa12e06..1833c62 100644
--- a/samples/monster_generated.h
+++ b/samples/monster_generated.h
@@ -92,6 +92,7 @@
 STRUCT_END(Vec3, 12);
 
 struct MonsterT : public flatbuffers::NativeTable {
+  typedef Monster TableType;
   std::unique_ptr<Vec3> pos;
   int16_t mana;
   int16_t hp;
@@ -103,6 +104,7 @@
 };
 
 struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
   enum {
     VT_POS = 4,
     VT_MANA = 6,
@@ -151,6 +153,7 @@
            verifier.EndTable();
   }
   MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
+  static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
 };
 
 struct MonsterBuilder {
@@ -212,11 +215,13 @@
 inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
 
 struct WeaponT : public flatbuffers::NativeTable {
+  typedef Weapon TableType;
   std::string name;
   int16_t damage;
 };
 
 struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef WeaponT NativeTableType;
   enum {
     VT_NAME = 4,
     VT_DAMAGE = 6
@@ -233,6 +238,7 @@
            verifier.EndTable();
   }
   WeaponT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
+  static flatbuffers::Offset<Weapon> Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
 };
 
 struct WeaponBuilder {
@@ -280,6 +286,10 @@
   return _o;
 }
 
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonster(_fbb, _o, _rehasher);
+}
+
 inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher) {
   (void)rehasher;
   return CreateMonster(_fbb,
@@ -302,6 +312,10 @@
   return _o;
 }
 
+inline flatbuffers::Offset<Weapon> Weapon::Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateWeapon(_fbb, _o, _rehasher);
+}
+
 inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *rehasher) {
   (void)rehasher;
   return CreateWeapon(_fbb,
diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp
index 7ca7d0b..8681e17 100644
--- a/src/idl_gen_cpp.cpp
+++ b/src/idl_gen_cpp.cpp
@@ -413,6 +413,16 @@
            (predecl ? " = nullptr" : "") + ")";
   }
 
+  std::string TablePackSignature(StructDef &struct_def, bool inclass) {
+    return std::string(inclass ? "static " : "") +
+           "flatbuffers::Offset<" + struct_def.name + "> " +
+           (inclass ? "" : struct_def.name + "::") +
+           "Pack(flatbuffers::FlatBufferBuilder &_fbb, " +
+           "const " + NativeName(struct_def.name) + "* _o, " +
+           "const flatbuffers::rehasher_function_t *_rehasher" +
+           (inclass ? " = nullptr" : "") + ")";
+  }
+
   std::string TableUnPackSignature(StructDef &struct_def, bool inclass) {
     return NativeName(struct_def.name) + " *" +
            (inclass ? "" : struct_def.name + "::") +
@@ -691,6 +701,9 @@
       // table.
       code += "struct " + NativeName(struct_def.name);
       code += " : public flatbuffers::NativeTable {\n";
+      code += "  typedef " + struct_def.name + " TableType;\n";
+      // Generate GetFullyQualifiedName
+      GenFullyQualifiedNameGetter(NativeName(struct_def.name), code);
       for (auto it = struct_def.fields.vec.begin();
            it != struct_def.fields.vec.end(); ++it) {
         auto &field = **it;
@@ -711,6 +724,10 @@
     code += "struct " + struct_def.name;
     code += " FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table";
     code += " {\n";
+    if (parser_.opts.generate_object_based_api) {
+      code += "  typedef " + NativeName(struct_def.name) +
+              " NativeTableType;\n";
+    }
     // Generate GetFullyQualifiedName
     GenFullyQualifiedNameGetter(struct_def.name, code);
     // Generate field id constants.
@@ -874,6 +891,7 @@
     if (parser_.opts.generate_object_based_api) {
       // Generate the UnPack() pre declaration.
       code += "  " + TableUnPackSignature(struct_def, true) + ";\n";
+      code += "  " + TablePackSignature(struct_def, true) + ";\n";
     }
 
     code += "};\n\n";  // End of table.
@@ -1105,6 +1123,12 @@
       }
       code += "  return _o;\n}\n\n";
 
+      // Generate the X::Pack member function that simply calls the global
+      // CreateX function.
+      code += "inline " + TablePackSignature(struct_def, false) + " {\n";
+      code += "  return Create" + struct_def.name + "(_fbb, _o, _rehasher);\n";
+      code += "}\n\n";
+
       // Generate a CreateX method that works with an unpacked C++ object.
       code += TableCreateSignature(struct_def, false) + " {\n";
       code += "  (void)rehasher;\n";
diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h
index 6e8831e..f1be4ac 100644
--- a/tests/monster_test_generated.h
+++ b/tests/monster_test_generated.h
@@ -151,14 +151,17 @@
 namespace Example2 {
 
 struct MonsterT : public flatbuffers::NativeTable {
+  typedef Monster TableType;
 };
 
 struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
   bool Verify(flatbuffers::Verifier &verifier) const {
     return VerifyTableStart(verifier) &&
            verifier.EndTable();
   }
   MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
+  static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
 };
 
 struct MonsterBuilder {
@@ -184,10 +187,12 @@
 namespace Example {
 
 struct TestSimpleTableWithEnumT : public flatbuffers::NativeTable {
+  typedef TestSimpleTableWithEnum TableType;
   Color color;
 };
 
 struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TestSimpleTableWithEnumT NativeTableType;
   enum {
     VT_COLOR = 4
   };
@@ -199,6 +204,7 @@
            verifier.EndTable();
   }
   TestSimpleTableWithEnumT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
+  static flatbuffers::Offset<TestSimpleTableWithEnum> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
 };
 
 struct TestSimpleTableWithEnumBuilder {
@@ -223,12 +229,14 @@
 inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
 
 struct StatT : public flatbuffers::NativeTable {
+  typedef Stat TableType;
   std::string id;
   int64_t val;
   uint16_t count;
 };
 
 struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef StatT NativeTableType;
   enum {
     VT_ID = 4,
     VT_VAL = 6,
@@ -249,6 +257,7 @@
            verifier.EndTable();
   }
   StatT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
+  static flatbuffers::Offset<Stat> Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
 };
 
 struct StatBuilder {
@@ -286,6 +295,7 @@
 inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
 
 struct MonsterT : public flatbuffers::NativeTable {
+  typedef Monster TableType;
   std::unique_ptr<Vec3> pos;
   int16_t mana;
   int16_t hp;
@@ -317,6 +327,7 @@
 
 /// an example documentation comment: monster object
 struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef MonsterT NativeTableType;
   enum {
     VT_POS = 4,
     VT_MANA = 6,
@@ -455,6 +466,7 @@
            verifier.EndTable();
   }
   MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
+  static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
 };
 
 struct MonsterBuilder {
@@ -602,6 +614,10 @@
   return _o;
 }
 
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonster(_fbb, _o, _rehasher);
+}
+
 inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher) {
   (void)rehasher;
   (void)_o;
@@ -619,6 +635,10 @@
   return _o;
 }
 
+inline flatbuffers::Offset<TestSimpleTableWithEnum> TestSimpleTableWithEnum::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateTestSimpleTableWithEnum(_fbb, _o, _rehasher);
+}
+
 inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *rehasher) {
   (void)rehasher;
   return CreateTestSimpleTableWithEnum(_fbb,
@@ -634,6 +654,10 @@
   return _o;
 }
 
+inline flatbuffers::Offset<Stat> Stat::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateStat(_fbb, _o, _rehasher);
+}
+
 inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *rehasher) {
   (void)rehasher;
   return CreateStat(_fbb,
@@ -676,6 +700,10 @@
   return _o;
 }
 
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+  return CreateMonster(_fbb, _o, _rehasher);
+}
+
 inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher) {
   (void)rehasher;
   return CreateMonster(_fbb,