diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 1ff528d4b..79767e197 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -302,7 +302,8 @@ extern void GenerateText(const Parser &parser, // Generate a C++ header from the definitions in the Parser object. // See idl_gen_cpp. -extern std::string GenerateCPP(const Parser &parser); +extern std::string GenerateCPP(const Parser &parser, + const std::string &include_guard_ident); extern bool GenerateCPP(const Parser &parser, const std::string &path, const std::string &file_name); diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index b5ad8657d..e0b2be6ef 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -298,7 +298,7 @@ static void GenStruct(StructDef &struct_def, std::string *code_ptr) { // Iterate through all definitions we haven't generate code for (enums, structs, // and tables) and output them to a single file. -std::string GenerateCPP(const Parser &parser) { +std::string GenerateCPP(const Parser &parser, const std::string &include_guard_ident) { using namespace cpp; // Generate code for all the enum declarations. @@ -331,28 +331,54 @@ std::string GenerateCPP(const Parser &parser) { // Only output file-level code if there were any declarations. if (enum_code.length() || forward_decl_code.length() || decl_code.length()) { std::string code; - code = "// automatically generated, do not modify\n\n"; + code = "// automatically generated by the FlatBuffers compiler," + " do not modify\n\n"; + + // Generate include guard. + std::string include_guard = "FLATBUFFERS_GENERATED_" + include_guard_ident; + include_guard += "_"; + for (auto it = parser.name_space_.begin(); + it != parser.name_space_.end(); ++it) { + include_guard += *it + "_"; + } + include_guard += "H_"; + std::transform(include_guard.begin(), include_guard.end(), + include_guard.begin(), ::toupper); + code += "#ifndef " + include_guard + "\n"; + code += "#define " + include_guard + "\n\n"; + code += "#include \"flatbuffers/flatbuffers.h\"\n\n"; + + // Generate nested namespaces. for (auto it = parser.name_space_.begin(); it != parser.name_space_.end(); ++it) { code += "namespace " + *it + " {\n"; } + + // Output the main declaration code from above. code += "\n"; code += enum_code; code += forward_decl_code; code += "\n"; code += decl_code; + + // Generate convenient root datatype accessor. if (parser.root_struct_def) { code += "inline const " + parser.root_struct_def->name + " *Get"; code += parser.root_struct_def->name; code += "(const void *buf) { return flatbuffers::GetRoot<"; code += parser.root_struct_def->name + ">(buf); }\n\n"; } + + // Close the namespaces. for (auto it = parser.name_space_.begin(); it != parser.name_space_.end(); ++it) { - code += "}; // namespace " + *it + "\n"; + code += "}; // namespace " + *it + "\n"; } + // Close the include guard. + code += "\n#endif // " + include_guard + "\n"; + return code; } @@ -362,7 +388,7 @@ std::string GenerateCPP(const Parser &parser) { bool GenerateCPP(const Parser &parser, const std::string &path, const std::string &file_name) { - auto code = GenerateCPP(parser); + auto code = GenerateCPP(parser, file_name); return !code.length() || SaveFile((path + file_name + "_generated.h").c_str(), code, false); } diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h index 4b240fa6d..6b85c6b30 100755 --- a/tests/monster_test_generated.h +++ b/tests/monster_test_generated.h @@ -1,4 +1,7 @@ -// automatically generated, do not modify +// automatically generated by the FlatBuffers compiler, do not modify + +#ifndef FLATBUFFERS_GENERATED_MONSTER_TEST_MYGAME_EXAMPLE_H_ +#define FLATBUFFERS_GENERATED_MONSTER_TEST_MYGAME_EXAMPLE_H_ #include "flatbuffers/flatbuffers.h" @@ -119,5 +122,7 @@ inline flatbuffers::Offset CreateMonster(flatbuffers::FlatBufferBuilder inline const Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot(buf); } -}; // namespace MyGame -}; // namespace Example +}; // namespace MyGame +}; // namespace Example + +#endif // FLATBUFFERS_GENERATED_MONSTER_TEST_MYGAME_EXAMPLE_H_