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:
Christian Helmich
2018-03-06 01:40:56 +09:00
committed by Wouter van Oortmerssen
parent 4ea1be53d4
commit 9ce98dd77d
16 changed files with 1074 additions and 74 deletions

View File

@@ -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 + ")";