diff --git a/docs/html/md__compiler.html b/docs/html/md__compiler.html index 043cb23b046cce8870e7e3e38ca192ec02225b25..6ae87ed392403fd57ae9d3edb7e6bdfcfea529a9 100644 --- a/docs/html/md__compiler.html +++ b/docs/html/md__compiler.html @@ -78,6 +78,7 @@ $(document).ready(function(){initNavTree('md__compiler.html','');}); <li><code>--strict-json</code> : Require & generate strict JSON (field names are enclosed in quotes, no trailing commas in tables/vectors). By default, no quotes are required/generated, and trailing commas are allowed.</li> <li><code>--defaults-json</code> : Output fields whose value is equal to the default value when writing JSON text.</li> <li><code>--no-prefix</code> : Don't prefix enum values in generated C++ by their enum type.</li> +<li><code>--scoped-enums</code> : Use C++11 style scoped and strongly typed enums in generated C++. This also implies <code>--no-prefix</code>.</li> <li><code>--gen-includes</code> : (deprecated), this is the default behavior. If the original behavior is required (no include statements) use <code>--no-includes.</code></li> <li><code>--no-includes</code> : Don't generate include statements for included schemas the generated file depends on (C++).</li> <li><code>--gen-mutable</code> : Generate additional non-const accessors for mutating FlatBuffers in-place.</li> diff --git a/docs/source/Compiler.md b/docs/source/Compiler.md index 5d254dfa57851393ba007879b11f79b3dce2004a..e4663e172767020993c625b6e8f1889c9fa430cf 100755 --- a/docs/source/Compiler.md +++ b/docs/source/Compiler.md @@ -51,6 +51,9 @@ be generated for each file processed: - `--no-prefix` : Don't prefix enum values in generated C++ by their enum type. +- `--scoped-enums` : Use C++11 style scoped and strongly typed enums in + generated C++. This also implies `--no-prefix`. + - `--gen-includes` : (deprecated), this is the default behavior. If the original behavior is required (no include statements) use `--no-includes.` diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 8a912de5c892b0c68c75a97bdd56bbf4087125b8..44154ebac5622374e23c2a01ac272744d5c4d67c 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -425,6 +425,7 @@ struct GeneratorOptions { int indent_step; bool output_enum_identifiers; bool prefixed_enums; + bool scoped_enums; bool include_dependence_headers; bool mutable_buffer; bool one_file; @@ -437,7 +438,7 @@ struct GeneratorOptions { GeneratorOptions() : strict_json(false), output_default_scalars_in_json(false), indent_step(2), - output_enum_identifiers(true), prefixed_enums(true), + output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false), include_dependence_headers(true), mutable_buffer(false), one_file(false), diff --git a/src/flatc.cpp b/src/flatc.cpp index 9b8b50d70aae7eaeaba15fb868c168272fbed258..7f654b0ba42c5f7c1d8a75732e75764a5ee9ccd8 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -90,6 +90,8 @@ static void Error(const std::string &err, bool usage, bool show_exe_name) { " --defaults-json Output fields whose value is the default when\n" " writing JSON\n" " --no-prefix Don\'t prefix enum values with the enum type in C++.\n" + " --scoped-enums Use C++11 style scoped and strongly typed enums.\n" + " also implies --no-prefix.\n" " --gen-includes (deprecated), this is the default behavior.\n" " If the original behavior is required (no include\n" " statements) use --no-includes.\n" @@ -142,6 +144,9 @@ int main(int argc, const char *argv[]) { opts.output_default_scalars_in_json = true; } else if(arg == "--no-prefix") { opts.prefixed_enums = false; + } else if(arg == "--scoped-enums") { + opts.prefixed_enums = false; + opts.scoped_enums = true; } else if(arg == "--gen-mutable") { opts.mutable_buffer = true; } else if(arg == "--gen-includes") { diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 2cb15b56c33b429aad31f772409b807eee37a6d9..acdc6304078e5c6f6de5b29d45eaa850547f3408 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -124,12 +124,28 @@ static std::string GenTypeGet(const Parser &parser, const Type &type, : beforeptr + GenTypePointer(parser, type) + afterptr; } +static std::string GenEnumDecl(const EnumDef &enum_def, + const GeneratorOptions &opts) { + return (opts.scoped_enums ? "enum class " : "enum ") + enum_def.name; +} + static std::string GenEnumVal(const EnumDef &enum_def, const EnumVal &enum_val, const GeneratorOptions &opts) { return opts.prefixed_enums ? enum_def.name + "_" + enum_val.name : enum_val.name; } +static std::string GetEnumVal(const EnumDef &enum_def, const EnumVal &enum_val, + const GeneratorOptions &opts) { + if (opts.scoped_enums) { + return enum_def.name + "::" + enum_val.name; + } else if (opts.prefixed_enums) { + return enum_def.name + "_" + enum_val.name; + } else { + return enum_val.name; + } +} + // Generate an enum declaration and an enum string lookup table. static void GenEnum(const Parser &parser, EnumDef &enum_def, std::string *code_ptr, std::string *code_ptr_post, @@ -138,7 +154,7 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def, std::string &code = *code_ptr; std::string &code_post = *code_ptr_post; GenComment(enum_def.doc_comment, code_ptr, nullptr); - code += "enum " + enum_def.name + " {\n"; + code += GenEnumDecl(enum_def, opts) + " {\n"; for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); ++it) { @@ -171,9 +187,9 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def, } code += "nullptr };\n return names;\n}\n\n"; code += "inline const char *EnumName" + enum_def.name; - code += "(" + enum_def.name + " e) { return EnumNames" + enum_def.name + "()[e"; + code += "(" + enum_def.name + " e) { return EnumNames" + enum_def.name + "()[static_cast<int>(e)"; if (enum_def.vals.vec.front()->value) - code += " - " + GenEnumVal(enum_def, *enum_def.vals.vec.front(), opts); + code += " - static_cast<int>(" + GetEnumVal(enum_def, *enum_def.vals.vec.front(), opts) +")"; code += "]; }\n\n"; } @@ -192,7 +208,7 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def, it != enum_def.vals.vec.end(); ++it) { auto &ev = **it; - code_post += " case " + GenEnumVal(enum_def, ev, opts); + code_post += " case " + GetEnumVal(enum_def, ev, opts); if (!ev.value) { code_post += ": return true;\n"; // "NONE" enum value. } else { @@ -425,7 +441,7 @@ static void GenTable(const Parser &parser, StructDef &struct_def, if (ev) { code += WrapInNameSpace(parser, field.value.type.enum_def->defined_namespace, - GenEnumVal(*field.value.type.enum_def, *ev, + GetEnumVal(*field.value.type.enum_def, *ev, opts)); } else { code += GenUnderlyingCast(parser, field, true, field.value.constant);