Default Vector Support C++ (#8870)

This commit is contained in:
Derek Bailey
2025-12-19 14:32:51 -08:00
committed by GitHub
parent 8cb53ccc95
commit 57fdd4f995
12 changed files with 526 additions and 31 deletions

View File

@@ -1924,6 +1924,10 @@ class CppGenerator : public BaseGenerator {
} else {
return "0";
}
} else if (IsVector(type) && field.value.constant == "[]") {
return "0";
} else if (IsString(type) && field.value.constant != "0") {
return "0";
} else if (IsStruct(type) && (field.value.constant == "0")) {
return "nullptr";
} else {
@@ -2427,12 +2431,40 @@ class CppGenerator : public BaseGenerator {
break;
}
case BASE_TYPE_STRING: {
code_ += "{{PRE}}verifier.VerifyString({{NAME}}())\\";
if (field.value.constant != "0") {
if (field.offset64) {
code_ +=
"{{PRE}}VerifyStringWithDefault<::flatbuffers::uoffset64_t>("
"verifier, "
"{{OFFSET}})\\";
} else {
code_ += "{{PRE}}VerifyStringWithDefault(verifier, {{OFFSET}})\\";
}
} else {
code_ += "{{PRE}}verifier.VerifyString({{NAME}}())\\";
}
break;
}
case BASE_TYPE_VECTOR64:
case BASE_TYPE_VECTOR: {
code_ += "{{PRE}}verifier.VerifyVector({{NAME}}())\\";
if (field.value.constant == "[]") {
const auto& vec_type = field.value.type.VectorType();
const std::string vtype_wire = GenTypeWire(
vec_type, "", VectorElementUserFacing(vec_type), field.offset64);
std::string verify_call;
if (field.offset64) {
verify_call = "{{PRE}}VerifyVector64WithDefault<" + vtype_wire;
} else {
verify_call = "{{PRE}}VerifyVectorWithDefault<" + vtype_wire;
}
if (field.value.type.base_type == BASE_TYPE_VECTOR64) {
verify_call += ", ::flatbuffers::uoffset64_t";
}
verify_call += ">(verifier, {{OFFSET}})\\";
code_ += verify_call;
} else {
code_ += "{{PRE}}verifier.VerifyVector({{NAME}}())\\";
}
switch (field.value.type.element) {
case BASE_TYPE_STRING: {
@@ -2723,7 +2755,37 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, call));
code_.SetValue("NULLABLE_EXT", NullableExtension());
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
code_ += " return {{FIELD_VALUE}};";
if (IsVector(type) && field.value.constant == "[]") {
const auto& vec_type = type.VectorType();
const std::string vtype_wire = GenTypeWire(
vec_type, "", VectorElementUserFacing(vec_type), field.offset64);
std::string get_call;
if (field.offset64) {
get_call = " return GetVectorPointer64OrEmpty<" + vtype_wire;
} else {
get_call = " return GetVectorPointerOrEmpty<" + vtype_wire;
}
if (type.base_type == BASE_TYPE_VECTOR64) {
get_call += ", ::flatbuffers::uoffset64_t";
}
get_call += ">(" + offset_str + ");";
code_ += get_call;
} else if (IsString(type) && field.value.constant != "0") {
// TODO: Add logic to always convert the string to a valid C++ string
// literal by handling string escapes.
code_ += " auto* ptr = {{FIELD_VALUE}};";
code_ += " if (ptr) return ptr;";
code_ += " static const struct { uint32_t len; const char s[" +
NumToString(field.value.constant.length() + 1) +
"]; } bfbs_string = { " +
NumToString(field.value.constant.length()) + ", \"" +
field.value.constant + "\" };";
code_ +=
" return reinterpret_cast<const ::flatbuffers::String "
" *>(&bfbs_string);";
} else {
code_ += " return {{FIELD_VALUE}};";
}
code_ += " }";
} else {
auto wire_type = GenTypeBasic(type, false);
@@ -2910,22 +2972,43 @@ class CppGenerator : public BaseGenerator {
} else {
auto postptr = " *" + NullableExtension();
auto wire_type = GenTypeGet(type, " ", "", postptr.c_str(), true);
const std::string accessor = [&]() {
if (IsStruct(type)) {
return "GetStruct<";
}
if (field.offset64) {
return "GetPointer64<";
}
return "GetPointer<";
}();
auto underlying = accessor + wire_type + ">(" + offset_str + ")";
code_.SetValue("FIELD_TYPE", wire_type);
code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, underlying));
code_ += " {{FIELD_TYPE}}mutable_{{FIELD_NAME}}() {";
code_ += " return {{FIELD_VALUE}};";
code_ += " }";
if (IsVector(type) && field.value.constant == "[]") {
const auto& vec_type = type.VectorType();
const std::string vtype_wire = GenTypeWire(
vec_type, "", VectorElementUserFacing(vec_type), field.offset64);
code_ += " {{FIELD_TYPE}}mutable_{{FIELD_NAME}}() {";
std::string get_call;
if (field.offset64) {
get_call =
" return GetMutableVectorPointer64OrEmpty<" + vtype_wire;
} else {
get_call = " return GetMutableVectorPointerOrEmpty<" + vtype_wire;
}
if (type.base_type == BASE_TYPE_VECTOR64) {
get_call += ", ::flatbuffers::uoffset64_t";
}
get_call += ">(" + offset_str + ");";
code_ += get_call;
code_ += " }";
} else {
const std::string accessor = [&]() {
if (IsStruct(type)) {
return "GetStruct<";
}
if (field.offset64) {
return "GetPointer64<";
}
return "GetPointer<";
}();
auto underlying = accessor + wire_type + ">(" + offset_str + ")";
code_.SetValue("FIELD_VALUE",
GenUnderlyingCast(field, true, underlying));
code_ += " {{FIELD_TYPE}}mutable_{{FIELD_NAME}}() {";
code_ += " return {{FIELD_VALUE}};";
code_ += " }";
}
}
}
@@ -3305,9 +3388,17 @@ class CppGenerator : public BaseGenerator {
} else {
code_.SetValue("CREATE_STRING", "CreateSharedString");
}
code_ +=
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
"_fbb.{{CREATE_STRING}}({{FIELD_NAME}}) : 0;";
if (field->value.constant != "0") {
code_ +=
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
"_fbb.{{CREATE_STRING}}({{FIELD_NAME}}) : "
"_fbb.{{CREATE_STRING}}(\"" +
field->value.constant + "\");";
} else {
code_ +=
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
"_fbb.{{CREATE_STRING}}({{FIELD_NAME}}) : 0;";
}
} else if (IsVector(field->value.type)) {
const std::string force_align_code =
GenVectorForceAlign(*field, Name(*field) + "->size()");