mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-02 04:04:19 +00:00
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:
@@ -242,6 +242,41 @@ provide the following functions to aide in the serialization process:
|
||||
}
|
||||
```
|
||||
|
||||
- `native_type("type")` (on a table): Tables can also be represented with
|
||||
native types. For example, the following schema:
|
||||
|
||||
```cpp
|
||||
table Matrix (native_type: "NativeMatrix") {
|
||||
rows: int32;
|
||||
columns: int32;
|
||||
values: [float];
|
||||
}
|
||||
```
|
||||
|
||||
Would be represented by a user-defined C++ class:
|
||||
|
||||
```cpp
|
||||
class NativeMatrix { ... }
|
||||
```
|
||||
|
||||
In this case, the following function declarations are generated by the compiler.
|
||||
The user must provide and link the matching function definitions:
|
||||
|
||||
```cpp
|
||||
struct Matrix FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
// ...
|
||||
|
||||
static ::flatbuffers::Offset<Matrix> Pack(
|
||||
::flatbuffers::FlatBufferBuilder& _fbb,
|
||||
const NativeMatrix* _o,
|
||||
const ::flatbuffers::rehasher_function_t* _rehasher = nullptr);
|
||||
|
||||
void UnPackTo(
|
||||
NativeMatrix* _o,
|
||||
const ::flatbuffers::resolver_function_t* _resolver = nullptr) const;
|
||||
}
|
||||
```
|
||||
|
||||
Finally, the following top-level attributes:
|
||||
|
||||
- `native_include("path")` (at file level): Because the `native_type` attribute
|
||||
|
||||
@@ -501,7 +501,10 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
if (!struct_def->fixed) {
|
||||
// Don't declare a new object API struct type if the table is a
|
||||
// native type.
|
||||
const auto native_type = struct_def->attributes.Lookup("native_type");
|
||||
if (!struct_def->fixed && !native_type) {
|
||||
code_ += "struct " + nativeName + ";";
|
||||
}
|
||||
}
|
||||
@@ -886,12 +889,23 @@ class CppGenerator : public BaseGenerator {
|
||||
|
||||
static std::string NativeName(const std::string& name, const StructDef* sd,
|
||||
const IDLOptions& opts) {
|
||||
// If the table is a native_type, return the native_type name.
|
||||
const auto native_type = sd->attributes.Lookup("native_type");
|
||||
if (native_type && !sd->fixed) {
|
||||
return native_type->constant;
|
||||
}
|
||||
|
||||
return sd && !sd->fixed ? opts.object_prefix + name + opts.object_suffix
|
||||
: name;
|
||||
}
|
||||
|
||||
std::string WrapNativeNameInNameSpace(const StructDef& struct_def,
|
||||
const IDLOptions& opts) {
|
||||
// If the table is a native_type, return the native_type name.
|
||||
const auto native_type = struct_def.attributes.Lookup("native_type");
|
||||
if (native_type && !struct_def.fixed) {
|
||||
return native_type->constant;
|
||||
}
|
||||
return WrapInNameSpace(struct_def.defined_namespace,
|
||||
NativeName(Name(struct_def), &struct_def, opts));
|
||||
}
|
||||
@@ -2883,7 +2897,9 @@ class CppGenerator : public BaseGenerator {
|
||||
|
||||
// Generate an accessor struct, builder structs & function for a table.
|
||||
void GenTable(const StructDef& struct_def) {
|
||||
if (opts_.generate_object_based_api) {
|
||||
// Don't generate an object API struct for the table if it is a native type.
|
||||
const auto native_type = struct_def.attributes.Lookup("native_type");
|
||||
if (opts_.generate_object_based_api && !native_type) {
|
||||
GenNativeTable(struct_def);
|
||||
}
|
||||
|
||||
@@ -2891,6 +2907,8 @@ class CppGenerator : public BaseGenerator {
|
||||
// type name() const { return GetField<type>(offset, defaultval); }
|
||||
GenComment(struct_def.doc_comment);
|
||||
|
||||
const auto native_name = NativeName(Name(struct_def), &struct_def, opts_);
|
||||
code_.SetValue("NATIVE_NAME", native_name);
|
||||
code_.SetValue("STRUCT_NAME", Name(struct_def));
|
||||
code_ +=
|
||||
"struct {{STRUCT_NAME}} FLATBUFFERS_FINAL_CLASS"
|
||||
@@ -3766,7 +3784,9 @@ class CppGenerator : public BaseGenerator {
|
||||
|
||||
// Generate code for tables that needs to come after the regular definition.
|
||||
void GenTablePost(const StructDef& struct_def) {
|
||||
if (opts_.generate_object_based_api) {
|
||||
// Don't generate an object API struct for the table if it is a native type.
|
||||
const auto native_type = struct_def.attributes.Lookup("native_type");
|
||||
if (opts_.generate_object_based_api && !native_type) {
|
||||
GenNativeTablePost(struct_def);
|
||||
}
|
||||
|
||||
@@ -3776,7 +3796,9 @@ class CppGenerator : public BaseGenerator {
|
||||
|
||||
if (opts_.generate_object_based_api) {
|
||||
// Generate the >= C++11 copy ctor and assignment operator definitions.
|
||||
GenCopyCtorAssignOpDefs(struct_def);
|
||||
if (!native_type) {
|
||||
GenCopyCtorAssignOpDefs(struct_def);
|
||||
}
|
||||
|
||||
// Generate the X::UnPack() method.
|
||||
code_ +=
|
||||
@@ -3799,33 +3821,38 @@ class CppGenerator : public BaseGenerator {
|
||||
code_ += " return _o.release();";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
code_ +=
|
||||
"inline " + TableUnPackToSignature(struct_def, false, opts_) + " {";
|
||||
code_ += " (void)_o;";
|
||||
code_ += " (void)_resolver;";
|
||||
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
const auto& field = **it;
|
||||
if (field.deprecated) {
|
||||
continue;
|
||||
// Generate an Unpack method for the C++ object if that table does not
|
||||
// have a native type.
|
||||
if (!native_type) {
|
||||
code_ +=
|
||||
"inline " + TableUnPackToSignature(struct_def, false, opts_) + " {";
|
||||
code_ += " (void)_o;";
|
||||
code_ += " (void)_resolver;";
|
||||
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
const auto& field = **it;
|
||||
if (field.deprecated) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Assign a value from |this| to |_o|. Values from |this| are stored
|
||||
// in a variable |_e| by calling this->field_type(). The value is
|
||||
// then assigned to |_o| using the GenUnpackFieldStatement.
|
||||
const bool is_union = field.value.type.base_type == BASE_TYPE_UTYPE;
|
||||
const auto statement =
|
||||
GenUnpackFieldStatement(field, is_union ? *(it + 1) : nullptr);
|
||||
|
||||
code_.SetValue("FIELD_NAME", Name(field));
|
||||
auto prefix = " { auto _e = {{FIELD_NAME}}(); ";
|
||||
auto check = IsScalar(field.value.type.base_type) ? "" : "if (_e) ";
|
||||
auto postfix = " }";
|
||||
code_ += std::string(prefix) + check + statement + postfix;
|
||||
}
|
||||
|
||||
// Assign a value from |this| to |_o|. Values from |this| are stored
|
||||
// in a variable |_e| by calling this->field_type(). The value is then
|
||||
// assigned to |_o| using the GenUnpackFieldStatement.
|
||||
const bool is_union = field.value.type.base_type == BASE_TYPE_UTYPE;
|
||||
const auto statement =
|
||||
GenUnpackFieldStatement(field, is_union ? *(it + 1) : nullptr);
|
||||
|
||||
code_.SetValue("FIELD_NAME", Name(field));
|
||||
auto prefix = " { auto _e = {{FIELD_NAME}}(); ";
|
||||
auto check = IsScalar(field.value.type.base_type) ? "" : "if (_e) ";
|
||||
auto postfix = " }";
|
||||
code_ += std::string(prefix) + check + statement + postfix;
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
}
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
|
||||
// Generate the global CreateX function that simply calls the
|
||||
// X::Pack member function.
|
||||
@@ -3835,78 +3862,85 @@ class CppGenerator : public BaseGenerator {
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
|
||||
// Generate a CreateX method that works with an unpacked C++ object.
|
||||
code_ += "inline " + TablePackSignature(struct_def, false, opts_) + " {";
|
||||
code_ += " (void)_rehasher;";
|
||||
code_ += " (void)_o;";
|
||||
if (!native_type) {
|
||||
// Generate a Pack method that works with an unpacked C++ object if it
|
||||
// does not have a native type.
|
||||
code_ +=
|
||||
"inline " + TablePackSignature(struct_def, false, opts_) + " {";
|
||||
code_ += " (void)_rehasher;";
|
||||
code_ += " (void)_o;";
|
||||
|
||||
code_ +=
|
||||
" struct _VectorArgs "
|
||||
"{ " +
|
||||
GetBuilder() +
|
||||
" *__fbb; "
|
||||
"const " +
|
||||
NativeName(Name(struct_def), &struct_def, opts_) +
|
||||
"* __o; "
|
||||
"const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { "
|
||||
"&_fbb, _o, _rehasher}; (void)_va;";
|
||||
code_ +=
|
||||
" struct _VectorArgs "
|
||||
"{ " +
|
||||
GetBuilder() +
|
||||
" *__fbb; "
|
||||
"const " +
|
||||
NativeName(Name(struct_def), &struct_def, opts_) +
|
||||
"* __o; "
|
||||
"const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { "
|
||||
"&_fbb, _o, _rehasher}; (void)_va;";
|
||||
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto& field = **it;
|
||||
if (field.deprecated) {
|
||||
continue;
|
||||
}
|
||||
if (IsVector(field.value.type)) {
|
||||
const std::string force_align_code =
|
||||
GenVectorForceAlign(field, "_o->" + Name(field) + ".size()");
|
||||
if (!force_align_code.empty()) {
|
||||
code_ += " " + force_align_code;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto& field = **it;
|
||||
if (field.deprecated) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
code_ += " auto _" + Name(field) + " = " + GenCreateParam(field) + ";";
|
||||
}
|
||||
// Need to call "Create" with the struct namespace.
|
||||
const auto qualified_create_name =
|
||||
struct_def.defined_namespace->GetFullyQualifiedName("Create");
|
||||
code_.SetValue("CREATE_NAME", TranslateNameSpace(qualified_create_name));
|
||||
|
||||
code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}(";
|
||||
code_ += " _fbb\\";
|
||||
for (const auto& field : struct_def.fields.vec) {
|
||||
if (field->deprecated) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool pass_by_address = false;
|
||||
bool check_ptr = false;
|
||||
if (field->value.type.base_type == BASE_TYPE_STRUCT) {
|
||||
if (IsStruct(field->value.type)) {
|
||||
auto native_type =
|
||||
field->value.type.struct_def->attributes.Lookup("native_type");
|
||||
auto native_inline = field->attributes.Lookup("native_inline");
|
||||
if (native_type) {
|
||||
pass_by_address = true;
|
||||
}
|
||||
if (native_type && !native_inline) {
|
||||
check_ptr = true;
|
||||
if (IsVector(field.value.type)) {
|
||||
const std::string force_align_code =
|
||||
GenVectorForceAlign(field, "_o->" + Name(field) + ".size()");
|
||||
if (!force_align_code.empty()) {
|
||||
code_ += " " + force_align_code;
|
||||
}
|
||||
}
|
||||
code_ +=
|
||||
" auto _" + Name(field) + " = " + GenCreateParam(field) + ";";
|
||||
}
|
||||
// Need to call "Create" with the struct namespace.
|
||||
const auto qualified_create_name =
|
||||
struct_def.defined_namespace->GetFullyQualifiedName("Create");
|
||||
code_.SetValue("CREATE_NAME",
|
||||
TranslateNameSpace(qualified_create_name));
|
||||
|
||||
// Call the CreateX function using values from |_o|.
|
||||
if (pass_by_address && check_ptr) {
|
||||
code_ += ",\n _o->" + Name(*field) + " ? &_" + Name(*field) +
|
||||
" : nullptr\\";
|
||||
} else if (pass_by_address) {
|
||||
code_ += ",\n &_" + Name(*field) + "\\";
|
||||
} else {
|
||||
code_ += ",\n _" + Name(*field) + "\\";
|
||||
code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}(";
|
||||
code_ += " _fbb\\";
|
||||
for (const auto& field : struct_def.fields.vec) {
|
||||
if (field->deprecated) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool pass_by_address = false;
|
||||
bool check_ptr = false;
|
||||
if (field->value.type.base_type == BASE_TYPE_STRUCT) {
|
||||
if (IsStruct(field->value.type)) {
|
||||
auto native_type =
|
||||
field->value.type.struct_def->attributes.Lookup(
|
||||
"native_type");
|
||||
auto native_inline = field->attributes.Lookup("native_inline");
|
||||
if (native_type) {
|
||||
pass_by_address = true;
|
||||
}
|
||||
if (native_type && !native_inline) {
|
||||
check_ptr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the CreateX function using values from |_o|.
|
||||
if (pass_by_address && check_ptr) {
|
||||
code_ += ",\n _o->" + Name(*field) + " ? &_" + Name(*field) +
|
||||
" : nullptr\\";
|
||||
} else if (pass_by_address) {
|
||||
code_ += ",\n &_" + Name(*field) + "\\";
|
||||
} else {
|
||||
code_ += ",\n _" + Name(*field) + "\\";
|
||||
}
|
||||
}
|
||||
code_ += ");";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
}
|
||||
code_ += ");";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user