mirror of
https://github.com/oxen-io/oxen-core.git
synced 2023-12-14 02:22:56 +01:00
b7dd5e8911
When targetting macos <10.14 macos won't allow use of anything from C++17 that throws, such as: - std::get on a variant - std::visit - std::optional::value() - std::any_cast This avoids all of these. For std::get, we either replace with std::get_if (where appropriate), or else use a `var::get` implementation of std::get added to lokimq (also updated here). (This `var` namespace is just an `std` alias everywhere *except* old target macos). For std::visit, likewise lokimq adds an var::visit implementation for old macos that we use. std::optional::value() uses weren't useful anyway as everywhere it calls them we've already checked that the option has a value, in which case we can use `*opt` (which doesn't check for contents and throw). std::any just has to be avoided as far as I can tell, but the one place we used it is only ever a block, so I just replaced it with a `const block*`.
52 lines
1.8 KiB
C++
52 lines
1.8 KiB
C++
#pragma once
|
|
|
|
// Adapts boost::serialization to support std::variant, serializing just as a boost::variant would
|
|
// be serialized (so that the serialized boost::variant<T...> and std::variant<T...> values are
|
|
// interchangeable).
|
|
//
|
|
|
|
#include <lokimq/variant.h>
|
|
|
|
#include <boost/archive/archive_exception.hpp>
|
|
|
|
#include <boost/serialization/split_free.hpp>
|
|
#include <boost/serialization/serialization.hpp>
|
|
#include <boost/serialization/nvp.hpp>
|
|
|
|
namespace boost::serialization {
|
|
|
|
template <class Archive, typename... T>
|
|
void save(Archive& ar, std::variant<T...> const& v, unsigned int /*version*/) {
|
|
int index = static_cast<int>(v.index());
|
|
ar << boost::serialization::make_nvp("which", index);
|
|
var::visit([&ar](const auto& v) { ar << boost::serialization::make_nvp("value", v); }, v);
|
|
}
|
|
|
|
template <class Archive, typename Variant, typename T, typename... More>
|
|
void load_variant_impl(Archive& ar, int index, Variant& v) {
|
|
if (index == 0) {
|
|
T value;
|
|
ar >> boost::serialization::make_nvp("value", value);
|
|
v = value;
|
|
ar.reset_object_address(&var::get<T>(v), &value);
|
|
}
|
|
else if constexpr (sizeof...(More) > 0) {
|
|
return load_variant_impl<Archive, Variant, More...>(ar, index - 1, v);
|
|
}
|
|
}
|
|
|
|
template <class Archive, typename... T>
|
|
void load(Archive & ar, std::variant<T...>& v, const unsigned int version) {
|
|
int index;
|
|
ar >> boost::serialization::make_nvp("which", index);
|
|
if (index < 0 || index >= (int) sizeof...(T))
|
|
throw boost::archive::archive_exception{boost::archive::archive_exception::unsupported_version};
|
|
load_variant_impl<Archive, std::variant<T...>, T...>(ar, index, v);
|
|
}
|
|
|
|
template <class Archive, typename... T>
|
|
inline void serialize(Archive& ar, std::variant<T...>& v, const unsigned int file_version) {
|
|
split_free(ar,v,file_version);
|
|
}
|
|
|
|
} // namespace boost::serialization
|