#ifndef BOOST_SERIALIZATION_VARIANT_HPP #define BOOST_SERIALIZATION_VARIANT_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #if defined(_MSC_VER) && (_MSC_VER <= 1020) # pragma warning (disable : 4786) // too long name, harmless warning #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // variant.hpp - non-intrusive serialization of variant types // // copyright (c) 2005 // troy d. straszheim // http://www.resophonic.com // // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org for updates, documentation, and revision history. // // thanks to Robert Ramey, Peter Dimov, and Richard Crossley. // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace serialization { namespace detail { template struct write_variant_value_to_archive_visitor : boost::static_visitor<> { write_variant_value_to_archive_visitor(OArchive& archive) : archive(archive) {} template void operator() (T const& value) const { archive << BOOST_SERIALIZATION_NVP(value); } private: OArchive& archive; }; namespace mpl = ::boost::mpl; /** select type in Types by Index but * return int on out-of-range */ template struct SelectWithDefault : mpl::eval_if< //check range mpl::less< mpl::int_, mpl::size >, //if ok, choose by Index mpl::at< Types, mpl::int_ >, //else return int mpl::identity > {}; } //namespace detail /////////////////////////////////////////////////////////////////////////////// // serialization is split up into save/load /////////////////////////////////////// // save template< typename OArchive, BOOST_VARIANT_ENUM_PARAMS(typename T) > void save( OArchive& archive, boost::variant const &var, const unsigned int /*version*/ ) { const unsigned int which = var.which(); archive << BOOST_SERIALIZATION_NVP(which); detail::write_variant_value_to_archive_visitor writer(archive); apply_visitor(writer, var); } /////////////////////////////////////// // load template< typename IArchive, BOOST_VARIANT_ENUM_PARAMS(typename T) > void load( IArchive& archive, boost::variant& var, const unsigned int /*version*/ ) { namespace mpl = ::boost::mpl; //convienient typedefs / constants typedef variant Variant; typedef BOOST_DEDUCED_TYPENAME Variant::types Types; const int TypesLen = mpl::size::value; unsigned int which; archive >> BOOST_SERIALIZATION_NVP(which); if( which >= TypesLen ) boost::throw_exception( boost::archive::archive_exception( boost::archive::archive_exception::unsupported_version ) ); //dispatch type by 'which' //for which>=TypesLen try to read an int; //the int type is provided by SelectWithDefault //the code for reading these ints should actually // not be executed, since always which::type value; \ archive >> boost::serialization::make_nvp("data", t); \ var = value; \ archive.reset_object_address(&var, &value); \ } \ break; \ /**/ BOOST_PP_REPEAT( BOOST_VARIANT_LIMIT_TYPES, BOOST_SERIALIZATION_VARIANT_SWITCH_MACRO, _ ) #undef BOOST_SERIALIZATION_VARIANT_SWITCH_MACRO }; } /////////////////////////////////////// // call to split template< typename Archive, BOOST_VARIANT_ENUM_PARAMS(typename T) > inline void serialize( Archive& archive, boost::variant& var, const unsigned int version ) { split_free(archive, var, version); } }} //namespace boost::serialization #endif