mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-02 20:15:34 +00:00
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).
This commit is contained in:
@@ -75,7 +75,7 @@ Additional options:
|
||||
- `--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.)
|
||||
|
||||
- `--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."
|
||||
|
||||
- `--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-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.
|
||||
|
||||
@@ -168,7 +174,7 @@ Additional options:
|
||||
an evolution of. Gives errors if not. Useful to check if schema
|
||||
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`.
|
||||
|
||||
- `--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
|
||||
flatbuffer field set the `cpp_ptr_type` attribute to `default_ptr_type`.
|
||||
|
||||
|
||||
# Using different string type.
|
||||
|
||||
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
|
||||
`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 *, uint32_t).
|
||||
Please note that the character array is not guaranteed to be NUL terminated,
|
||||
you should always use the provided size to determine end of string.
|
||||
|
||||
## Reflection (& Resizing)
|
||||
|
||||
|
||||
@@ -410,6 +410,7 @@ struct IDLOptions {
|
||||
bool gen_compare;
|
||||
std::string cpp_object_api_pointer_type;
|
||||
std::string cpp_object_api_string_type;
|
||||
bool cpp_object_api_string_flexible_constructor;
|
||||
bool gen_nullable;
|
||||
bool gen_generated;
|
||||
std::string object_prefix;
|
||||
@@ -486,6 +487,7 @@ struct IDLOptions {
|
||||
generate_object_based_api(false),
|
||||
gen_compare(false),
|
||||
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||
cpp_object_api_string_flexible_constructor(false),
|
||||
gen_nullable(false),
|
||||
gen_generated(false),
|
||||
object_suffix("T"),
|
||||
@@ -627,6 +629,7 @@ class Parser : public ParserState {
|
||||
known_attributes_["cpp_ptr_type"] = true;
|
||||
known_attributes_["cpp_ptr_type_get"] = true;
|
||||
known_attributes_["cpp_str_type"] = true;
|
||||
known_attributes_["cpp_str_flex_ctor"] = true;
|
||||
known_attributes_["native_inline"] = true;
|
||||
known_attributes_["native_custom_alloc"] = 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-nullable Add Clang _Nullable for C++ pointer. or @Nullable 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"
|
||||
" 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"
|
||||
" file.\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"
|
||||
" 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-suffix Customise class suffix for C++ object-based API.\n"
|
||||
" Default value is \"T\".\n"
|
||||
@@ -247,6 +251,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
||||
} else if (arg == "--cpp-str-type") {
|
||||
if (++argi >= argc) Error("missing type following" + arg, true);
|
||||
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") {
|
||||
opts.gen_nullable = true;
|
||||
} else if (arg == "--gen-generated") {
|
||||
|
||||
@@ -578,6 +578,12 @@ class CppGenerator : public BaseGenerator {
|
||||
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,
|
||||
bool is_constructor) {
|
||||
auto &ptr_type = PtrType(field);
|
||||
@@ -2138,7 +2144,11 @@ class CppGenerator : public BaseGenerator {
|
||||
bool invector, const FieldDef &afield) {
|
||||
switch (type.base_type) {
|
||||
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: {
|
||||
const auto name = WrapInNameSpace(*type.struct_def);
|
||||
@@ -2169,7 +2179,7 @@ class CppGenerator : public BaseGenerator {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
std::string GenUnpackFieldStatement(const FieldDef &field,
|
||||
const FieldDef *union_field) {
|
||||
|
||||
Reference in New Issue
Block a user