Skip to content

Commit

Permalink
Make persist compatible with C++17
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sparus committed Sep 11, 2024
1 parent ccb0a91 commit f7cff0f
Show file tree
Hide file tree
Showing 36 changed files with 295 additions and 144 deletions.
2 changes: 1 addition & 1 deletion doc/persist-introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Dependencies
------------

In addition to the `dependencies <introduction.html#dependencies>`_ of
``immer``, this library makes use of **C++20**, `Boost.Hana
``immer``, this library makes use of **C++17**, `Boost.Hana
<https://boostorg.github.io/hana/>`_, `fmt <https://fmt.dev/>`_ and
`cereal <https://uscilab.github.io/cereal/>`_.

Expand Down
2 changes: 2 additions & 0 deletions extra/fuzzer/persist/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ foreach(_file IN LISTS immer_fuzzers)
add_executable(${_target} EXCLUDE_FROM_ALL "${_file}")
set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output})
target_compile_options(${_target} PUBLIC ${immer_fuzzing_engine})
target_compile_options(${_target} PRIVATE ${immer_fuzzing_engine}
-Wno-c++20-designator)
target_include_directories(${_target} PRIVATE ../..)
target_link_libraries(${_target} PUBLIC ${immer_fuzzing_engine} immer-dev)
add_dependencies(fuzzers ${_target})
Expand Down
3 changes: 2 additions & 1 deletion extra/fuzzer/persist/flex-vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
#include <array>

namespace {
void require_eq(const auto& a, const auto& b)
template <class T>
void require_eq(const T& a, const T& b)
{
if (a != b) {
throw std::runtime_error{
Expand Down
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@
"-Dimmer_BUILD_TESTS=ON"
"-Dimmer_BUILD_PERSIST_TESTS=ON"
"-Dimmer_BUILD_EXAMPLES=OFF"
"-DCXX_STANDARD=20"
"-DCXX_STANDARD=17"
];
});
};
Expand Down
8 changes: 4 additions & 4 deletions immer/extra/persist/cereal/archives.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ struct blackhole_output_archive
// blackhole_output_archive doesn't care about names
struct empty_name_fn
{
void operator()(const auto& container) const {}
template <class T>
void operator()(const T& container) const
{
}
};

template <class Pools>
Expand Down Expand Up @@ -99,15 +102,13 @@ class output_pools_cereal_archive_wrapper

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

template <class... Args>
output_pools_cereal_archive_wrapper(Pools pools_, Args&&... args)
requires std::is_same_v<WrapFn, boost::hana::id_t>
: cereal::OutputArchive<output_pools_cereal_archive_wrapper>{this}
, previous{std::forward<Args>(args)...}
, pools{std::move(pools_)}
Expand Down Expand Up @@ -279,7 +280,6 @@ class input_pools_cereal_archive_wrapper

template <class... Args>
input_pools_cereal_archive_wrapper(Pools pools_, Args&&... args)
requires std::is_same_v<WrapFn, boost::hana::id_t>
: cereal::InputArchive<input_pools_cereal_archive_wrapper>{this}
, previous{std::forward<Args>(args)...}
, pools{std::move(pools_)}
Expand Down
13 changes: 5 additions & 8 deletions immer/extra/persist/cereal/load.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ namespace immer::persist {
* @ingroup persist-api
*/
template <class T,
class Archive = cereal::JSONInputArchive,
Policy<T> Policy = default_policy,
class Archive = cereal::JSONInputArchive,
class Policy = default_policy,
class... Args>
T cereal_load_with_pools(std::istream& is,
const Policy& policy = Policy{},
Expand All @@ -26,10 +26,7 @@ T cereal_load_with_pools(std::istream& is,
decltype(boost::hana::to_set(policy.get_pool_types(std::declval<T>())));
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);
using PoolNameFn = get_pool_name_fn_t<Policy>;

const auto wrap =
detail::wrap_known_types(TypesSet{}, detail::wrap_for_loading);
Expand All @@ -53,8 +50,8 @@ T cereal_load_with_pools(std::istream& is,
* @ingroup persist-api
*/
template <class T,
class Archive = cereal::JSONInputArchive,
Policy<T> Policy = default_policy>
class Archive = cereal::JSONInputArchive,
class Policy = default_policy>
T cereal_load_with_pools(const std::string& input,
const Policy& policy = Policy{})
{
Expand Down
53 changes: 30 additions & 23 deletions immer/extra/persist/cereal/policy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,6 @@ namespace immer::persist {
* @defgroup persist-policy
*/

/**
* @brief Policy is a type that describes certain aspects of serialization for
* `immer::persist`.
* - How to call into the `cereal` archive to save and load the
* user-provided value. Can be used to serealize the value inline (without the
* `value0` node) by taking a dependency on <a
* href="https://github.com/LowCostCustoms/cereal-inline">cereal-inline</a>, for
* example.
* - Types of `immer` containers that will be serialized using pools. One
* pool contains nodes of only one `immer` container type.
* - Names for each per-type pool.
*
* @ingroup persist-policy
*/
template <class T, class Value>
concept Policy =
requires(Value value, T policy) { policy.get_pool_types(value); };

template <class T>
auto get_pools_names(const T&)
{
Expand Down Expand Up @@ -67,6 +49,20 @@ struct value0_serialize_t
}
};

/**
* @brief Policy is a type that describes certain aspects of serialization for
* `immer::persist`.
* - How to call into the `cereal` archive to save and load the
* user-provided value. Can be used to serealize the value inline (without the
* `value0` node) by taking a dependency on <a
* href="https://github.com/LowCostCustoms/cereal-inline">cereal-inline</a>, for
* example.
* - Types of `immer` containers that will be serialized using pools. One
* pool contains nodes of only one `immer` container type.
* - Names for each per-type pool.
*
* @ingroup persist-policy
*/
template <class T>
struct via_get_pools_names_policy_t : value0_serialize_t
{
Expand Down Expand Up @@ -100,9 +96,10 @@ struct via_get_pools_names_policy_t : value0_serialize_t
*
* @ingroup persist-policy
*/
auto via_get_pools_names_policy(const auto& value)
template <class T>
auto via_get_pools_names_policy(const T& value)
{
return via_get_pools_names_policy_t<std::decay_t<decltype(value)>>{};
return via_get_pools_names_policy_t<std::decay_t<T>>{};
}

/**
Expand Down Expand Up @@ -187,12 +184,22 @@ struct hana_struct_auto_member_name_policy_t : value0_serialize_t
*
* @ingroup persist-policy
*/
auto hana_struct_auto_member_name_policy(const auto& value)
template <class T>
auto hana_struct_auto_member_name_policy(const T& value)
{
return hana_struct_auto_member_name_policy_t<
std::decay_t<decltype(value)>>{};
return hana_struct_auto_member_name_policy_t<std::decay_t<T>>{};
}

using default_policy = via_get_pools_types_policy;

template <class Policy>
struct get_pool_name_fn_t
{
template <class T>
auto operator()(const T& value) const
{
return Policy{}.get_pool_name(value);
}
};

} // namespace immer::persist
13 changes: 5 additions & 8 deletions immer/extra/persist/cereal/save.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace immer::persist {
*/
template <class Archive = cereal::JSONOutputArchive,
class T,
Policy<T> Policy = default_policy,
class Policy = default_policy,
class... Args>
void cereal_save_with_pools(std::ostream& os,
const T& value0,
Expand All @@ -31,14 +31,11 @@ void cereal_save_with_pools(std::ostream& os,
auto pools = detail::generate_output_pools(types);
const auto wrap = detail::wrap_known_types(types, detail::wrap_for_saving);
using Pools = std::decay_t<decltype(pools)>;
auto get_pool_name_fn = [](const auto& value) {
return Policy{}.get_pool_name(value);
};
auto ar = immer::persist::output_pools_cereal_archive_wrapper<
auto ar = immer::persist::output_pools_cereal_archive_wrapper<
Archive,
Pools,
decltype(wrap),
decltype(get_pool_name_fn)>{
get_pool_name_fn_t<Policy>>{
pools, wrap, os, std::forward<Args>(args)...};
policy.save(ar, value0);
// Calling finalize explicitly, as it might throw on saving the pools,
Expand All @@ -56,14 +53,14 @@ void cereal_save_with_pools(std::ostream& os,
*/
template <class Archive = cereal::JSONOutputArchive,
class T,
Policy<T> Policy = default_policy,
class 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<Archive>(
cereal_save_with_pools<Archive, T, Policy>(
os, value0, policy, std::forward<Args>(args)...);
return os.str();
}
Expand Down
11 changes: 9 additions & 2 deletions immer/extra/persist/detail/alias.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,15 @@ struct type_alias
{
}

friend bool operator==(const type_alias& left,
const type_alias& right) = default;
friend bool operator==(const type_alias& left, const type_alias& right)
{
return left.value == right.value;
}

friend bool operator!=(const type_alias& left, const type_alias& right)
{
return left.value != right.value;
}

/**
* This works only starting with fmt v10.
Expand Down
12 changes: 9 additions & 3 deletions immer/extra/persist/detail/array/pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ struct output_pool
return left.arrays == right.arrays;
}

friend bool operator!=(const output_pool& left, const output_pool& right)
{
return left.arrays != right.arrays;
}

template <class Archive>
void save(Archive& ar) const
{
Expand Down Expand Up @@ -78,8 +83,10 @@ struct input_pool
{
immer::vector<immer::array<T, MemoryPolicy>> arrays;

friend bool operator==(const input_pool& left,
const input_pool& right) = default;
friend bool operator==(const input_pool& left, const input_pool& right)
{
return left.arrays == right.arrays;
}

template <class Archive>
void load(Archive& ar)
Expand Down Expand Up @@ -125,7 +132,6 @@ class loader
{
public:
explicit loader(Pool pool)
requires std::is_same_v<TransformF, boost::hana::id_t>
: pool_{std::move(pool)}
{
}
Expand Down
12 changes: 9 additions & 3 deletions immer/extra/persist/detail/box/pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ struct output_pool
return left.boxes == right.boxes;
}

friend bool operator!=(const output_pool& left, const output_pool& right)
{
return left.boxes != right.boxes;
}

template <class Archive>
void save(Archive& ar) const
{
Expand Down Expand Up @@ -64,8 +69,10 @@ struct input_pool
{
immer::vector<immer::box<T, MemoryPolicy>> boxes;

friend bool operator==(const input_pool& left,
const input_pool& right) = default;
friend bool operator==(const input_pool& left, const input_pool& right)
{
return left.boxes == right.boxes;
}

template <class Archive>
void load(Archive& ar)
Expand Down Expand Up @@ -141,7 +148,6 @@ class loader
{
public:
explicit loader(Pool pool)
requires std::is_same_v<TransformF, boost::hana::id_t>
: pool_{std::move(pool)}
{
}
Expand Down
4 changes: 2 additions & 2 deletions immer/extra/persist/detail/cereal/input_archive_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

namespace immer::persist::detail {

template <class Pools, class Archive, class PoolNameFn>
auto load_pools(std::istream& is, const auto& wrap)
template <class Pools, class Archive, class PoolNameFn, class WrapF>
auto load_pools(std::istream& is, const WrapF& wrap)
{
const auto reload_pool =
[wrap](std::istream& is, Pools pools, bool ignore_pool_exceptions) {
Expand Down
11 changes: 9 additions & 2 deletions immer/extra/persist/detail/cereal/persistable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,15 @@ struct persistable
{
}

friend bool operator==(const persistable& left,
const persistable& right) = default;
friend bool operator==(const persistable& left, const persistable& right)
{
return left.container == right.container;
}

friend bool operator!=(const persistable& left, const persistable& right)
{
return left.container != right.container;
}
};

template <class Previous,
Expand Down
12 changes: 9 additions & 3 deletions immer/extra/persist/detail/cereal/pools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ struct input_pool
input_pool() = default;

explicit input_pool(Pool pool_)
requires std::is_same_v<TransformF, boost::hana::id_t>
: pool{std::move(pool_)}
{
}
Expand Down Expand Up @@ -201,6 +200,11 @@ struct input_pool
return left.pool == right.pool;
}

friend bool operator!=(const input_pool& left, const input_pool& right)
{
return left.pool != right.pool;
}

void merge_previous(const input_pool& original)
{
pool.merge_previous(original.pool);
Expand Down Expand Up @@ -429,7 +433,8 @@ class input_pools
}
};

inline auto generate_output_pools(auto types)
template <class T>
auto generate_output_pools(T types)
{
auto storage =
hana::fold_left(types, hana::make_map(), [](auto map, auto type) {
Expand All @@ -444,7 +449,8 @@ inline auto generate_output_pools(auto types)
return output_pools<Storage>{storage};
}

inline auto generate_input_pools(auto types)
template <class T>
auto generate_input_pools(T types)
{
auto storage =
hana::fold_left(types, hana::make_map(), [](auto map, auto type) {
Expand Down
Loading

0 comments on commit f7cff0f

Please sign in to comment.