Skip to content

Commit 4ab992b

Browse files
committed
Define policies to control how pool types and names are defined
1 parent d3311d9 commit 4ab992b

15 files changed

+1015
-893
lines changed

immer/extra/persist/common/type_traverse.hpp

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

3+
#include <immer/box.hpp>
34
#include <immer/flex_vector.hpp>
45
#include <immer/map.hpp>
56
#include <immer/set.hpp>
@@ -125,7 +126,7 @@ constexpr auto insert_conditionally = [](auto map, auto pair) {
125126
* Generate a map (type, member_name) for all members of a given type,
126127
* recursively.
127128
*/
128-
inline auto get_inner_types(const auto& type)
129+
inline auto get_inner_types_map(const auto& type)
129130
{
130131
namespace hana = boost::hana;
131132

@@ -159,4 +160,9 @@ inline auto get_inner_types(const auto& type)
159160
return hana::to_map(result);
160161
}
161162

163+
inline auto get_inner_types(const auto& type)
164+
{
165+
return boost::hana::keys(get_inner_types_map(type));
166+
}
167+
162168
} // namespace immer::persist::util

immer/extra/persist/json/json_immer.hpp

+34-26
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ struct blackhole_output_archive
5050
}
5151
};
5252

53+
// blackhole_output_archive doesn't care about names
54+
struct empty_name_fn
55+
{
56+
auto operator()(const auto& container) const { return ""; }
57+
};
58+
5359
template <class T>
5460
class error_duplicate_pool_name_found;
5561

@@ -85,32 +91,34 @@ constexpr bool is_pool_empty()
8591
* Adapted from cereal/archives/adapters.hpp
8692
*/
8793

88-
template <class Previous, class Pools, class WrapF = boost::hana::id_t>
94+
template <class Previous, class Pools, class WrapFn, class PoolNameFn>
8995
class json_immer_output_archive
9096
: public cereal::OutputArchive<
91-
json_immer_output_archive<Previous, Pools, WrapF>>
97+
json_immer_output_archive<Previous, Pools, WrapFn, PoolNameFn>>
9298
, public cereal::traits::TextArchive
9399
{
94100
public:
101+
using pool_name_fn = PoolNameFn;
102+
95103
template <class... Args>
96104
explicit json_immer_output_archive(Args&&... args)
97-
requires std::is_same_v<WrapF, boost::hana::id_t>
105+
requires std::is_same_v<WrapFn, boost::hana::id_t>
98106
: cereal::OutputArchive<json_immer_output_archive>{this}
99107
, previous{std::forward<Args>(args)...}
100108
{
101109
}
102110

103111
template <class... Args>
104112
json_immer_output_archive(Pools pools_, Args&&... args)
105-
requires std::is_same_v<WrapF, boost::hana::id_t>
113+
requires std::is_same_v<WrapFn, boost::hana::id_t>
106114
: cereal::OutputArchive<json_immer_output_archive>{this}
107115
, previous{std::forward<Args>(args)...}
108116
, pools{std::move(pools_)}
109117
{
110118
}
111119

112120
template <class... Args>
113-
json_immer_output_archive(Pools pools_, WrapF wrap_, Args&&... args)
121+
json_immer_output_archive(Pools pools_, WrapFn wrap_, Args&&... args)
114122
: cereal::OutputArchive<json_immer_output_archive>{this}
115123
, wrap{std::move(wrap_)}
116124
, previous{std::forward<Args>(args)...}
@@ -197,7 +205,7 @@ class json_immer_output_archive
197205
}
198206

199207
private:
200-
template <class Previous_, class Pools_, class WrapF_>
208+
template <class Previous_, class Pools_, class WrapFn_, class PoolNameFn_>
201209
friend class json_immer_output_archive;
202210

203211
// Recursively serializes the pools but not calling finalize
@@ -207,19 +215,15 @@ class json_immer_output_archive
207215
auto ar =
208216
json_immer_output_archive<detail::blackhole_output_archive,
209217
Pools,
210-
decltype(wrap)>{pools, wrap};
218+
decltype(wrap),
219+
detail::empty_name_fn>{pools, wrap};
211220
// Do not try to serialize pools again inside of this temporary
212221
// archive
213222
ar.finalized = true;
214223
ar(pools);
215224
return std::move(ar).get_output_pools();
216225
};
217226

218-
using Names = typename Pools::names_t;
219-
using IsUnique = decltype(detail::are_type_names_unique(Names{}));
220-
static_assert(IsUnique::value,
221-
"Pool names for each type must be unique");
222-
223227
auto prev = pools;
224228
while (true) {
225229
// Keep saving pools until everything is saved.
@@ -232,30 +236,32 @@ class json_immer_output_archive
232236
}
233237

234238
private:
235-
WrapF wrap;
239+
WrapFn wrap;
236240
Previous previous;
237241
Pools pools;
238242
bool finalized{false};
239243
};
240244

241-
template <class Previous, class Pools, class WrapF = boost::hana::id_t>
245+
template <class Previous, class Pools, class WrapFn, class PoolNameFn>
242246
class json_immer_input_archive
243247
: public cereal::InputArchive<
244-
json_immer_input_archive<Previous, Pools, WrapF>>
248+
json_immer_input_archive<Previous, Pools, WrapFn, PoolNameFn>>
245249
, public cereal::traits::TextArchive
246250
{
247251
public:
252+
using pool_name_fn = PoolNameFn;
253+
248254
template <class... Args>
249255
json_immer_input_archive(Pools pools_, Args&&... args)
250-
requires std::is_same_v<WrapF, boost::hana::id_t>
256+
requires std::is_same_v<WrapFn, boost::hana::id_t>
251257
: cereal::InputArchive<json_immer_input_archive>{this}
252258
, previous{std::forward<Args>(args)...}
253259
, pools{std::move(pools_)}
254260
{
255261
}
256262

257263
template <class... Args>
258-
json_immer_input_archive(Pools pools_, WrapF wrap_, Args&&... args)
264+
json_immer_input_archive(Pools pools_, WrapFn wrap_, Args&&... args)
259265
: cereal::InputArchive<json_immer_input_archive>{this}
260266
, wrap{std::move(wrap_)}
261267
, previous{std::forward<Args>(args)...}
@@ -333,7 +339,7 @@ class json_immer_input_archive
333339
bool ignore_pool_exceptions = false;
334340

335341
private:
336-
WrapF wrap;
342+
WrapFn wrap;
337343
Previous previous;
338344
Pools pools;
339345

@@ -347,19 +353,21 @@ class json_immer_input_archive
347353
namespace cereal {
348354
namespace traits {
349355
namespace detail {
350-
template <class Previous, class Pools, class WrapF>
356+
template <class Previous, class Pools, class WrapFn, class PoolNameFn>
351357
struct get_output_from_input<
352-
immer::persist::json_immer_input_archive<Previous, Pools, WrapF>>
358+
immer::persist::
359+
json_immer_input_archive<Previous, Pools, WrapFn, PoolNameFn>>
353360
{
354-
using type =
355-
immer::persist::json_immer_output_archive<Previous, Pools, WrapF>;
361+
using type = immer::persist::
362+
json_immer_output_archive<Previous, Pools, WrapFn, PoolNameFn>;
356363
};
357-
template <class Previous, class Pools, class WrapF>
364+
template <class Previous, class Pools, class WrapFn, class PoolNameFn>
358365
struct get_input_from_output<
359-
immer::persist::json_immer_output_archive<Previous, Pools, WrapF>>
366+
immer::persist::
367+
json_immer_output_archive<Previous, Pools, WrapFn, PoolNameFn>>
360368
{
361-
using type =
362-
immer::persist::json_immer_input_archive<Previous, Pools, WrapF>;
369+
using type = immer::persist::
370+
json_immer_input_archive<Previous, Pools, WrapFn, PoolNameFn>;
363371
};
364372
} // namespace detail
365373
} // namespace traits

0 commit comments

Comments
 (0)