From 505ec2fb6a73e3f7f709ffb3665c72e1fe3b7eee Mon Sep 17 00:00:00 2001 From: Romain BOULLARD Date: Sat, 9 May 2026 20:48:32 +0200 Subject: [PATCH] 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 --- src/idl_gen_cpp.cpp | 23 ++++++++++++++++++----- tests/cpp_vec_type_native_type_test.fbs | 1 + tests/test.cpp | 10 ++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 67dcbf7f6..aeccb1db7 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -3855,16 +3855,20 @@ class CppGenerator : public BaseGenerator { code += ")"; } else { // 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) { - code += "_fbb.CreateVectorOfStructs64"; + code += "_fbb.CreateVectorOfStructs64" + vec_args; } else { code += "_fbb.CreateVectorOfStructs"; if (field.offset64) { // This is normal 32-bit vector, with 64-bit addressing. code += "64<::flatbuffers::Vector>"; } + code += vec_args; } - code += "(" + value + ")"; } } else { code += "_fbb.CreateVector<::flatbuffers::Offset<"; @@ -3883,7 +3887,12 @@ class CppGenerator : public BaseGenerator { break; } 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; } case BASE_TYPE_UNION: { @@ -3932,15 +3941,19 @@ class CppGenerator : public BaseGenerator { code += "; }, &_va )"; } else { // 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) { - code += "_fbb.CreateVector64(" + value + ")"; + code += "_fbb.CreateVector64" + vec_args; } else { code += "_fbb.CreateVector"; if (field.offset64) { // This is normal 32-bit vector, with 64-bit addressing. code += "64<::flatbuffers::Vector>"; } - code += "(" + value + ")"; + code += vec_args; } } break; diff --git a/tests/cpp_vec_type_native_type_test.fbs b/tests/cpp_vec_type_native_type_test.fbs index f8918fd6c..6a6065f75 100644 --- a/tests/cpp_vec_type_native_type_test.fbs +++ b/tests/cpp_vec_type_native_type_test.fbs @@ -10,6 +10,7 @@ struct Vec3 (native_type: "CppVecNativeTypeTest::Native::Vec3") { table Container { points: [Vec3] (cpp_vec_type: "CppVecNativeTypeTest::CustomVec"); + bytes: [ubyte] (cpp_vec_type: "CppVecNativeTypeTest::CustomVec"); } root_type Container; diff --git a/tests/test.cpp b/tests/test.cpp index 34dd753ad..83060de63 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -1051,12 +1051,17 @@ void CppVecTypeNativeTypeTest() { CppVecNativeTypeTest::CustomVec< CppVecNativeTypeTest::Native::Vec3>>::value, "points should be CustomVec"); + static_assert( + std::is_same>::value, + "bytes should be CustomVec"); const int N = 3; CppVecNativeTypeTest::ContainerT src; for (int i = 0; i < N; ++i) { src.points.push_back( CppVecNativeTypeTest::Native::Vec3(1.0f * i, 2.0f * i, 3.0f * i)); + src.bytes.push_back(static_cast(i * 10)); } flatbuffers::FlatBufferBuilder fbb; @@ -1071,6 +1076,11 @@ void CppVecTypeNativeTypeTest() { TEST_EQ(dst->points[i].y, 2.0f * i); TEST_EQ(dst->points[i].z, 3.0f * i); } + + TEST_EQ(dst->bytes.size(), static_cast(N)); + for (int i = 0; i < N; ++i) { + TEST_EQ(dst->bytes[i], static_cast(i * 10)); + } } // Guard against -Wunused-function on platforms without file tests.