os/ossrv/ossrv_pub/boost_apis/boost/serialization/shared_ptr.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 #ifndef BOOST_SERIALIZATION_SHARED_PTR_HPP
     2 #define BOOST_SERIALIZATION_SHARED_PTR_HPP
     3 
     4 // MS compatible compilers support #pragma once
     5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
     6 # pragma once
     7 #endif
     8 
     9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
    10 // shared_ptr.hpp: serialization for boost shared pointer
    11 
    12 // (C) Copyright 2004 Robert Ramey and Martin Ecker
    13 // Use, modification and distribution is subject to the Boost Software
    14 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    15 // http://www.boost.org/LICENSE_1_0.txt)
    16 
    17 //  See http://www.boost.org for updates, documentation, and revision history.
    18 
    19 #include <map>
    20 
    21 #include <boost/config.hpp>
    22 #include <boost/mpl/integral_c.hpp>
    23 #include <boost/mpl/integral_c_tag.hpp>
    24 
    25 #include <boost/detail/workaround.hpp>
    26 #include <boost/shared_ptr.hpp>
    27 #include <boost/throw_exception.hpp>
    28 
    29 #include <boost/archive/archive_exception.hpp>
    30 
    31 #include <boost/serialization/type_info_implementation.hpp>
    32 #include <boost/serialization/split_free.hpp>
    33 #include <boost/serialization/nvp.hpp>
    34 #include <boost/serialization/version.hpp>
    35 #include <boost/serialization/tracking.hpp>
    36 #include <boost/static_assert.hpp>
    37 
    38 #include <boost/serialization/void_cast_fwd.hpp>
    39 
    40 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
    41 // shared_ptr serialization traits
    42 // version 1 to distinguish from boost 1.32 version. Note: we can only do this
    43 // for a template when the compiler supports partial template specialization
    44 
    45 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
    46     namespace boost {
    47     namespace serialization{
    48         template<class T>
    49         struct version< ::boost::shared_ptr<T> > {
    50             typedef mpl::integral_c_tag tag;
    51 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
    52             typedef BOOST_DEDUCED_TYPENAME mpl::int_<1> type;
    53 #else
    54             typedef mpl::int_<1> type;
    55 #endif
    56 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
    57             BOOST_STATIC_CONSTANT(unsigned int, value = 1);
    58 #else
    59             BOOST_STATIC_CONSTANT(unsigned int, value = type::value);
    60 #endif
    61         };
    62         // don't track shared pointers
    63         template<class T>
    64         struct tracking_level< ::boost::shared_ptr<T> > { 
    65             typedef mpl::integral_c_tag tag;
    66 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
    67             typedef BOOST_DEDUCED_TYPENAME mpl::int_< ::boost::serialization::track_never> type;
    68 #else
    69             typedef mpl::int_< ::boost::serialization::track_never> type;
    70 #endif
    71 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
    72             BOOST_STATIC_CONSTANT(int, value = ::boost::serialization::track_never);
    73 #else
    74             BOOST_STATIC_CONSTANT(int, value = type::value);
    75 #endif
    76         };
    77     }}
    78     #define BOOST_SERIALIZATION_SHARED_PTR(T)
    79 #else
    80     // define macro to let users of these compilers do this
    81     #define BOOST_SERIALIZATION_SHARED_PTR(T)                         \
    82     BOOST_CLASS_VERSION(                                              \
    83         ::boost::shared_ptr< T >,                                     \
    84         1                                                             \
    85     )                                                                 \
    86     BOOST_CLASS_TRACKING(                                             \
    87         ::boost::shared_ptr< T >,                                     \
    88         ::boost::serialization::track_never                           \
    89     )                                                                 \
    90     /**/
    91 #endif
    92 
    93 namespace boost {
    94 namespace serialization{
    95 
    96 class extended_type_info;
    97 
    98 namespace detail {
    99 
   100 struct null_deleter {
   101     void operator()(void const *) const {}
   102 };
   103 
   104 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
   105 // a common class for holding various types of shared pointers
   106 
   107 class shared_ptr_helper {
   108     typedef std::map<void*, shared_ptr<void> > collection_type;
   109     typedef collection_type::const_iterator iterator_type;
   110     // list of shared_pointers create accessable by raw pointer. This
   111     // is used to "match up" shared pointers loaded at diferent
   112     // points in the archive
   113     collection_type m_pointers;
   114     // return a void pointer to the most derived type
   115     template<class T>
   116     void * object_identifier(T * t) const {
   117         const extended_type_info * true_type 
   118             = type_info_implementation<T>::type::get_derived_extended_type_info(*t);
   119         // note:if this exception is thrown, be sure that derived pointer
   120         // is either regsitered or exported.
   121         if(NULL == true_type)
   122             boost::throw_exception(
   123                 boost::archive::archive_exception(
   124                     boost::archive::archive_exception::unregistered_class
   125                 )
   126             );
   127         const boost::serialization::extended_type_info * this_type
   128             = boost::serialization::type_info_implementation<T>::type::get_instance();
   129         void * vp = void_downcast(*true_type, *this_type, t);
   130         return vp;
   131     }
   132 public:
   133     template<class T>
   134     void reset(shared_ptr<T> & s, T * r){
   135         if(NULL == r){
   136             s.reset();
   137             return;
   138         }
   139         // get pointer to the most derived object.  This is effectively
   140         // the object identifer
   141         void * od = object_identifier(r);
   142 
   143         iterator_type it = m_pointers.find(od);
   144 
   145         if(it == m_pointers.end()){
   146             s.reset(r);
   147             m_pointers.insert(collection_type::value_type(od,s));
   148         }
   149         else{
   150             s = static_pointer_cast<T>((*it).second);
   151         }
   152     }
   153     virtual ~shared_ptr_helper(){}
   154 };
   155 
   156 } // namespace detail
   157 
   158 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
   159 // utility function for creating/getting a helper - could be useful in general
   160 // but shared_ptr is the only class (so far that needs it) and I don't have a
   161 // convenient header to place it into.
   162 template<class Archive, class H>
   163 H &
   164 get_helper(Archive & ar){
   165     extended_type_info * eti = type_info_implementation<H>::type::get_instance();
   166     shared_ptr<void> sph;
   167     ar.lookup_helper(eti, sph);
   168     if(NULL == sph.get()){
   169         sph = shared_ptr<H>(new H);
   170         ar.insert_helper(eti, sph);
   171     }
   172     return * static_cast<H *>(sph.get());
   173 }
   174 
   175 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
   176 // serialization for shared_ptr
   177 
   178 template<class Archive, class T>
   179 inline void save(
   180     Archive & ar,
   181     const boost::shared_ptr<T> &t,
   182     const unsigned int /* file_version */
   183 ){
   184     // The most common cause of trapping here would be serializing
   185     // something like shared_ptr<int>.  This occurs because int
   186     // is never tracked by default.  Wrap int in a trackable type
   187     BOOST_STATIC_ASSERT((tracking_level<T>::value != track_never));
   188     const T * t_ptr = t.get();
   189     ar << boost::serialization::make_nvp("px", t_ptr);
   190 }
   191 
   192 template<class Archive, class T>
   193 inline void load(
   194     Archive & ar,
   195     boost::shared_ptr<T> &t,
   196     const unsigned int file_version
   197 ){
   198     // The most common cause of trapping here would be serializing
   199     // something like shared_ptr<int>.  This occurs because int
   200     // is never tracked by default.  Wrap int in a trackable type
   201     BOOST_STATIC_ASSERT((tracking_level<T>::value != track_never));
   202     T* r;
   203     #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
   204     if(file_version < 1){
   205         ar.register_type(static_cast<
   206             boost_132::detail::sp_counted_base_impl<T *, boost::checked_deleter<T> > *
   207         >(NULL));
   208         boost_132::shared_ptr<T> sp;
   209         ar >> boost::serialization::make_nvp("px", sp.px);
   210         ar >> boost::serialization::make_nvp("pn", sp.pn);
   211         // got to keep the sps around so the sp.pns don't disappear
   212         get_helper<Archive, boost_132::serialization::detail::shared_ptr_helper>(ar).append(sp);
   213         r = sp.get();
   214     }
   215     else    
   216     #endif
   217     {
   218         ar >> boost::serialization::make_nvp("px", r);
   219     }
   220     get_helper<Archive, detail::shared_ptr_helper >(ar).reset(t,r);
   221 }
   222 
   223 template<class Archive, class T>
   224 inline void serialize(
   225     Archive & ar,
   226     boost::shared_ptr<T> &t,
   227     const unsigned int file_version
   228 ){
   229     // correct shared_ptr serialization depends upon object tracking
   230     // being used.
   231     BOOST_STATIC_ASSERT(
   232         boost::serialization::tracking_level<T>::value
   233         != boost::serialization::track_never
   234     );
   235     boost::serialization::split_free(ar, t, file_version);
   236 }
   237 
   238 } // namespace serialization
   239 } // namespace boost
   240 
   241 #endif // BOOST_SERIALIZATION_SHARED_PTR_HPP