#include #include #include // include extensions to work with tuples and variants // these extesions only work with C++17 #if __cplusplus > 201402L #include #include // let's include this extension to make it more interesting :) #include struct MyStruct { std::vector v{}; float f{}; bool operator==(const MyStruct& rhs) const { return v == rhs.v && f == rhs.f; } }; template void serialize(S& s, MyStruct& o) { s.container4b(o.v, 1000); s.value4b(o.f); } // this will be the type that we want to serialize/deserialize using MyTuple = std::tuple; using MyVariant = std::variant; // define default serialize function for MyVariant, so that we could use // quickSerialization/Deserialization functions template void serialize(S& s, MyVariant& o) { // in order to serialize a variant, it needs to know how to do it for all // types we can do this simply by providing any callable object, that accepts // serializer and type as arguments s.ext( o, bitsery::ext::StdVariant{ // specify how to serialize tuple by creating a lambda [](S& s, MyTuple& o) { // StdTuple is used exactly the same as StdVariant s.ext( o, bitsery::ext::StdTuple{ // this is convenient callable object to specify integral value size // it is different equivalent to lambda [](auto& s, float&o) { // s.value4b(o);} bitsery::ext::OverloadValue{}, // it is not required to provide MyStruct overload, because it we // have defined 'serialize' function for it }); }, // this might also be useful if you want to overload using extension bitsery::ext::OverloadExtValue{}, // you can even go further and instead of writing lambda for MyTuple you // can as well compose the same functionality // with OverloadExtObject, like this: // (comment out MyTuple lambda, and uncomment this) // ext::OverloadExtObject>>{}, // we can also override default 'serialize' function by creating an // overloading for that type [](S& s, MyStruct& o) { s.value4b(o.f); s.container(o.v, 1000, [](S& s, int32_t& v) { s.ext4b(v, bitsery::ext::CompactValue{}); }); }, // NOTE. // it is possible to provide "auto" as type parameter // this will allow you to override all default 'serialize' functions // but in this case it will not be called, because we have explicitly // provided overloads for all variant types // also note, that first parameter (serializer) is also "auto", this is // required, so that it would be least specialized case // otherwise it will not compile if you any ext::Overload* helper defined, // because it will have ambiguous definitions // (ext::OverLoad* defines (templated_type& s, concrete_type& o) and // lambda would be (concrete_type& s, templated_type& o)) [](auto&, auto&) { assert(false); } }); } // some helper types using Buffer = std::vector; using OutputAdapter = bitsery::OutputBufferAdapter; using InputAdapter = bitsery::InputBufferAdapter; int main() { // set some random data MyVariant data{ MyTuple{ -7549, { { -451, 2, 968, 75, 4, 156, 49 }, 874.4f } } }; MyVariant res{}; // create buffer to store data Buffer buffer; // use quick serialization function, // it will use default configuration to setup all the nesessary steps // and serialize data to container auto writtenSize = bitsery::quickSerialization(buffer, data); // same as serialization, but returns deserialization state as a pair // first = error code, second = is buffer was successfully read from begin to // the end. auto state = bitsery::quickDeserialization( { buffer.begin(), writtenSize }, res); assert(state.first == bitsery::ReaderError::NoError && state.second); assert(data == res); } #else #if defined(_MSC_VER) #pragma message( \ "C++17 and /Zc:__cplusplus option is required to enable this example") #else #pragma message("C++17 is required to enable this example") #endif int main() { return 0; } #endif