Skip to content

Commit c77ca34

Browse files
committed
Split with_pools.hpp into save and load
1 parent 6b47b15 commit c77ca34

14 files changed

+178
-163
lines changed

immer/extra/persist/cereal/load.hpp

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#pragma once
2+
3+
#include <immer/extra/persist/cereal/policy.hpp>
4+
#include <immer/extra/persist/detail/cereal/input_archive_util.hpp>
5+
#include <immer/extra/persist/detail/cereal/pools.hpp>
6+
#include <immer/extra/persist/detail/cereal/wrap.hpp>
7+
8+
namespace immer::persist {
9+
10+
/**
11+
* @brief Load a value of the given type `T` from the provided stream using
12+
* pools. By default, `cereal::JSONInputArchive` is used but a different
13+
* `cereal` input archive can be provided.
14+
*
15+
* @ingroup persist-api
16+
*/
17+
template <class T,
18+
class Archive = cereal::JSONInputArchive,
19+
Policy<T> Policy = default_policy,
20+
class... Args>
21+
T cereal_load_with_pools(std::istream& is,
22+
const Policy& policy = Policy{},
23+
Args&&... args)
24+
{
25+
using TypesSet =
26+
decltype(boost::hana::to_set(policy.get_pool_types(std::declval<T>())));
27+
using Pools = decltype(detail::generate_input_pools(TypesSet{}));
28+
29+
auto get_pool_name_fn = [](const auto& value) {
30+
return Policy{}.get_pool_name(value);
31+
};
32+
using PoolNameFn = decltype(get_pool_name_fn);
33+
34+
const auto wrap =
35+
detail::wrap_known_types(TypesSet{}, detail::wrap_for_loading);
36+
auto pools = load_pools<Pools, Archive, PoolNameFn>(is, wrap);
37+
38+
auto ar = immer::persist::input_pools_cereal_archive_wrapper<Archive,
39+
Pools,
40+
decltype(wrap),
41+
PoolNameFn>{
42+
std::move(pools), wrap, is, std::forward<Args>(args)...};
43+
auto value0 = T{};
44+
policy.load(ar, value0);
45+
return value0;
46+
}
47+
48+
/**
49+
* @brief Load a value of the given type `T` from the provided string using
50+
* pools. By default, `cereal::JSONInputArchive` is used but a different
51+
* `cereal` input archive can be provided.
52+
*
53+
* @ingroup persist-api
54+
*/
55+
template <class T,
56+
class Archive = cereal::JSONInputArchive,
57+
Policy<T> Policy = default_policy>
58+
T cereal_load_with_pools(const std::string& input,
59+
const Policy& policy = Policy{})
60+
{
61+
auto is = std::istringstream{input};
62+
return cereal_load_with_pools<T, Archive>(is, policy);
63+
}
64+
65+
} // namespace immer::persist

immer/extra/persist/cereal/save.hpp

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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

immer/extra/persist/cereal/with_pools.hpp

-155
This file was deleted.

immer/extra/persist/detail/array/pool.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <immer/extra/cereal/immer_array.hpp>
44
#include <immer/extra/cereal/immer_vector.hpp>
55
#include <immer/extra/persist/detail/common/pool.hpp>
6+
#include <immer/extra/persist/detail/traits.hpp>
7+
#include <immer/extra/persist/errors.hpp>
68

79
#include <boost/hana/functional/id.hpp>
810

immer/extra/persist/detail/node_ptr.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <functional>
34
#include <immer/vector.hpp>
45

56
namespace immer::persist::detail {

immer/extra/persist/transform.hpp

+28
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,34 @@ namespace immer::persist {
88
* @defgroup persist-transform
99
*/
1010

11+
/**
12+
* @brief Return just the pools of all the containers of the provided value
13+
* serialized using the provided policy.
14+
*
15+
* @ingroup persist-transform
16+
* @see convert_container
17+
*/
18+
template <typename T, Policy<T> Policy = hana_struct_auto_policy>
19+
auto get_output_pools(const T& value0, const Policy& policy = Policy{})
20+
{
21+
const auto types = boost::hana::to_set(policy.get_pool_types(value0));
22+
auto pools = detail::generate_output_pools(types);
23+
const auto wrap = detail::wrap_known_types(types, detail::wrap_for_saving);
24+
using Pools = std::decay_t<decltype(pools)>;
25+
26+
{
27+
auto ar = output_pools_cereal_archive_wrapper<
28+
detail::blackhole_output_archive,
29+
Pools,
30+
decltype(wrap),
31+
detail::empty_name_fn>{pools, wrap};
32+
ar(CEREAL_NVP(value0));
33+
ar.finalize();
34+
pools = std::move(ar).get_output_pools();
35+
}
36+
return pools;
37+
}
38+
1139
/**
1240
* Given output_pools and a map of transformations, produce a new type of
1341
* input pools with those transformations applied.

test/extra/persist/CMakeLists.txt

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ add_executable(
2222
test_table_box_recursive.cpp
2323
test_for_docs.cpp
2424
${PROJECT_SOURCE_DIR}/immer/extra/persist/xxhash/xxhash_64.cpp)
25-
target_precompile_headers(persist-tests PRIVATE
26-
<immer/extra/persist/cereal/with_pools.hpp>)
25+
target_precompile_headers(
26+
persist-tests PRIVATE <immer/extra/persist/cereal/save.hpp>
27+
<immer/extra/persist/cereal/load.hpp>)
2728
add_dependencies(tests persist-tests)
2829
add_test("test/persist-tests" persist-tests)
2930
target_include_directories(persist-tests PRIVATE ${CMAKE_SOURCE_DIR})

test/extra/persist/test_circular_dependency_conversion.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <catch2/catch_test_macros.hpp>
22

3-
#include <immer/extra/persist/cereal/with_pools.hpp>
3+
#include <immer/extra/persist/cereal/save.hpp>
44
#include <immer/extra/persist/transform.hpp>
55

66
#include "utils.hpp"

test/extra/persist/test_conversion.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <catch2/catch_test_macros.hpp>
22

3-
#include <immer/extra/persist/cereal/with_pools.hpp>
3+
#include <immer/extra/persist/cereal/save.hpp>
44
#include <immer/extra/persist/detail/type_traverse.hpp>
55
#include <immer/extra/persist/transform.hpp>
66

test/extra/persist/test_for_docs.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <catch2/catch_test_macros.hpp>
22

3-
#include <immer/extra/persist/cereal/with_pools.hpp>
3+
#include <immer/extra/persist/cereal/save.hpp>
44
#include <immer/extra/persist/transform.hpp>
55

66
#include "utils.hpp"

test/extra/persist/test_special_pool.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "utils.hpp"
66

77
#include <boost/hana.hpp>
8-
#include <immer/extra/persist/cereal/with_pools.hpp>
8+
#include <immer/extra/persist/cereal/save.hpp>
99
#include <immer/extra/persist/xxhash/xxhash.hpp>
1010

1111
// to save std::pair

test/extra/persist/test_special_pool_auto.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
#include "utils.hpp"
66

7-
#include <immer/extra/persist/cereal/with_pools.hpp>
7+
#include <immer/extra/persist/cereal/save.hpp>
88
#include <immer/extra/persist/transform.hpp>
99
#include <nlohmann/json.hpp>
1010

0 commit comments

Comments
 (0)