-
-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cereal implementation for immer::map #105
Comments
I use this code. I could maybe add it to the repo some time. Note that it uses a different shape if the element stored has an attrbute called #pragma once
#include <cereal/cereal.hpp>
#include <immer/map.hpp>
namespace cereal {
template <typename Element>
auto get_auto_id(const Element& x) -> decltype(x.id)
{
return x.id;
}
template <typename K, typename T>
struct has_auto_id : std::false_type
{};
template <typename T>
struct has_auto_id<std::decay_t<decltype(get_auto_id(std::declval<T>()))>, T>
: std::true_type
{};
template <typename Archive,
typename K,
typename T,
typename H,
typename E,
typename MP,
std::uint32_t B>
std::enable_if_t<has_auto_id<K, T>::value>
CEREAL_LOAD_FUNCTION_NAME(Archive& ar, immer::map<K, T, H, E, MP, B>& m)
{
size_type size;
ar(make_size_tag(size));
for (auto i = size_type{}; i < size; ++i) {
T x;
ar(x);
auto id = get_auto_id(x);
m = std::move(m).set(std::move(id), std::move(x));
}
if (size != m.size())
throw std::runtime_error{"duplicate ids?"};
}
template <typename Archive,
typename K,
typename T,
typename H,
typename E,
typename MP,
std::uint32_t B>
std::enable_if_t<has_auto_id<K, T>::value>
CEREAL_SAVE_FUNCTION_NAME(Archive& ar, const immer::map<K, T, H, E, MP, B>& m)
{
ar(make_size_tag(static_cast<size_type>(m.size())));
for (auto&& v : m)
ar(v.second);
}
template <typename Archive,
typename K,
typename T,
typename H,
typename E,
typename MP,
std::uint32_t B>
std::enable_if_t<!has_auto_id<K, T>::value>
CEREAL_LOAD_FUNCTION_NAME(Archive& ar, immer::map<K, T, H, E, MP, B>& m)
{
size_type size;
ar(make_size_tag(size));
for (auto i = size_type{}; i < size; ++i) {
K k;
T x;
ar(make_map_item(k, x));
m = std::move(m).set(std::move(k), std::move(x));
}
if (size != m.size())
throw std::runtime_error{"duplicate ids?"};
}
template <typename Archive,
typename K,
typename T,
typename H,
typename E,
typename MP,
std::uint32_t B>
std::enable_if_t<!has_auto_id<K, T>::value>
CEREAL_SAVE_FUNCTION_NAME(Archive& ar, const immer::map<K, T, H, E, MP, B>& m)
{
ar(make_size_tag(static_cast<size_type>(m.size())));
for (auto&& v : m)
ar(make_map_item(v.first, v.second));
}
} // namespace cereal |
Thank you! Works perfectly :) would make sense to have this in the repo, at least from an easy-start point of view. Or maybe in the immer library itself? |
Yes, it probably should! I have a bunch of Lager related utilities that I often copy from project to project and I've been thinking for some time about what the best way to add them here is. Prob for this one I can just copy it in the |
I'll reopen this as a reminder :) |
Is there a cereal serializer (or load/save pair) available for the
immer::map
type? It seems like there is code forimmer::vector
,immer::flex_vector
etc. in thelager/debug/cereal/
folder, but I cannot find one for map.I'm asking because adapting the load/save functionality in the todos example is giving a compile error from cereal about missing implementation for the map type.
If it's not available, can someone provide a pointer to how one would go about implementing it? I assume I could adapt the vector/flex_vector code:
My C++ fu is weak so any advice is greatly appreciated! Thanks :)
The text was updated successfully, but these errors were encountered: