28 using DecayedT = std::decay_t<T>;
77 if constexpr (std::is_trivially_copyable_v<T>) {
78 return SerializeTrivial();
79 }
else if constexpr (is_container<T>::value) {
80 return SerializeContainer();
81 }
else if constexpr (is_pair<T>::value) {
82 return SerializePair();
83 }
else if constexpr (is_optional<T>::value) {
84 return SerializeOptional();
86 return SerializeComplex();
101 if constexpr (std::is_trivially_copyable_v<T>) {
102 return DeserializeTrivial(data);
103 }
else if constexpr (is_container<T>::value) {
104 return DeserializeContainer(data);
105 }
else if constexpr (is_pair<T>::value) {
106 return DeserializePair(data);
107 }
else if constexpr (is_optional<T>::value) {
108 return DeserializeOptional(data);
110 return DeserializeComplex(data);
125 return Deserialize(std::span<const std::byte>(data.data(), data.size()));
136 static std::size_t
Size(
const DecayedT& data)
noexcept {
137 if constexpr (std::is_trivially_copyable_v<T>) {
139 }
else if constexpr (is_container<T>::value) {
140 return SizeContainer(data);
141 }
else if constexpr (is_pair<T>::value) {
142 return SizePair(data);
143 }
else if constexpr (is_optional<T>::value) {
144 return SizeOptional(data);
146 return SizeComplex(data);
151 const DecayedT& m_data;
161 std::vector<std::byte> SerializeTrivial() const noexcept {
162 return {
reinterpret_cast<const std::byte*
>(&m_data),
reinterpret_cast<const std::byte*
>(&m_data) +
sizeof(m_data) };
173 std::vector<std::byte> SerializeComplex() const noexcept;
183 std::vector<std::
byte> SerializeContainer() const noexcept {
184 std::size_t size = m_data.size();
185 Serializable<std::size_t> size_serial(size);
186 std::vector<std::byte> buffer = size_serial.Serialize();
187 buffer.reserve(buffer.size() + SizeContainer(m_data));
188 for (
const auto& element: m_data) {
189 Serializable<std::decay_t<
decltype(element)>> element_serial(element);
190 auto element_data = element_serial.Serialize();
191 append_vector(buffer, std::move(element_data));
204 std::vector<std::byte> SerializePair() const noexcept {
205 Serializable<std::decay_t<typename T::first_type>> first_serial(m_data.first);
206 Serializable<std::decay_t<typename T::second_type>> second_serial(m_data.second);
207 std::vector<std::byte> buffer;
208 buffer.reserve(SizePair(m_data));
209 auto first_data = first_serial.Serialize();
210 auto second_data = second_serial.Serialize();
211 append_vector(buffer, std::move(first_data));
212 append_vector(buffer, std::move(second_data));
224 std::vector<std::byte> SerializeOptional() const noexcept {
225 bool has_value = m_data.has_value();
226 std::vector<std::byte> buffer;
227 buffer.reserve(SizeOptional(m_data));
228 auto has_value_data = Serializable<bool>(has_value).Serialize();
229 append_vector(buffer, std::move(has_value_data));
230 if (m_data.has_value()) {
231 Serializable<std::decay_t<
decltype(m_data.value())>> value_serial(m_data.value());
232 auto value_data = value_serial.Serialize();
233 append_vector(buffer, std::move(value_data));
247 static std::size_t SizeComplex(
const DecayedT& data)
noexcept;
258 static std::size_t SizeContainer(
const DecayedT& data)
noexcept {
259 std::size_t size =
sizeof(std::size_t);
260 for (
const auto& element: data) {
275 static std::size_t SizePair(
const DecayedT& data)
noexcept {
277 Serializable<std::decay_t<typename T::first_type>>
::Size(data.first) +
278 Serializable<std::decay_t<typename T::second_type>>
::Size(data.second);
290 static std::size_t SizeOptional(
const DecayedT& data)
noexcept {
291 std::size_t size =
sizeof(bool);
292 if (data.has_value()) {
309 if (data.size() <
sizeof(T))
310 return StormByte::Unexpected<DeserializeError>(
"Insufficient data for deserialization");
312 std::memcpy(&result, data.data(),
sizeof(T));
327 return DeserializeTrivial(std::span<const std::byte>(data.data(), data.size()));
353 return DeserializeComplex(std::span<const std::byte>(data.data(), data.size()));
367 std::size_t offset = 0;
370 if (offset +
sizeof(std::size_t) > data.size())
371 return StormByte::Unexpected<DeserializeError>(
"Insufficient data for container size");
374 if (!expected_container_size)
377 std::size_t size = expected_container_size.value();
378 offset +=
sizeof(std::size_t);
381 for (std::size_t i = 0; i < size; ++i) {
382 using ElementT = std::decay_t<typename T::value_type>;
384 if (offset >= data.size())
385 return StormByte::Unexpected<DeserializeError>(
"Insufficient data for container element");
388 if (!expected_element)
393 container.insert(container.end(), std::move(expected_element.value()));
394 offset += element_size;
410 return DeserializeContainer(std::span<const std::byte>(data.data(), data.size()));
424 using FirstT = std::decay_t<typename T::first_type>;
425 using SecondT = std::decay_t<typename T::second_type>;
426 std::size_t offset = 0;
436 if (offset >= data.size())
437 return StormByte::Unexpected<DeserializeError>(
"Insufficient data for pair second element");
440 if (!expected_second)
443 return T { std::move(expected_first.value()), std::move(expected_second.value()) };
457 return DeserializePair(std::span<const std::byte>(data.data(), data.size()));
471 std::size_t offset = 0;
474 if (offset +
sizeof(
bool) > data.size())
475 return StormByte::Unexpected<DeserializeError>(
"Insufficient data for optional flag");
478 if (!expected_has_value)
481 offset +=
sizeof(bool);
483 if (expected_has_value.value()) {
484 if (offset >= data.size())
485 return StormByte::Unexpected<DeserializeError>(
"Insufficient data for optional value");
487 using ValueT = std::decay_t<typename T::value_type>;
492 return T { std::move(expected_value.value()) };
509 return DeserializeOptional(std::span<const std::byte>(data.data(), data.size()));