mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-02 04:04:19 +00:00
Support attribute "cpp_ptr_type" on table elements marked as "hash" (#4643)
* added intended use-cases to monster_test.fbs * added check for `cpp_ptr_type` on hashed fields added default value 'naked' to `cpp_ptr_type` on hashed fields * added C++ generation of cpp_type vectors removed ctor call for vector fields added condition !vector for cpp_type check added Pack() and UnPack() code generation for vector of hashes added generation of correct resolve/rehash for cpp_type elements * added attribute 'cpp_ptr_type_get' to hold accessor for pointer types possible where '.get()' does not work use case: cpp_ptr_type:"std::weak_ptr", cpp_ptr_type_get:".lock().get()" * run flatc to re-generate headers * added bool param is_ctor to GetDefaultScalarValue() to differentiate between usage places * modified monster_test.fbs to remove usage of shared_ptr/weak_ptr reason: STLport does not support std::shared_ptr and std::weak_ptr * run flatc again to re-generate headers * fixed symbol unique_ptr not in namespace std when building with STLport
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
4ea1be53d4
commit
9ce98dd77d
@@ -567,6 +567,9 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
|
||||
std::string GenPtrGet(const FieldDef &field) {
|
||||
auto cpp_ptr_type_get = field.attributes.Lookup("cpp_ptr_type_get");
|
||||
if (cpp_ptr_type_get)
|
||||
return cpp_ptr_type_get->constant;
|
||||
auto &ptr_type = PtrType(&field);
|
||||
return ptr_type == "naked" ? "" : ".get()";
|
||||
}
|
||||
@@ -1319,7 +1322,7 @@ class CppGenerator : public BaseGenerator {
|
||||
: field.value.constant;
|
||||
}
|
||||
|
||||
std::string GetDefaultScalarValue(const FieldDef &field) {
|
||||
std::string GetDefaultScalarValue(const FieldDef &field, bool is_ctor) {
|
||||
if (field.value.type.enum_def && IsScalar(field.value.type.base_type)) {
|
||||
auto ev = field.value.type.enum_def->ReverseLookup(
|
||||
StringToInt(field.value.constant.c_str()), false);
|
||||
@@ -1331,6 +1334,16 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
} else if (field.value.type.base_type == BASE_TYPE_BOOL) {
|
||||
return field.value.constant == "0" ? "false" : "true";
|
||||
} else if (field.attributes.Lookup("cpp_type")) {
|
||||
if (is_ctor) {
|
||||
if (PtrType(&field) == "naked") {
|
||||
return "nullptr";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
} else {
|
||||
return GenDefaultConstant(field);
|
||||
}
|
||||
@@ -1354,7 +1367,7 @@ class CppGenerator : public BaseGenerator {
|
||||
code_.SetValue("PARAM_VALUE", "nullptr");
|
||||
} else {
|
||||
code_.SetValue("PARAM_TYPE", GenTypeWire(field.value.type, " ", true));
|
||||
code_.SetValue("PARAM_VALUE", GetDefaultScalarValue(field));
|
||||
code_.SetValue("PARAM_VALUE", GetDefaultScalarValue(field, false));
|
||||
}
|
||||
code_ += "{{PRE}}{{PARAM_TYPE}}{{PARAM_NAME}} = {{PARAM_VALUE}}\\";
|
||||
}
|
||||
@@ -1367,9 +1380,11 @@ class CppGenerator : public BaseGenerator {
|
||||
field.value.type.element != BASE_TYPE_UTYPE)) {
|
||||
auto type = GenTypeNative(field.value.type, false, field);
|
||||
auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||
auto full_type = (cpp_type ?
|
||||
(field.value.type.base_type == BASE_TYPE_VECTOR ? "std::vector<" + cpp_type->constant + "*> " : cpp_type->constant + " *")
|
||||
: type + " ");
|
||||
auto full_type =
|
||||
(cpp_type ? (field.value.type.base_type == BASE_TYPE_VECTOR
|
||||
? "std::vector<" + GenTypeNativePtr(cpp_type->constant, &field, false) + "> "
|
||||
: GenTypeNativePtr(cpp_type->constant, &field, false))
|
||||
: type + " ");
|
||||
code_.SetValue("FIELD_TYPE", full_type);
|
||||
code_.SetValue("FIELD_NAME", Name(field));
|
||||
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}};";
|
||||
@@ -1386,14 +1401,14 @@ class CppGenerator : public BaseGenerator {
|
||||
if (!field.deprecated && // Deprecated fields won't be accessible.
|
||||
field.value.type.base_type != BASE_TYPE_UTYPE) {
|
||||
auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||
auto native_default = field.attributes.Lookup("native_default");
|
||||
// Scalar types get parsed defaults, raw pointers get nullptrs.
|
||||
if (IsScalar(field.value.type.base_type)) {
|
||||
if (!initializer_list.empty()) { initializer_list += ",\n "; }
|
||||
initializer_list += Name(field);
|
||||
initializer_list += "(" + GetDefaultScalarValue(field) + ")";
|
||||
initializer_list += "(" + (native_default ? std::string(native_default->constant) : GetDefaultScalarValue(field, true)) + ")";
|
||||
} else if (field.value.type.base_type == BASE_TYPE_STRUCT) {
|
||||
if (IsStruct(field.value.type)) {
|
||||
auto native_default = field.attributes.Lookup("native_default");
|
||||
if (native_default) {
|
||||
if (!initializer_list.empty()) {
|
||||
initializer_list += ",\n ";
|
||||
@@ -2048,12 +2063,19 @@ class CppGenerator : public BaseGenerator {
|
||||
// (*resolver)(&_o->field, (hash_value_t)(_e));
|
||||
// else
|
||||
// _o->field = nullptr;
|
||||
code += "//vector resolver, " + PtrType(&field) + "\n";
|
||||
code += "if (_resolver) ";
|
||||
code += "(*_resolver)";
|
||||
code += "(reinterpret_cast<void **>(&_o->" + name + "[_i]" + access + "), ";
|
||||
code += "static_cast<flatbuffers::hash_value_t>(" + indexing + "));";
|
||||
code += " else ";
|
||||
code += "_o->" + name + "[_i]" + access + " = nullptr";
|
||||
if (PtrType(&field) == "naked") {
|
||||
code += " else ";
|
||||
code += "_o->" + name + "[_i]" + access + " = nullptr";
|
||||
} else {
|
||||
//code += " else ";
|
||||
//code += "_o->" + name + "[_i]" + access + " = " + GenTypeNativePtr(cpp_type->constant, &field, true) + "();";
|
||||
code += "/* else do nothing */";
|
||||
}
|
||||
} else {
|
||||
code += "_o->" + name + "[_i]" + access + " = ";
|
||||
code +=
|
||||
@@ -2085,12 +2107,19 @@ class CppGenerator : public BaseGenerator {
|
||||
// (*resolver)(&_o->field, (hash_value_t)(_e));
|
||||
// else
|
||||
// _o->field = nullptr;
|
||||
code += "//scalar resolver, " + PtrType(&field) + " \n";
|
||||
code += "if (_resolver) ";
|
||||
code += "(*_resolver)";
|
||||
code += "(reinterpret_cast<void **>(&_o->" + Name(field) + "), ";
|
||||
code += "static_cast<flatbuffers::hash_value_t>(_e));";
|
||||
code += " else ";
|
||||
code += "_o->" + Name(field) + " = nullptr;";
|
||||
if (PtrType(&field) == "naked") {
|
||||
code += " else ";
|
||||
code += "_o->" + Name(field) + " = nullptr;";
|
||||
} else {
|
||||
//code += " else ";
|
||||
//code += "_o->" + Name(field) + " = " + GenTypeNativePtr(cpp_type->constant, &field, true) + "();";
|
||||
code += "/* else do nothing */;";
|
||||
}
|
||||
} else {
|
||||
// Generate code for assigning the value, of the form:
|
||||
// _o->field = value;
|
||||
@@ -2116,9 +2145,10 @@ class CppGenerator : public BaseGenerator {
|
||||
value =
|
||||
"_rehasher ? "
|
||||
"static_cast<" +
|
||||
type + ">((*_rehasher)(" + value + ")) : 0";
|
||||
type + ">((*_rehasher)(" + value + GenPtrGet(field) + ")) : 0";
|
||||
}
|
||||
|
||||
|
||||
std::string code;
|
||||
switch (field.value.type.base_type) {
|
||||
// String fields are of the form:
|
||||
@@ -2205,7 +2235,7 @@ class CppGenerator : public BaseGenerator {
|
||||
code += "[](size_t i, _VectorArgs *__va) { ";
|
||||
code += "return __va->__rehasher ? ";
|
||||
code += "static_cast<" + type + ">((*__va->__rehasher)";
|
||||
code += "(__va->_" + value + "[i]" + ")) : 0";
|
||||
code += "(__va->_" + value + "[i]" + GenPtrGet(field) + ")) : 0";
|
||||
code += "; }, &_va )";
|
||||
} else {
|
||||
code += "_fbb.CreateVector(" + value + ")";
|
||||
|
||||
Reference in New Issue
Block a user