Chris@16: #ifndef BOOST_SERIALIZATION_VARIANT_HPP Chris@16: #define BOOST_SERIALIZATION_VARIANT_HPP Chris@16: Chris@16: // MS compatible compilers support #pragma once Chris@101: #if defined(_MSC_VER) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 Chris@16: // variant.hpp - non-intrusive serialization of variant types Chris@16: // Chris@16: // copyright (c) 2005 Chris@16: // troy d. straszheim Chris@16: // http://www.resophonic.com Chris@16: // Chris@16: // Use, modification and distribution is subject to the Boost Software Chris@16: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // See http://www.boost.org for updates, documentation, and revision history. Chris@16: // Chris@16: // thanks to Robert Ramey, Peter Dimov, and Richard Crossley. Chris@16: // Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace serialization { Chris@16: Chris@16: template Chris@16: struct variant_save_visitor : Chris@16: boost::static_visitor<> Chris@16: { Chris@16: variant_save_visitor(Archive& ar) : Chris@16: m_ar(ar) Chris@16: {} Chris@16: template Chris@16: void operator()(T const & value) const Chris@16: { Chris@16: m_ar << BOOST_SERIALIZATION_NVP(value); Chris@16: } Chris@16: private: Chris@16: Archive & m_ar; Chris@16: }; Chris@16: Chris@16: template Chris@16: void save( Chris@16: Archive & ar, Chris@16: boost::variant const & v, Chris@16: unsigned int /*version*/ Chris@16: ){ Chris@16: int which = v.which(); Chris@16: ar << BOOST_SERIALIZATION_NVP(which); Chris@101: typedef typename boost::variant::types types; Chris@16: variant_save_visitor visitor(ar); Chris@16: v.apply_visitor(visitor); Chris@16: } Chris@16: Chris@16: template Chris@16: struct variant_impl { Chris@16: Chris@16: struct load_null { Chris@16: template Chris@16: static void invoke( Chris@16: Archive & /*ar*/, Chris@16: int /*which*/, Chris@16: V & /*v*/, Chris@16: const unsigned int /*version*/ Chris@16: ){} Chris@16: }; Chris@16: Chris@16: struct load_impl { Chris@16: template Chris@16: static void invoke( Chris@16: Archive & ar, Chris@16: int which, Chris@16: V & v, Chris@16: const unsigned int version Chris@16: ){ Chris@16: if(which == 0){ Chris@16: // note: A non-intrusive implementation (such as this one) Chris@16: // necessary has to copy the value. This wouldn't be necessary Chris@16: // with an implementation that de-serialized to the address of the Chris@16: // aligned storage included in the variant. Chris@101: typedef typename mpl::front::type head_type; Chris@16: head_type value; Chris@16: ar >> BOOST_SERIALIZATION_NVP(value); Chris@16: v = value; Chris@16: ar.reset_object_address(& boost::get(v), & value); Chris@16: return; Chris@16: } Chris@101: typedef typename mpl::pop_front::type type; Chris@16: variant_impl::load(ar, which - 1, v, version); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: static void load( Chris@16: Archive & ar, Chris@16: int which, Chris@16: V & v, Chris@16: const unsigned int version Chris@16: ){ Chris@101: typedef typename mpl::eval_if, Chris@16: mpl::identity, Chris@16: mpl::identity Chris@16: >::type typex; Chris@16: typex::invoke(ar, which, v, version); Chris@16: } Chris@16: Chris@16: }; Chris@16: Chris@16: template Chris@16: void load( Chris@16: Archive & ar, Chris@16: boost::variant& v, Chris@16: const unsigned int version Chris@16: ){ Chris@16: int which; Chris@101: typedef typename boost::variant::types types; Chris@16: ar >> BOOST_SERIALIZATION_NVP(which); Chris@16: if(which >= mpl::size::value) Chris@16: // this might happen if a type was removed from the list of variant types Chris@16: boost::serialization::throw_exception( Chris@16: boost::archive::archive_exception( Chris@16: boost::archive::archive_exception::unsupported_version Chris@16: ) Chris@16: ); Chris@16: variant_impl::load(ar, which, v, version); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void serialize( Chris@16: Archive & ar, Chris@16: boost::variant & v, Chris@16: const unsigned int file_version Chris@16: ){ Chris@16: split_free(ar,v,file_version); Chris@16: } Chris@16: Chris@16: } // namespace serialization Chris@16: } // namespace boost Chris@16: Chris@16: #endif //BOOST_SERIALIZATION_VARIANT_HPP