Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 10 additions & 181 deletions include/boost/serialization/std_variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#endif

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// variant.hpp - non-intrusive serialization of variant types
// std_variant.hpp - deprecated, forwards to variant.hpp
//
// copyright (c) 2019 Samuel Debionne, ESRF
//
Expand All @@ -17,188 +17,17 @@
//
// See http://www.boost.org for updates, documentation, and revision history.
//
// Widely inspired form boost::variant serialization
//

#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 /*version*/
){
const std::size_t which = v.index();
ar << BOOST_SERIALIZATION_NVP(which);
std_variant_save_visitor<Archive> visitor(ar);
std::visit(visitor, v);
}

// Minimalist metaprogramming for handling parameter pack
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...>;
};
} //namespace detail

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;
} // namespace mp

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){
// note: A non-intrusive implementation (such as this one)
// necessary has to copy the value. This wouldn't be necessary
// with an implementation that de-serialized to the address of the
// aligned storage included in the variant.
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;
}
//typedef typename mpl::pop_front<S>::type type;
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 & /*ar*/,
std::size_t /*which*/,
V & /*v*/,
const unsigned int /*version*/
){}
};

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))
// this might happen if a type was removed from the list of variant 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);
}

// Specialization for std::monostate
template<class Archive>
void serialize(Archive &, std::monostate &, const unsigned int /*version*/)
{}

} // namespace serialization
} // namespace boost

//template<typename T0_, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)>
// variant.hpp serializes std::variant, next to boost::variant and
// boost::variant2::variant, and defines the same save, load and serialize
// this header used to, so the two could not both be included. Nothing is
// left here but the forwarding, which keeps code including this header
// working and lets it include variant.hpp as well.

#include <boost/serialization/tracking.hpp>
#include <boost/config/header_deprecated.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);
};
BOOST_HEADER_DEPRECATED("<boost/serialization/variant.hpp>")

} // namespace serialization
} // namespace boost
#include <boost/serialization/variant.hpp>

#endif //BOOST_SERIALIZATION_VARIANT_HPP
#endif // BOOST_SERIALIZATION_STD_VARIANT_HPP
174 changes: 0 additions & 174 deletions include/boost/serialization/variant2.hpp

This file was deleted.

1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ test-suite "serialization" :

# should compile
[ compile test_public_base_type.cpp ]
[ compile test_std_variant_forwarding.cpp ]
[ compile test_strong_typedef.cpp ]
;

Expand Down
Loading