| | #ifndef BOOST_SERIALIZATION_STD_VARIANT_HPP |
| | #define BOOST_SERIALIZATION_STD_VARIANT_HPP |
| |
|
| | |
| | #if defined(_MSC_VER) |
| | # pragma once |
| | #endif |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include <boost/serialization/throw_exception.hpp> |
| |
|
| | #include <variant> |
| |
|
| | #include <boost/archive/archive_exception.hpp> |
| |
|
| | #include <boost/serialization/split_free.hpp> |
| | #include <boost/serialization/serialization.hpp> |
| | #include <boost/serialization/nvp.hpp> |
| |
|
| | namespace boost { |
| | namespace serialization { |
| |
|
| | template<class Archive> |
| | struct std_variant_save_visitor |
| | { |
| | std_variant_save_visitor(Archive& ar) : |
| | m_ar(ar) |
| | {} |
| | template<class T> |
| | void operator()(T const & value) const |
| | { |
| | m_ar << BOOST_SERIALIZATION_NVP(value); |
| | } |
| | private: |
| | Archive & m_ar; |
| | }; |
| |
|
| |
|
| | template<class Archive> |
| | struct std_variant_load_visitor |
| | { |
| | std_variant_load_visitor(Archive& ar) : |
| | m_ar(ar) |
| | {} |
| | template<class T> |
| | void operator()(T & value) const |
| | { |
| | m_ar >> BOOST_SERIALIZATION_NVP(value); |
| | } |
| | private: |
| | Archive & m_ar; |
| | }; |
| |
|
| | template<class Archive, class ...Types> |
| | void save( |
| | Archive & ar, |
| | std::variant<Types...> const & v, |
| | unsigned int |
| | ){ |
| | const std::size_t which = v.index(); |
| | ar << BOOST_SERIALIZATION_NVP(which); |
| | std_variant_save_visitor<Archive> visitor(ar); |
| | std::visit(visitor, v); |
| | } |
| |
|
| | |
| | namespace mp { |
| | namespace detail { |
| | template <typename Seq> |
| | struct front_impl; |
| |
|
| | template <template <typename...> class Seq, typename T, typename... Ts> |
| | struct front_impl<Seq<T, Ts...>> { |
| | using type = T; |
| | }; |
| |
|
| | template <typename Seq> |
| | struct pop_front_impl; |
| |
|
| | template <template <typename...> class Seq, typename T, typename... Ts> |
| | struct pop_front_impl<Seq<T, Ts...>> { |
| | using type = Seq<Ts...>; |
| | }; |
| | } |
| |
|
| | template <typename... Ts> |
| | struct typelist {}; |
| |
|
| | template <typename Seq> |
| | using front = typename detail::front_impl<Seq>::type; |
| |
|
| | template <typename Seq> |
| | using pop_front = typename detail::pop_front_impl<Seq>::type; |
| | } |
| |
|
| | template<std::size_t N, class Seq> |
| | struct variant_impl |
| | { |
| | template<class Archive, class V> |
| | static void load ( |
| | Archive & ar, |
| | std::size_t which, |
| | V & v, |
| | const unsigned int version |
| | ){ |
| | if(which == 0){ |
| | |
| | |
| | |
| | |
| | using type = mp::front<Seq>; |
| | type value; |
| | ar >> BOOST_SERIALIZATION_NVP(value); |
| | v = std::move(value); |
| | type * new_address = & std::get<type>(v); |
| | ar.reset_object_address(new_address, & value); |
| | return; |
| | } |
| | |
| | using types = mp::pop_front<Seq>; |
| | variant_impl<N - 1, types>::load(ar, which - 1, v, version); |
| | } |
| | }; |
| |
|
| | template<class Seq> |
| | struct variant_impl<0, Seq> |
| | { |
| | template<class Archive, class V> |
| | static void load ( |
| | Archive & , |
| | std::size_t , |
| | V & , |
| | const unsigned int |
| | ){} |
| | }; |
| |
|
| | template<class Archive, class... Types> |
| | void load( |
| | Archive & ar, |
| | std::variant<Types...>& v, |
| | const unsigned int version |
| | ){ |
| | std::size_t which; |
| | ar >> BOOST_SERIALIZATION_NVP(which); |
| | if(which >= sizeof...(Types)) |
| | |
| | boost::serialization::throw_exception( |
| | boost::archive::archive_exception( |
| | boost::archive::archive_exception::unsupported_version |
| | ) |
| | ); |
| | variant_impl<sizeof...(Types), mp::typelist<Types...>>::load(ar, which, v, version); |
| | } |
| |
|
| | template<class Archive,class... Types> |
| | inline void serialize( |
| | Archive & ar, |
| | std::variant<Types...> & v, |
| | const unsigned int file_version |
| | ){ |
| | split_free(ar,v,file_version); |
| | } |
| |
|
| | |
| | template<class Archive> |
| | void serialize(Archive &ar, std::monostate &, const unsigned int ) |
| | {} |
| |
|
| | } |
| | } |
| |
|
| | |
| |
|
| | #include <boost/serialization/tracking.hpp> |
| |
|
| | namespace boost { |
| | namespace serialization { |
| |
|
| | template<class... Types> |
| | struct tracking_level< |
| | std::variant<Types...> |
| | >{ |
| | typedef mpl::integral_c_tag tag; |
| | typedef mpl::int_< ::boost::serialization::track_always> type; |
| | BOOST_STATIC_CONSTANT(int, value = type::value); |
| | }; |
| |
|
| | } |
| | } |
| |
|
| | #endif |
| |
|