Support native_type for tables when using the C++ object API. (#8668)

* Support native_type for tables when using the C++ object API.

If native_type is specified on a table:
- No object API struct type is generated.
- The object API refers to the table by its native_type.
- UnPack and Create<TableName> methods are declared but not defined; as they
  must be user-provided.

* Add tests for native_type on tables.

* Add documentation for native_type on tables.
This commit is contained in:
cosmith-nvidia
2025-11-05 07:50:10 -08:00
committed by GitHub
parent 4173b84d4b
commit 599847236c
7 changed files with 251 additions and 153 deletions

View File

@@ -14,8 +14,7 @@ struct Vector3DAlt (native_type:"Native::Vector3D", native_type_pack_name:"Vecto
c:float;
}
// table Matrix (native_type:"Native::Matrix") {
table Matrix {
table Matrix (native_type:"Native::Matrix") {
rows:int32;
columns:int32;
values:[float];

View File

@@ -23,14 +23,11 @@ struct Vector3DAlt;
struct Matrix;
struct MatrixBuilder;
struct MatrixT;
struct ApplicationData;
struct ApplicationDataBuilder;
struct ApplicationDataT;
bool operator==(const MatrixT &lhs, const MatrixT &rhs);
bool operator!=(const MatrixT &lhs, const MatrixT &rhs);
bool operator==(const ApplicationDataT &lhs, const ApplicationDataT &rhs);
bool operator!=(const ApplicationDataT &lhs, const ApplicationDataT &rhs);
@@ -124,15 +121,8 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3DAlt FLATBUFFERS_FINAL_CLASS {
};
FLATBUFFERS_STRUCT_END(Vector3DAlt, 12);
struct MatrixT : public ::flatbuffers::NativeTable {
typedef Matrix TableType;
int32_t rows = 0;
int32_t columns = 0;
std::vector<float> values{};
};
struct Matrix FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef MatrixT NativeTableType;
typedef Native::Matrix NativeTableType;
typedef MatrixBuilder Builder;
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
return MatrixTypeTable();
@@ -168,9 +158,9 @@ struct Matrix FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
verifier.VerifyVector(values()) &&
verifier.EndTable();
}
MatrixT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(MatrixT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
static ::flatbuffers::Offset<Matrix> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const MatrixT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
Native::Matrix *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(Native::Matrix *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
static ::flatbuffers::Offset<Matrix> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const Native::Matrix* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct MatrixBuilder {
@@ -222,7 +212,7 @@ inline ::flatbuffers::Offset<Matrix> CreateMatrixDirect(
values__);
}
::flatbuffers::Offset<Matrix> CreateMatrix(::flatbuffers::FlatBufferBuilder &_fbb, const MatrixT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
::flatbuffers::Offset<Matrix> CreateMatrix(::flatbuffers::FlatBufferBuilder &_fbb, const Native::Matrix *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
struct ApplicationDataT : public ::flatbuffers::NativeTable {
typedef ApplicationData TableType;
@@ -230,8 +220,8 @@ struct ApplicationDataT : public ::flatbuffers::NativeTable {
std::vector<Native::Vector3D> vectors_alt{};
std::unique_ptr<Native::Vector3D> position{};
Native::Vector3D position_inline{};
std::unique_ptr<Geometry::MatrixT> matrix{};
std::vector<std::unique_ptr<Geometry::MatrixT>> matrices{};
std::unique_ptr<Native::Matrix> matrix{};
std::vector<std::unique_ptr<Native::Matrix>> matrices{};
ApplicationDataT() = default;
ApplicationDataT(const ApplicationDataT &o);
ApplicationDataT(ApplicationDataT&&) FLATBUFFERS_NOEXCEPT = default;
@@ -382,51 +372,16 @@ inline ::flatbuffers::Offset<ApplicationData> CreateApplicationDataDirect(
::flatbuffers::Offset<ApplicationData> CreateApplicationData(::flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline bool operator==(const MatrixT &lhs, const MatrixT &rhs) {
return
(lhs.rows == rhs.rows) &&
(lhs.columns == rhs.columns) &&
(lhs.values == rhs.values);
}
inline bool operator!=(const MatrixT &lhs, const MatrixT &rhs) {
return !(lhs == rhs);
}
inline MatrixT *Matrix::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::unique_ptr<MatrixT>(new MatrixT());
inline Native::Matrix *Matrix::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::unique_ptr<Native::Matrix>(new Native::Matrix());
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void Matrix::UnPackTo(MatrixT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = rows(); _o->rows = _e; }
{ auto _e = columns(); _o->columns = _e; }
{ auto _e = values(); if (_e) { _o->values.resize(_e->size()); for (::flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->values[_i] = _e->Get(_i); } } else { _o->values.resize(0); } }
}
inline ::flatbuffers::Offset<Matrix> CreateMatrix(::flatbuffers::FlatBufferBuilder &_fbb, const MatrixT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
inline ::flatbuffers::Offset<Matrix> CreateMatrix(::flatbuffers::FlatBufferBuilder &_fbb, const Native::Matrix *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
return Matrix::Pack(_fbb, _o, _rehasher);
}
inline ::flatbuffers::Offset<Matrix> Matrix::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const MatrixT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const MatrixT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _rows = _o->rows;
auto _columns = _o->columns;
auto _values = _o->values.size() ? _fbb.CreateVector(_o->values) : 0;
return Geometry::CreateMatrix(
_fbb,
_rows,
_columns,
_values);
}
inline bool operator==(const ApplicationDataT &lhs, const ApplicationDataT &rhs) {
return
@@ -435,7 +390,7 @@ inline bool operator==(const ApplicationDataT &lhs, const ApplicationDataT &rhs)
((lhs.position == rhs.position) || (lhs.position && rhs.position && *lhs.position == *rhs.position)) &&
(lhs.position_inline == rhs.position_inline) &&
((lhs.matrix == rhs.matrix) || (lhs.matrix && rhs.matrix && *lhs.matrix == *rhs.matrix)) &&
(lhs.matrices.size() == rhs.matrices.size() && std::equal(lhs.matrices.cbegin(), lhs.matrices.cend(), rhs.matrices.cbegin(), [](std::unique_ptr<Geometry::MatrixT> const &a, std::unique_ptr<Geometry::MatrixT> const &b) { return (a == b) || (a && b && *a == *b); }));
(lhs.matrices.size() == rhs.matrices.size() && std::equal(lhs.matrices.cbegin(), lhs.matrices.cend(), rhs.matrices.cbegin(), [](std::unique_ptr<Native::Matrix> const &a, std::unique_ptr<Native::Matrix> const &b) { return (a == b) || (a && b && *a == *b); }));
}
inline bool operator!=(const ApplicationDataT &lhs, const ApplicationDataT &rhs) {
@@ -448,9 +403,9 @@ inline ApplicationDataT::ApplicationDataT(const ApplicationDataT &o)
vectors_alt(o.vectors_alt),
position((o.position) ? new Native::Vector3D(*o.position) : nullptr),
position_inline(o.position_inline),
matrix((o.matrix) ? new Geometry::MatrixT(*o.matrix) : nullptr) {
matrix((o.matrix) ? new Native::Matrix(*o.matrix) : nullptr) {
matrices.reserve(o.matrices.size());
for (const auto &matrices_ : o.matrices) { matrices.emplace_back((matrices_) ? new Geometry::MatrixT(*matrices_) : nullptr); }
for (const auto &matrices_ : o.matrices) { matrices.emplace_back((matrices_) ? new Native::Matrix(*matrices_) : nullptr); }
}
inline ApplicationDataT &ApplicationDataT::operator=(ApplicationDataT o) FLATBUFFERS_NOEXCEPT {
@@ -476,8 +431,8 @@ inline void ApplicationData::UnPackTo(ApplicationDataT *_o, const ::flatbuffers:
{ 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)); } } else { _o->vectors_alt.resize(0); } }
{ auto _e = position(); if (_e) _o->position = std::unique_ptr<Native::Vector3D>(new Native::Vector3D(::flatbuffers::UnPack(*_e))); }
{ auto _e = position_inline(); if (_e) _o->position_inline = ::flatbuffers::UnPack(*_e); }
{ auto _e = matrix(); if (_e) { if(_o->matrix) { _e->UnPackTo(_o->matrix.get(), _resolver); } else { _o->matrix = std::unique_ptr<Geometry::MatrixT>(_e->UnPack(_resolver)); } } else if (_o->matrix) { _o->matrix.reset(); } }
{ auto _e = matrices(); if (_e) { _o->matrices.resize(_e->size()); for (::flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->matrices[_i]) { _e->Get(_i)->UnPackTo(_o->matrices[_i].get(), _resolver); } else { _o->matrices[_i] = std::unique_ptr<Geometry::MatrixT>(_e->Get(_i)->UnPack(_resolver)); } } } else { _o->matrices.resize(0); } }
{ auto _e = matrix(); if (_e) { if(_o->matrix) { _e->UnPackTo(_o->matrix.get(), _resolver); } else { _o->matrix = std::unique_ptr<Native::Matrix>(_e->UnPack(_resolver)); } } else if (_o->matrix) { _o->matrix.reset(); } }
{ auto _e = matrices(); if (_e) { _o->matrices.resize(_e->size()); for (::flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->matrices[_i]) { _e->Get(_i)->UnPackTo(_o->matrices[_i].get(), _resolver); } else { _o->matrices[_i] = std::unique_ptr<Native::Matrix>(_e->Get(_i)->UnPack(_resolver)); } } } else { _o->matrices.resize(0); } }
}
inline ::flatbuffers::Offset<ApplicationData> CreateApplicationData(::flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {

View File

@@ -19,3 +19,34 @@ const Native::Vector3D UnPackVector3DAlt(const Geometry::Vector3DAlt& obj) {
return Native::Vector3D(obj.a(), obj.b(), obj.c());
}
} // namespace flatbuffers
namespace Geometry {
void Matrix::UnPackTo(
Native::Matrix *_o,
const ::flatbuffers::resolver_function_t *_resolver) const {
(void)_resolver;
auto _rows = rows();
if (_rows) { _o->rows = _rows; }
auto _columns = columns();
if (_columns) { _o->columns = _columns; }
auto _values = values();
if (_values) {
_o->values.resize(_values->size());
for (::flatbuffers::uoffset_t i = 0; i < _values->size(); i++) {
_o->values[i] = _values->Get(i);
}
}
}
::flatbuffers::Offset<Matrix> Matrix::Pack(
::flatbuffers::FlatBufferBuilder &_fbb, const Native::Matrix *_o,
const ::flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
return CreateMatrix(_fbb, _o->rows, _o->columns,
_fbb.CreateVector<float>(_o->values));
}
} // namespace Geometry

View File

@@ -1,6 +1,8 @@
#ifndef NATIVE_TYPE_TEST_IMPL_H
#define NATIVE_TYPE_TEST_IMPL_H
#include <vector>
namespace Native {
struct Vector3D {
float x;
@@ -22,6 +24,25 @@ struct Vector3D {
return (x == other.x) && (y == other.y) && (z == other.z);
}
};
struct Matrix {
int rows;
int columns;
std::vector<float> values;
Matrix() : Matrix(0, 0) {}
Matrix(int _rows, int _columns) {
this->rows = _rows;
this->columns = _columns;
values.resize(_rows * _columns);
}
bool operator==(const Matrix &other) const {
return (rows == other.rows) && (columns == other.columns) &&
(values == other.values);
}
};
} // namespace Native
namespace Geometry {

View File

@@ -920,6 +920,15 @@ void NativeTypeTest() {
Native::Vector3D(20 * i + 0.1f, 20 * i + 0.2f, 20 * i + 0.3f));
}
src_data.matrix = std::make_unique<Native::Matrix>(1, 2);
src_data.matrix->values = {3, 4};
for (int i = 0; i < N; ++i) {
src_data.matrices.push_back(std::make_unique<Native::Matrix>(1, i));
std::fill(src_data.matrices[i]->values.begin(),
src_data.matrices[i]->values.end(), i + 0.5f);
}
flatbuffers::FlatBufferBuilder fbb;
fbb.Finish(Geometry::ApplicationData::Pack(fbb, &src_data));
@@ -943,6 +952,20 @@ void NativeTypeTest() {
TEST_EQ(v2.y, 20 * i + 0.2f);
TEST_EQ(v2.z, 20 * i + 0.3f);
}
TEST_EQ(dstDataT->matrix->rows, 1);
TEST_EQ(dstDataT->matrix->columns, 2);
TEST_EQ(dstDataT->matrix->values[0], 3);
TEST_EQ(dstDataT->matrix->values[1], 4);
for (int i = 0; i < N; ++i) {
const Native::Matrix &m = *dstDataT->matrices[i];
TEST_EQ(m.rows, 1);
TEST_EQ(m.columns, i);
for (int j = 0; j < i; ++j) {
TEST_EQ(m.values[j], i + 0.5f);
}
}
}
// Guard against -Wunused-function on platforms without file tests.