diff --git a/README.md b/README.md index a386683..dbcc428 100644 --- a/README.md +++ b/README.md @@ -74,68 +74,55 @@ g++-16 -std=c++26 -freflection -fcontracts -fcontract-evaluation-semantic=observ **`serialize`** - serializes one or more objects into a stack-allocated byte array ```cpp -template -[[nodiscard]] constexpr auto serialize( - Endian endianness, - const Args&... data -) -> std::array>; - -template -[[nodiscard]] constexpr auto serialize( - const Args&... data -) -> std::array>; +UserDefinedType a, b, c; + +auto raw_bytes_of_a = stse::serialize(a); +auto raw_bytes_of_bc = stse::serialize(b, c); + +// endian overloads +auto raw_bytes_of_a_big_endian = stse::serialize(stse::big_endian, a); +auto raw_bytes_of_bc_big_endian = stse::serialize(stse::big_endian, b, c); ``` -**`serialize_advance`** - serializes into an existing span, returning the -remaining span after the written bytes. +**`serialize_advance`** - serializes into an existing contiguous container, returning +span after the written bytes ```cpp -template -constexpr auto serialize_advance( - Endian endianness, - const std::span destination, - const Args&... data -) -> std::span; - -template -constexpr auto serialize_advance( - const std::span destination, - const Args&... data -) -> std::span; +UserDefinedType a, b, c; + +std::array write_buffer{}; +std::span write_ptr; +write_ptr = stse::serialize_advance(write_buffer, a); +write_ptr = stse::serialize_advance(write_ptr, b, c); + +// endian overloads +write_ptr = stse::serialize_advance(stse::big_endian, write_buffer, a); +write_ptr = stse::serialize_advance(stse::big_endian, write_ptr, b, c); ``` -**`deserialize`** - deserializes one or more objects from a byte span, returning -results and remaining span. +**`deserialize`** - deserializes one or more objects from a contiguous container, returning +result(s) and span after read bytes ```cpp -[[nodiscard]] constexpr auto deserialize( - Endian endianness, - const std::span data -) -> DeserializeResult - pre(data.size() >= serial_size_v); +std::array read_buffer; +auto [a, read_ptr] = stse::deserialize(read_buffer); +auto [b, c] = stse::deserialize(read_ptr).result; -template -[[nodiscard]] constexpr auto deserialize( - const std::span data -) -> DeserializeResult - pre(data.size() >= serial_size_v); +auto [a, read_ptr] = stse::deserialize(stse::big_endian, read_buffer); +auto [b, c] = stse::deserialize(stse::big_endian, read_ptr).result; ``` **`deserialize_advance`** — deserializes into existing objects, returning -remaining span. +span after read bytes ```cpp -template -constexpr auto deserialize_advance( - Endian endianness, - const std::span data, - Args&... parsed -) -> std::span - pre(data.size() >= serial_size_v) +UserDefinedType a, b, c; -template -constexpr auto deserialize_advance( - const std::span data, - Args&... parsed -) -> std::span - pre(data.size() >= serial_size_v) +std::array read_buffer{}; +std::span read_ptr; +read_ptr = stse::deserialize_advance(read_buffer, a); +read_ptr = stse::deserialize_advance(read_ptr, b, c); + +// endian overloads +read_ptr = stse::deserialize_advance(stse::big_endian, read_buffer, a); +read_ptr = stse::deserialize_advance(stse::big_endian, read_ptr, b, c); ``` **Skip & Ignore Member Annotation** @@ -150,21 +137,22 @@ inline constexpr auto ignore = ignoreserialization{}; **Properties** ```cpp -template -inline constexpr bool is_serializable_v; +// checks if type is serializable +template inline constexpr bool is_serializable_v; -template -inline constexpr std::size_t serial_size_v; +// returns wire size in bytes of type +template inline constexpr std::size_t serial_size_v; ``` **Endian Specifiers** ```cpp -inline constexpr BigEndian big_endian{}; -inline constexpr LittleEndian little_endian{}; -inline constexpr NativeEndian native_endian{}; +_ = stse::serialize(stse::big_endian, a); +_ = stse::serialize(stse::litte_endian, a); +_ = stse::serialize(stse::native_endian, a); ``` **Return Schema** +> Planning to deprecate this. ```cpp template [[nodiscard]] std::string schema(); @@ -172,9 +160,13 @@ template **Deserialize Return Type** ```cpp -template +template struct DeserializeResult { - T object; + std::conditional_t< + sizeof...(Args) == 1, + Args...[0], + std::tuple + > result; std::span remaining; }; ``` diff --git a/demo.cpp b/demo.cpp index 1c5e081..1833608 100644 --- a/demo.cpp +++ b/demo.cpp @@ -61,9 +61,8 @@ int main() { [[maybe_unused]] auto moved_ptr = stse::serialize_advance(raw_bytes, snapshot); - MarketSnapshot restored_snapshot; - stse::deserialize_advance(raw_bytes, restored_snapshot); - // assert(snapshot == restored_snapshot); + auto restored_snapshot = stse::deserialize(raw_bytes).result; + assert(snapshot == restored_snapshot); std::string schema = stse::schema(); std::print("{}", schema); diff --git a/include/stse/stse.hpp b/include/stse/stse.hpp index 06b3967..4c4eaeb 100644 --- a/include/stse/stse.hpp +++ b/include/stse/stse.hpp @@ -71,7 +71,11 @@ constexpr auto serialize_advance( template struct DeserializeResult { - std::tuple objects; + std::conditional_t< + sizeof...(Args) == 1, + Args...[0], + std::tuple + > result; std::span remaining; }; @@ -89,8 +93,8 @@ template auto remaining_ptr = data; ((remaining_ptr = detail::deserialize(parsed, remaining_ptr, endianness)), ...); - return DeserializeResult{ - .objects = parsed_objects, + return DeserializeResult{ + .result = {parsed...}, .remaining = remaining_ptr }; } diff --git a/tests/static_serial_test.hpp b/tests/static_serial_test.hpp index 927fb93..e28d46b 100644 --- a/tests/static_serial_test.hpp +++ b/tests/static_serial_test.hpp @@ -19,7 +19,7 @@ constexpr bool test_round_trip_inplace(const auto& data) { constexpr bool test_round_trip_heap(const auto& data) { using T = std::remove_cvref_t; auto bytes = stse::serialize(data); - auto [restored] = stse::deserialize(bytes).objects; + auto restored = stse::deserialize(bytes).result; return data == restored; } @@ -31,15 +31,15 @@ constexpr bool test_round_trip(const auto& data) { template consteval bool test_round_trip_endianness(Endian binary_endianness, const auto& data) { using T = decltype(data); - auto raw_bytes = stse::serialize(binary_endianness, data); - auto [restored] = stse::deserialize(binary_endianness, raw_bytes).objects; + auto raw_bytes = stse::serialize(binary_endianness, data); + auto restored = stse::deserialize(binary_endianness, raw_bytes).result; return data == restored; } consteval bool test_variadic_round_trip(const auto&... data) { auto raw_bytes = stse::serialize(data...); auto result = stse::deserialize(raw_bytes); - auto& [...restored] = result.objects; + auto& [...restored] = result.result; return ((data == restored) && ...); } @@ -56,7 +56,7 @@ template consteval bool test_variadic_round_trip_endian(const auto&... data) { auto raw_bytes = stse::serialize(endianness, data...); auto result = stse::deserialize(endianness, raw_bytes); - auto& [...restored] = result.objects; + auto& [...restored] = result.result; return ((data == restored) && ...); }