mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-01 19:58:15 +00:00
[C++] Object API: document custom string type requirements,
implement better custom string type constructor alternative for Unpack() and fix bug with vector of custom string types in Pack(). Squashed commit of the following: commite9519c647eAuthor: Luca Longinotti <luca.longinotti@inivation.com> Date: Tue Mar 5 18:24:49 2019 +0100 tests: regenerate code, reverts change to CreateVectorOfStrings(). commit117e3b0679Author: Luca Longinotti <luca.longinotti@inivation.com> Date: Tue Mar 5 18:15:05 2019 +0100 idl_gen_cpp.cpp: move clang-format on/off outside of declaration, so they are kept properly aligned automatically. commit4791923806Author: Luca Longinotti <luca.longinotti@inivation.com> Date: Tue Mar 5 18:11:40 2019 +0100 idl_gen_cpp.cpp: full clang-format run with provided Google format file, enforce 80 lines width. commit2f0402f9ffAuthor: Luca Longinotti <luca.longinotti@inivation.com> Date: Tue Mar 5 18:09:32 2019 +0100 CppUsage: address requested changes. idl_gen_cpp.cpp: fix formatting, keep CreateVectorOfStrings for normal string cases. commit371d4e0b79Author: Luca Longinotti <luca.longinotti@inivation.com> Date: Fri Mar 1 16:35:29 2019 +0100 Fix compile error with a vector of non-std::strings. CreateVectorOfStrings() expects a vector of std::string types, but that's not always the case. commit92b90d7f0fAuthor: Luca Longinotti <luca.longinotti@inivation.com> Date: Fri Mar 1 16:15:36 2019 +0100 Document requirement for custom string types to implement empty() and be constructible from std::string. Add new option --cpp-str-flex-ctor to construct custom string types not via std::string, but (char * + length). commit28cb2e92d5Author: Luca Longinotti <luca.longinotti@inivation.com> Date: Fri Mar 1 14:31:17 2019 +0100 idl_gen_cpp.cpp: clang-format run, to better separate changes in content from formatting. Change-Id: I4887ba2f2c632b9e7a8c938659b088cd95690870
This commit is contained in:
@@ -75,7 +75,7 @@ Additional options:
|
|||||||
- `--allow-non-utf8` : Pass non-UTF-8 input through parser and emit nonstandard
|
- `--allow-non-utf8` : Pass non-UTF-8 input through parser and emit nonstandard
|
||||||
\x escapes in JSON. (Default is to raise parse error on non-UTF-8 input.)
|
\x escapes in JSON. (Default is to raise parse error on non-UTF-8 input.)
|
||||||
|
|
||||||
- `--natural-utf8` : Output strings with UTF-8 as human-readable strings.
|
- `--natural-utf8` : Output strings with UTF-8 as human-readable strings.
|
||||||
By default, UTF-8 characters are printed as \uXXXX escapes."
|
By default, UTF-8 characters are printed as \uXXXX escapes."
|
||||||
|
|
||||||
- `--defaults-json` : Output fields whose value is equal to the default value
|
- `--defaults-json` : Output fields whose value is equal to the default value
|
||||||
@@ -120,7 +120,13 @@ Additional options:
|
|||||||
- `--cpp-ptr-type T` : Set object API pointer type (default std::unique_ptr)
|
- `--cpp-ptr-type T` : Set object API pointer type (default std::unique_ptr)
|
||||||
|
|
||||||
- `--cpp-str-type T` : Set object API string type (default std::string)
|
- `--cpp-str-type T` : Set object API string type (default std::string)
|
||||||
- T::c_str() and T::length() must be supported.
|
T::c_str(), T::length() and T::empty() must be supported.
|
||||||
|
The custom type also needs to be constructible from std::string (see the
|
||||||
|
--cpp-str-flex-ctor option to change this behavior).
|
||||||
|
|
||||||
|
- `--cpp-str-flex-ctor` : Don't construct custom string types by passing
|
||||||
|
std::string from Flatbuffers, but (char* + length). This allows efficient
|
||||||
|
construction of custom string types, including zero-copy construction.
|
||||||
|
|
||||||
- `--object-prefix` : Customise class prefix for C++ object-based API.
|
- `--object-prefix` : Customise class prefix for C++ object-based API.
|
||||||
|
|
||||||
@@ -168,7 +174,7 @@ Additional options:
|
|||||||
an evolution of. Gives errors if not. Useful to check if schema
|
an evolution of. Gives errors if not. Useful to check if schema
|
||||||
modifications don't break schema evolution rules.
|
modifications don't break schema evolution rules.
|
||||||
|
|
||||||
- `--conform-includes PATH` : Include path for the schema given with
|
- `--conform-includes PATH` : Include path for the schema given with
|
||||||
`--conform PATH`.
|
`--conform PATH`.
|
||||||
|
|
||||||
- `--include-prefix PATH` : Prefix this path to any generated include
|
- `--include-prefix PATH` : Prefix this path to any generated include
|
||||||
|
|||||||
@@ -255,14 +255,24 @@ you, so you'll have to manage their lifecycles manually. To reference the
|
|||||||
pointer type specified by the `--cpp-ptr-type` argument to `flatc` from a
|
pointer type specified by the `--cpp-ptr-type` argument to `flatc` from a
|
||||||
flatbuffer field set the `cpp_ptr_type` attribute to `default_ptr_type`.
|
flatbuffer field set the `cpp_ptr_type` attribute to `default_ptr_type`.
|
||||||
|
|
||||||
|
|
||||||
# Using different string type.
|
# Using different string type.
|
||||||
|
|
||||||
By default the object tree is built out of `std::string`, but you can
|
By default the object tree is built out of `std::string`, but you can
|
||||||
influence this either globally (using the `--cpp-str-type` argument to
|
influence this either globally (using the `--cpp-str-type` argument to
|
||||||
`flatc`) or per field using the `cpp_str_type` attribute.
|
`flatc`) or per field using the `cpp_str_type` attribute.
|
||||||
|
|
||||||
The type must support T::c_str() and T::length() as member functions.
|
The type must support T::c_str(), T::length() and T::empty() as member functions.
|
||||||
|
|
||||||
|
Further, the type must be constructible from std::string, as by default a
|
||||||
|
std::string instance is constructed and then used to initialize the custom
|
||||||
|
string type. This behavior impedes efficient and zero-copy construction of
|
||||||
|
custom string types; the `--cpp-str-flex-ctor` argument to `flatc` or the
|
||||||
|
per field attribute `cpp_str_flex_ctor` can be used to change this behavior,
|
||||||
|
so that the custom string type is constructed by passing the pointer and
|
||||||
|
length of the FlatBuffers String. The custom string class will require a
|
||||||
|
constructor in the following format: custom_str_class(const char *, size_t).
|
||||||
|
Please note that the character array is not guaranteed to be NULL terminated,
|
||||||
|
you should always use the provided size to determine end of string.
|
||||||
|
|
||||||
## Reflection (& Resizing)
|
## Reflection (& Resizing)
|
||||||
|
|
||||||
|
|||||||
@@ -410,6 +410,7 @@ struct IDLOptions {
|
|||||||
bool gen_compare;
|
bool gen_compare;
|
||||||
std::string cpp_object_api_pointer_type;
|
std::string cpp_object_api_pointer_type;
|
||||||
std::string cpp_object_api_string_type;
|
std::string cpp_object_api_string_type;
|
||||||
|
bool cpp_object_api_string_flexible_constructor;
|
||||||
bool gen_nullable;
|
bool gen_nullable;
|
||||||
bool gen_generated;
|
bool gen_generated;
|
||||||
std::string object_prefix;
|
std::string object_prefix;
|
||||||
@@ -486,6 +487,7 @@ struct IDLOptions {
|
|||||||
generate_object_based_api(false),
|
generate_object_based_api(false),
|
||||||
gen_compare(false),
|
gen_compare(false),
|
||||||
cpp_object_api_pointer_type("std::unique_ptr"),
|
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||||
|
cpp_object_api_string_flexible_constructor(false),
|
||||||
gen_nullable(false),
|
gen_nullable(false),
|
||||||
gen_generated(false),
|
gen_generated(false),
|
||||||
object_suffix("T"),
|
object_suffix("T"),
|
||||||
@@ -627,6 +629,7 @@ class Parser : public ParserState {
|
|||||||
known_attributes_["cpp_ptr_type"] = true;
|
known_attributes_["cpp_ptr_type"] = true;
|
||||||
known_attributes_["cpp_ptr_type_get"] = true;
|
known_attributes_["cpp_ptr_type_get"] = true;
|
||||||
known_attributes_["cpp_str_type"] = true;
|
known_attributes_["cpp_str_type"] = true;
|
||||||
|
known_attributes_["cpp_str_flex_ctor"] = true;
|
||||||
known_attributes_["native_inline"] = true;
|
known_attributes_["native_inline"] = true;
|
||||||
known_attributes_["native_custom_alloc"] = true;
|
known_attributes_["native_custom_alloc"] = true;
|
||||||
known_attributes_["native_type"] = true;
|
known_attributes_["native_type"] = true;
|
||||||
|
|||||||
@@ -100,14 +100,18 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
|
|||||||
" --gen-compare Generate operator== for object-based API types.\n"
|
" --gen-compare Generate operator== for object-based API types.\n"
|
||||||
" --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n"
|
" --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n"
|
||||||
" --gen-generated Add @Generated annotation for Java\n"
|
" --gen-generated Add @Generated annotation for Java\n"
|
||||||
" --gen-all Generate not just code for the current schema files,\n"
|
" --gen-all Generate not just code for the current schema files,\n"
|
||||||
" but for all files it includes as well.\n"
|
" but for all files it includes as well.\n"
|
||||||
" If the language uses a single file for output (by default\n"
|
" If the language uses a single file for output (by default\n"
|
||||||
" the case for C++ and JS), all code will end up in this one\n"
|
" the case for C++ and JS), all code will end up in this one\n"
|
||||||
" file.\n"
|
" file.\n"
|
||||||
" --cpp-ptr-type T Set object API pointer type (default std::unique_ptr).\n"
|
" --cpp-ptr-type T Set object API pointer type (default std::unique_ptr).\n"
|
||||||
" --cpp-str-type T Set object API string type (default std::string).\n"
|
" --cpp-str-type T Set object API string type (default std::string).\n"
|
||||||
" T::c_str() and T::length() must be supported.\n"
|
" T::c_str(), T::length() and T::empty() must be supported.\n"
|
||||||
|
" The custom type also needs to be constructible from std::string\n"
|
||||||
|
" (see the --cpp-str-flex-ctor option to change this behavior).\n"
|
||||||
|
" --cpp-str-flex-ctor Don't construct custom string types by passing std::string\n"
|
||||||
|
" from Flatbuffers, but (char* + length).\n"
|
||||||
" --object-prefix Customise class prefix for C++ object-based API.\n"
|
" --object-prefix Customise class prefix for C++ object-based API.\n"
|
||||||
" --object-suffix Customise class suffix for C++ object-based API.\n"
|
" --object-suffix Customise class suffix for C++ object-based API.\n"
|
||||||
" Default value is \"T\".\n"
|
" Default value is \"T\".\n"
|
||||||
@@ -247,6 +251,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
|||||||
} else if (arg == "--cpp-str-type") {
|
} else if (arg == "--cpp-str-type") {
|
||||||
if (++argi >= argc) Error("missing type following" + arg, true);
|
if (++argi >= argc) Error("missing type following" + arg, true);
|
||||||
opts.cpp_object_api_string_type = argv[argi];
|
opts.cpp_object_api_string_type = argv[argi];
|
||||||
|
} else if (arg == "--cpp-str-flex-ctor") {
|
||||||
|
opts.cpp_object_api_string_flexible_constructor = true;
|
||||||
} else if (arg == "--gen-nullable") {
|
} else if (arg == "--gen-nullable") {
|
||||||
opts.gen_nullable = true;
|
opts.gen_nullable = true;
|
||||||
} else if (arg == "--gen-generated") {
|
} else if (arg == "--gen-generated") {
|
||||||
|
|||||||
@@ -43,103 +43,104 @@ class CppGenerator : public BaseGenerator {
|
|||||||
float_const_gen_("std::numeric_limits<double>::",
|
float_const_gen_("std::numeric_limits<double>::",
|
||||||
"std::numeric_limits<float>::", "quiet_NaN()",
|
"std::numeric_limits<float>::", "quiet_NaN()",
|
||||||
"infinity()") {
|
"infinity()") {
|
||||||
static const char * const keywords[] = {
|
static const char *const keywords[] = {
|
||||||
"alignas",
|
"alignas",
|
||||||
"alignof",
|
"alignof",
|
||||||
"and",
|
"and",
|
||||||
"and_eq",
|
"and_eq",
|
||||||
"asm",
|
"asm",
|
||||||
"atomic_cancel",
|
"atomic_cancel",
|
||||||
"atomic_commit",
|
"atomic_commit",
|
||||||
"atomic_noexcept",
|
"atomic_noexcept",
|
||||||
"auto",
|
"auto",
|
||||||
"bitand",
|
"bitand",
|
||||||
"bitor",
|
"bitor",
|
||||||
"bool",
|
"bool",
|
||||||
"break",
|
"break",
|
||||||
"case",
|
"case",
|
||||||
"catch",
|
"catch",
|
||||||
"char",
|
"char",
|
||||||
"char16_t",
|
"char16_t",
|
||||||
"char32_t",
|
"char32_t",
|
||||||
"class",
|
"class",
|
||||||
"compl",
|
"compl",
|
||||||
"concept",
|
"concept",
|
||||||
"const",
|
"const",
|
||||||
"constexpr",
|
"constexpr",
|
||||||
"const_cast",
|
"const_cast",
|
||||||
"continue",
|
"continue",
|
||||||
"co_await",
|
"co_await",
|
||||||
"co_return",
|
"co_return",
|
||||||
"co_yield",
|
"co_yield",
|
||||||
"decltype",
|
"decltype",
|
||||||
"default",
|
"default",
|
||||||
"delete",
|
"delete",
|
||||||
"do",
|
"do",
|
||||||
"double",
|
"double",
|
||||||
"dynamic_cast",
|
"dynamic_cast",
|
||||||
"else",
|
"else",
|
||||||
"enum",
|
"enum",
|
||||||
"explicit",
|
"explicit",
|
||||||
"export",
|
"export",
|
||||||
"extern",
|
"extern",
|
||||||
"false",
|
"false",
|
||||||
"float",
|
"float",
|
||||||
"for",
|
"for",
|
||||||
"friend",
|
"friend",
|
||||||
"goto",
|
"goto",
|
||||||
"if",
|
"if",
|
||||||
"import",
|
"import",
|
||||||
"inline",
|
"inline",
|
||||||
"int",
|
"int",
|
||||||
"long",
|
"long",
|
||||||
"module",
|
"module",
|
||||||
"mutable",
|
"mutable",
|
||||||
"namespace",
|
"namespace",
|
||||||
"new",
|
"new",
|
||||||
"noexcept",
|
"noexcept",
|
||||||
"not",
|
"not",
|
||||||
"not_eq",
|
"not_eq",
|
||||||
"nullptr",
|
"nullptr",
|
||||||
"operator",
|
"operator",
|
||||||
"or",
|
"or",
|
||||||
"or_eq",
|
"or_eq",
|
||||||
"private",
|
"private",
|
||||||
"protected",
|
"protected",
|
||||||
"public",
|
"public",
|
||||||
"register",
|
"register",
|
||||||
"reinterpret_cast",
|
"reinterpret_cast",
|
||||||
"requires",
|
"requires",
|
||||||
"return",
|
"return",
|
||||||
"short",
|
"short",
|
||||||
"signed",
|
"signed",
|
||||||
"sizeof",
|
"sizeof",
|
||||||
"static",
|
"static",
|
||||||
"static_assert",
|
"static_assert",
|
||||||
"static_cast",
|
"static_cast",
|
||||||
"struct",
|
"struct",
|
||||||
"switch",
|
"switch",
|
||||||
"synchronized",
|
"synchronized",
|
||||||
"template",
|
"template",
|
||||||
"this",
|
"this",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
"throw",
|
"throw",
|
||||||
"true",
|
"true",
|
||||||
"try",
|
"try",
|
||||||
"typedef",
|
"typedef",
|
||||||
"typeid",
|
"typeid",
|
||||||
"typename",
|
"typename",
|
||||||
"union",
|
"union",
|
||||||
"unsigned",
|
"unsigned",
|
||||||
"using",
|
"using",
|
||||||
"virtual",
|
"virtual",
|
||||||
"void",
|
"void",
|
||||||
"volatile",
|
"volatile",
|
||||||
"wchar_t",
|
"wchar_t",
|
||||||
"while",
|
"while",
|
||||||
"xor",
|
"xor",
|
||||||
"xor_eq",
|
"xor_eq",
|
||||||
nullptr };
|
nullptr,
|
||||||
|
};
|
||||||
for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
|
for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,10 +231,9 @@ class CppGenerator : public BaseGenerator {
|
|||||||
SetNameSpace(struct_def.defined_namespace);
|
SetNameSpace(struct_def.defined_namespace);
|
||||||
code_ += "struct " + Name(struct_def) + ";";
|
code_ += "struct " + Name(struct_def) + ";";
|
||||||
if (parser_.opts.generate_object_based_api) {
|
if (parser_.opts.generate_object_based_api) {
|
||||||
auto nativeName = NativeName(Name(struct_def), &struct_def, parser_.opts);
|
auto nativeName =
|
||||||
if (!struct_def.fixed) {
|
NativeName(Name(struct_def), &struct_def, parser_.opts);
|
||||||
code_ += "struct " + nativeName + ";";
|
if (!struct_def.fixed) { code_ += "struct " + nativeName + ";"; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
code_ += "";
|
code_ += "";
|
||||||
}
|
}
|
||||||
@@ -242,12 +242,14 @@ class CppGenerator : public BaseGenerator {
|
|||||||
// Generate forward declarations for all equal operators
|
// Generate forward declarations for all equal operators
|
||||||
if (parser_.opts.generate_object_based_api && parser_.opts.gen_compare) {
|
if (parser_.opts.generate_object_based_api && parser_.opts.gen_compare) {
|
||||||
for (auto it = parser_.structs_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser_.structs_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
const auto &struct_def = **it;
|
const auto &struct_def = **it;
|
||||||
if (!struct_def.generated) {
|
if (!struct_def.generated) {
|
||||||
SetNameSpace(struct_def.defined_namespace);
|
SetNameSpace(struct_def.defined_namespace);
|
||||||
auto nativeName = NativeName(Name(struct_def), &struct_def, parser_.opts);
|
auto nativeName =
|
||||||
code_ += "bool operator==(const " + nativeName + " &lhs, const " + nativeName + " &rhs);";
|
NativeName(Name(struct_def), &struct_def, parser_.opts);
|
||||||
|
code_ += "bool operator==(const " + nativeName + " &lhs, const " +
|
||||||
|
nativeName + " &rhs);";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
code_ += "";
|
code_ += "";
|
||||||
@@ -357,7 +359,8 @@ class CppGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
code_ += "inline \\";
|
code_ += "inline \\";
|
||||||
code_ +=
|
code_ +=
|
||||||
"const {{CPP_NAME}} *{{NULLABLE_EXT}}GetSizePrefixed{{STRUCT_NAME}}(const void "
|
"const {{CPP_NAME}} "
|
||||||
|
"*{{NULLABLE_EXT}}GetSizePrefixed{{STRUCT_NAME}}(const void "
|
||||||
"*buf) {";
|
"*buf) {";
|
||||||
code_ += " return flatbuffers::GetSizePrefixedRoot<{{CPP_NAME}}>(buf);";
|
code_ += " return flatbuffers::GetSizePrefixedRoot<{{CPP_NAME}}>(buf);";
|
||||||
code_ += "}";
|
code_ += "}";
|
||||||
@@ -402,7 +405,8 @@ class CppGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
code_ += "inline bool VerifySizePrefixed{{STRUCT_NAME}}Buffer(";
|
code_ += "inline bool VerifySizePrefixed{{STRUCT_NAME}}Buffer(";
|
||||||
code_ += " flatbuffers::Verifier &verifier) {";
|
code_ += " flatbuffers::Verifier &verifier) {";
|
||||||
code_ += " return verifier.VerifySizePrefixedBuffer<{{CPP_NAME}}>({{ID}});";
|
code_ +=
|
||||||
|
" return verifier.VerifySizePrefixedBuffer<{{CPP_NAME}}>({{ID}});";
|
||||||
code_ += "}";
|
code_ += "}";
|
||||||
code_ += "";
|
code_ += "";
|
||||||
|
|
||||||
@@ -494,15 +498,15 @@ class CppGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Return a C++ type from the table in idl.h
|
// Return a C++ type from the table in idl.h
|
||||||
std::string GenTypeBasic(const Type &type, bool user_facing_type) const {
|
std::string GenTypeBasic(const Type &type, bool user_facing_type) const {
|
||||||
static const char * const ctypename[] = {
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
static const char *const ctypename[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
|
||||||
RTYPE) \
|
RTYPE) \
|
||||||
#CTYPE,
|
#CTYPE,
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
// clang-format on
|
|
||||||
};
|
};
|
||||||
|
// clang-format on
|
||||||
if (user_facing_type) {
|
if (user_facing_type) {
|
||||||
if (type.enum_def) return WrapInNameSpace(*type.enum_def);
|
if (type.enum_def) return WrapInNameSpace(*type.enum_def);
|
||||||
if (type.base_type == BASE_TYPE_BOOL) return "bool";
|
if (type.base_type == BASE_TYPE_BOOL) return "bool";
|
||||||
@@ -577,12 +581,24 @@ class CppGenerator : public BaseGenerator {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FlexibleStringConstructor(const FieldDef *field) {
|
||||||
|
auto attr = field
|
||||||
|
? (field->attributes.Lookup("cpp_str_flex_ctor") != nullptr)
|
||||||
|
: false;
|
||||||
|
auto ret =
|
||||||
|
attr ? attr : parser_.opts.cpp_object_api_string_flexible_constructor;
|
||||||
|
return ret && NativeString(field) !=
|
||||||
|
"std::string"; // Only for custom string types.
|
||||||
|
}
|
||||||
|
|
||||||
std::string GenTypeNativePtr(const std::string &type, const FieldDef *field,
|
std::string GenTypeNativePtr(const std::string &type, const FieldDef *field,
|
||||||
bool is_constructor) {
|
bool is_constructor) {
|
||||||
auto &ptr_type = PtrType(field);
|
auto &ptr_type = PtrType(field);
|
||||||
if (ptr_type != "naked") {
|
if (ptr_type != "naked") {
|
||||||
return (ptr_type != "default_ptr_type" ? ptr_type :
|
return (ptr_type != "default_ptr_type"
|
||||||
parser_.opts.cpp_object_api_pointer_type) + "<" + type + ">";
|
? ptr_type
|
||||||
|
: parser_.opts.cpp_object_api_pointer_type) +
|
||||||
|
"<" + type + ">";
|
||||||
} else if (is_constructor) {
|
} else if (is_constructor) {
|
||||||
return "";
|
return "";
|
||||||
} else {
|
} else {
|
||||||
@@ -592,8 +608,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
std::string GenPtrGet(const FieldDef &field) {
|
std::string GenPtrGet(const FieldDef &field) {
|
||||||
auto cpp_ptr_type_get = field.attributes.Lookup("cpp_ptr_type_get");
|
auto cpp_ptr_type_get = field.attributes.Lookup("cpp_ptr_type_get");
|
||||||
if (cpp_ptr_type_get)
|
if (cpp_ptr_type_get) return cpp_ptr_type_get->constant;
|
||||||
return cpp_ptr_type_get->constant;
|
|
||||||
auto &ptr_type = PtrType(&field);
|
auto &ptr_type = PtrType(&field);
|
||||||
return ptr_type == "naked" ? "" : ".get()";
|
return ptr_type == "naked" ? "" : ".get()";
|
||||||
}
|
}
|
||||||
@@ -943,14 +958,15 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_ += "};";
|
code_ += "};";
|
||||||
|
|
||||||
if (parser_.opts.scoped_enums && enum_def.attributes.Lookup("bit_flags")) {
|
if (parser_.opts.scoped_enums && enum_def.attributes.Lookup("bit_flags")) {
|
||||||
code_ += "FLATBUFFERS_DEFINE_BITMASK_OPERATORS({{ENUM_NAME}}, {{BASE_TYPE}})";
|
code_ +=
|
||||||
|
"FLATBUFFERS_DEFINE_BITMASK_OPERATORS({{ENUM_NAME}}, {{BASE_TYPE}})";
|
||||||
}
|
}
|
||||||
code_ += "";
|
code_ += "";
|
||||||
|
|
||||||
// Generate an array of all enumeration values
|
// Generate an array of all enumeration values
|
||||||
auto num_fields = NumToString(enum_def.vals.vec.size());
|
auto num_fields = NumToString(enum_def.vals.vec.size());
|
||||||
code_ += "inline const {{ENUM_NAME}} (&EnumValues{{ENUM_NAME}}())[" + num_fields +
|
code_ += "inline const {{ENUM_NAME}} (&EnumValues{{ENUM_NAME}}())[" +
|
||||||
"] {";
|
num_fields + "] {";
|
||||||
code_ += " static const {{ENUM_NAME}} values[] = {";
|
code_ += " static const {{ENUM_NAME}} values[] = {";
|
||||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
@@ -994,7 +1010,8 @@ class CppGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
code_ += "inline const char *EnumName{{ENUM_NAME}}({{ENUM_NAME}} e) {";
|
code_ += "inline const char *EnumName{{ENUM_NAME}}({{ENUM_NAME}} e) {";
|
||||||
|
|
||||||
code_ += " if (e < " + GetEnumValUse(enum_def, *enum_def.vals.vec.front()) +
|
code_ += " if (e < " +
|
||||||
|
GetEnumValUse(enum_def, *enum_def.vals.vec.front()) +
|
||||||
" || e > " + GetEnumValUse(enum_def, *enum_def.vals.vec.back()) +
|
" || e > " + GetEnumValUse(enum_def, *enum_def.vals.vec.back()) +
|
||||||
") return \"\";";
|
") return \"\";";
|
||||||
|
|
||||||
@@ -1123,22 +1140,28 @@ class CppGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
if (parser_.opts.gen_compare) {
|
if (parser_.opts.gen_compare) {
|
||||||
code_ += "";
|
code_ += "";
|
||||||
code_ += "inline bool operator==(const {{NAME}}Union &lhs, const {{NAME}}Union &rhs) {";
|
code_ +=
|
||||||
|
"inline bool operator==(const {{NAME}}Union &lhs, const "
|
||||||
|
"{{NAME}}Union &rhs) {";
|
||||||
code_ += " if (lhs.type != rhs.type) return false;";
|
code_ += " if (lhs.type != rhs.type) return false;";
|
||||||
code_ += " switch (lhs.type) {";
|
code_ += " switch (lhs.type) {";
|
||||||
|
|
||||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
const auto &ev = **it;
|
const auto &ev = **it;
|
||||||
code_.SetValue("NATIVE_ID", GetEnumValUse(enum_def, ev));
|
code_.SetValue("NATIVE_ID", GetEnumValUse(enum_def, ev));
|
||||||
if (ev.value) {
|
if (ev.value) {
|
||||||
const auto native_type =
|
const auto native_type =
|
||||||
NativeName(GetUnionElement(ev, true, true, true),
|
NativeName(GetUnionElement(ev, true, true, true),
|
||||||
ev.union_type.struct_def, parser_.opts);
|
ev.union_type.struct_def, parser_.opts);
|
||||||
code_.SetValue("NATIVE_TYPE", native_type);
|
code_.SetValue("NATIVE_TYPE", native_type);
|
||||||
code_ += " case {{NATIVE_ID}}: {";
|
code_ += " case {{NATIVE_ID}}: {";
|
||||||
code_ += " return *(reinterpret_cast<const {{NATIVE_TYPE}} *>(lhs.value)) ==";
|
code_ +=
|
||||||
code_ += " *(reinterpret_cast<const {{NATIVE_TYPE}} *>(rhs.value));";
|
" return *(reinterpret_cast<const {{NATIVE_TYPE}} "
|
||||||
|
"*>(lhs.value)) ==";
|
||||||
|
code_ +=
|
||||||
|
" *(reinterpret_cast<const {{NATIVE_TYPE}} "
|
||||||
|
"*>(rhs.value));";
|
||||||
code_ += " }";
|
code_ += " }";
|
||||||
} else {
|
} else {
|
||||||
code_ += " case {{NATIVE_ID}}: {";
|
code_ += " case {{NATIVE_ID}}: {";
|
||||||
@@ -1319,7 +1342,8 @@ class CppGenerator : public BaseGenerator {
|
|||||||
" value = new {{TYPE}}(*reinterpret_cast<{{TYPE}} *>"
|
" value = new {{TYPE}}(*reinterpret_cast<{{TYPE}} *>"
|
||||||
"(u.value));";
|
"(u.value));";
|
||||||
} else {
|
} else {
|
||||||
code_ += " FLATBUFFERS_ASSERT(false); // {{TYPE}} not copyable.";
|
code_ +=
|
||||||
|
" FLATBUFFERS_ASSERT(false); // {{TYPE}} not copyable.";
|
||||||
}
|
}
|
||||||
code_ += " break;";
|
code_ += " break;";
|
||||||
code_ += " }";
|
code_ += " }";
|
||||||
@@ -1395,7 +1419,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string GenDefaultConstant(const FieldDef &field) {
|
std::string GenDefaultConstant(const FieldDef &field) {
|
||||||
if(IsFloat(field.value.type.base_type))
|
if (IsFloat(field.value.type.base_type))
|
||||||
return float_const_gen_.GenFloatConstant(field);
|
return float_const_gen_.GenFloatConstant(field);
|
||||||
else
|
else
|
||||||
return field.value.constant;
|
return field.value.constant;
|
||||||
@@ -1460,10 +1484,14 @@ class CppGenerator : public BaseGenerator {
|
|||||||
auto type = GenTypeNative(field.value.type, false, field);
|
auto type = GenTypeNative(field.value.type, false, field);
|
||||||
auto cpp_type = field.attributes.Lookup("cpp_type");
|
auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||||
auto full_type =
|
auto full_type =
|
||||||
(cpp_type ? (field.value.type.base_type == BASE_TYPE_VECTOR
|
(cpp_type
|
||||||
? "std::vector<" + GenTypeNativePtr(cpp_type->constant, &field, false) + "> "
|
? (field.value.type.base_type == BASE_TYPE_VECTOR
|
||||||
|
? "std::vector<" +
|
||||||
|
GenTypeNativePtr(cpp_type->constant, &field,
|
||||||
|
false) +
|
||||||
|
"> "
|
||||||
: GenTypeNativePtr(cpp_type->constant, &field, false))
|
: GenTypeNativePtr(cpp_type->constant, &field, false))
|
||||||
: type + " ");
|
: type + " ");
|
||||||
code_.SetValue("FIELD_TYPE", full_type);
|
code_.SetValue("FIELD_TYPE", full_type);
|
||||||
code_.SetValue("FIELD_NAME", Name(field));
|
code_.SetValue("FIELD_NAME", Name(field));
|
||||||
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}};";
|
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}};";
|
||||||
@@ -1485,7 +1513,11 @@ class CppGenerator : public BaseGenerator {
|
|||||||
if (IsScalar(field.value.type.base_type)) {
|
if (IsScalar(field.value.type.base_type)) {
|
||||||
if (!initializer_list.empty()) { initializer_list += ",\n "; }
|
if (!initializer_list.empty()) { initializer_list += ",\n "; }
|
||||||
initializer_list += Name(field);
|
initializer_list += Name(field);
|
||||||
initializer_list += "(" + (native_default ? std::string(native_default->constant) : GetDefaultScalarValue(field, true)) + ")";
|
initializer_list +=
|
||||||
|
"(" +
|
||||||
|
(native_default ? std::string(native_default->constant)
|
||||||
|
: GetDefaultScalarValue(field, true)) +
|
||||||
|
")";
|
||||||
} else if (field.value.type.base_type == BASE_TYPE_STRUCT) {
|
} else if (field.value.type.base_type == BASE_TYPE_STRUCT) {
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
if (native_default) {
|
if (native_default) {
|
||||||
@@ -1514,18 +1546,17 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_ += " }";
|
code_ += " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenCompareOperator(const StructDef &struct_def, std::string accessSuffix = "") {
|
void GenCompareOperator(const StructDef &struct_def,
|
||||||
|
std::string accessSuffix = "") {
|
||||||
std::string compare_op;
|
std::string compare_op;
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto &field = **it;
|
||||||
if (!field.deprecated && // Deprecated fields won't be accessible.
|
if (!field.deprecated && // Deprecated fields won't be accessible.
|
||||||
field.value.type.base_type != BASE_TYPE_UTYPE &&
|
field.value.type.base_type != BASE_TYPE_UTYPE &&
|
||||||
(field.value.type.base_type != BASE_TYPE_VECTOR ||
|
(field.value.type.base_type != BASE_TYPE_VECTOR ||
|
||||||
field.value.type.element != BASE_TYPE_UTYPE)) {
|
field.value.type.element != BASE_TYPE_UTYPE)) {
|
||||||
if (!compare_op.empty()) {
|
if (!compare_op.empty()) { compare_op += " &&\n "; }
|
||||||
compare_op += " &&\n ";
|
|
||||||
}
|
|
||||||
auto accessor = Name(field) + accessSuffix;
|
auto accessor = Name(field) + accessSuffix;
|
||||||
compare_op += "(lhs." + accessor + " == rhs." + accessor + ")";
|
compare_op += "(lhs." + accessor + " == rhs." + accessor + ")";
|
||||||
}
|
}
|
||||||
@@ -1547,7 +1578,9 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("CMP_LHS", cmp_lhs);
|
code_.SetValue("CMP_LHS", cmp_lhs);
|
||||||
code_.SetValue("CMP_RHS", cmp_rhs);
|
code_.SetValue("CMP_RHS", cmp_rhs);
|
||||||
code_ += "";
|
code_ += "";
|
||||||
code_ += "inline bool operator==(const {{NATIVE_NAME}} &{{CMP_LHS}}, const {{NATIVE_NAME}} &{{CMP_RHS}}) {";
|
code_ +=
|
||||||
|
"inline bool operator==(const {{NATIVE_NAME}} &{{CMP_LHS}}, const "
|
||||||
|
"{{NATIVE_NAME}} &{{CMP_RHS}}) {";
|
||||||
code_ += "{{CMP_OP}}";
|
code_ += "{{CMP_OP}}";
|
||||||
code_ += "}";
|
code_ += "}";
|
||||||
}
|
}
|
||||||
@@ -1701,12 +1734,12 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_ += " typedef {{NATIVE_NAME}} NativeTableType;";
|
code_ += " typedef {{NATIVE_NAME}} NativeTableType;";
|
||||||
}
|
}
|
||||||
if (parser_.opts.mini_reflect != IDLOptions::kNone) {
|
if (parser_.opts.mini_reflect != IDLOptions::kNone) {
|
||||||
code_ += " static const flatbuffers::TypeTable *MiniReflectTypeTable() {";
|
code_ +=
|
||||||
|
" static const flatbuffers::TypeTable *MiniReflectTypeTable() {";
|
||||||
code_ += " return {{STRUCT_NAME}}TypeTable();";
|
code_ += " return {{STRUCT_NAME}}TypeTable();";
|
||||||
code_ += " }";
|
code_ += " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GenFullyQualifiedNameGetter(struct_def, Name(struct_def));
|
GenFullyQualifiedNameGetter(struct_def, Name(struct_def));
|
||||||
|
|
||||||
// Generate field id constants.
|
// Generate field id constants.
|
||||||
@@ -1714,7 +1747,8 @@ class CppGenerator : public BaseGenerator {
|
|||||||
// We need to add a trailing comma to all elements except the last one as
|
// We need to add a trailing comma to all elements except the last one as
|
||||||
// older versions of gcc complain about this.
|
// older versions of gcc complain about this.
|
||||||
code_.SetValue("SEP", "");
|
code_.SetValue("SEP", "");
|
||||||
code_ += " enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {";
|
code_ +=
|
||||||
|
" enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto &field = **it;
|
||||||
@@ -1789,9 +1823,8 @@ class CppGenerator : public BaseGenerator {
|
|||||||
auto full_struct_name = GetUnionElement(ev, true, true);
|
auto full_struct_name = GetUnionElement(ev, true, true);
|
||||||
|
|
||||||
// @TODO: Mby make this decisions more universal? How?
|
// @TODO: Mby make this decisions more universal? How?
|
||||||
code_.SetValue(
|
code_.SetValue("U_GET_TYPE",
|
||||||
"U_GET_TYPE",
|
EscapeKeyword(field.name + UnionTypeFieldSuffix()));
|
||||||
EscapeKeyword(field.name + UnionTypeFieldSuffix()));
|
|
||||||
code_.SetValue(
|
code_.SetValue(
|
||||||
"U_ELEMENT_TYPE",
|
"U_ELEMENT_TYPE",
|
||||||
WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev)));
|
WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev)));
|
||||||
@@ -1855,7 +1888,9 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("CPP_NAME", TranslateNameSpace(qualified_name));
|
code_.SetValue("CPP_NAME", TranslateNameSpace(qualified_name));
|
||||||
|
|
||||||
code_ += " const {{CPP_NAME}} *{{FIELD_NAME}}_nested_root() const {";
|
code_ += " const {{CPP_NAME}} *{{FIELD_NAME}}_nested_root() const {";
|
||||||
code_ += " return flatbuffers::GetRoot<{{CPP_NAME}}>({{FIELD_NAME}}()->Data());";
|
code_ +=
|
||||||
|
" return "
|
||||||
|
"flatbuffers::GetRoot<{{CPP_NAME}}>({{FIELD_NAME}}()->Data());";
|
||||||
code_ += " }";
|
code_ += " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1863,7 +1898,8 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_ +=
|
code_ +=
|
||||||
" flexbuffers::Reference {{FIELD_NAME}}_flexbuffer_root()"
|
" flexbuffers::Reference {{FIELD_NAME}}_flexbuffer_root()"
|
||||||
" const {";
|
" const {";
|
||||||
// Both Data() and size() are const-methods, therefore call order doesn't matter.
|
// Both Data() and size() are const-methods, therefore call order
|
||||||
|
// doesn't matter.
|
||||||
code_ +=
|
code_ +=
|
||||||
" return flexbuffers::GetRoot({{FIELD_NAME}}()->Data(), "
|
" return flexbuffers::GetRoot({{FIELD_NAME}}()->Data(), "
|
||||||
"{{FIELD_NAME}}()->size());";
|
"{{FIELD_NAME}}()->size());";
|
||||||
@@ -1871,9 +1907,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a comparison function for this field if it is a key.
|
// Generate a comparison function for this field if it is a key.
|
||||||
if (field.key) {
|
if (field.key) { GenKeyFieldMethods(field); }
|
||||||
GenKeyFieldMethods(field);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a verifier function that can check a buffer from an untrusted
|
// Generate a verifier function that can check a buffer from an untrusted
|
||||||
@@ -2064,8 +2098,9 @@ class CppGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Generate a CreateXDirect function with vector types as parameters
|
// Generate a CreateXDirect function with vector types as parameters
|
||||||
if (has_string_or_vector_fields) {
|
if (has_string_or_vector_fields) {
|
||||||
code_ += "inline flatbuffers::Offset<{{STRUCT_NAME}}> "
|
code_ +=
|
||||||
"Create{{STRUCT_NAME}}Direct(";
|
"inline flatbuffers::Offset<{{STRUCT_NAME}}> "
|
||||||
|
"Create{{STRUCT_NAME}}Direct(";
|
||||||
code_ += " flatbuffers::FlatBufferBuilder &_fbb\\";
|
code_ += " flatbuffers::FlatBufferBuilder &_fbb\\";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
@@ -2128,17 +2163,22 @@ class CppGenerator : public BaseGenerator {
|
|||||||
std::string GenUnionUnpackVal(const FieldDef &afield,
|
std::string GenUnionUnpackVal(const FieldDef &afield,
|
||||||
const char *vec_elem_access,
|
const char *vec_elem_access,
|
||||||
const char *vec_type_access) {
|
const char *vec_type_access) {
|
||||||
return afield.value.type.enum_def->name +
|
return afield.value.type.enum_def->name + "Union::UnPack(" + "_e" +
|
||||||
"Union::UnPack(" + "_e" + vec_elem_access + ", " +
|
vec_elem_access + ", " +
|
||||||
EscapeKeyword(afield.name + UnionTypeFieldSuffix()) +
|
EscapeKeyword(afield.name + UnionTypeFieldSuffix()) + "()" +
|
||||||
"()" + vec_type_access + ", _resolver)";
|
vec_type_access + ", _resolver)";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenUnpackVal(const Type &type, const std::string &val,
|
std::string GenUnpackVal(const Type &type, const std::string &val,
|
||||||
bool invector, const FieldDef &afield) {
|
bool invector, const FieldDef &afield) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRING: {
|
case BASE_TYPE_STRING: {
|
||||||
return val + "->str()";
|
if (FlexibleStringConstructor(&afield)) {
|
||||||
|
return NativeString(&afield) + "(" + val + "->c_str(), " + val +
|
||||||
|
"->size())";
|
||||||
|
} else {
|
||||||
|
return val + "->str()";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case BASE_TYPE_STRUCT: {
|
case BASE_TYPE_STRUCT: {
|
||||||
const auto name = WrapInNameSpace(*type.struct_def);
|
const auto name = WrapInNameSpace(*type.struct_def);
|
||||||
@@ -2210,26 +2250,29 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code += "//vector resolver, " + PtrType(&field) + "\n";
|
code += "//vector resolver, " + PtrType(&field) + "\n";
|
||||||
code += "if (_resolver) ";
|
code += "if (_resolver) ";
|
||||||
code += "(*_resolver)";
|
code += "(*_resolver)";
|
||||||
code += "(reinterpret_cast<void **>(&_o->" + name + "[_i]" + access + "), ";
|
code += "(reinterpret_cast<void **>(&_o->" + name + "[_i]" + access +
|
||||||
|
"), ";
|
||||||
code += "static_cast<flatbuffers::hash_value_t>(" + indexing + "));";
|
code += "static_cast<flatbuffers::hash_value_t>(" + indexing + "));";
|
||||||
if (PtrType(&field) == "naked") {
|
if (PtrType(&field) == "naked") {
|
||||||
code += " else ";
|
code += " else ";
|
||||||
code += "_o->" + name + "[_i]" + access + " = nullptr";
|
code += "_o->" + name + "[_i]" + access + " = nullptr";
|
||||||
} else {
|
} else {
|
||||||
//code += " else ";
|
// code += " else ";
|
||||||
//code += "_o->" + name + "[_i]" + access + " = " + GenTypeNativePtr(cpp_type->constant, &field, true) + "();";
|
// code += "_o->" + name + "[_i]" + access + " = " +
|
||||||
|
// GenTypeNativePtr(cpp_type->constant, &field, true) + "();";
|
||||||
code += "/* else do nothing */";
|
code += "/* else do nothing */";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
code += "_o->" + name + "[_i]" + access + " = ";
|
code += "_o->" + name + "[_i]" + access + " = ";
|
||||||
code +=
|
code += GenUnpackVal(field.value.type.VectorType(), indexing, true,
|
||||||
GenUnpackVal(field.value.type.VectorType(), indexing, true, field);
|
field);
|
||||||
}
|
}
|
||||||
code += "; } }";
|
code += "; } }";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UTYPE: {
|
case BASE_TYPE_UTYPE: {
|
||||||
FLATBUFFERS_ASSERT(union_field->value.type.base_type == BASE_TYPE_UNION);
|
FLATBUFFERS_ASSERT(union_field->value.type.base_type ==
|
||||||
|
BASE_TYPE_UNION);
|
||||||
// Generate code that sets the union type, of the form:
|
// Generate code that sets the union type, of the form:
|
||||||
// _o->field.type = _e;
|
// _o->field.type = _e;
|
||||||
code += "_o->" + union_field->name + ".type = _e;";
|
code += "_o->" + union_field->name + ".type = _e;";
|
||||||
@@ -2260,8 +2303,9 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code += " else ";
|
code += " else ";
|
||||||
code += "_o->" + Name(field) + " = nullptr;";
|
code += "_o->" + Name(field) + " = nullptr;";
|
||||||
} else {
|
} else {
|
||||||
//code += " else ";
|
// code += " else ";
|
||||||
//code += "_o->" + Name(field) + " = " + GenTypeNativePtr(cpp_type->constant, &field, true) + "();";
|
// code += "_o->" + Name(field) + " = " +
|
||||||
|
// GenTypeNativePtr(cpp_type->constant, &field, true) + "();";
|
||||||
code += "/* else do nothing */;";
|
code += "/* else do nothing */;";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2286,7 +2330,8 @@ class CppGenerator : public BaseGenerator {
|
|||||||
} else {
|
} else {
|
||||||
value += Name(field);
|
value += Name(field);
|
||||||
}
|
}
|
||||||
if (field.value.type.base_type != BASE_TYPE_VECTOR && field.attributes.Lookup("cpp_type")) {
|
if (field.value.type.base_type != BASE_TYPE_VECTOR &&
|
||||||
|
field.attributes.Lookup("cpp_type")) {
|
||||||
auto type = GenTypeBasic(field.value.type, false);
|
auto type = GenTypeBasic(field.value.type, false);
|
||||||
value =
|
value =
|
||||||
"_rehasher ? "
|
"_rehasher ? "
|
||||||
@@ -2294,7 +2339,6 @@ class CppGenerator : public BaseGenerator {
|
|||||||
type + ">((*_rehasher)(" + value + GenPtrGet(field) + ")) : 0";
|
type + ">((*_rehasher)(" + value + GenPtrGet(field) + ")) : 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string code;
|
std::string code;
|
||||||
switch (field.value.type.base_type) {
|
switch (field.value.type.base_type) {
|
||||||
// String fields are of the form:
|
// String fields are of the form:
|
||||||
@@ -2332,7 +2376,20 @@ class CppGenerator : public BaseGenerator {
|
|||||||
auto vector_type = field.value.type.VectorType();
|
auto vector_type = field.value.type.VectorType();
|
||||||
switch (vector_type.base_type) {
|
switch (vector_type.base_type) {
|
||||||
case BASE_TYPE_STRING: {
|
case BASE_TYPE_STRING: {
|
||||||
code += "_fbb.CreateVectorOfStrings(" + value + ")";
|
if (NativeString(&field) == "std::string") {
|
||||||
|
code += "_fbb.CreateVectorOfStrings(" + value + ")";
|
||||||
|
} else {
|
||||||
|
// Use by-function serialization to emulate
|
||||||
|
// CreateVectorOfStrings(); this works also with non-std strings.
|
||||||
|
code +=
|
||||||
|
"_fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>"
|
||||||
|
" ";
|
||||||
|
code += "(" + value + ".size(), ";
|
||||||
|
code += "[](size_t i, _VectorArgs *__va) { ";
|
||||||
|
code +=
|
||||||
|
"return __va->__fbb->CreateString(__va->_" + value + "[i]);";
|
||||||
|
code += " }, &_va )";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_STRUCT: {
|
case BASE_TYPE_STRUCT: {
|
||||||
@@ -2710,9 +2767,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a comparison function for this field if it is a key.
|
// Generate a comparison function for this field if it is a key.
|
||||||
if (field.key) {
|
if (field.key) { GenKeyFieldMethods(field); }
|
||||||
GenKeyFieldMethods(field);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
code_.SetValue("NATIVE_NAME", Name(struct_def));
|
code_.SetValue("NATIVE_NAME", Name(struct_def));
|
||||||
GenOperatorNewDelete(struct_def);
|
GenOperatorNewDelete(struct_def);
|
||||||
|
|||||||
Reference in New Issue
Block a user