Sitelet https://github.com/simonbinary/flatbuffers/commit/f2071e4f80bf7ccd924337c7bf1bf33c79e3fc3e
Skip to content

Commit f2071e4

Browse files
emaxerrnoaardappel
authored andcommitted
Add arbitrary string type to the native object API (google#4218)
* Custom strings are very common for optimizations around small objects or growth style optimizations, i.e.: grow at 1.57 times vs doubling vs.. A second common strategy is to cooperate w/ the memory allocator see FBString[1] and seastar[2] string for examples. [1] fbstring: https://github.com/facebook/folly/blob/master/folly/docs/FBString.md [2] sstring: https://github.com/scylladb/seastar/blob/master/core/sstring.hh
1 parent 9c25ecd commit f2071e4

5 files changed

Lines changed: 35 additions & 2 deletions

File tree

‎docs/source/CppUsage.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,15 @@ pointer type (`my_ptr<T>`), or by specifying `naked` as the type to get `T *`
200200
pointers. Unlike the smart pointers, naked pointers do not manage memory for
201201
you, so you'll have to manage their lifecycles manually.
202202

203+
204+
# Using different string type.
205+
206+
By default the object tree is built out of `std::string`, but you can
207+
influence this either globally (using the `--cpp-str-type` argument to
208+
`flatc`) or per field using the `cpp_str_type` attribute.
209+
210+
The type must support T::c_str() and T::length() as member functions.
211+
203212
## Reflection (& Resizing)
204213

205214
There is experimental support for reflection in FlatBuffers, allowing you to

‎include/flatbuffers/flatbuffers.h‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,15 @@ FLATBUFFERS_FINAL_CLASS
980980
return str ? CreateString(str->c_str(), str->Length()) : 0;
981981
}
982982

983+
/// @brief Store a string in the buffer, which can contain any binary data.
984+
/// @param[in] str A const reference to a std::string like type with support
985+
/// of T::c_str() and T::length() to store in the buffer.
986+
/// @return Returns the offset in the buffer where the string starts.
987+
template<typename T>
988+
Offset<String> CreateString(const T &str) {
989+
return CreateString(str.c_str(), str.length());
990+
}
991+
983992
/// @brief Store a string in the buffer, which can contain any binary data.
984993
/// If a string with this exact contents has already been serialized before,
985994
/// instead simply returns the offset of the existing string.

‎include/flatbuffers/idl.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ struct IDLOptions {
353353
bool escape_proto_identifiers;
354354
bool generate_object_based_api;
355355
std::string cpp_object_api_pointer_type;
356+
std::string cpp_object_api_string_type;
356357
bool union_value_namespacing;
357358
bool allow_non_utf8;
358359
std::string include_prefix;
@@ -479,6 +480,7 @@ class Parser : public ParserState {
479480
known_attributes_["idempotent"] = true;
480481
known_attributes_["cpp_type"] = true;
481482
known_attributes_["cpp_ptr_type"] = true;
483+
known_attributes_["cpp_str_type"] = true;
482484
known_attributes_["native_inline"] = true;
483485
known_attributes_["native_type"] = true;
484486
known_attributes_["native_default"] = true;
@@ -743,4 +745,3 @@ bool GenerateGoGRPC(const Parser &parser,
743745
} // namespace flatbuffers
744746

745747
#endif // FLATBUFFERS_IDL_H_
746-

‎src/flatc.cpp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ std::string FlatCompiler::GetUsageString(const char* program_name) const {
8686
" --escape-proto-ids Disable appending '_' in namespaces names.\n"
8787
" --gen-object-api Generate an additional object-based API.\n"
8888
" --cpp-ptr-type T Set object API pointer type (default std::unique_ptr)\n"
89+
" --cpp-str-type T Set object API string type (default std::string)\n"
90+
" T::c_str() and T::length() must be supported\n"
8991
" --no-js-exports Removes Node.js style export lines in JS.\n"
9092
" --goog-js-export Uses goog.exports* for closure compiler exporting in JS.\n"
9193
" --raw-binary Allow binaries without file_indentifier to be read.\n"
@@ -178,6 +180,9 @@ int FlatCompiler::Compile(int argc, const char** argv) {
178180
} else if (arg == "--cpp-ptr-type") {
179181
if (++argi >= argc) Error("missing type following" + arg, true);
180182
opts.cpp_object_api_pointer_type = argv[argi];
183+
} else if (arg == "--cpp-str-type") {
184+
if (++argi >= argc) Error("missing type following" + arg, true);
185+
opts.cpp_object_api_string_type = argv[argi];
181186
} else if(arg == "--gen-all") {
182187
opts.generate_all = true;
183188
opts.include_dependence_headers = false;

‎src/idl_gen_cpp.cpp‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,15 @@ class CppGenerator : public BaseGenerator {
362362
return attr ? attr->constant : parser_.opts.cpp_object_api_pointer_type;
363363
}
364364

365+
const std::string NativeString(const FieldDef *field) {
366+
auto attr = field ? field->attributes.Lookup("cpp_str_type") : nullptr;
367+
auto &ret = attr ? attr->constant : parser_.opts.cpp_object_api_string_type;
368+
if (ret.empty()) {
369+
return "std::string";
370+
}
371+
return ret;
372+
}
373+
365374
std::string GenTypeNativePtr(const std::string &type, const FieldDef *field,
366375
bool is_constructor) {
367376
auto &ptr_type = PtrType(field);
@@ -383,7 +392,7 @@ class CppGenerator : public BaseGenerator {
383392
const FieldDef &field) {
384393
switch (type.base_type) {
385394
case BASE_TYPE_STRING: {
386-
return "std::string";
395+
return NativeString(&field);
387396
}
388397
case BASE_TYPE_VECTOR: {
389398
const auto type_name = GenTypeNative(type.VectorType(), true, field);

0 commit comments

Comments
 (0)