[C++17] Add compile-time reflection for fields. (#6324)

* [C++17] Add compile-time reflection for fields.

Included in this commit is the following:

  - The C++ generator has been modified so that,
    when in C++17 mode, it will emit Table and
    Struct field traits that can be used at com-
    pile time as a form of static reflection. This
    includes field types, field names, and a tuple
    of field getter results.

  - Diffs to the cpp17 generated files. No other
    generated files are affected.

  - A unit test that also serves as an example. It
    demonstrates how to use the full power of this
    reflection to implement a full recursive
    JSON-like stringifier for Flatbuffers types,
    but without needing any runtime access to the
    *.fbs definition files; the computation is
    done using only static reflection.

Tested on Linux with gcc 10.2.0.

Fixes #6285.

* Fix int-conversion warning on MSVC.

* Try to fix std::to_string ambiguity on MSVC.

* Fix clang-format diffs.

* Fix more clang-format diffs.

* Fix last clang-format diff.

* Enable C++17 build/test for VC 19 platform in CI.

* Forgot to add value to cmake command line variable.

* Various fixes/changes in response to @vglavnyy's feedback.

* Replace "fields pack" with index-based getters.

* Fix MSVC error.

* Fix clang-format diffs.

* getter_for method returns result instead of address-of-getter.

* Next round of reviewer suggestions.

* Use type instead of hardcoded struct name.

* Fix clang-format diff.

* Add test for FieldType since it is not used in the stringify test.

* Add fields_number field to Traits struct.

* Add --cpp-static-reflection flag and put those features behind it.

* Fix clang-format diffs.

* Remove <tuple> include.
This commit is contained in:
David P. Sicilia
2021-03-05 13:01:40 -05:00
committed by GitHub
parent 4033ff5892
commit a69815f72c
9 changed files with 834 additions and 11 deletions

View File

@@ -126,6 +126,9 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
" * 'c++0x' - generate code compatible with old compilers;\n"
" * 'c++11' - use C++11 code generator (default);\n"
" * 'c++17' - use C++17 features in generated code (experimental).\n"
" --cpp-static-reflection When using C++17, generate extra code to provide compile-time\n"
" (static) reflection of Flatbuffers types. Requires --cpp-std\n"
" to be \"c++17\" or higher.\n"
" --object-prefix Customise class prefix for C++ object-based API.\n"
" --object-suffix Customise class suffix for C++ object-based API.\n"
" Default value is \"T\".\n"
@@ -360,6 +363,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
opts.cpp_std = argv[argi];
} else if (arg.rfind("--cpp-std=", 0) == 0) {
opts.cpp_std = arg.substr(std::string("--cpp-std=").size());
} else if (arg == "--cpp-static-reflection") {
opts.cpp_static_reflection = true;
} else {
for (size_t i = 0; i < params_.num_generators; ++i) {
if (arg == params_.generators[i].generator_opt_long ||