|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include <immer/extra/persist/cereal/policy.hpp> |
| 4 | +#include <immer/extra/persist/detail/cereal/pools.hpp> |
| 5 | +#include <immer/extra/persist/detail/cereal/wrap.hpp> |
| 6 | + |
| 7 | +namespace immer::persist { |
| 8 | + |
| 9 | +/** |
| 10 | + * @defgroup persist-api |
| 11 | + */ |
| 12 | + |
| 13 | +/** |
| 14 | + * @brief Serialize the provided value with pools using the provided policy |
| 15 | + * outputting into the provided stream. By default, `cereal::JSONOutputArchive` |
| 16 | + * is used but a different `cereal` output archive can be provided. |
| 17 | + * |
| 18 | + * @see Policy |
| 19 | + * @ingroup persist-api |
| 20 | + */ |
| 21 | +template <class Archive = cereal::JSONOutputArchive, |
| 22 | + class T, |
| 23 | + Policy<T> Policy = default_policy, |
| 24 | + class... Args> |
| 25 | +void cereal_save_with_pools(std::ostream& os, |
| 26 | + const T& value0, |
| 27 | + const Policy& policy = Policy{}, |
| 28 | + Args&&... args) |
| 29 | +{ |
| 30 | + const auto types = boost::hana::to_set(policy.get_pool_types(value0)); |
| 31 | + auto pools = detail::generate_output_pools(types); |
| 32 | + const auto wrap = detail::wrap_known_types(types, detail::wrap_for_saving); |
| 33 | + using Pools = std::decay_t<decltype(pools)>; |
| 34 | + auto get_pool_name_fn = [](const auto& value) { |
| 35 | + return Policy{}.get_pool_name(value); |
| 36 | + }; |
| 37 | + auto ar = immer::persist::output_pools_cereal_archive_wrapper< |
| 38 | + Archive, |
| 39 | + Pools, |
| 40 | + decltype(wrap), |
| 41 | + decltype(get_pool_name_fn)>{ |
| 42 | + pools, wrap, os, std::forward<Args>(args)...}; |
| 43 | + policy.save(ar, value0); |
| 44 | + // Calling finalize explicitly, as it might throw on saving the pools, |
| 45 | + // for example if pool names are not unique. |
| 46 | + ar.finalize(); |
| 47 | +} |
| 48 | + |
| 49 | +/** |
| 50 | + * @brief Serialize the provided value with pools using the provided policy. By |
| 51 | + * default, `cereal::JSONOutputArchive` is used but a different `cereal` output |
| 52 | + * archive can be provided. |
| 53 | + * |
| 54 | + * @return std::string The resulting JSON. |
| 55 | + * @ingroup persist-api |
| 56 | + */ |
| 57 | +template <class Archive = cereal::JSONOutputArchive, |
| 58 | + class T, |
| 59 | + Policy<T> Policy = default_policy, |
| 60 | + class... Args> |
| 61 | +std::string cereal_save_with_pools(const T& value0, |
| 62 | + const Policy& policy = Policy{}, |
| 63 | + Args&&... args) |
| 64 | +{ |
| 65 | + auto os = std::ostringstream{}; |
| 66 | + cereal_save_with_pools<Archive>( |
| 67 | + os, value0, policy, std::forward<Args>(args)...); |
| 68 | + return os.str(); |
| 69 | +} |
| 70 | + |
| 71 | +} // namespace immer::persist |
0 commit comments