38template <
typename T,
typename... I>
68template <
typename T,
typename... I>
70 std::span<uint8_t> out, T&& value,
72 typename Struct<typename std::remove_cvref_t<T>,
73 typename std::remove_cvref_t<I>...>;
75 Struct<typename std::remove_cvref_t<T>,
77 } -> std::convertible_to<std::string_view>;
79 Struct<typename std::remove_cvref_t<T>,
80 typename std::remove_cvref_t<I>...>::GetSize(info...)
81 } -> std::convertible_to<size_t>;
83 Struct<typename std::remove_cvref_t<T>,
84 typename std::remove_cvref_t<I>...>::GetSchema(info...)
85 } -> std::convertible_to<std::string_view>;
87 Struct<typename std::remove_cvref_t<T>,
88 typename std::remove_cvref_t<I>...>::Unpack(in, info...)
89 } -> std::same_as<typename std::remove_cvref_t<T>>;
90 Struct<typename std::remove_cvref_t<T>,
91 typename std::remove_cvref_t<I>...>::Pack(out, std::forward<T>(value),
102template <
typename T,
typename... I>
105 requires(T* out, std::span<const uint8_t> in,
const I&... info) {
106 Struct<typename std::remove_cvref_t<T>,
107 typename std::remove_cvref_t<I>...>::UnpackInto(out, in, info...);
119template <
typename T,
typename... I>
122 requires(function_ref<void(std::string_view, std::string_view)> fn,
124 Struct<typename std::remove_cvref_t<T>,
125 typename std::remove_cvref_t<I>...>::ForEachNested(fn, info...);
136template <
typename T,
typename... I>
138inline T
UnpackStruct(std::span<const uint8_t> data,
const I&... info) {
140 return S::Unpack(data, info...);
153template <
typename T,
size_t Offset,
typename... I>
154 requires StructSerializable<T, I...>
155inline T
UnpackStruct(std::span<const uint8_t> data,
const I&... info) {
157 return S::Unpack(data.subspan(Offset), info...);
171template <StructSerializable T,
size_t Offset,
size_t N>
176 [&]<
size_t... Is>(std::index_sequence<Is...>) {
178 }(std::make_index_sequence<N>{});
183 for (
size_t i = 0; i < N; i++) {
185 data = data.subspan(size);
198template <
typename T,
typename... I>
199 requires StructSerializable<T, I...>
200inline void PackStruct(std::span<uint8_t> data, T&& value,
const I&... info) {
202 typename std::remove_cvref_t<I>...>;
203 S::Pack(data, std::forward<T>(value), info...);
215template <
size_t Offset,
typename T,
typename... I>
216 requires StructSerializable<T, I...>
217inline void PackStruct(std::span<uint8_t> data, T&& value,
const I&... info) {
219 typename std::remove_cvref_t<I>...>;
220 S::Pack(data.subspan(Offset), std::forward<T>(value), info...);
233template <
size_t Offset,
size_t N, StructSerializable T>
238 [&]<
size_t... Is>(std::index_sequence<Is...>) {
240 }(std::make_index_sequence<N>{});
243 for (
auto&& val : arr) {
245 data = data.subspan(size);
257template <
typename T,
typename... I>
258 requires StructSerializable<T, I...>
263 S::UnpackInto(out, data, info...);
279template <
size_t Offset,
typename T,
typename... I>
280 requires StructSerializable<T, I...>
285 S::UnpackInto(out, data.subspan(Offset), info...);
298template <
typename T,
typename... I>
299 requires StructSerializable<T, I...>
302 return S::GetTypeName(info...);
312template <
typename T,
typename... I>
313 requires StructSerializable<T, I...>
316 if constexpr (
sizeof...(I) == 0 &&
318 constexpr auto typeName = S::GetTypeName(info...);
322 ct_string<
char, std::char_traits<char>, typeName.
size()>{typeName});
324 return fmt::format(
"struct:{}", S::GetTypeName(info...));
335template <
typename T,
typename... I>
336 requires StructSerializable<T, I...>
339 return S::GetSize(info...);
342template <
typename T,
size_t N,
typename... I>
343 requires StructSerializable<T, I...>
346 if constexpr (
sizeof...(I) == 0 &&
348 constexpr auto typeName = S::GetTypeName(info...);
350 if constexpr (N == std::dynamic_extent) {
352 ct_string<
char, std::char_traits<char>, typeName.
size()>{typeName},
356 ct_string<
char, std::char_traits<char>, typeName.
size()>{typeName},
360 if constexpr (N == std::dynamic_extent) {
361 return fmt::format(
"{}[]", S::GetTypeName(info...));
363 return fmt::format(
"{}[{}]", S::GetTypeName(info...), N);
368template <
typename T,
size_t N,
typename... I>
369 requires StructSerializable<T, I...>
372 if constexpr (
sizeof...(I) == 0 &&
381template <
typename T,
size_t N,
typename... I>
382 requires StructSerializable<T, I...>
385 if constexpr (
sizeof...(I) == 0 &&
387 constexpr auto schema = S::GetSchema(info...);
389 if constexpr (N == std::dynamic_extent) {
391 ct_string<
char, std::char_traits<char>, schema.
size()>{schema},
395 ct_string<
char, std::char_traits<char>, schema.
size()>{schema},
399 if constexpr (N == std::dynamic_extent) {
400 return fmt::format(
"{}[]", S::GetSchema(info...));
402 return fmt::format(
"{}[{}]", S::GetSchema(info...), N);
407template <
typename T,
typename... I>
408 requires StructSerializable<T, I...>
411 return S::GetSchema(info...);
414template <
typename T,
typename... I>
415 requires StructSerializable<T, I...>
418 auto schema = S::GetSchema(info...);
419 return {
reinterpret_cast<const uint8_t*
>(schema.data()), schema.size()};
422template <
typename T,
typename... I>
423 requires StructSerializable<T, I...>
425 std::invocable<std::string_view, std::string_view>
auto fn,
428 typename std::remove_cvref_t<I>...>;
430 S::ForEachNested(fn, info...);
435template <
typename T,
typename... I>
436 requires StructSerializable<T, I...>
446 m_buf = std::move(rhs.m_buf);
450 template <
typename U,
typename F>
452#if __cpp_lib_ranges >= 201911L
453 std::ranges::range<U> &&
454 std::convertible_to<std::ranges::range_value_t<U>, T> &&
456 std::invocable<F, std::span<const uint8_t>>
457 void Write(U&& data, F&& func,
const I&... info) {
458 auto size = S::GetSize(info...);
459 if ((std::size(data) * size) < 256) {
463 for (
auto&& val : data) {
464 S::Pack(std::span<uint8_t>{std::to_address(out), size},
465 std::forward<decltype(val)>(val), info...);
468 func(std::span<uint8_t>{buf, out});
470 std::scoped_lock lock{m_mutex};
471 m_buf.resize(std::size(data) * size);
472 auto out = m_buf.begin();
473 for (
auto&& val : data) {
474 S::Pack(std::span<uint8_t>{std::to_address(out), size},
475 std::forward<decltype(val)>(val), info...);
484 std::vector<uint8_t> m_buf;
490template <
typename T,
size_t N,
typename... I>
491 requires StructSerializable<T, I...>
496 static constexpr size_t GetSize(
const I&... info) {
502 static std::array<T, N>
Unpack(std::span<const uint8_t> data,
505 std::array<T, N> result;
506 for (
size_t i = 0; i < N; ++i) {
508 data = data.subspan(size);
512 static void Pack(std::span<uint8_t> data, std::span<const T, N> values,
515 std::span<uint8_t> unsizedData = data;
516 for (
auto&& val : values) {
518 unsizedData = unsizedData.subspan(size);
521 static void UnpackInto(std::array<T, N>* out, std::span<const uint8_t> data,
523 UnpackInto(std::span{*out}, data, info...);
526 static void UnpackInto(std::span<T, N> out, std::span<const uint8_t> data,
529 std::span<const uint8_t> unsizedData = data;
530 for (
size_t i = 0; i < N; ++i) {
532 unsizedData = unsizedData.subspan(size);
543 static constexpr std::string_view
GetTypeName() {
return "bool"; }
544 static constexpr size_t GetSize() {
return 1; }
545 static constexpr std::string_view
GetSchema() {
return "bool value"; }
546 static bool Unpack(std::span<const uint8_t> data) {
return data[0]; }
547 static void Pack(std::span<uint8_t> data,
bool value) {
548 data[0] =
static_cast<char>(value ? 1 : 0);
558 static constexpr std::string_view
GetTypeName() {
return "uint8"; }
559 static constexpr size_t GetSize() {
return 1; }
560 static constexpr std::string_view
GetSchema() {
return "uint8 value"; }
561 static uint8_t
Unpack(std::span<const uint8_t> data) {
return data[0]; }
562 static void Pack(std::span<uint8_t> data, uint8_t value) { data[0] = value; }
571 static constexpr std::string_view
GetTypeName() {
return "int8"; }
572 static constexpr size_t GetSize() {
return 1; }
573 static constexpr std::string_view
GetSchema() {
return "int8 value"; }
574 static int8_t
Unpack(std::span<const uint8_t> data) {
return data[0]; }
575 static void Pack(std::span<uint8_t> data, int8_t value) { data[0] = value; }
584 static constexpr std::string_view
GetTypeName() {
return "uint16"; }
585 static constexpr size_t GetSize() {
return 2; }
586 static constexpr std::string_view
GetSchema() {
return "uint16 value"; }
587 static uint16_t
Unpack(std::span<const uint8_t> data) {
590 static void Pack(std::span<uint8_t> data, uint16_t value) {
601 static constexpr std::string_view
GetTypeName() {
return "int16"; }
602 static constexpr size_t GetSize() {
return 2; }
603 static constexpr std::string_view
GetSchema() {
return "int16 value"; }
604 static int16_t
Unpack(std::span<const uint8_t> data) {
607 static void Pack(std::span<uint8_t> data, int16_t value) {
618 static constexpr std::string_view
GetTypeName() {
return "uint32"; }
619 static constexpr size_t GetSize() {
return 4; }
620 static constexpr std::string_view
GetSchema() {
return "uint32 value"; }
621 static uint32_t
Unpack(std::span<const uint8_t> data) {
624 static void Pack(std::span<uint8_t> data, uint32_t value) {
635 static constexpr std::string_view
GetTypeName() {
return "int32"; }
636 static constexpr size_t GetSize() {
return 4; }
637 static constexpr std::string_view
GetSchema() {
return "int32 value"; }
638 static int32_t
Unpack(std::span<const uint8_t> data) {
641 static void Pack(std::span<uint8_t> data, int32_t value) {
652 static constexpr std::string_view
GetTypeName() {
return "uint64"; }
653 static constexpr size_t GetSize() {
return 8; }
654 static constexpr std::string_view
GetSchema() {
return "uint64 value"; }
655 static uint64_t
Unpack(std::span<const uint8_t> data) {
658 static void Pack(std::span<uint8_t> data, uint64_t value) {
669 static constexpr std::string_view
GetTypeName() {
return "int64"; }
670 static constexpr size_t GetSize() {
return 8; }
671 static constexpr std::string_view
GetSchema() {
return "int64 value"; }
672 static int64_t
Unpack(std::span<const uint8_t> data) {
675 static void Pack(std::span<uint8_t> data, int64_t value) {
686 static constexpr std::string_view
GetTypeName() {
return "float"; }
687 static constexpr size_t GetSize() {
return 4; }
688 static constexpr std::string_view
GetSchema() {
return "float value"; }
689 static float Unpack(std::span<const uint8_t> data) {
692 static void Pack(std::span<uint8_t> data,
float value) {
703 static constexpr std::string_view
GetTypeName() {
return "double"; }
704 static constexpr size_t GetSize() {
return 8; }
705 static constexpr std::string_view
GetSchema() {
return "double value"; }
706 static double Unpack(std::span<const uint8_t> data) {
709 static void Pack(std::span<uint8_t> data,
double value) {
This file implements the C++20 <bit> header.
void Write(U &&data, F &&func, const I &... info)
Definition Struct.h:457
StructArrayBuffer()=default
StructArrayBuffer(StructArrayBuffer &&rhs)
Definition Struct.h:444
StructArrayBuffer & operator=(StructArrayBuffer &&rhs)
Definition Struct.h:445
StructArrayBuffer(const StructArrayBuffer &)=delete
StructArrayBuffer & operator=(const StructArrayBuffer &)=delete
This class is a wrapper around std::array that does compile time size checking.
Definition array.h:26
Specifies that a struct type has nested struct declarations.
Definition Struct.h:120
Specifies that a type is capable of in-place raw struct deserialization.
Definition Struct.h:103
Specifies that a type is capable of raw struct serialization and deserialization.
Definition Struct.h:69
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
uint32_t read32le(const void *P)
Definition Endian.h:427
uint64_t read64le(const void *P)
Definition Endian.h:430
void write32le(void *P, uint32_t V)
Definition Endian.h:470
uint16_t read16le(const void *P)
Definition Endian.h:424
void write64le(void *P, uint64_t V)
Definition Endian.h:473
void write16le(void *P, uint16_t V)
Definition Endian.h:467
Foonathan namespace.
Definition ntcore_cpp.h:26
constexpr auto GetStructTypeString(const I &... info)
Get the type string for a raw struct serializable type.
Definition Struct.h:314
constexpr auto MakeStructArrayTypeName(const I &... info)
Definition Struct.h:344
constexpr auto NumToCtString()
Converts any integral to a ct_string at compile-time.
Definition ct_string.h:202
constexpr auto Concat(ct_string< Char, Traits, N1 > const &s1, ct_string< Char, Traits, N > const &... s)
Concatenates multiple fixed_strings into a larger fixed_string at compile time.
Definition ct_string.h:168
constexpr auto MakeStructArraySchema(const I &... info)
Definition Struct.h:383
void UnpackStructInto(T *out, std::span< const uint8_t > data, const I &... info)
Unpack a serialized struct into an existing object, overwriting its contents.
Definition Struct.h:259
constexpr auto MakeStructArrayTypeString(const I &... info)
Definition Struct.h:370
T UnpackStruct(std::span< const uint8_t > data, const I &... info)
Unpack a serialized struct.
Definition Struct.h:138
constexpr std::span< const uint8_t > GetStructSchemaBytes(const I &... info)
Definition Struct.h:416
void PackStructArray(std::span< uint8_t > data, const wpi::array< T, N > &arr)
Pack a serialized struct array starting at a given offset within the data.
Definition Struct.h:234
constexpr std::string_view GetStructSchema(const I &... info)
Definition Struct.h:409
constexpr auto GetStructTypeName(const I &... info)
Get the type name for a raw struct serializable type.
Definition Struct.h:300
constexpr empty_array_t empty_array
Definition array.h:16
constexpr size_t GetStructSize(const I &... info)
Get the size for a raw struct serializable type.
Definition Struct.h:337
void ForEachStructSchema(std::invocable< std::string_view, std::string_view > auto fn, const I &... info)
Definition Struct.h:424
To bit_cast(const From &from) noexcept
Definition bit.h:51
wpi::array< T, N > UnpackStructArray(std::span< const uint8_t > data)
Unpack a serialized struct array starting at a given offset within the data.
Definition Struct.h:172
constexpr bool is_constexpr(Lambda)
Definition type_traits.h:81
::std::mutex mutex
Definition mutex.h:17
std::string GetTypeName(const T &type)
Returns the type name of an object.
Definition Demangle.h:27
void PackStruct(std::span< uint8_t > data, T &&value, const I &... info)
Pack a serialized struct.
Definition Struct.h:200
static constexpr size_t GetSize()
Definition Struct.h:544
static constexpr std::string_view GetSchema()
Definition Struct.h:545
static bool Unpack(std::span< const uint8_t > data)
Definition Struct.h:546
static constexpr std::string_view GetTypeName()
Definition Struct.h:543
static void Pack(std::span< uint8_t > data, bool value)
Definition Struct.h:547
static void Pack(std::span< uint8_t > data, double value)
Definition Struct.h:709
static constexpr std::string_view GetSchema()
Definition Struct.h:705
static constexpr std::string_view GetTypeName()
Definition Struct.h:703
static double Unpack(std::span< const uint8_t > data)
Definition Struct.h:706
static constexpr size_t GetSize()
Definition Struct.h:704
static constexpr std::string_view GetSchema()
Definition Struct.h:688
static float Unpack(std::span< const uint8_t > data)
Definition Struct.h:689
static void Pack(std::span< uint8_t > data, float value)
Definition Struct.h:692
static constexpr size_t GetSize()
Definition Struct.h:687
static constexpr std::string_view GetTypeName()
Definition Struct.h:686
static constexpr size_t GetSize()
Definition Struct.h:602
static int16_t Unpack(std::span< const uint8_t > data)
Definition Struct.h:604
static void Pack(std::span< uint8_t > data, int16_t value)
Definition Struct.h:607
static constexpr std::string_view GetSchema()
Definition Struct.h:603
static constexpr std::string_view GetTypeName()
Definition Struct.h:601
static void Pack(std::span< uint8_t > data, int32_t value)
Definition Struct.h:641
static constexpr size_t GetSize()
Definition Struct.h:636
static int32_t Unpack(std::span< const uint8_t > data)
Definition Struct.h:638
static constexpr std::string_view GetSchema()
Definition Struct.h:637
static constexpr std::string_view GetTypeName()
Definition Struct.h:635
static constexpr size_t GetSize()
Definition Struct.h:670
static constexpr std::string_view GetSchema()
Definition Struct.h:671
static constexpr std::string_view GetTypeName()
Definition Struct.h:669
static void Pack(std::span< uint8_t > data, int64_t value)
Definition Struct.h:675
static int64_t Unpack(std::span< const uint8_t > data)
Definition Struct.h:672
static constexpr std::string_view GetTypeName()
Definition Struct.h:571
static int8_t Unpack(std::span< const uint8_t > data)
Definition Struct.h:574
static void Pack(std::span< uint8_t > data, int8_t value)
Definition Struct.h:575
static constexpr std::string_view GetSchema()
Definition Struct.h:573
static constexpr size_t GetSize()
Definition Struct.h:572
static void UnpackInto(std::array< T, N > *out, std::span< const uint8_t > data, const I &... info)
Definition Struct.h:521
static std::array< T, N > Unpack(std::span< const uint8_t > data, const I &... info)
Definition Struct.h:502
static void UnpackInto(std::span< T, N > out, std::span< const uint8_t > data, const I &... info)
Definition Struct.h:526
static constexpr auto GetTypeName(const I &... info)
Definition Struct.h:493
static constexpr size_t GetSize(const I &... info)
Definition Struct.h:496
static constexpr auto GetSchema(const I &... info)
Definition Struct.h:499
static void Pack(std::span< uint8_t > data, std::span< const T, N > values, const I &... info)
Definition Struct.h:512
static void Pack(std::span< uint8_t > data, uint16_t value)
Definition Struct.h:590
static constexpr size_t GetSize()
Definition Struct.h:585
static constexpr std::string_view GetTypeName()
Definition Struct.h:584
static constexpr std::string_view GetSchema()
Definition Struct.h:586
static uint16_t Unpack(std::span< const uint8_t > data)
Definition Struct.h:587
static uint32_t Unpack(std::span< const uint8_t > data)
Definition Struct.h:621
static constexpr std::string_view GetTypeName()
Definition Struct.h:618
static void Pack(std::span< uint8_t > data, uint32_t value)
Definition Struct.h:624
static constexpr std::string_view GetSchema()
Definition Struct.h:620
static constexpr size_t GetSize()
Definition Struct.h:619
static uint64_t Unpack(std::span< const uint8_t > data)
Definition Struct.h:655
static constexpr size_t GetSize()
Definition Struct.h:653
static constexpr std::string_view GetSchema()
Definition Struct.h:654
static void Pack(std::span< uint8_t > data, uint64_t value)
Definition Struct.h:658
static constexpr std::string_view GetTypeName()
Definition Struct.h:652
static constexpr std::string_view GetSchema()
Definition Struct.h:560
static void Pack(std::span< uint8_t > data, uint8_t value)
Definition Struct.h:562
static uint8_t Unpack(std::span< const uint8_t > data)
Definition Struct.h:561
static constexpr std::string_view GetTypeName()
Definition Struct.h:558
static constexpr size_t GetSize()
Definition Struct.h:559
Struct serialization template.
Definition Struct.h:39
Fixed length string (array of character) for compile time use.
Definition ct_string.h:29
constexpr auto size() const noexcept
Definition ct_string.h:124
#define S(label, offset, message)
Definition Errors.h:113