Fix CreateVector/CreateVectorOfStructs for non-std vector types (cpp_vec_type)

When cpp_vec_type is set to a non-std container, Pack methods for scalar,
bool, and plain-struct vectors now use the pointer+size overloads of
CreateVector/CreateVectorOfStructs instead of the std::vector-only overloads.
Extends the combined cpp_vec_type+native_type test to also cover scalar
(ubyte) vectors with a custom container type.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-09 20:48:32 +02:00
parent 19aa2ce420
commit 505ec2fb6a
3 changed files with 29 additions and 5 deletions

View File

@@ -3855,16 +3855,20 @@ class CppGenerator : public BaseGenerator {
code += ")"; code += ")";
} else { } else {
// If the field uses 64-bit addressing, create a 64-bit vector. // If the field uses 64-bit addressing, create a 64-bit vector.
const bool is_std_vec = NativeVector(&field) == "std::vector";
const std::string vec_args =
is_std_vec ? ("(" + value + ")")
: ("(" + value + ".data(), " + value + ".size())");
if (field.value.type.base_type == BASE_TYPE_VECTOR64) { if (field.value.type.base_type == BASE_TYPE_VECTOR64) {
code += "_fbb.CreateVectorOfStructs64"; code += "_fbb.CreateVectorOfStructs64" + vec_args;
} else { } else {
code += "_fbb.CreateVectorOfStructs"; code += "_fbb.CreateVectorOfStructs";
if (field.offset64) { if (field.offset64) {
// This is normal 32-bit vector, with 64-bit addressing. // This is normal 32-bit vector, with 64-bit addressing.
code += "64<::flatbuffers::Vector>"; code += "64<::flatbuffers::Vector>";
} }
code += vec_args;
} }
code += "(" + value + ")";
} }
} else { } else {
code += "_fbb.CreateVector<::flatbuffers::Offset<"; code += "_fbb.CreateVector<::flatbuffers::Offset<";
@@ -3883,7 +3887,12 @@ class CppGenerator : public BaseGenerator {
break; break;
} }
case BASE_TYPE_BOOL: { case BASE_TYPE_BOOL: {
code += "_fbb.CreateVector(" + value + ")"; if (NativeVector(&field) == "std::vector") {
code += "_fbb.CreateVector(" + value + ")";
} else {
code += "_fbb.CreateVector(" + value + ".data(), " + value +
".size())";
}
break; break;
} }
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
@@ -3932,15 +3941,19 @@ class CppGenerator : public BaseGenerator {
code += "; }, &_va )"; code += "; }, &_va )";
} else { } else {
// If the field uses 64-bit addressing, create a 64-bit vector. // If the field uses 64-bit addressing, create a 64-bit vector.
const bool is_std_vec = NativeVector(&field) == "std::vector";
const std::string vec_args =
is_std_vec ? ("(" + value + ")")
: ("(" + value + ".data(), " + value + ".size())");
if (field.value.type.base_type == BASE_TYPE_VECTOR64) { if (field.value.type.base_type == BASE_TYPE_VECTOR64) {
code += "_fbb.CreateVector64(" + value + ")"; code += "_fbb.CreateVector64" + vec_args;
} else { } else {
code += "_fbb.CreateVector"; code += "_fbb.CreateVector";
if (field.offset64) { if (field.offset64) {
// This is normal 32-bit vector, with 64-bit addressing. // This is normal 32-bit vector, with 64-bit addressing.
code += "64<::flatbuffers::Vector>"; code += "64<::flatbuffers::Vector>";
} }
code += "(" + value + ")"; code += vec_args;
} }
} }
break; break;

View File

@@ -10,6 +10,7 @@ struct Vec3 (native_type: "CppVecNativeTypeTest::Native::Vec3") {
table Container { table Container {
points: [Vec3] (cpp_vec_type: "CppVecNativeTypeTest::CustomVec"); points: [Vec3] (cpp_vec_type: "CppVecNativeTypeTest::CustomVec");
bytes: [ubyte] (cpp_vec_type: "CppVecNativeTypeTest::CustomVec");
} }
root_type Container; root_type Container;

View File

@@ -1051,12 +1051,17 @@ void CppVecTypeNativeTypeTest() {
CppVecNativeTypeTest::CustomVec< CppVecNativeTypeTest::CustomVec<
CppVecNativeTypeTest::Native::Vec3>>::value, CppVecNativeTypeTest::Native::Vec3>>::value,
"points should be CustomVec<Native::Vec3>"); "points should be CustomVec<Native::Vec3>");
static_assert(
std::is_same<decltype(CppVecNativeTypeTest::ContainerT{}.bytes),
CppVecNativeTypeTest::CustomVec<uint8_t>>::value,
"bytes should be CustomVec<uint8_t>");
const int N = 3; const int N = 3;
CppVecNativeTypeTest::ContainerT src; CppVecNativeTypeTest::ContainerT src;
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
src.points.push_back( src.points.push_back(
CppVecNativeTypeTest::Native::Vec3(1.0f * i, 2.0f * i, 3.0f * i)); CppVecNativeTypeTest::Native::Vec3(1.0f * i, 2.0f * i, 3.0f * i));
src.bytes.push_back(static_cast<uint8_t>(i * 10));
} }
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
@@ -1071,6 +1076,11 @@ void CppVecTypeNativeTypeTest() {
TEST_EQ(dst->points[i].y, 2.0f * i); TEST_EQ(dst->points[i].y, 2.0f * i);
TEST_EQ(dst->points[i].z, 3.0f * i); TEST_EQ(dst->points[i].z, 3.0f * i);
} }
TEST_EQ(dst->bytes.size(), static_cast<size_t>(N));
for (int i = 0; i < N; ++i) {
TEST_EQ(dst->bytes[i], static_cast<uint8_t>(i * 10));
}
} }
// Guard against -Wunused-function on platforms without file tests. // Guard against -Wunused-function on platforms without file tests.