Your binary serialization library

Bitsery

Build Status Join the chat at https://gitter.im/bitsery/Lobby

Header only C++ binary serialization library. It is designed around the networking requirements for real-time data delivery, especially for games.

All cross-platform requirements are enforced at compile time, so serialized data do not store any meta-data information and is as small as possible.

bitsery is looking for your feedback on gitter

Features

  • Cross-platform compatible.
  • Optimized for speed and space.
  • No code generation required: no IDL or metadata, just use your types directly.
  • Configurable runtime error checking on deserialization.
  • Can read/write from any source: stream (file, network stream. etc... ), or buffer (vector, c-array, etc...).
  • Don't pay for what you don't use! - customize your serialization via extensions. Some notable extensions allow:
    • fine-grained bit-level serialization control.
    • forward/backward compatibility for your types.
    • smart and raw pointers with allocators support and customizable runtime polymorphism.
  • Easily extendable for any type.
  • Allows brief (similar to cereal) or/and verbose syntax for better serialization control.
  • Configurable endianness support.
  • No macros.

Why use bitsery

Look at the numbers and features list, and decide yourself.

library data size serialize deserialize
bitsery 6913B 959ms 927ms
bitsery_compress 4213B 1282ms 1115ms
boost 11037B 9826ms 8313ms
cereal 10413B 6324ms 5698ms
flatbuffers 14924B 5129ms 2142ms
protobuf 10018B 11966ms 13919ms
yas 10463B 1908ms 1217ms

benchmarked on Ubuntu with GCC 8.3.0, more details can be found here

If still not convinced read more in library motivation section.

Usage example

#include <bitsery/bitsery.h>
#include <bitsery/adapter/buffer.h>
#include <bitsery/traits/vector.h>

enum class MyEnum:uint16_t { V1,V2,V3 };
struct MyStruct {
    uint32_t i;
    MyEnum e;
    std::vector<float> fs;
};

template <typename S>
void serialize(S& s, MyStruct& o) {
    s.value4b(o.i);
    s.value2b(o.e);
    s.container4b(o.fs, 10);
}

using Buffer = std::vector<uint8_t>;
using OutputAdapter = bitsery::OutputBufferAdapter<Buffer>;
using InputAdapter = bitsery::InputBufferAdapter<Buffer>;

int main() {
    MyStruct data{8941, MyEnum::V2, {15.0f, -8.5f, 0.045f}};
    MyStruct res{};

    Buffer buffer;

    auto writtenSize = bitsery::quickSerialization<OutputAdapter>(buffer, data);
    auto state = bitsery::quickDeserialization<InputAdapter>({buffer.begin(), writtenSize}, res);

    assert(state.first == bitsery::ReaderError::NoError && state.second);
    assert(data.fs == res.fs && data.i == res.i && data.e == res.e);
}

For more details go directly to quick start tutorial.

How to use it

This documentation comprises these parts:

documentation is in progress, most parts are empty, but contributions are welcome.

Requirements

Works with C++11 compiler, no additional dependencies, include <bitsery/bitsery.h> and you're done.

some bitsery extensions might require higher C++ standard (e.g. StdVariant)

Platforms

This library was tested on

  • Windows: Visual Studio 2015, MinGW (GCC 5.2)
  • Linux: GCC 5.4, Clang 3.9
  • OS X Mavericks: AppleClang 8

There is a patch that allows using bitsery with non-fully compatible C++11 compilers.

  • CentOS 7 with gcc 4.8.2.

License

bitsery is licensed under the MIT license.

Owner
Comments
  • Error on Centos7

    Error on Centos7

    I am trying to use Bitsery5.0.1 on a Centos7 witg gcc4.8.2. I got this error:

    /usr/include/c++/4.8.2/bits/hashtable.h: In instantiation of 'class std::_Hashtable<long unsigned int, std::pair<const long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> > >, bitsery::ext::pointer_utils::StdPolyAlloc<std::pair<const long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> > > >, std::__detail::_Select1st, std::equal_to<long unsigned int>, std::hash<long unsigned int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >':
    /usr/include/c++/4.8.2/bits/unordered_map.h:100:18:   required from 'class std::unordered_map<long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> >, std::hash<long unsigned int>, std::equal_to<long unsigned int>, bitsery::ext::pointer_utils::StdPolyAlloc<std::pair<const long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> > > > >'
    /__w/OpenGeode/OpenGeode/build/third_party/bitsery/install/include/bitsery/ext/utils/polymorphism_utils.h:182:19:   required from here
    /usr/include/c++/4.8.2/bits/hashtable.h:194:47: error: no type named 'pointer' in 'class bitsery::ext::pointer_utils::StdPolyAlloc<std::pair<const long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> > > >'
           typedef typename _Alloc::pointer        pointer;
                                                   ^
    /usr/include/c++/4.8.2/bits/hashtable.h:195:55: error: no type named 'const_pointer' in 'class bitsery::ext::pointer_utils::StdPolyAlloc<std::pair<const long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> > > >'
           typedef typename _Alloc::const_pointer          const_pointer;
                                                           ^
    /usr/include/c++/4.8.2/bits/hashtable.h:196:55: error: no type named 'reference' in 'class bitsery::ext::pointer_utils::StdPolyAlloc<std::pair<const long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> > > >'
           typedef typename _Alloc::reference              reference;
                                                           ^
    /usr/include/c++/4.8.2/bits/hashtable.h:197:55: error: no type named 'const_reference' in 'class bitsery::ext::pointer_utils::StdPolyAlloc<std::pair<const long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> > > >'
           typedef typename _Alloc::const_reference        const_reference;
                                                           ^
    /usr/include/c++/4.8.2/bits/hashtable.h:317:8: error: no class template named 'rebind' in 'class bitsery::ext::pointer_utils::StdPolyAlloc<std::pair<const long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> > > >'
            _Node_allocator_type;
            ^
    /usr/include/c++/4.8.2/bits/hashtable.h:319:8: error: no class template named 'rebind' in 'class bitsery::ext::pointer_utils::StdPolyAlloc<std::pair<const long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> > > >'
            _Bucket_allocator_type;
            ^
    /usr/include/c++/4.8.2/bits/hashtable.h:321:75: error: no class template named 'rebind' in 'class bitsery::ext::pointer_utils::StdPolyAlloc<std::pair<const long unsigned int, std::vector<long unsigned int, bitsery::ext::pointer_utils::StdPolyAlloc<long unsigned int> > > >'
           using __before_begin = __detail::_Before_begin<_Node_allocator_type>;
                                                                               ^
    

    Do you have an idea of the origin of this error?

  • Serializing forward-declared types

    Serializing forward-declared types

    I have a bunch of forward declares for types used in my classes and in order to use bitsery it looks like I need to include the headers for them (forward declaring doesn't work).

    More of a detail: I use forward declares because I hold raw pointers to my types, but I don't actually use bitsery's raw pointer features because I manage the memory/hierarchy myself. Instead I serialize them dereferenced.

    Anyway, is there a way to avoid having the includes? Using forward declares is better practice.

    Thanks, great library :)

  • Read Serialized Buffers in Place

    Read Serialized Buffers in Place

    not sure the effort that would be required to implement this, but, given the memory layout of variables and their data in serialized buffers must (?) be deterministic, it is certainly possible to read buffers in place.

    right now I use flatbuffers instead of bitsery to serialize/deserialize the information I exchange between my app and server solely because of the ability to read flatbuffers in place-- in my architecture philosophy of minimizing the usage of server resources and time by executing any work on the client possible. so even though the sum total work to serialize/deserialize with bitsery is much less than with flatbuffers, it's still the less optimal choice.

    adding this ability would instantly make bitsery the absolutely optimal choice for networking!

  • SegFault while deserializing

    SegFault while deserializing

    I am trying to upgrade my code to bitsery 5. No issue during the porting. However, I have a seg fault in my tests.

    Here is the valgrind log of one of them:

    valgrind ./test-vertex-identifier 
    ==26526== Memcheck, a memory error detector
    ==26526== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==26526== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
    ==26526== Command: ./test-vertex-identifier
    ==26526== 
    ==26526== Invalid read of size 8
    ==26526==    at 0x5306FE2: void bitsery::ext::pointer_utils::PolyAllocWithTypeId::deallocate<std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2> >(std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2>*, unsigned long, unsigned long) const (memory_resource.h:86)
    ==26526==    by 0x5306B42: bitsery::ext::pointer_utils::StdPolyAlloc<std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2> >::deallocate(__gnu_cxx::_Lock_policy*, unsigned long) (memory_resource.h:147)
    ==26526==    by 0x530680D: std::allocator_traits<bitsery::ext::pointer_utils::StdPolyAlloc<std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2> > >::deallocate(std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2>&, __gnu_cxx::_Lock_policy*, unsigned long) (alloc_traits.h:328)
    ==26526==    by 0x53062AF: std::__allocated_ptr<bitsery::ext::pointer_utils::StdPolyAlloc<std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2> > >::~__allocated_ptr() (allocated_ptr.h:73)
    ==26526==    by 0x5308249: std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2>::_M_destroy() (shared_ptr_base.h:476)
    ==26526==    by 0x723AB28: bitsery::ext::pointer_utils::StdPolyAlloc<bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> > >::deallocate(bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >*, unsigned long) (memory_resource.h:147)
    ==26526==    by 0x72249B6: void bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>::addToMap<bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >(std::integral_constant<bool, false>)::{lambda(bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >*)#1}::operator()(bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >*) const (polymorphism_utils.h:150)
    ==26526==    by 0x72DE8B1: std::_Sp_counted_deleter<bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >*, void bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>::addToMap<bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >(std::integral_constant<bool, false>)::{lambda(bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> > >, (__gnu_cxx::_Lock_policy)2>::_M_dispose() (shared_ptr_base.h:470)
    ==26526==    by 0x5277691: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:154)
    ==26526==    by 0x5277342: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:684)
    ==26526==    by 0x5298AA9: std::__shared_ptr<bitsery::ext::PolymorphicHandlerBase, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:1123)
    ==26526==    by 0x5298AC5: std::shared_ptr<bitsery::ext::PolymorphicHandlerBase>::~shared_ptr() (shared_ptr.h:93)
    ==26526==  Address 0x8 is not stack'd, malloc'd or (recently) free'd
    ==26526== 
    ==26526== 
    ==26526== Process terminating with default action of signal 11 (SIGSEGV)
    ==26526==  Access not within mapped region at address 0x8
    ==26526==    at 0x5306FE2: void bitsery::ext::pointer_utils::PolyAllocWithTypeId::deallocate<std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2> >(std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2>*, unsigned long, unsigned long) const (memory_resource.h:86)
    ==26526==    by 0x5306B42: bitsery::ext::pointer_utils::StdPolyAlloc<std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2> >::deallocate(__gnu_cxx::_Lock_policy*, unsigned long) (memory_resource.h:147)
    ==26526==    by 0x530680D: std::allocator_traits<bitsery::ext::pointer_utils::StdPolyAlloc<std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2> > >::deallocate(std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2>&, __gnu_cxx::_Lock_policy*, unsigned long) (alloc_traits.h:328)
    ==26526==    by 0x53062AF: std::__allocated_ptr<bitsery::ext::pointer_utils::StdPolyAlloc<std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2> > >::~__allocated_ptr() (allocated_ptr.h:73)
    ==26526==    by 0x5308249: std::_Sp_counted_deleter<geode::VariableAttribute<unsigned int>*, bitsery::ext::smart_ptr_details::SmartPtrOwnerManager<std::shared_ptr<geode::VariableAttribute<unsigned int> > >::createSharedPolymorphic(bitsery::ext::smart_ptr_details::SharedPtrSharedState&, std::shared_ptr<geode::VariableAttribute<unsigned int> >&, bitsery::ext::MemResourceBase*, std::shared_ptr<bitsery::ext::PolymorphicHandlerBase> const&)::{lambda(geode::VariableAttribute<unsigned int>*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<geode::VariableAttribute<unsigned int> >, (__gnu_cxx::_Lock_policy)2>::_M_destroy() (shared_ptr_base.h:476)
    ==26526==    by 0x723AB28: bitsery::ext::pointer_utils::StdPolyAlloc<bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> > >::deallocate(bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >*, unsigned long) (memory_resource.h:147)
    ==26526==    by 0x72249B6: void bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>::addToMap<bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >(std::integral_constant<bool, false>)::{lambda(bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >*)#1}::operator()(bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >*) const (polymorphism_utils.h:150)
    ==26526==    by 0x72DE8B1: std::_Sp_counted_deleter<bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >*, void bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>::addToMap<bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >(std::integral_constant<bool, false>)::{lambda(bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> >*)#1}, bitsery::ext::pointer_utils::StdPolyAlloc<bitsery::ext::PolymorphicHandler<bitsery::ext::StandardRTTI, bitsery::Deserializer<bitsery::BasicInputStreamAdapter<char, bitsery::DefaultConfig, std::char_traits<char> >, std::tuple<bitsery::ext::PolymorphicContext<bitsery::ext::StandardRTTI>, bitsery::ext::PointerLinkingContext, bitsery::ext::InheritanceContext> >, geode::VariableAttribute<unsigned int>, geode::VariableAttribute<unsigned int> > >, (__gnu_cxx::_Lock_policy)2>::_M_dispose() (shared_ptr_base.h:470)
    ==26526==    by 0x5277691: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:154)
    ==26526==    by 0x5277342: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:684)
    ==26526==    by 0x5298AA9: std::__shared_ptr<bitsery::ext::PolymorphicHandlerBase, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:1123)
    ==26526==    by 0x5298AC5: std::shared_ptr<bitsery::ext::PolymorphicHandlerBase>::~shared_ptr() (shared_ptr.h:93)
    ==26526==  If you believe this happened as a result of a stack
    ==26526==  overflow in your program's main thread (unlikely but
    ==26526==  possible), you can try to increase the size of the
    ==26526==  main thread stack using the --main-stacksize= flag.
    ==26526==  The main thread stack size used in this run was 8388608.
    ==26526== 
    ==26526== HEAP SUMMARY:
    ==26526==     in use at exit: 23,006 bytes in 393 blocks
    ==26526==   total heap usage: 2,459 allocs, 2,066 frees, 199,049 bytes allocated
    ==26526== 
    ==26526== LEAK SUMMARY:
    ==26526==    definitely lost: 0 bytes in 0 blocks
    ==26526==    indirectly lost: 0 bytes in 0 blocks
    ==26526==      possibly lost: 0 bytes in 0 blocks
    ==26526==    still reachable: 23,006 bytes in 393 blocks
    ==26526==         suppressed: 0 bytes in 0 blocks
    ==26526== Rerun with --leak-check=full to see details of leaked memory
    ==26526== 
    ==26526== For counts of detected and suppressed errors, rerun with: -v
    ==26526== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
    Erreur de segmentation (core dumped)
    

    Do you have an idea of the issue and its origin?

  • Recreate Pointer Objects w/ Custom Allocator During Deserialization

    Recreate Pointer Objects w/ Custom Allocator During Deserialization

    title is pretty self explanatory :)

    i have some objects i'm currently using new to allocate, but want to switch over to using a custom allocator. i serialize/deserialize these objects with bitsery, and so would need the custom allocator to be triggered upon deserialization.

    maybe i missed it but i didn't see any hooks to allocate memory when deserializing a pointer.

  • Vector of bit-packed structs not measuring correctly?

    Vector of bit-packed structs not measuring correctly?

    Hello, me again with a measurement problem. This time, I've learned my lesson and boiled it down to a simple example before bringing it here :D

    I have the following code, where an EntityUpdate struct contains a vector of Input structs. Input contains an array that gets bit-packed on serialization.

    #include "bitsery/bitsery.h"
    #include "bitsery/adapter/buffer.h"
    #include "bitsery/adapter/stream.h"
    #include "bitsery/adapter/measure_size.h"
    #include "bitsery/traits/vector.h"
    #include "bitsery/ext/value_range.h"
    
    struct Input {
    public:
        enum Type : uint8_t { XUp, XDown, YUp, YDown, ZUp, ZDown, NumTypes, None };
        enum State : uint8_t { Released = 0, Pressed = 1 };
    
        typedef std::array<State, Type::NumTypes> StateArr;
        StateArr inputStates{};
    };
    
    struct EntityUpdate {
        std::vector<Input> inputs;
    };
    
    template<typename S>
    void serialize(S& serializer, EntityUpdate& entityUpdate)
    {
        serializer.container(entityUpdate.inputs,
                             static_cast<std::size_t>(1000));
    }
    
    template<typename S>
    void serialize(S& serializer, Input& input)
    {
        serializer.enableBitPacking([&input](typename S::BPEnabledType& sbp) {
            sbp.container(input.inputStates, [](typename S::BPEnabledType& sbp,
                                                Input::State& inputState) {
                constexpr bitsery::ext::ValueRange<Input::State> range{
                    Input::State::Released, Input::State::Pressed};
                sbp.ext(inputState, range);
            });
        });
    }
    
    using OutputAdapter = bitsery::OutputBufferAdapter<std::vector<uint8_t>>;
    
    int main()
    {
        EntityUpdate entityUpdate{};
        for (unsigned int i = 0; i < 4; ++i) {
            entityUpdate.inputs.push_back(Input{});
        }
    
        // Measure the size.
        std::size_t measuredSize{bitsery::quickSerialization(
            bitsery::MeasureSize{}, entityUpdate)};
    
        // Serialize and get the real size.
        std::vector<uint8_t> buffer{};
        std::size_t finalSize{bitsery::quickSerialization<OutputAdapter>(
            buffer, entityUpdate)};
    
        assert(measuredSize == finalSize);
    
        return 0;
    }
    

    The issue is, when the array is filled with more than 4 inputs, I'm getting different values between the measured size and the serialized size. In the example, I'm getting 4B for measured and 5B for final. 5B makes sense, since each Input can fit in 1B and the array will use 1B for its size.

    Am I doing something incorrectly, or is there a bug?

  • serialization of 3rd party datastructures

    serialization of 3rd party datastructures

    Is it possible to serialize e.g. glm datastructures (glm::vec2, glm::vec3, ...)? The examples show only serialization of classes and struct defined by the user, and simply defining

    #include <glm/vec3.hpp>
    
    template<typename S>
    void serialize(S& s, glm::vec3& vec) {
        s.value4b(vec.x);
        s.value4b(vec.y);
        s.value4b(vec.z);
    }
    
    

    somewhere where the serialization is done was apparently not the correct way.

  • Deserializing a file with different PolymorphicContext

    Deserializing a file with different PolymorphicContext

    I have an issue while deserializing a file with different PolymorphicContext. I have a custom PolymorphicContext build using the registerSingleBaseBanch method, let's call it PC_A. I save a file using PC_A, say file.txt. Then, I add a new base branch into PC_A, so PC_B = PC_A + one branch. And then I try to deserialize file.txt using PC_B, I got this error:

    include/bitsery/ext/utils/pointer_utils.h:95: void bitsery::ext::pointer_utils::PLCInfo::update(bitsery::ext::PointerOwnershipType): Assertion `ptrType == PointerOwnershipType::SharedOwner || ptrType == PointerOwnershipType::SharedObserver' failed.
    

    The new branch added to the context is not used during this all process. I want to add a polymorphic class to the contexte for future usage.

    Another test: saving and loading a file with the same context is working, both PC_A and PC_B.

  • Why does the buffer uses resize instead of reserve?

    Why does the buffer uses resize instead of reserve?

    https://github.com/fraillt/bitsery/blob/master/include/bitsery/traits/core/std_defaults.h#L85

    Wouldn't be the reserve method a better solution instead of resize? Wasn't that possible?

  • Serializer value() size auto-deduction

    Serializer value() size auto-deduction

    Probably discussed somewhere before, but.

    Serializer have

    template<size_t VSIZE, typename T>
    void value(const T &v)
    

    why this is impossible:

    template<typename T>
    void value(const T &v)
    {
        value<sizeof(T)>(v);
    }
    

    ?

    Why value size must be always specified?

  • Dynamic polymorphic class registration

    Dynamic polymorphic class registration

    I would like to know how to dynamically extend bitsery polymorphism. Let's take your example and assume this code is in a library A:

    template<>
    struct PolymorphicBaseClass<Shape> : PolymorphicDerivedClasses<Circle, Rectangle> {
    };
    

    Now, in another library B, I would like to add another class Square derived from Shape. Is it possible to register this new relationship between Square and Shape without modifying the library A which does not know Square?

  • bug in apple libc++ ARM hash_code function

    bug in apple libc++ ARM hash_code function

    if you check the backtrace below you'll see that the code crashes on the __ptr dereference in __non_unique_impl:: __hash because it's dereferencing a junk address.

    apparently __non_unique_impl is a specialization specifically and only for apple arm. crazy that it's broken out of the box.

    so we definitely need some kind of workaround for when called on apple platforms.

    struct __non_unique_impl : __string_impl_base {
        _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
        static size_t __hash(__type_name_t __ptr) _NOEXCEPT {
          size_t __hash = 5381;
          while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
            __hash = (__hash * 33) ^ __c;
          return __hash;
        }
    ...
    

    #0 0x0000000102672e5c in std::__type_info_implementations::__non_unique_impl::__hash(char const*) [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.0.sdk/usr/include/c++/v1/typeinfo:222 #1 0x0000000102672e48 in std::__type_info_implementations::__non_unique_arm_rtti_bit_impl::__hash(unsigned long) [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.0.sdk/usr/include/c++/v1/typeinfo:253 #2 0x0000000102672e14 in std::type_info::hash_code() const at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.0.sdk/usr/include/c++/v1/typeinfo:338 #3 0x0000000102692efc in unsigned long bitsery::ext::StandardRTTI::get(Person&) at /x/libraries/include/bitsery/ext/utils/rtti_utils.h:41 #4 0x0000000102692e50 in void bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI::deserialize<bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >, Person, void bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>::deserializeImpl<bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >, Person*, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)>(bitsery::ext::MemResourceBase*, bitsery::ext::pointer_utils::PLCInfoDeserializer&, Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>&, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)&&, std::__1::integral_constant<bool, true>, std::__1::integral_constant<bitsery::ext::PointerOwnershipType, (bitsery::ext::PointerOwnershipType)1>) const::'lambda'(std::__1::shared_ptrbitsery::ext::PolymorphicHandlerBase const&), void bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>::deserializeImpl<bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >, Person*, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)>(bitsery::ext::MemResourceBase*, bitsery::ext::pointer_utils::PLCInfoDeserializer&, Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>&, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)&&, std::__1::integral_constant<bool, true>, std::__1::integral_constant<bitsery::ext::PointerOwnershipType, (bitsery::ext::PointerOwnershipType)1>) const::'lambda0'(std::__1::shared_ptrbitsery::ext::PolymorphicHandlerBase const&)>(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&), void bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>::deserializeImpl<bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >, Person*, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)>(bitsery::ext::MemResourceBase*, bitsery::ext::pointer_utils::PLCInfoDeserializer&, Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>&, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)&&, std::__1::integral_constant<bool, true>, std::__1::integral_constant<bitsery::ext::PointerOwnershipType, (bitsery::ext::PointerOwnershipType)1>) const::'lambda0'(std::__1::shared_ptrbitsery::ext::PolymorphicHandlerBase const&)) const at /x/libraries/include/bitsery/ext/utils/polymorphism_utils.h:261

  • ContainerTraits::size and BufferAdapterTraits::increaseBufferSize

    ContainerTraits::size and BufferAdapterTraits::increaseBufferSize

    thoughts on renaming size to remainingCapacity? because it really requests remainingCapacity not size. just debugged an infinite loop where i'd implemented these as size when really the intention was remainingCapacity.

  • Rename error() function

    Rename error() function

    error is a really common name and if bitsery's user codebase defines it to a macro, bitsery won't compile.

    Related to #48.

    Feel free to close this if you think it's ridiculous :)

  • No Heap Array support?

    No Heap Array support?

    you have text1b(), which would be the closest thing to char array support, though generic heap arrays arent supported at all, not even an option like

    s.ext(ObjectPtr, PointerOwner{PointerType::NotNull}, ObjectCount);
    
Zmeya is a header-only C++11 binary serialization library designed for games and performance-critical applications

Zmeya Zmeya is a header-only C++11 binary serialization library designed for games and performance-critical applications. Zmeya is not even a serializ

Nov 2, 2022
Fast Binary Encoding is ultra fast and universal serialization solution for C++, C#, Go, Java, JavaScript, Kotlin, Python, Ruby, Swift

Fast Binary Encoding (FBE) Fast Binary Encoding allows to describe any domain models, business objects, complex data structures, client/server request

Dec 1, 2022
Binary Serialization

Binn Binn is a binary data serialization format designed to be compact, fast and easy to use. Performance The elements are stored with their sizes to

Nov 24, 2022
Cap'n Proto serialization/RPC system - core tools and C++ library
Cap'n Proto serialization/RPC system - core tools and C++ library

Cap'n Proto is an insanely fast data interchange format and capability-based RPC system. Think JSON, except binary. Or think Protocol Buffers, except

Dec 1, 2022
A C++11 library for serialization
A C++11 library for serialization

cereal - A C++11 library for serialization cereal is a header-only C++11 serialization library. cereal takes arbitrary data types and reversibly turns

Dec 2, 2022
FlatBuffers: Memory Efficient Serialization Library

FlatBuffers FlatBuffers is a cross platform serialization library architected for maximum memory efficiency. It allows you to directly access serializ

Dec 8, 2022
Simple C++ 20 Serialization Library that works out of the box with aggregate types!

BinaryLove3 Simple C++ 20 Serialization Library that works out of the box with aggregate types! Requirements BinaryLove3 is a c++20 only library.

Sep 2, 2022
CppSerdes is a serialization/deserialization library designed with embedded systems in mind
CppSerdes is a serialization/deserialization library designed with embedded systems in mind

A C++ serialization/deserialization library designed with embedded systems in mind

Nov 5, 2022
Header-only library for automatic (de)serialization of C++ types to/from JSON.

fuser 1-file header-only library for automatic (de)serialization of C++ types to/from JSON. how it works The library has a predefined set of (de)seria

Oct 20, 2022
Yet another JSON/YAML/BSON serialization library for C++.
Yet another JSON/YAML/BSON serialization library for C++.

ThorsSerializer Support for Json Yaml Bson NEW Benchmark Results Conformance mac linux Performance max linux For details see: JsonBenchmark Yet anothe

Oct 27, 2022
Cista is a simple, high-performance, zero-copy C++ serialization & reflection library.

Simple C++ Serialization & Reflection. Cista++ is a simple, open source (MIT license) C++17 compatible way of (de-)serializing C++ data structures. Si

Dec 1, 2022
Nov 28, 2022
Yet Another Serialization
Yet Another Serialization

YAS Yet Another Serialization - YAS is created as a replacement of boost.serialization because of its insufficient speed of serialization (benchmark 1

Nov 30, 2022
An implementation of the MessagePack serialization format in C / msgpack.org[C]

CMP CMP is a C implementation of the MessagePack serialization format. It currently implements version 5 of the MessagePack Spec. CMP's goal is to be

Nov 17, 2022
MPack - A C encoder/decoder for the MessagePack serialization format / msgpack.org[C]

Introduction MPack is a C implementation of an encoder and decoder for the MessagePack serialization format. It is: Simple and easy to use Secure agai

Nov 30, 2022
Serialization framework for Unreal Engine Property System that just works!

DataConfig Serialization framework for Unreal Engine Property System that just works! Unreal Engine features a powerful Property System which implemen

Nov 27, 2022
Yet Another Serialization
Yet Another Serialization

YAS Yet Another Serialization - YAS is created as a replacement of boost.serialization because of its insufficient speed of serialization (benchmark 1

Sep 7, 2021
universal serialization engine

A Universal Serialization Engine Based on compile-time Reflection iguana is a modern, universal and easy-to-use serialization engine developed in c++1

Dec 2, 2022
A lightweight C++20 serialization framework

zpp::bits A modern C++20 binary serialization library, with just one header file. This library is a successor to zpp::serializer. The library tries to

Nov 28, 2022