26 using DecayedT = std::decay_t<T>;
72 if constexpr (std::is_trivially_copyable_v<T>) {
73 return SerializeTrivial();
75 return SerializeContainer();
77 return SerializePair();
79 return SerializeOptional();
81 return SerializeComplex();
91 if constexpr (std::is_trivially_copyable_v<T>) {
92 return DeserializeTrivial(data);
94 return DeserializeContainer(data);
96 return DeserializePair(data);
98 return DeserializeOptional(data);
100 return DeserializeComplex(data);
104 static std::size_t Size(
const DecayedT& data)
noexcept {
105 if constexpr (std::is_trivially_copyable_v<T>) {
107 }
else if constexpr (is_container<T>::value) {
108 return SizeContainer(data);
109 }
else if constexpr (is_pair<T>::value) {
110 return SizePair(data);
111 }
else if constexpr (is_optional<T>::value) {
112 return SizeOptional(data);
114 return SizeComplex(data);
119 const DecayedT& m_data;
126 Buffer::Simple SerializeTrivial() const noexcept {
127 return {
reinterpret_cast<const char*
>(&m_data),
sizeof(m_data) };
135 Buffer::Simple SerializeComplex() const noexcept;
142 Buffer::Simple SerializeContainer() const noexcept {
143 std::size_t size = m_data.size();
144 Serializable<std::size_t> size_serial(size);
145 Buffer::Simple buffer(std::move(size_serial.Serialize()));
146 for (
const auto& element: m_data) {
147 Serializable<std::decay_t<
decltype(element)>> element_serial(element);
148 buffer << std::move(element_serial.Serialize());
158 Buffer::Simple SerializePair() const noexcept {
159 Serializable<std::decay_t<typename T::first_type>> first_serial(m_data.first);
160 Serializable<std::decay_t<typename T::second_type>> second_serial(m_data.second);
161 return first_serial.Serialize() << std::move(second_serial.Serialize());
169 Buffer::Simple SerializeOptional() const noexcept {
170 bool has_value = m_data.has_value();
171 Buffer::Simple buffer = std::move(Serializable<bool>(has_value).
Serialize());
172 if (m_data.has_value()) {
173 Serializable<std::decay_t<
decltype(m_data.value())>> value_serial(m_data.value());
174 buffer << std::move(value_serial.Serialize());
184 static std::size_t SizeComplex(
const DecayedT& data)
noexcept;
191 static std::size_t SizeContainer(
const DecayedT& data)
noexcept {
192 std::size_t size =
sizeof(std::size_t);
193 for (
const auto& element: data) {
194 size +=
Serializable<std::decay_t<
decltype(element)>>::Size(element);
204 static std::size_t SizePair(
const DecayedT& data)
noexcept {
206 Serializable<std::decay_t<typename T::first_type>>::Size(data.first) +
207 Serializable<std::decay_t<typename T::second_type>>::Size(data.second);
215 static std::size_t SizeOptional(
const DecayedT& data)
noexcept {
216 std::size_t size =
sizeof(bool);
217 if (data.has_value()) {
218 size +=
Serializable<std::decay_t<
decltype(data.value())>>::Size(data.value());
229 auto expected_value = data.Read(
sizeof(T));
232 return T { *
reinterpret_cast<const T*
>(expected_value.value().data()) };
249 if (!expected_container_size)
252 std::size_t size = expected_container_size.value();
255 for (std::size_t i = 0; i < size; ++i) {
256 auto expected_element = Serializable<std::decay_t<typename T::value_type>>
::Deserialize(data);
257 if (!expected_element)
260 container.insert(container.end(), std::move(expected_element.value()));
271 using FirstT = std::decay_t<typename T::first_type>;
272 using SecondT = std::decay_t<typename T::second_type>;
279 if (!expected_second)
282 return T { expected_first.value(), expected_second.value() };
287 if (!expected_has_value)
290 if (expected_has_value.value()) {
295 return T { expected_value.value() };
static StormByte::Expected< T, Buffer::BufferOverflow > Deserialize(const Buffer::Simple &data) noexcept
The function to deserialize the data.
Definition serializable.hxx:90
std::conditional_t< is_reference< T >::value, std::expected< std::reference_wrapper< std::remove_reference_t< T > >, std::shared_ptr< E > >, std::expected< T, std::shared_ptr< E > > > Expected
Expected type with support for reference types.
Definition expected.hxx:32