diff options
author | Michael <7428276+Urmeli0815@users.noreply.github.com> | 2021-03-18 19:01:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-18 11:01:50 -0700 |
commit | 78f0c0d1d96a220163a03174d3240864a6a139da (patch) | |
tree | b77938a288487e20af8e0279e7cdf11d33313d00 /docs | |
parent | c992eafb5b50f1aab9d7863864a0a49fe278836e (diff) | |
download | flatbuffers-78f0c0d1d96a220163a03174d3240864a6a139da.tar.gz flatbuffers-78f0c0d1d96a220163a03174d3240864a6a139da.tar.bz2 flatbuffers-78f0c0d1d96a220163a03174d3240864a6a139da.zip |
[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
Diffstat (limited to 'docs')
-rw-r--r-- | docs/source/CppUsage.md | 82 |
1 files changed, 55 insertions, 27 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 |