1 #ifndef BOOST_SERIALIZATION_VARIANT_HPP
2 #define BOOST_SERIALIZATION_VARIANT_HPP
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
9 #if defined(_MSC_VER) && (_MSC_VER <= 1020)
10 # pragma warning (disable : 4786) // too long name, harmless warning
13 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
14 // variant.hpp - non-intrusive serialization of variant types
17 // troy d. straszheim <troy@resophonic.com>
18 // http://www.resophonic.com
20 // Use, modification and distribution is subject to the Boost Software
21 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
22 // http://www.boost.org/LICENSE_1_0.txt)
24 // See http://www.boost.org for updates, documentation, and revision history.
26 // thanks to Robert Ramey, Peter Dimov, and Richard Crossley.
29 #include <boost/mpl/front.hpp>
30 #include <boost/mpl/pop_front.hpp>
31 #include <boost/mpl/eval_if.hpp>
32 #include <boost/mpl/identity.hpp>
33 #include <boost/mpl/size.hpp>
34 #include <boost/mpl/empty.hpp>
36 #include <boost/serialization/throw_exception.hpp>
38 #include <boost/variant.hpp>
40 #include <boost/archive/archive_exception.hpp>
42 #include <boost/serialization/split_free.hpp>
43 #include <boost/serialization/serialization.hpp>
46 namespace serialization
{
48 template<class Archive
>
49 struct variant_save_visitor
: boost::static_visitor
<> {
50 variant_save_visitor(Archive
& ar
) :
54 void operator()(T
const & value
) const
56 m_ar
<< BOOST_SERIALIZATION_NVP(value
);
62 template<class Archive
, BOOST_VARIANT_ENUM_PARAMS(/* typename */ class T
)>
65 boost::variant
<BOOST_VARIANT_ENUM_PARAMS(T
)> const & v
,
66 unsigned int /*version*/
68 int which
= v
.which();
69 ar
<< BOOST_SERIALIZATION_NVP(which
);
70 typedef BOOST_DEDUCED_TYPENAME
boost::variant
<BOOST_VARIANT_ENUM_PARAMS(T
)>::types types
;
71 variant_save_visitor
<Archive
> visitor(ar
);
72 v
.apply_visitor(visitor
);
79 template<class Archive
, class V
>
84 const unsigned int /*version*/
89 template<class Archive
, class V
>
94 const unsigned int version
97 // note: A non-intrusive implementation (such as this one)
98 // necessary has to copy the value. This wouldn't be necessary
99 // with an implementation that de-serialized to the address of the
100 // aligned storage included in the variant.
101 typedef BOOST_DEDUCED_TYPENAME
mpl::front
<S
>::type head_type
;
103 ar
>> BOOST_SERIALIZATION_NVP(value
);
105 ar
.reset_object_address(& boost::get
<head_type
>(v
), & value
);
108 typedef BOOST_DEDUCED_TYPENAME
mpl::pop_front
<S
>::type type
;
109 variant_impl
<type
>::load(ar
, which
- 1, v
, version
);
113 template<class Archive
, class V
>
118 const unsigned int version
120 typedef BOOST_DEDUCED_TYPENAME
mpl::eval_if
<mpl::empty
<S
>,
121 mpl::identity
<load_null
>,
122 mpl::identity
<load_impl
>
124 typex::invoke(ar
, which
, v
, version
);
129 template<class Archive
, BOOST_VARIANT_ENUM_PARAMS(/* typename */ class T
)>
132 boost::variant
<BOOST_VARIANT_ENUM_PARAMS(T
)>& v
,
133 const unsigned int version
136 typedef BOOST_DEDUCED_TYPENAME
boost::variant
<BOOST_VARIANT_ENUM_PARAMS(T
)>::types types
;
137 ar
>> BOOST_SERIALIZATION_NVP(which
);
138 if(which
>= mpl::size
<types
>::value
)
139 // this might happen if a type was removed from the list of variant types
140 boost::serialization::throw_exception(
141 boost::archive::archive_exception(
142 boost::archive::archive_exception::unsupported_version
145 variant_impl
<types
>::load(ar
, which
, v
, version
);
148 template<class Archive
,BOOST_VARIANT_ENUM_PARAMS(/* typename */ class T
)>
149 inline void serialize(
151 boost::variant
<BOOST_VARIANT_ENUM_PARAMS(T
)> & v
,
152 const unsigned int file_version
154 split_free(ar
,v
,file_version
);
157 } // namespace serialization
160 #endif //BOOST_SERIALIZATION_VARIANT_HPP