How-To work with binary data
C++ effectively has three ways for dealing with binary data:
The old way was to treat things as a
char *
, which generally reflects the fact thatchar
is one byte in size. Unfortunately, this is messy e.g. when using literals, not only becausechar
may be signed or unsigned.The other old way was to use
void *
everywhere, which correctly documents that binary data is essentially untyped – but introduces the problem that, being untyped, it is conceptually impossible to increment such a pointer, because one cannot know by how much to increment the underlying memory address.The C++17 way, which is to use
std::byte
. Sadly, this type is not uniformly available.
In order to deal with this a little better, liberate introduces a very simple
type of its own, liberate::types::byte
. Depending on whether it is
available, this is defined as std::byte
– or as a fallback, uint8_t
. In
either case, it is designed to be unsigned and available.
The liberate/types/byte.h header also introduces _b
literals:
1#include <liberate/types/byte.h>
2
3using namespace liberate::types::literals;
4
5auto a = 'A'_b;
6// => std::byte with value 0x65
7
8auto b = 0x65_b;
9// => same
10
11auto c = 123456_b;
12// => std::byte with value (123456 % 256)
13
14auto d = "hello"_b;
15// => std::vector<byte>