Commit c02b16e1 authored by vijairaj's avatar vijairaj

Implemented option --scoped-enum for C++ generator

This generates C++11 style scoped and strongly typed enums.
Enabling this option also implies --no-prefix.
parent 169df65d
...@@ -78,6 +78,7 @@ $(document).ready(function(){initNavTree('md__compiler.html','');}); ...@@ -78,6 +78,7 @@ $(document).ready(function(){initNavTree('md__compiler.html','');});
<li><code>--strict-json</code> : Require &amp; 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>--strict-json</code> : Require &amp; 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>--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>--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>--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>--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> <li><code>--gen-mutable</code> : Generate additional non-const accessors for mutating FlatBuffers in-place.</li>
......
...@@ -51,6 +51,9 @@ be generated for each file processed: ...@@ -51,6 +51,9 @@ be generated for each file processed:
- `--no-prefix` : Don't prefix enum values in generated C++ by their enum - `--no-prefix` : Don't prefix enum values in generated C++ by their enum
type. 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. - `--gen-includes` : (deprecated), this is the default behavior.
If the original behavior is required (no include If the original behavior is required (no include
statements) use `--no-includes.` statements) use `--no-includes.`
......
...@@ -425,6 +425,7 @@ struct GeneratorOptions { ...@@ -425,6 +425,7 @@ struct GeneratorOptions {
int indent_step; int indent_step;
bool output_enum_identifiers; bool output_enum_identifiers;
bool prefixed_enums; bool prefixed_enums;
bool scoped_enums;
bool include_dependence_headers; bool include_dependence_headers;
bool mutable_buffer; bool mutable_buffer;
bool one_file; bool one_file;
...@@ -437,7 +438,7 @@ struct GeneratorOptions { ...@@ -437,7 +438,7 @@ struct GeneratorOptions {
GeneratorOptions() : strict_json(false), GeneratorOptions() : strict_json(false),
output_default_scalars_in_json(false), output_default_scalars_in_json(false),
indent_step(2), indent_step(2),
output_enum_identifiers(true), prefixed_enums(true), output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false),
include_dependence_headers(true), include_dependence_headers(true),
mutable_buffer(false), mutable_buffer(false),
one_file(false), one_file(false),
......
...@@ -90,6 +90,8 @@ static void Error(const std::string &err, bool usage, bool show_exe_name) { ...@@ -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" " --defaults-json Output fields whose value is the default when\n"
" writing JSON\n" " writing JSON\n"
" --no-prefix Don\'t prefix enum values with the enum type in C++.\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" " --gen-includes (deprecated), this is the default behavior.\n"
" If the original behavior is required (no include\n" " If the original behavior is required (no include\n"
" statements) use --no-includes.\n" " statements) use --no-includes.\n"
...@@ -142,6 +144,9 @@ int main(int argc, const char *argv[]) { ...@@ -142,6 +144,9 @@ int main(int argc, const char *argv[]) {
opts.output_default_scalars_in_json = true; opts.output_default_scalars_in_json = true;
} else if(arg == "--no-prefix") { } else if(arg == "--no-prefix") {
opts.prefixed_enums = false; opts.prefixed_enums = false;
} else if(arg == "--scoped-enums") {
opts.prefixed_enums = false;
opts.scoped_enums = true;
} else if(arg == "--gen-mutable") { } else if(arg == "--gen-mutable") {
opts.mutable_buffer = true; opts.mutable_buffer = true;
} else if(arg == "--gen-includes") { } else if(arg == "--gen-includes") {
......
...@@ -124,12 +124,28 @@ static std::string GenTypeGet(const Parser &parser, const Type &type, ...@@ -124,12 +124,28 @@ static std::string GenTypeGet(const Parser &parser, const Type &type,
: beforeptr + GenTypePointer(parser, type) + afterptr; : 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, static std::string GenEnumVal(const EnumDef &enum_def, const EnumVal &enum_val,
const GeneratorOptions &opts) { const GeneratorOptions &opts) {
return opts.prefixed_enums ? enum_def.name + "_" + enum_val.name return opts.prefixed_enums ? enum_def.name + "_" + enum_val.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. // Generate an enum declaration and an enum string lookup table.
static void GenEnum(const Parser &parser, EnumDef &enum_def, static void GenEnum(const Parser &parser, EnumDef &enum_def,
std::string *code_ptr, std::string *code_ptr_post, std::string *code_ptr, std::string *code_ptr_post,
...@@ -138,7 +154,7 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def, ...@@ -138,7 +154,7 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def,
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string &code_post = *code_ptr_post; std::string &code_post = *code_ptr_post;
GenComment(enum_def.doc_comment, code_ptr, nullptr); 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(); for (auto it = enum_def.vals.vec.begin();
it != enum_def.vals.vec.end(); it != enum_def.vals.vec.end();
++it) { ++it) {
...@@ -171,9 +187,9 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def, ...@@ -171,9 +187,9 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def,
} }
code += "nullptr };\n return names;\n}\n\n"; code += "nullptr };\n return names;\n}\n\n";
code += "inline const char *EnumName" + enum_def.name; 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) 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"; code += "]; }\n\n";
} }
...@@ -192,7 +208,7 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def, ...@@ -192,7 +208,7 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def,
it != enum_def.vals.vec.end(); it != enum_def.vals.vec.end();
++it) { ++it) {
auto &ev = **it; auto &ev = **it;
code_post += " case " + GenEnumVal(enum_def, ev, opts); code_post += " case " + GetEnumVal(enum_def, ev, opts);
if (!ev.value) { if (!ev.value) {
code_post += ": return true;\n"; // "NONE" enum value. code_post += ": return true;\n"; // "NONE" enum value.
} else { } else {
...@@ -425,7 +441,7 @@ static void GenTable(const Parser &parser, StructDef &struct_def, ...@@ -425,7 +441,7 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
if (ev) { if (ev) {
code += WrapInNameSpace(parser, code += WrapInNameSpace(parser,
field.value.type.enum_def->defined_namespace, field.value.type.enum_def->defined_namespace,
GenEnumVal(*field.value.type.enum_def, *ev, GetEnumVal(*field.value.type.enum_def, *ev,
opts)); opts));
} else { } else {
code += GenUnderlyingCast(parser, field, true, field.value.constant); code += GenUnderlyingCast(parser, field, true, field.value.constant);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment