From the documentation:
Some simple classes could be serialized just by directly copying all bits of the class. This is, in particular, the case for POD data types containing no pointer members, and which are neither versioned nor tracked. Some archives, such as non-portable binary archives can make us of this information to substantially speed up serialization.
To indicate the possibility of bitwise serialization the type trait defined in the header file is_bitwise_serializable.hpp is used:
Here are the key points: this optimization
Note that this also explains that is_bit_wise_serializable<T>
is not partially specialized for any type that has is_pod<T>::value == true
(This could technically be done easily):
- some classes might not be interested in serializing all their state (so using bitwise copy would take a lot more space than just selecting the interesting bits (pun intended))
You didn't ask, specifically, but this is what the working implementation would look like:
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <sstream>
struct A { int a; char b;
template <typename Ar> void serialize(Ar& ar, unsigned) {
ar & a;
ar & b;
}
};
BOOST_IS_BITWISE_SERIALIZABLE(A)
int main() {
std::ostringstream oss;
boost::archive::binary_oarchive oa(oss);
A data { 1, 'z' };
oa << data;
}
UPDATE
In response to the commenter who basically posed the same question again, I came up with a demonstration when bitwise serializability would (a) kick in making a visible difference (b) not resulting in the smaller archive:
Live On Coliru
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/serialization.hpp>
#include <array>
#include <fmt/ranges.h>
#include <span>
#include <sstream>
struct A {
int a;
char b;
void serialize(auto& ar, unsigned) { ar& a& b; }
};
#ifdef BITWISE
BOOST_IS_BITWISE_SERIALIZABLE(A)
#endif
int main() {
std::ostringstream oss;
{
boost::archive::binary_oarchive oa(oss,
boost::archive::no_header |
boost::archive::no_tracking |
boost::archive::no_codecvt);
std::array<A, 26> data{{
{1, 'z'}, {2, 'y'}, {3, 'x'}, {4, 'w'}, {5, 'v'}, {6, 'u'}, {7, 't'},
{8, 's'}, {9, 'r'}, {10, 'q'}, {11, 'p'}, {12, 'o'}, {13, 'n'}, {14, 'm'},
{15, 'l'}, {16, 'k'}, {17, 'j'}, {18, 'i'}, {19, 'h'}, {20, 'g'}, {21, 'f'},
{22, 'e'}, {23, 'd'}, {24, 'c'}, {25, 'b'}, {26, 'a'},
}};
oa << data;
}
auto raw = oss.str();
fmt::print("raw serialized form {} bytes: {::#04x}\n", //
raw.size(), std::vector(raw.begin(), raw.end()));
}
When built an run:
for def in REGULAR BITWISE; do g++ -std=c++20 -O2 -Wall -pedantic main.cpp -lboost_serialization -lfmt -o $def -D$def & done; wait
set -x; ./REGULAR; ./BITWISE
Prints
+ ./REGULAR
raw serialized form 148 bytes: [0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7a, 0x02, 0x00, 0x00, 0x00, 0x79, 0x03, 0x00, 0x00, 0x00, 0x78, 0x04, 0x00, 0x00, 0x00, 0x77, 0x05, 0x00, 0x00, 0x00, 0x76, 0x06, 0x00, 0x00, 0x00, 0x75, 0x07, 0x00, 0x00, 0x00, 0x74, 0x08, 0x00, 0x00, 0x00, 0x73, 0x09, 0x00, 0x00, 0x00, 0x72, 0x0a, 0x00, 0x00, 0x00, 0x71, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x0c, 0x00, 0x00, 0x00, 0x6f, 0x0d, 0x00, 0x00, 0x00, 0x6e, 0x0e, 0x00, 0x00, 0x00, 0x6d, 0x0f, 0x00, 0x00, 0x00, 0x6c, 0x10, 0x00, 0x00, 0x00, 0x6b, 0x11, 0x00, 0x00, 0x00, 0x6a, 0x12, 0x00, 0x00, 0x00, 0x69, 0x13, 0x00, 0x00, 0x00, 0x68, 0x14, 0x00, 0x00, 0x00, 0x67, 0x15, 0x00, 0x00, 0x00, 0x66, 0x16, 0x00, 0x00, 0x00, 0x65, 0x17, 0x00, 0x00, 0x00, 0x64, 0x18, 0x00, 0x00, 0x00, 0x63, 0x19, 0x00, 0x00, 0x00, 0x62, 0x1a, 0x00, 0x00, 0x00, 0x61]
+ ./BITWISE
raw serialized form 221 bytes: [0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x77, 0x7f, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x76, 0x7f, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x75, 0x7f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x74, 0x7f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x73, 0x7f, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x72, 0x7f, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x71, 0x7f, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x6c, 0x7f, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x69, 0x7f, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x66, 0x7f, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x65, 0x7f, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x64, 0x7f, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x63, 0x7f, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00]