diff --git a/immer/extra/persist/cereal/load.hpp b/immer/extra/persist/cereal/load.hpp new file mode 100644 index 00000000..7ff99835 --- /dev/null +++ b/immer/extra/persist/cereal/load.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include +#include + +namespace immer::persist { + +/** + * @brief Load a value of the given type `T` from the provided stream using + * pools. By default, `cereal::JSONInputArchive` is used but a different + * `cereal` input archive can be provided. + * + * @ingroup persist-api + */ +template Policy = default_policy, + class... Args> +T cereal_load_with_pools(std::istream& is, + const Policy& policy = Policy{}, + Args&&... args) +{ + using TypesSet = + decltype(boost::hana::to_set(policy.get_pool_types(std::declval()))); + using Pools = decltype(detail::generate_input_pools(TypesSet{})); + + auto get_pool_name_fn = [](const auto& value) { + return Policy{}.get_pool_name(value); + }; + using PoolNameFn = decltype(get_pool_name_fn); + + const auto wrap = + detail::wrap_known_types(TypesSet{}, detail::wrap_for_loading); + auto pools = load_pools(is, wrap); + + auto ar = immer::persist::input_pools_cereal_archive_wrapper{ + std::move(pools), wrap, is, std::forward(args)...}; + auto value0 = T{}; + policy.load(ar, value0); + return value0; +} + +/** + * @brief Load a value of the given type `T` from the provided string using + * pools. By default, `cereal::JSONInputArchive` is used but a different + * `cereal` input archive can be provided. + * + * @ingroup persist-api + */ +template Policy = default_policy> +T cereal_load_with_pools(const std::string& input, + const Policy& policy = Policy{}) +{ + auto is = std::istringstream{input}; + return cereal_load_with_pools(is, policy); +} + +} // namespace immer::persist diff --git a/immer/extra/persist/cereal/save.hpp b/immer/extra/persist/cereal/save.hpp new file mode 100644 index 00000000..e37945ff --- /dev/null +++ b/immer/extra/persist/cereal/save.hpp @@ -0,0 +1,71 @@ +#pragma once + +#include +#include +#include + +namespace immer::persist { + +/** + * @defgroup persist-api + */ + +/** + * @brief Serialize the provided value with pools using the provided policy + * outputting into the provided stream. By default, `cereal::JSONOutputArchive` + * is used but a different `cereal` output archive can be provided. + * + * @see Policy + * @ingroup persist-api + */ +template Policy = default_policy, + class... Args> +void cereal_save_with_pools(std::ostream& os, + const T& value0, + const Policy& policy = Policy{}, + Args&&... args) +{ + const auto types = boost::hana::to_set(policy.get_pool_types(value0)); + auto pools = detail::generate_output_pools(types); + const auto wrap = detail::wrap_known_types(types, detail::wrap_for_saving); + using Pools = std::decay_t; + auto get_pool_name_fn = [](const auto& value) { + return Policy{}.get_pool_name(value); + }; + auto ar = immer::persist::output_pools_cereal_archive_wrapper< + Archive, + Pools, + decltype(wrap), + decltype(get_pool_name_fn)>{ + pools, wrap, os, std::forward(args)...}; + policy.save(ar, value0); + // Calling finalize explicitly, as it might throw on saving the pools, + // for example if pool names are not unique. + ar.finalize(); +} + +/** + * @brief Serialize the provided value with pools using the provided policy. By + * default, `cereal::JSONOutputArchive` is used but a different `cereal` output + * archive can be provided. + * + * @return std::string The resulting JSON. + * @ingroup persist-api + */ +template Policy = default_policy, + class... Args> +std::string cereal_save_with_pools(const T& value0, + const Policy& policy = Policy{}, + Args&&... args) +{ + auto os = std::ostringstream{}; + cereal_save_with_pools( + os, value0, policy, std::forward(args)...); + return os.str(); +} + +} // namespace immer::persist diff --git a/immer/extra/persist/cereal/with_pools.hpp b/immer/extra/persist/cereal/with_pools.hpp deleted file mode 100644 index 2828ddb8..00000000 --- a/immer/extra/persist/cereal/with_pools.hpp +++ /dev/null @@ -1,155 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace immer::persist { - -/** - * @defgroup persist-api - */ - -/** - * @brief Serialize the provided value with pools using the provided policy - * outputting into the provided stream. By default, `cereal::JSONOutputArchive` - * is used but a different `cereal` output archive can be provided. - * - * @see Policy - * @ingroup persist-api - */ -template Policy = default_policy, - class... Args> -void cereal_save_with_pools(std::ostream& os, - const T& value0, - const Policy& policy = Policy{}, - Args&&... args) -{ - const auto types = boost::hana::to_set(policy.get_pool_types(value0)); - auto pools = detail::generate_output_pools(types); - const auto wrap = detail::wrap_known_types(types, detail::wrap_for_saving); - using Pools = std::decay_t; - auto get_pool_name_fn = [](const auto& value) { - return Policy{}.get_pool_name(value); - }; - auto ar = immer::persist::output_pools_cereal_archive_wrapper< - Archive, - Pools, - decltype(wrap), - decltype(get_pool_name_fn)>{ - pools, wrap, os, std::forward(args)...}; - policy.save(ar, value0); - // Calling finalize explicitly, as it might throw on saving the pools, - // for example if pool names are not unique. - ar.finalize(); -} - -/** - * @brief Serialize the provided value with pools using the provided policy. By - * default, `cereal::JSONOutputArchive` is used but a different `cereal` output - * archive can be provided. - * - * @return std::string The resulting JSON. - * @ingroup persist-api - */ -template Policy = default_policy, - class... Args> -std::string cereal_save_with_pools(const T& value0, - const Policy& policy = Policy{}, - Args&&... args) -{ - auto os = std::ostringstream{}; - cereal_save_with_pools( - os, value0, policy, std::forward(args)...); - return os.str(); -} - -/** - * @brief Load a value of the given type `T` from the provided stream using - * pools. By default, `cereal::JSONInputArchive` is used but a different - * `cereal` input archive can be provided. - * - * @ingroup persist-api - */ -template Policy = default_policy, - class... Args> -T cereal_load_with_pools(std::istream& is, - const Policy& policy = Policy{}, - Args&&... args) -{ - using TypesSet = - decltype(boost::hana::to_set(policy.get_pool_types(std::declval()))); - using Pools = decltype(detail::generate_input_pools(TypesSet{})); - - auto get_pool_name_fn = [](const auto& value) { - return Policy{}.get_pool_name(value); - }; - using PoolNameFn = decltype(get_pool_name_fn); - - const auto wrap = - detail::wrap_known_types(TypesSet{}, detail::wrap_for_loading); - auto pools = load_pools(is, wrap); - - auto ar = immer::persist::input_pools_cereal_archive_wrapper{ - std::move(pools), wrap, is, std::forward(args)...}; - auto value0 = T{}; - policy.load(ar, value0); - return value0; -} - -/** - * @brief Load a value of the given type `T` from the provided string using - * pools. By default, `cereal::JSONInputArchive` is used but a different - * `cereal` input archive can be provided. - * - * @ingroup persist-api - */ -template Policy = default_policy> -T cereal_load_with_pools(const std::string& input, - const Policy& policy = Policy{}) -{ - auto is = std::istringstream{input}; - return cereal_load_with_pools(is, policy); -} - -/** - * @brief Return just the pools of all the containers of the provided value - * serialized using the provided policy. - * - * @ingroup persist-transform - * @see convert_container - */ -template Policy = hana_struct_auto_policy> -auto get_output_pools(const T& value0, const Policy& policy = Policy{}) -{ - const auto types = boost::hana::to_set(policy.get_pool_types(value0)); - auto pools = detail::generate_output_pools(types); - const auto wrap = detail::wrap_known_types(types, detail::wrap_for_saving); - using Pools = std::decay_t; - - { - auto ar = output_pools_cereal_archive_wrapper< - detail::blackhole_output_archive, - Pools, - decltype(wrap), - detail::empty_name_fn>{pools, wrap}; - ar(CEREAL_NVP(value0)); - ar.finalize(); - pools = std::move(ar).get_output_pools(); - } - return pools; -} - -} // namespace immer::persist diff --git a/immer/extra/persist/detail/array/pool.hpp b/immer/extra/persist/detail/array/pool.hpp index 72a8e205..5cee43a3 100644 --- a/immer/extra/persist/detail/array/pool.hpp +++ b/immer/extra/persist/detail/array/pool.hpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include diff --git a/immer/extra/persist/detail/node_ptr.hpp b/immer/extra/persist/detail/node_ptr.hpp index 449b95ee..ae0c55ba 100644 --- a/immer/extra/persist/detail/node_ptr.hpp +++ b/immer/extra/persist/detail/node_ptr.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include namespace immer::persist::detail { diff --git a/immer/extra/persist/transform.hpp b/immer/extra/persist/transform.hpp index ccd02a05..a4a6d72f 100644 --- a/immer/extra/persist/transform.hpp +++ b/immer/extra/persist/transform.hpp @@ -8,6 +8,34 @@ namespace immer::persist { * @defgroup persist-transform */ +/** + * @brief Return just the pools of all the containers of the provided value + * serialized using the provided policy. + * + * @ingroup persist-transform + * @see convert_container + */ +template Policy = hana_struct_auto_policy> +auto get_output_pools(const T& value0, const Policy& policy = Policy{}) +{ + const auto types = boost::hana::to_set(policy.get_pool_types(value0)); + auto pools = detail::generate_output_pools(types); + const auto wrap = detail::wrap_known_types(types, detail::wrap_for_saving); + using Pools = std::decay_t; + + { + auto ar = output_pools_cereal_archive_wrapper< + detail::blackhole_output_archive, + Pools, + decltype(wrap), + detail::empty_name_fn>{pools, wrap}; + ar(CEREAL_NVP(value0)); + ar.finalize(); + pools = std::move(ar).get_output_pools(); + } + return pools; +} + /** * Given output_pools and a map of transformations, produce a new type of * input pools with those transformations applied. diff --git a/test/extra/persist/CMakeLists.txt b/test/extra/persist/CMakeLists.txt index 3830cb92..213e3372 100644 --- a/test/extra/persist/CMakeLists.txt +++ b/test/extra/persist/CMakeLists.txt @@ -22,8 +22,9 @@ add_executable( test_table_box_recursive.cpp test_for_docs.cpp ${PROJECT_SOURCE_DIR}/immer/extra/persist/xxhash/xxhash_64.cpp) -target_precompile_headers(persist-tests PRIVATE - ) +target_precompile_headers( + persist-tests PRIVATE + ) add_dependencies(tests persist-tests) add_test("test/persist-tests" persist-tests) target_include_directories(persist-tests PRIVATE ${CMAKE_SOURCE_DIR}) diff --git a/test/extra/persist/test_circular_dependency_conversion.cpp b/test/extra/persist/test_circular_dependency_conversion.cpp index 1dfef4f5..391b0b09 100644 --- a/test/extra/persist/test_circular_dependency_conversion.cpp +++ b/test/extra/persist/test_circular_dependency_conversion.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include "utils.hpp" diff --git a/test/extra/persist/test_conversion.cpp b/test/extra/persist/test_conversion.cpp index cba50c96..bd60f3d8 100644 --- a/test/extra/persist/test_conversion.cpp +++ b/test/extra/persist/test_conversion.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include diff --git a/test/extra/persist/test_for_docs.cpp b/test/extra/persist/test_for_docs.cpp index eeec20f0..fc23ef1c 100644 --- a/test/extra/persist/test_for_docs.cpp +++ b/test/extra/persist/test_for_docs.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include "utils.hpp" diff --git a/test/extra/persist/test_special_pool.cpp b/test/extra/persist/test_special_pool.cpp index 8fa3fd15..d262ea1e 100644 --- a/test/extra/persist/test_special_pool.cpp +++ b/test/extra/persist/test_special_pool.cpp @@ -5,7 +5,7 @@ #include "utils.hpp" #include -#include +#include #include // to save std::pair diff --git a/test/extra/persist/test_special_pool_auto.cpp b/test/extra/persist/test_special_pool_auto.cpp index 400786de..e911f7d0 100644 --- a/test/extra/persist/test_special_pool_auto.cpp +++ b/test/extra/persist/test_special_pool_auto.cpp @@ -4,7 +4,7 @@ #include "utils.hpp" -#include +#include #include #include diff --git a/test/extra/persist/test_table_box_recursive.cpp b/test/extra/persist/test_table_box_recursive.cpp index d22635a0..365d970b 100644 --- a/test/extra/persist/test_table_box_recursive.cpp +++ b/test/extra/persist/test_table_box_recursive.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include diff --git a/test/extra/persist/utils.hpp b/test/extra/persist/utils.hpp index 45b06164..c3ca58be 100644 --- a/test/extra/persist/utils.hpp +++ b/test/extra/persist/utils.hpp @@ -1,5 +1,7 @@ #pragma once +#include +#include #include #include