Skip to content

Commit 6ab4b74

Browse files
committed
Reduced allocations during serialization
1 parent f1c86e9 commit 6ab4b74

File tree

1 file changed

+28
-40
lines changed

1 file changed

+28
-40
lines changed

include/msgpack23/msgpack23.h

+28-40
Original file line numberDiff line numberDiff line change
@@ -142,24 +142,28 @@ namespace msgpack23 {
142142
data_.emplace_back(static_cast<std::byte>(std::to_underlying(value)));
143143
}
144144

145-
template<typename T>
146-
requires std::is_integral_v<T>
145+
template<std::integral T>
147146
void emplace_integral(T const &value) {
148147
auto const serialize_value = to_big_endian(value);
149148
auto const bytes = std::bit_cast<std::array<std::byte, sizeof(serialize_value)> >(serialize_value);
150149
data_.insert(data_.end(), bytes.begin(), bytes.end());
151150
}
152151

152+
template<std::integral T>
153+
void emplace_combined(FormatConstants const &constant, T const &value) {
154+
data_.reserve(1 + sizeof(T));
155+
emplace_constant(constant);
156+
emplace_integral<T>(value);
157+
}
158+
153159
[[nodiscard]] bool pack_map_header(std::size_t const n) {
154160
if (n < 16) {
155161
constexpr auto size_mask = static_cast<std::byte>(0b10000000);
156162
data_.emplace_back(static_cast<std::byte>(n) | size_mask);
157163
} else if (n < std::numeric_limits<std::uint16_t>::max()) {
158-
emplace_constant(FormatConstants::map16);
159-
emplace_integral(static_cast<std::uint16_t>(n));
164+
emplace_combined(FormatConstants::map16, static_cast<std::uint16_t>(n));
160165
} else if (n < std::numeric_limits<std::uint32_t>::max()) {
161-
emplace_constant(FormatConstants::map32);
162-
emplace_integral(static_cast<std::uint32_t>(n));
166+
emplace_combined(FormatConstants::map32, static_cast<std::uint32_t>(n));
163167
} else {
164168
return false;
165169
}
@@ -171,11 +175,9 @@ namespace msgpack23 {
171175
constexpr auto size_mask = static_cast<std::byte>(0b10010000);
172176
data_.emplace_back(static_cast<std::byte>(n) | size_mask);
173177
} else if (n < std::numeric_limits<std::uint16_t>::max()) {
174-
emplace_constant(FormatConstants::array16);
175-
emplace_integral(static_cast<std::uint16_t>(n));
178+
emplace_combined(FormatConstants::array16, static_cast<std::uint16_t>(n));
176179
} else if (n < std::numeric_limits<std::uint32_t>::max()) {
177-
emplace_constant(FormatConstants::array32);
178-
emplace_integral(static_cast<std::uint32_t>(n));
180+
emplace_combined(FormatConstants::array32, static_cast<std::uint32_t>(n));
179181
} else {
180182
return false;
181183
}
@@ -222,6 +224,7 @@ namespace msgpack23 {
222224
if (index > 127) {
223225
throw std::overflow_error("Variant index is to large to be serialized.");
224226
}
227+
225228
if (data.size() == 1) {
226229
emplace_constant(FormatConstants::fixext1);
227230
} else if (data.size() == 2) {
@@ -233,14 +236,11 @@ namespace msgpack23 {
233236
} else if (data.size() == 16) {
234237
emplace_constant(FormatConstants::fixext16);
235238
} else if (data.size() < std::numeric_limits<std::uint8_t>::max()) {
236-
emplace_constant(FormatConstants::ext8);
237-
emplace_integral(static_cast<std::uint8_t>(data.size()));
239+
emplace_combined(FormatConstants::ext8, static_cast<std::uint8_t>(data.size()));
238240
} else if (data.size() < std::numeric_limits<std::uint16_t>::max()) {
239-
emplace_constant(FormatConstants::ext16);
240-
emplace_integral(static_cast<std::uint16_t>(data.size()));
241+
emplace_combined(FormatConstants::ext16, static_cast<std::uint16_t>(data.size()));
241242
} else if (data.size() < std::numeric_limits<std::uint32_t>::max()) {
242-
emplace_constant(FormatConstants::ext32);
243-
emplace_integral(static_cast<std::uint32_t>(data.size()));
243+
emplace_combined(FormatConstants::ext32, static_cast<std::uint32_t>(data.size()));
244244
} else {
245245
throw std::length_error("Variant is too long to be serialized.");
246246
}
@@ -318,8 +318,7 @@ namespace msgpack23 {
318318
) {
319319
pack_type(static_cast<std::int8_t>(value));
320320
} else {
321-
emplace_constant(FormatConstants::int16);
322-
emplace_integral(value);
321+
emplace_combined(FormatConstants::int16, value);
323322
}
324323
}
325324

@@ -331,8 +330,7 @@ namespace msgpack23 {
331330
) {
332331
pack_type(static_cast<std::int16_t>(value));
333332
} else {
334-
emplace_constant(FormatConstants::int32);
335-
emplace_integral(value);
333+
emplace_combined(FormatConstants::int32, value);
336334
}
337335
}
338336

@@ -344,8 +342,7 @@ namespace msgpack23 {
344342
) {
345343
pack_type(static_cast<std::int32_t>(value));
346344
} else {
347-
emplace_constant(FormatConstants::int64);
348-
emplace_integral(value);
345+
emplace_combined(FormatConstants::int64, value);
349346
}
350347
}
351348

@@ -362,8 +359,7 @@ namespace msgpack23 {
362359
template<>
363360
inline void Packer::pack_type(std::uint16_t const &value) {
364361
if (value > std::numeric_limits<std::uint8_t>::max()) {
365-
emplace_constant(FormatConstants::uint16);
366-
emplace_integral(value);
362+
emplace_combined(FormatConstants::uint16, value);
367363
} else {
368364
pack_type(static_cast<std::uint8_t>(value));
369365
}
@@ -372,8 +368,7 @@ namespace msgpack23 {
372368
template<>
373369
inline void Packer::pack_type(std::uint32_t const &value) {
374370
if (value > std::numeric_limits<std::uint16_t>::max()) {
375-
emplace_constant(FormatConstants::uint32);
376-
emplace_integral(value);
371+
emplace_combined(FormatConstants::uint32, value);
377372
} else {
378373
pack_type(static_cast<std::uint16_t>(value));
379374
}
@@ -382,8 +377,7 @@ namespace msgpack23 {
382377
template<>
383378
inline void Packer::pack_type(std::uint64_t const &value) {
384379
if (value > std::numeric_limits<std::uint32_t>::max()) {
385-
emplace_constant(FormatConstants::uint64);
386-
emplace_integral(value);
380+
emplace_combined(FormatConstants::uint64, value);
387381
} else {
388382
pack_type(static_cast<std::uint32_t>(value));
389383
}
@@ -405,14 +399,12 @@ namespace msgpack23 {
405399

406400
template<>
407401
inline void Packer::pack_type(float const &value) {
408-
emplace_constant(FormatConstants::float32);
409-
emplace_integral(std::bit_cast<std::uint32_t>(value));
402+
emplace_combined(FormatConstants::float32, std::bit_cast<std::uint32_t>(value));
410403
}
411404

412405
template<>
413406
inline void Packer::pack_type(double const &value) {
414-
emplace_constant(FormatConstants::float64);
415-
emplace_integral(std::bit_cast<std::uint64_t>(value));
407+
emplace_combined(FormatConstants::float64, std::bit_cast<std::uint64_t>(value));
416408
}
417409

418410
template<>
@@ -423,11 +415,9 @@ namespace msgpack23 {
423415
emplace_constant(FormatConstants::str8);
424416
data_.emplace_back(static_cast<std::byte>(value.size()));
425417
} else if (value.size() < std::numeric_limits<std::uint16_t>::max()) {
426-
emplace_constant(FormatConstants::str16);
427-
emplace_integral(static_cast<std::uint16_t>(value.size()));
418+
emplace_combined(FormatConstants::str16, static_cast<std::uint16_t>(value.size()));
428419
} else if (value.size() < std::numeric_limits<std::uint32_t>::max()) {
429-
emplace_constant(FormatConstants::str32);
430-
emplace_integral(static_cast<std::uint32_t>(value.size()));
420+
emplace_combined(FormatConstants::str32, static_cast<std::uint32_t>(value.size()));
431421
} else {
432422
throw std::length_error("String is too long to be serialized.");
433423
}
@@ -446,11 +436,9 @@ namespace msgpack23 {
446436
emplace_constant(FormatConstants::bin8);
447437
data_.emplace_back(static_cast<std::byte>(value.size()));
448438
} else if (value.size() < std::numeric_limits<std::uint16_t>::max()) {
449-
emplace_constant(FormatConstants::bin16);
450-
emplace_integral(static_cast<std::uint16_t>(value.size()));
439+
emplace_combined(FormatConstants::bin16, static_cast<std::uint16_t>(value.size()));
451440
} else if (value.size() < std::numeric_limits<std::uint32_t>::max()) {
452-
emplace_constant(FormatConstants::bin32);
453-
emplace_integral(static_cast<std::uint32_t>(value.size()));
441+
emplace_combined(FormatConstants::bin32, static_cast<std::uint32_t>(value.size()));
454442
} else {
455443
throw std::length_error("Vector is too long to be serialized.");
456444
}

0 commit comments

Comments
 (0)