ossrv_pub/boost_apis/boost/serialization/variant.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 #ifndef BOOST_SERIALIZATION_VARIANT_HPP
       
     2 #define BOOST_SERIALIZATION_VARIANT_HPP
       
     3 
       
     4 // MS compatible compilers support #pragma once
       
     5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
       
     6 # pragma once
       
     7 #endif
       
     8 
       
     9 #if defined(_MSC_VER) && (_MSC_VER <= 1020)
       
    10 #  pragma warning (disable : 4786) // too long name, harmless warning
       
    11 #endif
       
    12 
       
    13 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
       
    14 // variant.hpp - non-intrusive serialization of variant types
       
    15 //
       
    16 // copyright (c) 2005   
       
    17 // troy d. straszheim <troy@resophonic.com>
       
    18 // http://www.resophonic.com
       
    19 //
       
    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)
       
    23 //
       
    24 // See http://www.boost.org for updates, documentation, and revision history.
       
    25 //
       
    26 // thanks to Robert Ramey, Peter Dimov, and Richard Crossley.
       
    27 //
       
    28 
       
    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>
       
    35 
       
    36 #include <boost/throw_exception.hpp>
       
    37 
       
    38 #include <boost/variant.hpp>
       
    39 
       
    40 #include <boost/archive/archive_exception.hpp>
       
    41 
       
    42 #include <boost/serialization/split_free.hpp>
       
    43 #include <boost/serialization/serialization.hpp>
       
    44 
       
    45 namespace boost {
       
    46 namespace serialization {
       
    47 
       
    48 template<class Archive>
       
    49 struct variant_save_visitor : boost::static_visitor<> {
       
    50     variant_save_visitor(Archive& ar) :
       
    51         m_ar(ar)
       
    52     {}
       
    53     template<class T>
       
    54     void operator()(T const & value) const
       
    55     {
       
    56         m_ar << BOOST_SERIALIZATION_NVP(value);
       
    57     }
       
    58 private:
       
    59     Archive & m_ar;
       
    60 };
       
    61 
       
    62 template<class Archive, BOOST_VARIANT_ENUM_PARAMS(/* typename */ class T)>
       
    63 void save(
       
    64     Archive & ar,
       
    65     boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const & v,
       
    66     unsigned int version
       
    67 ){
       
    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);
       
    73 }
       
    74 
       
    75 template<class S>
       
    76 struct variant_impl {
       
    77 
       
    78     struct load_null {
       
    79         template<class Archive, class V>
       
    80         static void invoke(
       
    81             Archive & ar,
       
    82             int which,
       
    83             V & v,
       
    84             unsigned int version
       
    85         ){}
       
    86     };
       
    87 
       
    88     struct load_impl {
       
    89         template<class Archive, class V>
       
    90         static void invoke(
       
    91             Archive & ar,
       
    92             int which,
       
    93             V & v,
       
    94             unsigned int version
       
    95         ){
       
    96             if(which == 0){
       
    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;
       
   102                 head_type value;
       
   103                 ar >> BOOST_SERIALIZATION_NVP(value);
       
   104                 v = value;
       
   105                 ar.reset_object_address(& boost::get<head_type>(v), & value);
       
   106                 return;
       
   107             }
       
   108             typedef BOOST_DEDUCED_TYPENAME mpl::pop_front<S>::type type;
       
   109             variant_impl<type>::load(ar, which - 1, v, version);
       
   110         }
       
   111     };
       
   112 
       
   113     template<class Archive, class V>
       
   114     static void load(
       
   115         Archive & ar,
       
   116         int which,
       
   117         V & v,
       
   118         unsigned int version
       
   119     ){
       
   120         typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<mpl::empty<S>,
       
   121             mpl::identity<load_null>,
       
   122             mpl::identity<load_impl>
       
   123         >::type typex;
       
   124         typex::invoke(ar, which, v, version);
       
   125     }
       
   126 
       
   127 };
       
   128 
       
   129 template<class Archive, BOOST_VARIANT_ENUM_PARAMS(/* typename */ class T)>
       
   130 void load(
       
   131     Archive & ar, 
       
   132     boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& v,
       
   133     unsigned int version
       
   134 ){
       
   135     int which;
       
   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::throw_exception(
       
   141             boost::archive::archive_exception(
       
   142                 boost::archive::archive_exception::unsupported_version
       
   143             )
       
   144         );
       
   145     variant_impl<types>::load(ar, which, v, version);
       
   146 }
       
   147 
       
   148 template<class Archive,BOOST_VARIANT_ENUM_PARAMS(/* typename */ class T)>
       
   149 inline void serialize(
       
   150     Archive & ar,
       
   151     boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> & v,
       
   152     unsigned int file_version
       
   153 ){
       
   154     split_free(ar,v,file_version);
       
   155 }
       
   156 
       
   157 } // namespace serialization
       
   158 } // namespace boost
       
   159 
       
   160 #endif //BOOST_SERIALIZATION_VARIANT_HPP
       
   161