Skip to content

Commit

Permalink
Define policies to control how pool types and names are defined
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sparus committed Jun 4, 2024
1 parent d3311d9 commit 4ab992b
Show file tree
Hide file tree
Showing 15 changed files with 1,015 additions and 893 deletions.
8 changes: 7 additions & 1 deletion immer/extra/persist/common/type_traverse.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <immer/box.hpp>
#include <immer/flex_vector.hpp>
#include <immer/map.hpp>
#include <immer/set.hpp>
Expand Down Expand Up @@ -125,7 +126,7 @@ constexpr auto insert_conditionally = [](auto map, auto pair) {
* Generate a map (type, member_name) for all members of a given type,
* recursively.
*/
inline auto get_inner_types(const auto& type)
inline auto get_inner_types_map(const auto& type)
{
namespace hana = boost::hana;

Expand Down Expand Up @@ -159,4 +160,9 @@ inline auto get_inner_types(const auto& type)
return hana::to_map(result);
}

inline auto get_inner_types(const auto& type)
{
return boost::hana::keys(get_inner_types_map(type));
}

} // namespace immer::persist::util
60 changes: 34 additions & 26 deletions immer/extra/persist/json/json_immer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ struct blackhole_output_archive
}
};

// blackhole_output_archive doesn't care about names
struct empty_name_fn
{
auto operator()(const auto& container) const { return ""; }
};

template <class T>
class error_duplicate_pool_name_found;

Expand Down Expand Up @@ -85,32 +91,34 @@ constexpr bool is_pool_empty()
* Adapted from cereal/archives/adapters.hpp
*/

template <class Previous, class Pools, class WrapF = boost::hana::id_t>
template <class Previous, class Pools, class WrapFn, class PoolNameFn>
class json_immer_output_archive
: public cereal::OutputArchive<
json_immer_output_archive<Previous, Pools, WrapF>>
json_immer_output_archive<Previous, Pools, WrapFn, PoolNameFn>>
, public cereal::traits::TextArchive
{
public:
using pool_name_fn = PoolNameFn;

template <class... Args>
explicit json_immer_output_archive(Args&&... args)
requires std::is_same_v<WrapF, boost::hana::id_t>
requires std::is_same_v<WrapFn, boost::hana::id_t>
: cereal::OutputArchive<json_immer_output_archive>{this}
, previous{std::forward<Args>(args)...}
{
}

template <class... Args>
json_immer_output_archive(Pools pools_, Args&&... args)
requires std::is_same_v<WrapF, boost::hana::id_t>
requires std::is_same_v<WrapFn, boost::hana::id_t>
: cereal::OutputArchive<json_immer_output_archive>{this}
, previous{std::forward<Args>(args)...}
, pools{std::move(pools_)}
{
}

template <class... Args>
json_immer_output_archive(Pools pools_, WrapF wrap_, Args&&... args)
json_immer_output_archive(Pools pools_, WrapFn wrap_, Args&&... args)
: cereal::OutputArchive<json_immer_output_archive>{this}
, wrap{std::move(wrap_)}
, previous{std::forward<Args>(args)...}
Expand Down Expand Up @@ -197,7 +205,7 @@ class json_immer_output_archive
}

private:
template <class Previous_, class Pools_, class WrapF_>
template <class Previous_, class Pools_, class WrapFn_, class PoolNameFn_>
friend class json_immer_output_archive;

// Recursively serializes the pools but not calling finalize
Expand All @@ -207,19 +215,15 @@ class json_immer_output_archive
auto ar =
json_immer_output_archive<detail::blackhole_output_archive,
Pools,
decltype(wrap)>{pools, wrap};
decltype(wrap),
detail::empty_name_fn>{pools, wrap};
// Do not try to serialize pools again inside of this temporary
// archive
ar.finalized = true;
ar(pools);
return std::move(ar).get_output_pools();
};

using Names = typename Pools::names_t;
using IsUnique = decltype(detail::are_type_names_unique(Names{}));
static_assert(IsUnique::value,
"Pool names for each type must be unique");

auto prev = pools;
while (true) {
// Keep saving pools until everything is saved.
Expand All @@ -232,30 +236,32 @@ class json_immer_output_archive
}

private:
WrapF wrap;
WrapFn wrap;
Previous previous;
Pools pools;
bool finalized{false};
};

template <class Previous, class Pools, class WrapF = boost::hana::id_t>
template <class Previous, class Pools, class WrapFn, class PoolNameFn>
class json_immer_input_archive
: public cereal::InputArchive<
json_immer_input_archive<Previous, Pools, WrapF>>
json_immer_input_archive<Previous, Pools, WrapFn, PoolNameFn>>
, public cereal::traits::TextArchive
{
public:
using pool_name_fn = PoolNameFn;

template <class... Args>
json_immer_input_archive(Pools pools_, Args&&... args)
requires std::is_same_v<WrapF, boost::hana::id_t>
requires std::is_same_v<WrapFn, boost::hana::id_t>
: cereal::InputArchive<json_immer_input_archive>{this}
, previous{std::forward<Args>(args)...}
, pools{std::move(pools_)}
{
}

template <class... Args>
json_immer_input_archive(Pools pools_, WrapF wrap_, Args&&... args)
json_immer_input_archive(Pools pools_, WrapFn wrap_, Args&&... args)
: cereal::InputArchive<json_immer_input_archive>{this}
, wrap{std::move(wrap_)}
, previous{std::forward<Args>(args)...}
Expand Down Expand Up @@ -333,7 +339,7 @@ class json_immer_input_archive
bool ignore_pool_exceptions = false;

private:
WrapF wrap;
WrapFn wrap;
Previous previous;
Pools pools;

Expand All @@ -347,19 +353,21 @@ class json_immer_input_archive
namespace cereal {
namespace traits {
namespace detail {
template <class Previous, class Pools, class WrapF>
template <class Previous, class Pools, class WrapFn, class PoolNameFn>
struct get_output_from_input<
immer::persist::json_immer_input_archive<Previous, Pools, WrapF>>
immer::persist::
json_immer_input_archive<Previous, Pools, WrapFn, PoolNameFn>>
{
using type =
immer::persist::json_immer_output_archive<Previous, Pools, WrapF>;
using type = immer::persist::
json_immer_output_archive<Previous, Pools, WrapFn, PoolNameFn>;
};
template <class Previous, class Pools, class WrapF>
template <class Previous, class Pools, class WrapFn, class PoolNameFn>
struct get_input_from_output<
immer::persist::json_immer_output_archive<Previous, Pools, WrapF>>
immer::persist::
json_immer_output_archive<Previous, Pools, WrapFn, PoolNameFn>>
{
using type =
immer::persist::json_immer_input_archive<Previous, Pools, WrapF>;
using type = immer::persist::
json_immer_input_archive<Previous, Pools, WrapFn, PoolNameFn>;
};
} // namespace detail
} // namespace traits
Expand Down
Loading

0 comments on commit 4ab992b

Please sign in to comment.