// // this example covers all the corner cases that can happen using inheritance // in reality virtual inherintance is usually avoided, so your code would look // much simpler. // #include #include #include // include inheritance extension // this header contains two extensions, that specifies inheritance type of base // class // BaseClass - normal inheritance // VirtualBaseClass - when virtual inheritance is used // in order for virtual inheritance to work, InheritanceContext is required. for // normal inheritance it is not required #include using bitsery::ext::BaseClass; using bitsery::ext::VirtualBaseClass; struct Base { uint8_t x{}; // Base doesn't have to be polymorphic class, inheritance works at // compile-time. }; template void serialize(S& s, Base& o) { s.value1b(o.x); } struct Derive1 : virtual Base { // virtually inherits from base uint8_t y1{}; }; template void serialize(S& s, Derive1& o) { // define virtual inheritance, it will not compile if InheritanceContext is // not defined in serializer/deserializer s.ext(o, VirtualBaseClass{}); s.value1b(o.y1); } // to make it more interesting, serialize private member struct Derived2 : virtual Base { explicit Derived2(uint8_t y) : y2{ y } { } uint8_t getY2() const { return y2; }; private: friend bitsery::Access; uint8_t y2{}; template void serialize(S& s) { // notice virtual inheritance s.ext(*this, VirtualBaseClass{}); s.value1b(y2); } }; struct MultipleInheritance : Derive1 , Derived2 { explicit MultipleInheritance(uint8_t y2) : Derived2{ y2 } { } uint8_t z{}; }; template void serialize(S& s, MultipleInheritance& o) { // has two bases, serialize them separately s.ext(o, BaseClass{}); s.ext(o, BaseClass{}); s.value1b(o.z); } namespace bitsery { // call to serialize function with Derived2 and MultipleInheritance is // ambiguous, it matches two serialize functions: Base classes non-member fnc // and Derived2 member fnc we need explicitly select which function to use template<> struct SelectSerializeFnc : UseMemberFnc {}; // multiple inheritance has non-member serialize function defined template<> struct SelectSerializeFnc : UseNonMemberFnc {}; } // some helper types using Buffer = std::vector; using Writer = bitsery::OutputBufferAdapter; using Reader = bitsery::InputBufferAdapter; int main() { MultipleInheritance data{ 98 }; data.x = 254; data.y1 = 47; data.z = 1; Buffer buf{}; bitsery::ext::InheritanceContext ctx1; auto writtenSize = bitsery::quickSerialization(ctx1, Writer{ buf }, data); assert(writtenSize == 4); // base is serialized once, because it is inherited virtually MultipleInheritance res{ 0 }; bitsery::ext::InheritanceContext ctx2; auto state = bitsery::quickDeserialization( ctx2, Reader{ buf.begin(), writtenSize }, res); assert(state.first == bitsery::ReaderError::NoError && state.second); assert(data.x == res.x && data.y1 == res.y1 && data.getY2() == res.getY2() && data.z == res.z); }