9 #ifndef EAGINE_SERIALIZE_READ_HPP
10 #define EAGINE_SERIALIZE_READ_HPP
12 #include "../math/functions.hpp"
13 #include "../memory/span_algo.hpp"
14 #include "../reflect/data_members.hpp"
15 #include "../reflect/enumerators.hpp"
16 #include "../valid_if/decl.hpp"
24 #include <type_traits>
30 class fragment_deserialize_wrapper<
span<T>> {
32 constexpr fragment_deserialize_wrapper() noexcept = default;
34 constexpr fragment_deserialize_wrapper(
span<T> dst) noexcept {
38 void set_target(span<T> dst) noexcept {
40 _done_bits.resize(
std_size(dst.size()),
false);
49 auto i =
math::minimum(_done_bits.begin() + offs, _done_bits.end());
60 auto is_done() const noexcept ->
bool {
61 return _done_size >= _dst.size();
66 std::vector<bool> _done_bits{};
71 struct deserializer<T&> : deserializer<T> {};
74 struct plain_deserializer {
76 template <
typename Backend>
79 return backend.read(cover_one(value), done);
82 template <
typename Backend>
83 static auto read(span<T> values, Backend& backend)
86 return backend.read(values, done);
91 struct deserializer<bool> : plain_deserializer<bool> {};
93 struct deserializer<char> : plain_deserializer<char> {};
95 struct deserializer<std::int8_t> : plain_deserializer<std::int8_t> {};
97 struct deserializer<short> : plain_deserializer<short> {};
99 struct deserializer<int> : plain_deserializer<int> {};
101 struct deserializer<long> : plain_deserializer<long> {};
103 struct deserializer<long long> : plain_deserializer<long long> {};
105 struct deserializer<std::uint8_t> : plain_deserializer<std::uint8_t> {};
107 struct deserializer<unsigned short> : plain_deserializer<unsigned short> {};
109 struct deserializer<unsigned> : plain_deserializer<unsigned> {};
111 struct deserializer<unsigned long> : plain_deserializer<unsigned long> {};
113 struct deserializer<unsigned long long>
114 : plain_deserializer<unsigned long long> {};
116 struct deserializer<float> : plain_deserializer<float> {};
118 struct deserializer<double> : plain_deserializer<double> {};
120 struct deserializer<
identifier> : plain_deserializer<identifier> {};
122 struct deserializer<decl_name_storage>
123 : plain_deserializer<decl_name_storage> {};
125 struct deserializer<std::string> : plain_deserializer<std::string> {};
127 template <
typename T>
128 struct common_deserializer {
130 template <
typename Backend>
131 auto read(span<T> values, Backend& backend)
const {
134 for(
auto& elem : values) {
136 static_cast<const deserializer<T>*
>(
this)->read(elem, backend);
137 if(result.has(ec::not_enough_data) || result.has(ec::backend_error)) {
145 template <
typename Bit>
146 struct deserializer<bitfield<Bit>> : common_deserializer<bitfield<Bit>> {
148 template <
typename Backend>
149 auto read(bitfield<Bit>& value, Backend& backend)
const {
151 auto errors{_deserializer.read(temp, backend)};
152 if(EAGINE_LIKELY(!errors)) {
153 value = bitfield<Bit>{temp};
162 template <
typename Rep>
163 struct deserializer<std::chrono::duration<Rep>>
164 : common_deserializer<std::chrono::duration<Rep>> {
166 template <
typename Backend>
167 auto read(std::chrono::duration<Rep>& value, Backend& backend)
const {
169 auto errors{_deserializer.read(temp, backend)};
170 if(EAGINE_LIKELY(!errors)) {
171 value = std::chrono::duration<Rep>{temp};
177 deserializer<Rep> _deserializer{};
180 template <
typename... T>
181 struct deserializer<std::tuple<T...>> : common_deserializer<std::tuple<T...>> {
183 using common_deserializer<std::tuple<T...>>::read;
185 template <
typename Backend>
186 auto read(std::tuple<T...>& values, Backend& backend)
const {
189 errors |= backend.begin_list(elem_count);
190 if(EAGINE_UNLIKELY(elem_count <
span_size(
sizeof...(T)))) {
192 }
else if(EAGINE_UNLIKELY(elem_count >
span_size(
sizeof...(T)))) {
198 errors, values, backend, std::make_index_sequence<
sizeof...(T)>());
199 errors |= backend.finish_list();
205 template <
typename Tuple,
typename Backend, std::size_t... I>
210 std::index_sequence<I...>)
const {
217 std::get<I>(_deserializers)));
220 template <
typename Elem,
typename Backend,
typename Serializer>
221 static void _read_element(
226 Serializer& serial) {
227 if(EAGINE_LIKELY(!errors)) {
228 errors |= backend.begin_element(
span_size(index));
229 if(EAGINE_LIKELY(!errors)) {
230 errors |= serial.read(elem, backend);
231 errors |= backend.finish_element(
span_size(index));
236 std::tuple<deserializer<T>...> _deserializers{};
239 template <
typename... T>
240 struct deserializer<std::tuple<std::pair<string_view, T>...>>
241 : common_deserializer<std::tuple<std::pair<string_view, T>...>> {
243 using common_deserializer<std::tuple<std::pair<string_view, T>...>>::read;
245 template <
typename Backend>
247 read(std::tuple<std::pair<string_view, T>...>& values, Backend& backend) {
250 errors |= backend.begin_struct(memb_count);
251 if(EAGINE_UNLIKELY(memb_count <
span_size(
sizeof...(T)))) {
253 }
else if(EAGINE_UNLIKELY(memb_count >
span_size(
sizeof...(T)))) {
259 errors, values, backend, std::make_index_sequence<
sizeof...(T)>());
260 errors |= backend.finish_struct();
266 template <
typename Tuple,
typename Backend, std::size_t... I>
271 std::index_sequence<I...>) {
275 std::get<0>(std::get<I>(values)),
276 std::get<1>(std::get<I>(values)),
278 std::get<I>(_deserializers)));
281 template <
typename Memb,
typename Backend,
typename Serializer>
282 static void _read_member(
287 Serializer& serial) {
288 if(EAGINE_LIKELY(!errors)) {
289 errors |= backend.begin_member(name);
290 if(EAGINE_LIKELY(!errors)) {
291 errors |= serial.read(value, backend);
292 errors |= backend.finish_member(name);
297 std::tuple<deserializer<T>...> _deserializers{};
300 template <
typename T>
301 struct deserializer<fragment_deserialize_wrapper<
span<T>>>
302 : common_deserializer<fragment_deserialize_wrapper<span<T>>> {
304 using common_deserializer<fragment_deserialize_wrapper<span<T>>>::read;
306 template <
typename Backend>
308 read(fragment_deserialize_wrapper<span<T>>& frag, Backend& backend)
const {
311 errors |= _size_deserializer.read(offs, backend);
312 if(EAGINE_LIKELY(!errors)) {
314 errors |= _size_deserializer.read(size, backend);
315 if(EAGINE_LIKELY(!errors)) {
317 errors |= backend.read(frag.slice(offs, size), done);
318 frag.mark_done(offs, done);
324 deserializer<span_size_t> _size_deserializer{};
327 template <
typename T, std::
size_t N>
328 struct deserializer<std::array<T, N>> : common_deserializer<std::array<T, N>> {
330 using common_deserializer<std::array<T, N>>::read;
332 template <
typename Backend>
333 auto read(std::array<T, N>& values, Backend& backend)
const {
336 errors |= backend.begin_list(elem_count);
337 if(EAGINE_UNLIKELY(elem_count <
span_size(N))) {
339 }
else if(EAGINE_UNLIKELY(elem_count >
span_size(N))) {
344 errors |= _elem_deserializer.read(
cover(values), backend);
345 errors |= backend.finish_list();
351 deserializer<T> _elem_deserializer{};
354 template <
typename T,
typename A>
355 struct deserializer<std::vector<T, A>>
356 : common_deserializer<std::vector<T, A>> {
358 template <
typename Backend>
359 auto read(std::vector<T, A>& values, Backend& backend)
const {
362 errors |= backend.begin_list(elem_count);
363 if(EAGINE_LIKELY(!errors)) {
364 values.resize(
std_size(elem_count));
365 errors |= _elem_deserializer.read(
cover(values), backend);
366 errors |= backend.finish_list();
372 deserializer<T> _elem_deserializer{};
375 template <
typename T,
typename P>
376 struct deserializer<valid_if<T, P>> : common_deserializer<valid_if<T, P>> {
378 template <
typename Backend>
379 auto read(valid_if<T, P>& value, Backend& backend)
const {
382 errors |= backend.begin_list(elem_count);
383 if(EAGINE_UNLIKELY(elem_count < 0)) {
385 }
else if(EAGINE_UNLIKELY(elem_count > 1)) {
388 if(EAGINE_LIKELY(!errors)) {
390 errors |= _deserializer.read(temp, backend);
391 errors |= backend.finish_list();
392 if(EAGINE_LIKELY(!errors)) {
393 _assign(value, std::move(temp));
400 static void _assign(valid_if<T, P>& dest, T&& src) noexcept {
401 if constexpr(std::is_same_v<P, valid_flag_policy>) {
402 dest = {std::move(src),
true};
404 dest = std::move(src);
408 deserializer<T> _deserializer{};
411 template <
typename T>
412 struct enum_deserializer {
414 template <
typename Backend>
415 auto read(T& enumerator, Backend& backend)
const {
417 if(backend.enum_as_string()) {
418 decl_name_storage temp_name{};
419 errors |= _name_deserializer.read(temp_name, backend);
420 if(EAGINE_LIKELY(!errors)) {
429 std::underlying_type_t<T> temp_value{};
430 errors |= _value_deserializer.read(temp_value, backend);
431 if(EAGINE_LIKELY(!errors)) {
432 if(
auto found = from_value(temp_value, type_identity<T>{})) {
443 deserializer<std::underlying_type_t<T>> _value_deserializer{};
444 deserializer<decl_name_storage> _name_deserializer{};
447 template <
typename T>
448 struct struct_deserializer {
450 template <
typename Backend>
451 auto read(T& instance, Backend& backend) {
452 auto member_map = map_data_members(instance);
453 return _deserializer.read(member_map, backend);
457 deserializer<decltype(map_data_members(std::declval<T&>()))> _deserializer{};
460 template <
typename T>
462 : std::conditional_t<
463 has_enumerator_mapping_v<T>,
464 enum_deserializer<T>,
466 has_data_member_mapping_v<T>,
467 struct_deserializer<T>,
474 template <
typename T,
typename Backend>
476 std::is_base_of_v<deserializer_backend, Backend>,
479 errors |= backend.begin();
480 if(EAGINE_LIKELY(!errors)) {
481 deserializer<T> reader;
482 errors |= reader.read(value, backend);
483 errors |= backend.finish();
490 #endif // EAGINE_SERIALIZE_READ_HPP