[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

@@ -1800,6 +1800,25 @@ class FlatBufferBuilder {
return Offset<Vector<const T *>>(EndVector(len));
}
/// @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.
/// @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.
@@ -1812,9 +1831,7 @@ class FlatBufferBuilder {
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
@@ -1871,6 +1888,22 @@ class FlatBufferBuilder {
return CreateVectorOfStructs(data(v), v.size());
}
/// @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`.
/// @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.

View File

@@ -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;