mirror of
https://github.com/fraillt/bitsery.git
synced 2026-06-08 08:13:56 +00:00
release v5.0.2
This commit is contained in:
@@ -6,7 +6,7 @@ Library design:
|
||||
* `valueNb instead of value`
|
||||
* `brief syntax`
|
||||
* `serializer/deserializer functions overloads`
|
||||
* `extending library functionality`
|
||||
* [extending library functionality](design/extensions.md)
|
||||
* `errors handling`
|
||||
* `forward/backward compatibility via Growable extension`
|
||||
* [pointers](design/pointers.md)
|
||||
@@ -64,8 +64,10 @@ Output adapters (buffer and stream) functions:
|
||||
* `writeBytes`
|
||||
* `writeBuffer`
|
||||
* `flush`
|
||||
* `currentyWritePos (get/set)` (buffer adapter only)
|
||||
* `writtenBytesCount` (buffer adapter only)
|
||||
* `currentyWritePos (get/set)` (buffer adapter only) gets/sets write position in buffer, it can jump past the buffer end, in this case buffer will be resized.
|
||||
This function doesn't write any bytes.
|
||||
* `writtenBytesCount` (buffer adapter only) this doesn't necessary mean how many bytes are written, but rather how many bytes in the buffer was "affected" during serialization.
|
||||
E.g. if `currentyWritePos` (set) jumps from 0 to 100, and then 4 bytes are written, `writtenBytesCount` return 104, it also returns 104 if you jump in somewhere in the middle.
|
||||
|
||||
|
||||
Tips and tricks:
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
Extensions are at the heart of bitsery. They allow implementing all sorts of things, that requires customizing serialization and deserialization flows separately.
|
||||
Bitsery already provides a lot of useful extensions, which can be found [here](../../include/bitsery/ext).
|
||||
|
||||
Let's see what are the core components of an extension:
|
||||
|
||||
1. Extension class itself, which implements templated `serialize` and `deserialize` methods. These functions provide similar capabilities to `save` and `load` functions in other frameworks e.g. [cereal](https://uscilab.github.io/cereal/) or [boost](https://www.boost.org/doc/libs/1_71_0/libs/serialization/doc/index.html), but are more powerful because extension itself can store extension related data as well, that can be used for additional functionality.
|
||||
```cpp
|
||||
class MyExtension {
|
||||
public:
|
||||
template<typename Ser, typename T, typename Fnc>
|
||||
void serialize(Ser& ser, const T& obj, Fnc&& fnc) const {
|
||||
...
|
||||
}
|
||||
|
||||
template<typename Des, typename T, typename Fnc>
|
||||
void deserialize(Des& des, T& obj, Fnc&& fnc) const {
|
||||
...
|
||||
}
|
||||
};
|
||||
```
|
||||
2. `ExtensionTraits` specialization for an extension, which specifies how it should be used:
|
||||
```cpp
|
||||
namespace bitsery {
|
||||
namespace traits {
|
||||
template<typename T>
|
||||
struct ExtensionTraits<ext::MyExtension, T> {
|
||||
using TValue = ...;
|
||||
static constexpr bool SupportValueOverload = ...;
|
||||
static constexpr bool SupportObjectOverload = ...;
|
||||
static constexpr bool SupportLambdaOverload = ...;
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now, that we know the core components of an extension, let's see how everything fits together.
|
||||
|
||||
An Extension can be called in 3 different ways, and `Support...Overload` methods basically define, what call syntax can be used with a particular extension.
|
||||
* `SupportValueOverload` - allows to call extension by providing the size of the value type, the same as `valueNb` function. e.g. `s.ext4b(value, MyExtension{})`.
|
||||
* `SupportObjectOverload` - allows to call extension the same as simple `object` function. e.g. `s.ext(value, MyExtension{})`.
|
||||
* `SupportLambdaOverload` - allows to call extension by providing a custom lambda. e.g. `s.ext(value, MyExtension{}, [](...) { ... })`.
|
||||
|
||||
You might wonder, how there are 3 ways to call an extension, but only one signature for `serialize` and `deserialize` functions?
|
||||
|
||||
This is where a `TValue` from `ExtensionTraits` and the third parameter `Fnc` in `serialize` and `deserialize` comes in.
|
||||
|
||||
In case of lambda overload is called, the lambda is passed straight to the serialize/deserialize function as the third parameter. In theory `SupportLambdaOverload` can be any object, not necessary a callable object.
|
||||
When value overload is used, then lambda is constructed by bitsery like this `[](Serializer& s, VType &v) { s.value<VSIZE>(v); }`, where `VType` is equal to `TValue` from `ExtensionTraits`.
|
||||
Similarly, when object overload is used `[](Serializer& s, VType &v) { s.object(v); }` lambda is constructed.
|
||||
|
||||
When there is no direct mapping from object type to its underlying value type, you can disable lambda generation for value and object overload, by setting `TValue=void`, in this case, a "dummy" lambda will be provided.
|
||||
Reference in New Issue
Block a user