diff options
-rw-r--r-- | docs/source/CppUsage.md | 82 | ||||
-rw-r--r-- | include/flatbuffers/flatbuffers.h | 39 | ||||
-rw-r--r-- | include/flatbuffers/idl.h | 1 | ||||
-rw-r--r-- | src/idl_gen_cpp.cpp | 36 | ||||
-rw-r--r-- | tests/native_type_test.fbs | 7 | ||||
-rw-r--r-- | tests/native_type_test_generated.h | 107 | ||||
-rw-r--r-- | tests/native_type_test_impl.cpp | 8 | ||||
-rw-r--r-- | tests/native_type_test_impl.h | 5 | ||||
-rw-r--r-- | tests/test.cpp | 10 |
9 files changed, 244 insertions, 51 deletions
diff --git a/docs/source/CppUsage.md b/docs/source/CppUsage.md index 2333f482..5b3a7a8b 100644 --- a/docs/source/CppUsage.md +++ b/docs/source/CppUsage.md @@ -133,11 +133,11 @@ The following attributes are specific to the object-based API code generation: This attribute changes the member declaration to use the type directly rather than wrapped in a unique_ptr. -- `native_default`: "value" (on a field): For members that are declared +- `native_default("value")` (on a field): For members that are declared "native_inline", the value specified with this attribute will be included verbatim in the class constructor initializer list for this member. -- `native_custom_alloc`:"custom_allocator" (on a table or struct): When using the +- `native_custom_alloc("custom_allocator")` (on a table or struct): When using the object-based API all generated NativeTables that are allocated when unpacking your flatbuffer will use "custom allocator". The allocator is also used by any std::vector that appears in a table defined with `native_custom_alloc`. @@ -148,12 +148,15 @@ The following attributes are specific to the object-based API code generation: schema: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} table mytable(native_custom_alloc:"custom_allocator") { ... } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - with custom_allocator defined before flatbuffers.h is included, as: + with custom_allocator defined before `flatbuffers.h` is included, as: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} template <typename T> struct custom_allocator : public std::allocator<T> { typedef T *pointer; @@ -175,48 +178,73 @@ The following attributes are specific to the object-based API code generation: template <class U> custom_allocator(const custom_allocator<U>&) throw() {} }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- `native_type`' "type" (on a struct): In some cases, a more optimal C++ data +- `native_type("type")` (on a struct): In some cases, a more optimal C++ data type exists for a given struct. For example, the following schema: - struct Vec2 { - x: float; - y: float; - } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + struct Vec2 { + x: float; + y: float; + } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ generates the following Object-Based API class: - struct Vec2T : flatbuffers::NativeTable { - float x; - float y; - }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + struct Vec2T : flatbuffers::NativeTable { + float x; + float y; + }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ However, it can be useful to instead use a user-defined C++ type since it can provide more functionality, eg. - struct vector2 { - float x = 0, y = 0; - vector2 operator+(vector2 rhs) const { ... } - vector2 operator-(vector2 rhs) const { ... } - float length() const { ... } - // etc. - }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + struct vector2 { + float x = 0, y = 0; + vector2 operator+(vector2 rhs) const { ... } + vector2 operator-(vector2 rhs) const { ... } + float length() const { ... } + // etc. + }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The `native_type` attribute will replace the usage of the generated class with the given type. So, continuing with the example, the generated - code would use |vector2| in place of |Vec2T| for all generated code. + code would use `vector2` in place of `Vec2T` for all generated code of + the Object-Based API. - However, becuase the native_type is unknown to flatbuffers, the user must + However, because the `native_type` is unknown to flatbuffers, the user must provide the following functions to aide in the serialization process: - namespace flatbuffers { - FlatbufferStruct Pack(const native_type& obj); - native_type UnPack(const FlatbufferStruct& obj); - } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + namespace flatbuffers { + Vec2 Pack(const vector2& obj); + vector2 UnPack(const Vec2& obj); + } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- `native_type_pack_name("name")` (on a struct when `native_type` is + specified, too): when you want to use the same `native_type` multiple times + (e. g. with different precision) you must make the names of the Pack/UnPack + functions unique, otherwise you will run into compile errors. This attribute + appends a name to the expected Pack/UnPack functions. So when you + specify `native_type_pack_name("Vec2")` in the above example you now need to + implement these serialization functions instead: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + namespace flatbuffers { + Vec2 PackVec2(const vector2& obj); + vector2 UnPackVec2(const Vec2& obj); + } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Finally, the following top-level attribute +Finally, the following top-level attributes: -- `native_include`: "path" (at file level): Because the `native_type` attribute +- `native_include("path")` (at file level): Because the `native_type` attribute can be used to introduce types that are unknown to flatbuffers, it may be necessary to include "external" header files in the generated code. This attribute can be used to directly add an #include directive to the top of diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index c7fadd51..bc4255c2 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -1806,15 +1806,32 @@ class FlatBufferBuilder { /// @param[in] v A pointer to the array of type `S` to serialize into the /// buffer as a `vector`. /// @param[in] len The number of elements to serialize. + /// @param[in] pack_func Pointer to a function to convert the native struct + /// to the FlatBuffer struct. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template<typename T, typename S> + Offset<Vector<const T *>> CreateVectorOfNativeStructs( + const S *v, size_t len, T((*const pack_func)(const S &))) { + FLATBUFFERS_ASSERT(pack_func); + std::vector<T> vv(len); + std::transform(v, v + len, vv.begin(), pack_func); + return CreateVectorOfStructs<T>(data(vv), vv.size()); + } + + /// @brief Serialize an array of native structs into a FlatBuffer `vector`. + /// @tparam T The data type of the struct array elements. + /// @tparam S The data type of the native struct array elements. + /// @param[in] v A pointer to the array of type `S` to serialize into the + /// buffer as a `vector`. + /// @param[in] len The number of elements to serialize. /// @return Returns a typed `Offset` into the serialized data indicating /// where the vector is stored. template<typename T, typename S> Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v, size_t len) { extern T Pack(const S &); - std::vector<T> vv(len); - std::transform(v, v + len, vv.begin(), Pack); - return CreateVectorOfStructs<T>(data(vv), vv.size()); + return CreateVectorOfNativeStructs(v, len, Pack); } // clang-format off @@ -1877,6 +1894,22 @@ class FlatBufferBuilder { /// @tparam S The data type of the `std::vector` native struct elements. /// @param[in] v A const reference to the `std::vector` of structs to /// serialize into the buffer as a `vector`. + /// @param[in] pack_func Pointer to a function to convert the native struct + /// to the FlatBuffer struct. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template<typename T, typename S> + Offset<Vector<const T *>> CreateVectorOfNativeStructs( + const std::vector<S> &v, T((*const pack_func)(const S &))) { + return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func); + } + + /// @brief Serialize a `std::vector` of native structs into a FlatBuffer + /// `vector`. + /// @tparam T The data type of the `std::vector` struct elements. + /// @tparam S The data type of the `std::vector` native struct elements. + /// @param[in] v A const reference to the `std::vector` of structs to + /// serialize into the buffer as a `vector`. /// @return Returns a typed `Offset` into the serialized data indicating /// where the vector is stored. template<typename T, typename S> diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index ab77893a..6ae07ab2 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -809,6 +809,7 @@ class Parser : public ParserState { known_attributes_["native_inline"] = true; known_attributes_["native_custom_alloc"] = true; known_attributes_["native_type"] = true; + known_attributes_["native_type_pack_name"] = true; known_attributes_["native_default"] = true; known_attributes_["flexbuffer"] = true; known_attributes_["private"] = true; diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 5896ad61..f80af045 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -2621,9 +2621,14 @@ class CppGenerator : public BaseGenerator { } case BASE_TYPE_STRUCT: { if (IsStruct(type)) { - auto native_type = type.struct_def->attributes.Lookup("native_type"); + const auto &struct_attrs = type.struct_def->attributes; + const auto native_type = struct_attrs.Lookup("native_type"); if (native_type) { - return "flatbuffers::UnPack(*" + val + ")"; + std::string unpack_call = "flatbuffers::UnPack"; + const auto pack_name = struct_attrs.Lookup("native_type_pack_name"); + if (pack_name) { unpack_call += pack_name->constant; } + unpack_call += "(*" + val + ")"; + return unpack_call; } else if (invector || afield.native_inline) { return "*" + val; } else { @@ -2849,15 +2854,24 @@ class CppGenerator : public BaseGenerator { } case BASE_TYPE_STRUCT: { if (IsStruct(vector_type)) { - auto native_type = - field.value.type.struct_def->attributes.Lookup("native_type"); + const auto &struct_attrs = + field.value.type.struct_def->attributes; + const auto native_type = struct_attrs.Lookup("native_type"); if (native_type) { code += "_fbb.CreateVectorOfNativeStructs<"; - code += WrapInNameSpace(*vector_type.struct_def) + ">"; + code += WrapInNameSpace(*vector_type.struct_def) + ", " + + native_type->constant + ">"; + code += "(" + value; + const auto pack_name = + struct_attrs.Lookup("native_type_pack_name"); + if (pack_name) { + code += ", flatbuffers::Pack" + pack_name->constant; + } + code += ")"; } else { code += "_fbb.CreateVectorOfStructs"; + code += "(" + value + ")"; } - code += "(" + value + ")"; } else { code += "_fbb.CreateVector<flatbuffers::Offset<"; code += WrapInNameSpace(*vector_type.struct_def) + ">> "; @@ -2932,10 +2946,14 @@ class CppGenerator : public BaseGenerator { } case BASE_TYPE_STRUCT: { if (IsStruct(field.value.type)) { - auto native_type = - field.value.type.struct_def->attributes.Lookup("native_type"); + const auto &struct_attribs = field.value.type.struct_def->attributes; + const auto native_type = struct_attribs.Lookup("native_type"); if (native_type) { - code += "flatbuffers::Pack(" + value + ")"; + code += "flatbuffers::Pack"; + const auto pack_name = + struct_attribs.Lookup("native_type_pack_name"); + if (pack_name) { code += pack_name->constant; } + code += "(" + value + ")"; } else if (field.native_inline) { code += "&" + value; } else { diff --git a/tests/native_type_test.fbs b/tests/native_type_test.fbs index de80bdf9..e22150f5 100644 --- a/tests/native_type_test.fbs +++ b/tests/native_type_test.fbs @@ -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; diff --git a/tests/native_type_test_generated.h b/tests/native_type_test_generated.h index 0fa959e2..a4fbf987 100644 --- a/tests/native_type_test_generated.h +++ b/tests/native_type_test_generated.h @@ -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 *Vector3DAltTypeTable() { + static const flatbuffers::TypeCode type_codes[] = { + { 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[] = { + "a", + "b", + "c" + }; + static const flatbuffers::TypeTable tt = { + 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, 0 }, + { flatbuffers::ET_SEQUENCE, 1, 1 } }; static const flatbuffers::TypeFunction type_refs[] = { - Geometry::Vector3DTypeTable + Geometry::Vector3DTypeTable, + Geometry::Vector3DAltTypeTable }; static const char * const names[] = { - "vectors" + "vectors", + "vectors_alt" }; static const flatbuffers::TypeTable tt = { - flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, nullptr, names + flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, nullptr, names }; return &tt; } diff --git a/tests/native_type_test_impl.cpp b/tests/native_type_test_impl.cpp index edf23ebf..b5b595b8 100644 --- a/tests/native_type_test_impl.cpp +++ b/tests/native_type_test_impl.cpp @@ -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 diff --git a/tests/native_type_test_impl.h b/tests/native_type_test_impl.h index fb35e0fc..58c288a0 100644 --- a/tests/native_type_test_impl.h +++ b/tests/native_type_test_impl.h @@ -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 diff --git a/tests/test.cpp b/tests/test.cpp index 87568c2e..33bc504d 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -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); } } |