Implement native_shared attribute for C++.

Fixes #5141. See also #5145.
This commit is contained in:
iceboy
2019-02-05 12:59:44 -08:00
parent 76a024137f
commit c5df650099
4 changed files with 30 additions and 5 deletions

View File

@@ -88,6 +88,12 @@ convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
*Note: That we never stored a `mana` value, so it will return the default.*
The following attributes are supported:
- `native_shared` (on a field): For string fields, this enables the usage of
CreateSharedString() instead of CreateString() for generated
CreateXxxDirect(), and Pack() in object-based API if enabled.
## Object based API. {#flatbuffers_cpp_object_based_api}
FlatBuffers is all about memory efficiency, which is why its base API is written

View File

@@ -259,6 +259,7 @@ struct FieldDef : public Definition {
required(false),
key(false),
native_inline(false),
native_shared(false),
flexbuffer(false),
nested_flatbuffer(NULL),
padding(0) {}
@@ -275,6 +276,8 @@ struct FieldDef : public Definition {
bool key; // Field functions as a key for creating sorted vectors.
bool native_inline; // Field will be defined inline (instead of as a pointer)
// for native tables if field is a struct.
bool native_shared; // Field will be using CreateSharedString while packing
// if field is a string.
bool flexbuffer; // This field contains FlexBuffer data.
StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data.
size_t padding; // Bytes to always pad after this field.
@@ -623,6 +626,7 @@ class Parser : public ParserState {
known_attributes_["cpp_str_type"] = true;
known_attributes_["native_inline"] = true;
known_attributes_["native_custom_alloc"] = true;
known_attributes_["native_shared"] = true;
known_attributes_["native_type"] = true;
known_attributes_["native_default"] = true;
known_attributes_["flexbuffer"] = true;

View File

@@ -2083,9 +2083,15 @@ class CppGenerator : public BaseGenerator {
if (!field.deprecated) {
code_.SetValue("FIELD_NAME", Name(field));
if (field.value.type.base_type == BASE_TYPE_STRING) {
code_ +=
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
"_fbb.CreateString({{FIELD_NAME}}) : 0;";
if (!field.native_shared) {
code_ +=
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
"_fbb.CreateString({{FIELD_NAME}}) : 0;";
} else {
code_ +=
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
"_fbb.CreateSharedString({{FIELD_NAME}}) : 0;";
}
} else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
code_ += " auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? \\";
const auto vtype = field.value.type.VectorType();
@@ -2294,8 +2300,14 @@ class CppGenerator : public BaseGenerator {
switch (field.value.type.base_type) {
// String fields are of the form:
// _fbb.CreateString(_o->field)
// or
// _fbb.CreateSharedString(_o->field)
case BASE_TYPE_STRING: {
code += "_fbb.CreateString(" + value + ")";
if (!field.native_shared) {
code += "_fbb.CreateString(" + value + ")";
} else {
code += "_fbb.CreateSharedString(" + value + ")";
}
// For optional fields, check to see if there actually is any data
// in _o->field before attempting to access it. If there isn't,

View File

@@ -777,7 +777,10 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
field->native_inline = field->attributes.Lookup("native_inline") != nullptr;
if (field->native_inline && !IsStruct(field->value.type))
return Error("native_inline can only be defined on structs'");
return Error("native_inline can only be defined on structs");
field->native_shared = field->attributes.Lookup("native_shared") != nullptr;
if (field->native_shared && field->value.type.base_type != BASE_TYPE_STRING)
return Error("native_shared can only be defined on strings");
auto nested = field->attributes.Lookup("nested_flatbuffer");
if (nested) {