|
26 | 26 | #ifndef MARSHALLING_ARRAY_LIST_HPP
|
27 | 27 | #define MARSHALLING_ARRAY_LIST_HPP
|
28 | 28 |
|
| 29 | +#include <functional> |
29 | 30 | #include <vector>
|
| 31 | +#include <map> |
30 | 32 |
|
31 | 33 | #include <nil/marshalling/status_type.hpp>
|
32 | 34 | #include <nil/marshalling/types/array_list/behaviour.hpp>
|
33 | 35 | #include <nil/marshalling/types/detail/options_parser.hpp>
|
34 | 36 |
|
35 | 37 | #include <nil/marshalling/types/tag.hpp>
|
| 38 | +#include <nil/detail/type_traits.hpp> |
36 | 39 |
|
37 | 40 | namespace nil {
|
38 | 41 | namespace marshalling {
|
@@ -404,6 +407,79 @@ namespace nil {
|
404 | 407 | return field;
|
405 | 408 | }
|
406 | 409 |
|
| 410 | + // We use this type of array_list waay too often, so this is a shortcut, not to copy-paste it all the time. |
| 411 | + template<typename TFieldBase, typename TElement> |
| 412 | + using standard_array_list = array_list< |
| 413 | + TFieldBase, |
| 414 | + TElement, |
| 415 | + nil::marshalling::option::size_t_sequence_size_field_prefix<TFieldBase>>; |
| 416 | + |
| 417 | + // Very often we just need an array list of std::size_t, so here's another shortcut. |
| 418 | + template<typename TFieldBase> |
| 419 | + using standard_size_t_array_list = array_list< |
| 420 | + TFieldBase, |
| 421 | + nil::marshalling::types::integral<TFieldBase, std::size_t>, |
| 422 | + nil::marshalling::option::size_t_sequence_size_field_prefix<TFieldBase>>; |
| 423 | + |
| 424 | + // Helper functions to convert to/from an arraylist. |
| 425 | + template<typename TFieldBase, typename TMarshalledElement, typename Range> |
| 426 | + typename std::enable_if< |
| 427 | + nil::detail::is_range<Range>::value, |
| 428 | + standard_array_list<TFieldBase, TMarshalledElement>>::type |
| 429 | + fill_standard_array_list( |
| 430 | + const Range& input_range, |
| 431 | + std::function<TMarshalledElement(const typename Range::value_type&)> element_marshalling) { |
| 432 | + standard_array_list<TFieldBase, TMarshalledElement> result; |
| 433 | + for (const auto& v: input_range) { |
| 434 | + result.value().push_back(element_marshalling(v)); |
| 435 | + } |
| 436 | + return result; |
| 437 | + } |
| 438 | + |
| 439 | + template<typename TFieldBase, typename TElement, typename TMarshalledElement> |
| 440 | + std::vector<TElement> make_standard_array_list( |
| 441 | + const standard_array_list<TFieldBase, TMarshalledElement>& filled_array, |
| 442 | + std::function<TElement(const TMarshalledElement&)> element_de_marshalling) { |
| 443 | + std::vector<TElement> result; |
| 444 | + for (const auto& v: filled_array.value()) { |
| 445 | + result.push_back(element_de_marshalling(v)); |
| 446 | + } |
| 447 | + return result; |
| 448 | + } |
| 449 | + |
| 450 | + // Helper functions to marshall an std::map. |
| 451 | + // We keep TKey, TValue at the end, because they can be decuded from the map type, but the other 3 |
| 452 | + // arguments must be provided explicitly. |
| 453 | + template<typename TFieldBase, typename TMarshalledKey, typename TMarshalledValue, typename TKey, typename TValue> |
| 454 | + std::pair<standard_array_list<TFieldBase, TMarshalledKey>, standard_array_list<TFieldBase, TMarshalledValue>> |
| 455 | + fill_std_map( |
| 456 | + const std::map<TKey, TValue>& input_map, |
| 457 | + std::function<TMarshalledKey(const TKey&)> key_marshalling, |
| 458 | + std::function<TMarshalledValue(const TValue&)> value_marshalling) { |
| 459 | + standard_array_list<TFieldBase, TMarshalledKey> result_keys; |
| 460 | + standard_array_list<TFieldBase, TMarshalledValue> result_values; |
| 461 | + for (const auto& [k, v]: input_map) { |
| 462 | + result_keys.value().push_back(key_marshalling(k)); |
| 463 | + result_values.value().push_back(value_marshalling(v)); |
| 464 | + } |
| 465 | + return {result_keys, result_values}; |
| 466 | + } |
| 467 | + |
| 468 | + template<typename TFieldBase, typename TKey, typename TValue, typename TMarshalledKey, typename TMarshalledValue> |
| 469 | + std::map<TKey, TValue> make_std_map( |
| 470 | + const standard_array_list<TFieldBase, TMarshalledKey>& filled_keys, |
| 471 | + const standard_array_list<TFieldBase, TMarshalledValue>& filled_values, |
| 472 | + std::function<TKey(const TMarshalledKey&)> key_de_marshalling, |
| 473 | + std::function<TValue(const TMarshalledValue&)> value_de_marshalling) { |
| 474 | + assert(filled_keys.value().size() == filled_values.value().size()); |
| 475 | + |
| 476 | + std::map<TKey, TValue> result; |
| 477 | + for (std::size_t i = 0; i < filled_keys.value().size(); ++i) { |
| 478 | + result[key_de_marshalling(filled_keys.value()[i])] = value_de_marshalling(filled_values.value()[i]); |
| 479 | + } |
| 480 | + return result; |
| 481 | + } |
| 482 | + |
407 | 483 | } // namespace types
|
408 | 484 | } // namespace marshalling
|
409 | 485 | } // namespace nil
|
|
0 commit comments