[C++] #6501 - Problem when mapping a native type multiple times (#6514)

* [C++] #6501 - Problem when mapping a native type multiple times
- idl.h:
added "native_type_pack_name"
- flatbuffers.h:
added CreateVectorOfNativeStructs variants which receive a pointer to the serialization function
- idl_gen_cpp.cpp:
adapted code generation in case "native_type_pack_name" attribute is present
- extended tests & docs; improved surrounding native_type docs a little

* integrated review feedback
This commit is contained in:
Michael
2021-03-18 19:01:50 +01:00
committed by GitHub
parent c992eafb5b
commit 78f0c0d1d9
9 changed files with 247 additions and 54 deletions

View File

@@ -8,8 +8,15 @@ struct Vector3D (native_type:"Native::Vector3D") {
z:float;
}
struct Vector3DAlt (native_type:"Native::Vector3D", native_type_pack_name:"Vector3DAlt") {
a:float;
b:float;
c:float;
}
table ApplicationData {
vectors:[Vector3D];
vectors_alt:[Vector3DAlt];
}
root_type ApplicationData;

View File

@@ -12,12 +12,16 @@ namespace Geometry {
struct Vector3D;
struct Vector3DAlt;
struct ApplicationData;
struct ApplicationDataBuilder;
struct ApplicationDataT;
inline const flatbuffers::TypeTable *Vector3DTypeTable();
inline const flatbuffers::TypeTable *Vector3DAltTypeTable();
inline const flatbuffers::TypeTable *ApplicationDataTypeTable();
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3D FLATBUFFERS_FINAL_CLASS {
@@ -61,9 +65,51 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3D FLATBUFFERS_FINAL_CLASS {
};
FLATBUFFERS_STRUCT_END(Vector3D, 12);
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3DAlt FLATBUFFERS_FINAL_CLASS {
private:
float a_;
float b_;
float c_;
public:
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return Vector3DAltTypeTable();
}
Vector3DAlt()
: a_(0),
b_(0),
c_(0) {
}
Vector3DAlt(float _a, float _b, float _c)
: a_(flatbuffers::EndianScalar(_a)),
b_(flatbuffers::EndianScalar(_b)),
c_(flatbuffers::EndianScalar(_c)) {
}
float a() const {
return flatbuffers::EndianScalar(a_);
}
void mutate_a(float _a) {
flatbuffers::WriteScalar(&a_, _a);
}
float b() const {
return flatbuffers::EndianScalar(b_);
}
void mutate_b(float _b) {
flatbuffers::WriteScalar(&b_, _b);
}
float c() const {
return flatbuffers::EndianScalar(c_);
}
void mutate_c(float _c) {
flatbuffers::WriteScalar(&c_, _c);
}
};
FLATBUFFERS_STRUCT_END(Vector3DAlt, 12);
struct ApplicationDataT : public flatbuffers::NativeTable {
typedef ApplicationData TableType;
std::vector<Native::Vector3D> vectors{};
std::vector<Native::Vector3D> vectors_alt{};
};
struct ApplicationData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@@ -73,7 +119,8 @@ struct ApplicationData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
return ApplicationDataTypeTable();
}
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_VECTORS = 4
VT_VECTORS = 4,
VT_VECTORS_ALT = 6
};
const flatbuffers::Vector<const Geometry::Vector3D *> *vectors() const {
return GetPointer<const flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
@@ -81,10 +128,18 @@ struct ApplicationData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
flatbuffers::Vector<const Geometry::Vector3D *> *mutable_vectors() {
return GetPointer<flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
}
const flatbuffers::Vector<const Geometry::Vector3DAlt *> *vectors_alt() const {
return GetPointer<const flatbuffers::Vector<const Geometry::Vector3DAlt *> *>(VT_VECTORS_ALT);
}
flatbuffers::Vector<const Geometry::Vector3DAlt *> *mutable_vectors_alt() {
return GetPointer<flatbuffers::Vector<const Geometry::Vector3DAlt *> *>(VT_VECTORS_ALT);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyOffset(verifier, VT_VECTORS) &&
verifier.VerifyVector(vectors()) &&
VerifyOffset(verifier, VT_VECTORS_ALT) &&
verifier.VerifyVector(vectors_alt()) &&
verifier.EndTable();
}
ApplicationDataT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
@@ -99,6 +154,9 @@ struct ApplicationDataBuilder {
void add_vectors(flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors) {
fbb_.AddOffset(ApplicationData::VT_VECTORS, vectors);
}
void add_vectors_alt(flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3DAlt *>> vectors_alt) {
fbb_.AddOffset(ApplicationData::VT_VECTORS_ALT, vectors_alt);
}
explicit ApplicationDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
@@ -112,19 +170,24 @@ struct ApplicationDataBuilder {
inline flatbuffers::Offset<ApplicationData> CreateApplicationData(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors = 0) {
flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors = 0,
flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3DAlt *>> vectors_alt = 0) {
ApplicationDataBuilder builder_(_fbb);
builder_.add_vectors_alt(vectors_alt);
builder_.add_vectors(vectors);
return builder_.Finish();
}
inline flatbuffers::Offset<ApplicationData> CreateApplicationDataDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const std::vector<Geometry::Vector3D> *vectors = nullptr) {
const std::vector<Geometry::Vector3D> *vectors = nullptr,
const std::vector<Geometry::Vector3DAlt> *vectors_alt = nullptr) {
auto vectors__ = vectors ? _fbb.CreateVectorOfStructs<Geometry::Vector3D>(*vectors) : 0;
auto vectors_alt__ = vectors_alt ? _fbb.CreateVectorOfStructs<Geometry::Vector3DAlt>(*vectors_alt) : 0;
return Geometry::CreateApplicationData(
_fbb,
vectors__);
vectors__,
vectors_alt__);
}
flatbuffers::Offset<ApplicationData> CreateApplicationData(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
@@ -139,6 +202,7 @@ inline void ApplicationData::UnPackTo(ApplicationDataT *_o, const flatbuffers::r
(void)_o;
(void)_resolver;
{ auto _e = vectors(); if (_e) { _o->vectors.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vectors[_i] = flatbuffers::UnPack(*_e->Get(_i)); } } }
{ auto _e = vectors_alt(); if (_e) { _o->vectors_alt.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vectors_alt[_i] = flatbuffers::UnPackVector3DAlt(*_e->Get(_i)); } } }
}
inline flatbuffers::Offset<ApplicationData> ApplicationData::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -149,10 +213,12 @@ inline flatbuffers::Offset<ApplicationData> CreateApplicationData(flatbuffers::F
(void)_rehasher;
(void)_o;
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ApplicationDataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _vectors = _o->vectors.size() ? _fbb.CreateVectorOfNativeStructs<Geometry::Vector3D>(_o->vectors) : 0;
auto _vectors = _o->vectors.size() ? _fbb.CreateVectorOfNativeStructs<Geometry::Vector3D, Native::Vector3D>(_o->vectors) : 0;
auto _vectors_alt = _o->vectors_alt.size() ? _fbb.CreateVectorOfNativeStructs<Geometry::Vector3DAlt, Native::Vector3D>(_o->vectors_alt, flatbuffers::PackVector3DAlt) : 0;
return Geometry::CreateApplicationData(
_fbb,
_vectors);
_vectors,
_vectors_alt);
}
inline const flatbuffers::TypeTable *Vector3DTypeTable() {
@@ -173,18 +239,39 @@ inline const flatbuffers::TypeTable *Vector3DTypeTable() {
return &tt;
}
inline const flatbuffers::TypeTable *ApplicationDataTypeTable() {
inline const flatbuffers::TypeTable *Vector3DAltTypeTable() {
static const flatbuffers::TypeCode type_codes[] = {
{ flatbuffers::ET_SEQUENCE, 1, 0 }
};
static const flatbuffers::TypeFunction type_refs[] = {
Geometry::Vector3DTypeTable
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 }
};
static const int64_t values[] = { 0, 4, 8, 12 };
static const char * const names[] = {
"vectors"
"a",
"b",
"c"
};
static const flatbuffers::TypeTable tt = {
flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, nullptr, names
flatbuffers::ST_STRUCT, 3, type_codes, nullptr, nullptr, values, names
};
return &tt;
}
inline const flatbuffers::TypeTable *ApplicationDataTypeTable() {
static const flatbuffers::TypeCode type_codes[] = {
{ flatbuffers::ET_SEQUENCE, 1, 0 },
{ flatbuffers::ET_SEQUENCE, 1, 1 }
};
static const flatbuffers::TypeFunction type_refs[] = {
Geometry::Vector3DTypeTable,
Geometry::Vector3DAltTypeTable
};
static const char * const names[] = {
"vectors",
"vectors_alt"
};
static const flatbuffers::TypeTable tt = {
flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, nullptr, names
};
return &tt;
}

View File

@@ -10,4 +10,12 @@ Geometry::Vector3D Pack(const Native::Vector3D &obj) {
const Native::Vector3D UnPack(const Geometry::Vector3D &obj) {
return Native::Vector3D(obj.x(), obj.y(), obj.z());
}
Geometry::Vector3DAlt PackVector3DAlt(const Native::Vector3D &obj) {
return Geometry::Vector3DAlt(obj.x, obj.y, obj.z);
}
const Native::Vector3D UnPackVector3DAlt(const Geometry::Vector3DAlt &obj) {
return Native::Vector3D(obj.a(), obj.b(), obj.c());
}
} // namespace flatbuffers

View File

@@ -22,11 +22,14 @@ struct Vector3D {
namespace Geometry {
struct Vector3D;
}
struct Vector3DAlt;
} // namespace Geometry
namespace flatbuffers {
Geometry::Vector3D Pack(const Native::Vector3D &obj);
const Native::Vector3D UnPack(const Geometry::Vector3D &obj);
Geometry::Vector3DAlt PackVector3DAlt(const Native::Vector3D &obj);
const Native::Vector3D UnPackVector3DAlt(const Geometry::Vector3DAlt &obj);
} // namespace flatbuffers
#endif // VECTOR3D_PACK_H

View File

@@ -3525,10 +3525,13 @@ void NativeTypeTest() {
Geometry::ApplicationDataT src_data;
src_data.vectors.reserve(N);
src_data.vectors_alt.reserve(N);
for (int i = 0; i < N; ++i) {
src_data.vectors.push_back(
Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f));
src_data.vectors_alt.push_back(
Native::Vector3D(20 * i + 0.1f, 20 * i + 0.2f, 20 * i + 0.3f));
}
flatbuffers::FlatBufferBuilder fbb;
@@ -3537,10 +3540,15 @@ void NativeTypeTest() {
auto dstDataT = Geometry::UnPackApplicationData(fbb.GetBufferPointer());
for (int i = 0; i < N; ++i) {
Native::Vector3D &v = dstDataT->vectors[i];
const Native::Vector3D &v = dstDataT->vectors[i];
TEST_EQ(v.x, 10 * i + 0.1f);
TEST_EQ(v.y, 10 * i + 0.2f);
TEST_EQ(v.z, 10 * i + 0.3f);
const Native::Vector3D &v2 = dstDataT->vectors_alt[i];
TEST_EQ(v2.x, 20 * i + 0.1f);
TEST_EQ(v2.y, 20 * i + 0.2f);
TEST_EQ(v2.z, 20 * i + 0.3f);
}
}