1#ifndef SERIALIZEBUFFER_HH
2#define SERIALIZEBUFFER_HH
38 void insert(
const void* __restrict data,
size_t len)
41 if (__builtin_constant_p(len)) {
43 insertN<1>(data);
return;
44 }
else if (len == 2) {
45 insertN<2>(data);
return;
46 }
else if (len == 4) {
47 insertN<4>(data);
return;
48 }
else if (len == 8) {
49 insertN<8>(data);
return;
56 template<
size_t N>
void insertN(
const void* __restrict data);
58 void insertN(
const void* __restrict data,
size_t len);
68 auto accum = [&](
auto* p) { len +=
sizeof(*p); };
69 std::apply([&](
auto&&... args) { (accum(args), ...); }, tuple);
71 uint8_t* newEnd = end + len;
72 if (newEnd > finish) [[unlikely]] {
77 auto write = [&](
auto* src) {
78 memcpy(dst, src,
sizeof(*src));
81 std::apply([&](
auto&&... args) { (write(args), ...); }, tuple);
82 assert(dst == (end + len));
90 insert(std::get<0>(tuple),
sizeof(T));
97 void insertAt(
size_t pos,
const void* __restrict data,
size_t len)
99 assert(buf.
data() + pos + len <= finish);
100 memcpy(buf.
data() + pos, data, len);
111 [[nodiscard]] std::span<uint8_t>
allocate(
size_t len)
113 auto* newEnd = end + len;
116 size_t newSize = newEnd - buf.
data();
117 lastSize =
std::max(lastSize, newSize + 1000);
118 if (newEnd <= finish) {
119 uint8_t* result = end;
121 return {result, len};
123 return {allocateGrow(len), len};
149 return end - buf.
data();
158 void insertGrow(
const void* __restrict data,
size_t len);
159 [[nodiscard]] uint8_t* allocateGrow(
size_t len);
160 void grow(
size_t len);
168 static inline size_t lastSize = 50000;
188 void read(
void* __restrict result,
size_t len) __restrict
190 memcpy(result, buf, len);
192 assert(buf <= finish);
202 assert(buf <= finish);
215 const uint8_t* finish;
const T * data() const
Returns pointer to the start of the memory buffer.
void insertAt(size_t pos, const void *data, size_t len)
Insert data at a given position.
ALWAYS_INLINE void insert_tuple_ptr(const std::tuple< T * > &tuple)
void insertN(const void *data, size_t len)
OutputBuffer()
Create an empty output buffer.
std::span< uint8_t > allocate(size_t len)
Reserve space to insert the given number of bytes.
MemBuffer< uint8_t > release(size_t &size)
Release ownership of the buffer.
ALWAYS_INLINE void insert_tuple_ptr(const TUPLE &tuple)
Insert all the elements of the given tuple.
size_t getPosition() const
Free part of a previously allocated buffer.
void insert(const void *data, size_t len)
Insert data at the end of this buffer.
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
This file implemented 3 utility functions:
size_t size(std::string_view utf8)