Skip to content

Commit 1bf1b17

Browse files
committed
Add --gen-absl-hash option to generate AbslHashValue for structs.
1 parent fb55e0c commit 1bf1b17

File tree

14 files changed

+186
-1
lines changed

14 files changed

+186
-1
lines changed

include/flatbuffers/idl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ struct IDLOptions {
664664
bool generate_name_strings;
665665
bool generate_object_based_api;
666666
bool gen_compare;
667+
bool gen_absl_hash;
667668
std::string cpp_object_api_pointer_type;
668669
std::string cpp_object_api_string_type;
669670
bool cpp_object_api_string_flexible_constructor;
@@ -818,6 +819,7 @@ struct IDLOptions {
818819
generate_name_strings(false),
819820
generate_object_based_api(false),
820821
gen_compare(false),
822+
gen_absl_hash(false),
821823
cpp_object_api_pointer_type("std::unique_ptr"),
822824
cpp_object_api_string_flexible_constructor(false),
823825
cpp_object_api_field_case_style(CaseStyle_Unchanged),

samples/monster_generated.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ inline bool operator!=(const Vec3 &lhs, const Vec3 &rhs) {
236236
return !(lhs == rhs);
237237
}
238238

239+
template <typename H>
240+
inline H AbslHashValue(H h, const Vec3 &obj) {
241+
return H::combine(std::move(h), obj.x(), obj.y(), obj.z());
242+
}
239243

240244
struct MonsterT : public ::flatbuffers::NativeTable {
241245
typedef Monster TableType;

scripts/generate_code.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def glob(path, pattern):
6969
CPP_OPTS = [
7070
"--cpp",
7171
"--gen-compare",
72+
"--gen-absl-hash",
7273
] + (["--cpp-std", "c++0x"] if args.cpp_0x else [])
7374

7475
CPP_17_OPTS = NO_INCL_OPTS + [

src/flatc.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
529529
opts.generate_object_based_api = true;
530530
} else if (arg == "--gen-compare") {
531531
opts.gen_compare = true;
532+
} else if (arg == "--gen-absl-hash") {
533+
opts.gen_absl_hash = true;
532534
} else if (arg == "--cpp-include") {
533535
if (++argi >= argc) Error("missing include following: " + arg, true);
534536
opts.cpp_includes.push_back(argv[argi]);

src/idl_gen_cpp.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2311,6 +2311,34 @@ class CppGenerator : public BaseGenerator {
23112311
code_ += "";
23122312
}
23132313

2314+
void GenAbslHashValue(const StructDef& struct_def) {
2315+
code_ += "template <typename H>";
2316+
code_ += "inline H AbslHashValue(H h, const {{NATIVE_NAME}} &obj) {";
2317+
std::string combine_args;
2318+
for (const auto& field : struct_def.fields.vec) {
2319+
if (field->deprecated) {
2320+
continue;
2321+
}
2322+
if (IsArray(field->value.type)) {
2323+
const auto field_accessor = "obj." + Name(*field) + "()";
2324+
const auto& element_type = field->value.type.VectorType();
2325+
if (IsStruct(element_type)) {
2326+
code_ += " for (const auto* element : *" + field_accessor + ") {";
2327+
code_ += " h = H::combine(std::move(h), *element);";
2328+
code_ += " }";
2329+
} else {
2330+
code_ += " for (auto element : *" + field_accessor + ") {";
2331+
code_ += " h = H::combine(std::move(h), element);";
2332+
code_ += " }";
2333+
}
2334+
} else {
2335+
combine_args += ", obj." + Name(*field) + "()";
2336+
}
2337+
}
2338+
code_ += " return H::combine(std::move(h)" + combine_args + ");";
2339+
code_ += "}";
2340+
}
2341+
23142342
void GenOperatorNewDelete(const StructDef& struct_def) {
23152343
if (auto native_custom_alloc =
23162344
struct_def.attributes.Lookup("native_custom_alloc")) {
@@ -4281,7 +4309,12 @@ class CppGenerator : public BaseGenerator {
42814309

42824310
code_.SetValue("STRUCT_BYTE_SIZE", NumToString(struct_def.bytesize));
42834311
code_ += "FLATBUFFERS_STRUCT_END({{STRUCT_NAME}}, {{STRUCT_BYTE_SIZE}});";
4284-
if (opts_.gen_compare) GenCompareOperator(struct_def, "()");
4312+
if (opts_.gen_compare) {
4313+
GenCompareOperator(struct_def, "()");
4314+
}
4315+
if (opts_.gen_absl_hash) {
4316+
GenAbslHashValue(struct_def);
4317+
}
42854318
code_ += "";
42864319

42874320
// Definition for type traits for this table type. This allows querying var-

tests/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ flatbuffer_cc_library(
213213
include_test_args = [
214214
"--gen-object-api",
215215
"--gen-compare",
216+
"--gen-absl-hash",
216217
"--gen-mutable",
217218
"--reflect-names",
218219
"--cpp-ptr-type flatbuffers::unique_ptr",

tests/evolution_test/evolution_v1_generated.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ inline bool operator!=(const Struct &lhs, const Struct &rhs) {
145145
return !(lhs == rhs);
146146
}
147147

148+
template <typename H>
149+
inline H AbslHashValue(H h, const Struct &obj) {
150+
return H::combine(std::move(h), obj.a(), obj.b());
151+
}
148152

149153
struct TableA FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
150154
typedef TableABuilder Builder;

tests/evolution_test/evolution_v2_generated.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ inline bool operator!=(const Struct &lhs, const Struct &rhs) {
161161
return !(lhs == rhs);
162162
}
163163

164+
template <typename H>
165+
inline H AbslHashValue(H h, const Struct &obj) {
166+
return H::combine(std::move(h), obj.a(), obj.b());
167+
}
164168

165169
struct TableA FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
166170
typedef TableABuilder Builder;

tests/monster_test_generated.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,10 @@ inline bool operator!=(const Test &lhs, const Test &rhs) {
712712
return !(lhs == rhs);
713713
}
714714

715+
template <typename H>
716+
inline H AbslHashValue(H h, const Test &obj) {
717+
return H::combine(std::move(h), obj.a(), obj.b());
718+
}
715719

716720
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Vec3 FLATBUFFERS_FINAL_CLASS {
717721
private:
@@ -810,6 +814,10 @@ inline bool operator!=(const Vec3 &lhs, const Vec3 &rhs) {
810814
return !(lhs == rhs);
811815
}
812816

817+
template <typename H>
818+
inline H AbslHashValue(H h, const Vec3 &obj) {
819+
return H::combine(std::move(h), obj.x(), obj.y(), obj.z(), obj.test1(), obj.test2(), obj.test3());
820+
}
813821

814822
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Ability FLATBUFFERS_FINAL_CLASS {
815823
private:
@@ -859,6 +867,10 @@ inline bool operator!=(const Ability &lhs, const Ability &rhs) {
859867
return !(lhs == rhs);
860868
}
861869

870+
template <typename H>
871+
inline H AbslHashValue(H h, const Ability &obj) {
872+
return H::combine(std::move(h), obj.id(), obj.distance());
873+
}
862874

863875
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) StructOfStructs FLATBUFFERS_FINAL_CLASS {
864876
private:
@@ -912,6 +924,10 @@ inline bool operator!=(const StructOfStructs &lhs, const StructOfStructs &rhs) {
912924
return !(lhs == rhs);
913925
}
914926

927+
template <typename H>
928+
inline H AbslHashValue(H h, const StructOfStructs &obj) {
929+
return H::combine(std::move(h), obj.a(), obj.b(), obj.c());
930+
}
915931

916932
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) StructOfStructsOfStructs FLATBUFFERS_FINAL_CLASS {
917933
private:
@@ -945,6 +961,10 @@ inline bool operator!=(const StructOfStructsOfStructs &lhs, const StructOfStruct
945961
return !(lhs == rhs);
946962
}
947963

964+
template <typename H>
965+
inline H AbslHashValue(H h, const StructOfStructsOfStructs &obj) {
966+
return H::combine(std::move(h), obj.a());
967+
}
948968

949969
} // namespace Example
950970

tests/monster_test_suffix/ext_only/monster_test_generated.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,10 @@ inline bool operator!=(const Test &lhs, const Test &rhs) {
709709
return !(lhs == rhs);
710710
}
711711

712+
template <typename H>
713+
inline H AbslHashValue(H h, const Test &obj) {
714+
return H::combine(std::move(h), obj.a(), obj.b());
715+
}
712716

713717
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Vec3 FLATBUFFERS_FINAL_CLASS {
714718
private:
@@ -807,6 +811,10 @@ inline bool operator!=(const Vec3 &lhs, const Vec3 &rhs) {
807811
return !(lhs == rhs);
808812
}
809813

814+
template <typename H>
815+
inline H AbslHashValue(H h, const Vec3 &obj) {
816+
return H::combine(std::move(h), obj.x(), obj.y(), obj.z(), obj.test1(), obj.test2(), obj.test3());
817+
}
810818

811819
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Ability FLATBUFFERS_FINAL_CLASS {
812820
private:
@@ -856,6 +864,10 @@ inline bool operator!=(const Ability &lhs, const Ability &rhs) {
856864
return !(lhs == rhs);
857865
}
858866

867+
template <typename H>
868+
inline H AbslHashValue(H h, const Ability &obj) {
869+
return H::combine(std::move(h), obj.id(), obj.distance());
870+
}
859871

860872
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) StructOfStructs FLATBUFFERS_FINAL_CLASS {
861873
private:
@@ -909,6 +921,10 @@ inline bool operator!=(const StructOfStructs &lhs, const StructOfStructs &rhs) {
909921
return !(lhs == rhs);
910922
}
911923

924+
template <typename H>
925+
inline H AbslHashValue(H h, const StructOfStructs &obj) {
926+
return H::combine(std::move(h), obj.a(), obj.b(), obj.c());
927+
}
912928

913929
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) StructOfStructsOfStructs FLATBUFFERS_FINAL_CLASS {
914930
private:
@@ -942,6 +958,10 @@ inline bool operator!=(const StructOfStructsOfStructs &lhs, const StructOfStruct
942958
return !(lhs == rhs);
943959
}
944960

961+
template <typename H>
962+
inline H AbslHashValue(H h, const StructOfStructsOfStructs &obj) {
963+
return H::combine(std::move(h), obj.a());
964+
}
945965

946966
} // namespace Example
947967

0 commit comments

Comments
 (0)