shared_ptr.hpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #ifndef BOOST_SERIALIZATION_SHARED_PTR_HPP
  2. #define BOOST_SERIALIZATION_SHARED_PTR_HPP
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER)
  5. # pragma once
  6. #endif
  7. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  8. // shared_ptr.hpp: serialization for boost shared pointer
  9. // (C) Copyright 2004 Robert Ramey and Martin Ecker
  10. // Use, modification and distribution is subject to the Boost Software
  11. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. // See http://www.boost.org for updates, documentation, and revision history.
  14. #include <cstddef> // NULL
  15. #include <memory>
  16. #include <boost/config.hpp>
  17. #include <boost/mpl/integral_c.hpp>
  18. #include <boost/mpl/integral_c_tag.hpp>
  19. #include <boost/detail/workaround.hpp>
  20. #include <boost/shared_ptr.hpp>
  21. #include <boost/serialization/shared_ptr_helper.hpp>
  22. #include <boost/serialization/split_free.hpp>
  23. #include <boost/serialization/nvp.hpp>
  24. #include <boost/serialization/version.hpp>
  25. #include <boost/serialization/tracking.hpp>
  26. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  27. // boost:: shared_ptr serialization traits
  28. // version 1 to distinguish from boost 1.32 version. Note: we can only do this
  29. // for a template when the compiler supports partial template specialization
  30. #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  31. namespace boost {
  32. namespace serialization{
  33. template<class T>
  34. struct version< ::boost::shared_ptr< T > > {
  35. typedef mpl::integral_c_tag tag;
  36. #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
  37. typedef typename mpl::int_<1> type;
  38. #else
  39. typedef mpl::int_<1> type;
  40. #endif
  41. BOOST_STATIC_CONSTANT(int, value = type::value);
  42. };
  43. // don't track shared pointers
  44. template<class T>
  45. struct tracking_level< ::boost::shared_ptr< T > > {
  46. typedef mpl::integral_c_tag tag;
  47. #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
  48. typedef typename mpl::int_< ::boost::serialization::track_never> type;
  49. #else
  50. typedef mpl::int_< ::boost::serialization::track_never> type;
  51. #endif
  52. BOOST_STATIC_CONSTANT(int, value = type::value);
  53. };
  54. }}
  55. #define BOOST_SERIALIZATION_SHARED_PTR(T)
  56. #else
  57. // define macro to let users of these compilers do this
  58. #define BOOST_SERIALIZATION_SHARED_PTR(T) \
  59. BOOST_CLASS_VERSION( \
  60. ::boost::shared_ptr< T >, \
  61. 1 \
  62. ) \
  63. BOOST_CLASS_TRACKING( \
  64. ::boost::shared_ptr< T >, \
  65. ::boost::serialization::track_never \
  66. ) \
  67. /**/
  68. #endif
  69. namespace boost {
  70. namespace serialization{
  71. struct null_deleter {
  72. void operator()(void const *) const {}
  73. };
  74. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  75. // serialization for boost::shared_ptr
  76. // Using a constant means that all shared pointers are held in the same set.
  77. // Thus we detect handle multiple pointers to the same value instances
  78. // in the archive.
  79. void * const shared_ptr_helper_id = 0;
  80. template<class Archive, class T>
  81. inline void save(
  82. Archive & ar,
  83. const boost::shared_ptr< T > &t,
  84. const unsigned int /* file_version */
  85. ){
  86. // The most common cause of trapping here would be serializing
  87. // something like shared_ptr<int>. This occurs because int
  88. // is never tracked by default. Wrap int in a trackable type
  89. BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
  90. const T * t_ptr = t.get();
  91. ar << boost::serialization::make_nvp("px", t_ptr);
  92. }
  93. #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
  94. template<class Archive, class T>
  95. inline void load(
  96. Archive & ar,
  97. boost::shared_ptr< T > &t,
  98. const unsigned int file_version
  99. ){
  100. // something like shared_ptr<int>. This occurs because int
  101. // is never tracked by default. Wrap int in a trackable type
  102. BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
  103. T* r;
  104. if(file_version < 1){
  105. ar.register_type(static_cast<
  106. boost_132::detail::sp_counted_base_impl<T *, null_deleter > *
  107. >(NULL));
  108. boost_132::shared_ptr< T > sp;
  109. ar >> boost::serialization::make_nvp("px", sp.px);
  110. ar >> boost::serialization::make_nvp("pn", sp.pn);
  111. // got to keep the sps around so the sp.pns don't disappear
  112. boost::serialization::shared_ptr_helper<boost::shared_ptr> & h =
  113. ar.template get_helper< shared_ptr_helper<boost::shared_ptr> >(
  114. shared_ptr_helper_id
  115. );
  116. h.append(sp);
  117. r = sp.get();
  118. }
  119. else{
  120. ar >> boost::serialization::make_nvp("px", r);
  121. }
  122. shared_ptr_helper<boost::shared_ptr> & h =
  123. ar.template get_helper<shared_ptr_helper<boost::shared_ptr> >(
  124. shared_ptr_helper_id
  125. );
  126. h.reset(t,r);
  127. }
  128. #else
  129. template<class Archive, class T>
  130. inline void load(
  131. Archive & ar,
  132. boost::shared_ptr< T > &t,
  133. const unsigned int /*file_version*/
  134. ){
  135. // The most common cause of trapping here would be serializing
  136. // something like shared_ptr<int>. This occurs because int
  137. // is never tracked by default. Wrap int in a trackable type
  138. BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
  139. T* r;
  140. ar >> boost::serialization::make_nvp("px", r);
  141. boost::serialization::shared_ptr_helper<boost::shared_ptr> & h =
  142. ar.template get_helper<shared_ptr_helper<boost::shared_ptr> >(
  143. shared_ptr_helper_id
  144. );
  145. h.reset(t,r);
  146. }
  147. #endif
  148. template<class Archive, class T>
  149. inline void serialize(
  150. Archive & ar,
  151. boost::shared_ptr< T > &t,
  152. const unsigned int file_version
  153. ){
  154. // correct shared_ptr serialization depends upon object tracking
  155. // being used.
  156. BOOST_STATIC_ASSERT(
  157. boost::serialization::tracking_level< T >::value
  158. != boost::serialization::track_never
  159. );
  160. boost::serialization::split_free(ar, t, file_version);
  161. }
  162. } // namespace serialization
  163. } // namespace boost
  164. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  165. // std::shared_ptr serialization traits
  166. // version 1 to distinguish from boost 1.32 version. Note: we can only do this
  167. // for a template when the compiler supports partial template specialization
  168. #ifndef BOOST_NO_CXX11_SMART_PTR
  169. #include <boost/static_assert.hpp>
  170. // note: we presume that any compiler/library which supports C++11
  171. // std::pointers also supports template partial specialization
  172. // trap here if such presumption were to turn out to wrong!!!
  173. #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  174. BOOST_STATIC_ASSERT(false);
  175. #endif
  176. namespace boost {
  177. namespace serialization{
  178. template<class T>
  179. struct version< ::std::shared_ptr< T > > {
  180. typedef mpl::integral_c_tag tag;
  181. typedef mpl::int_<1> type;
  182. BOOST_STATIC_CONSTANT(int, value = type::value);
  183. };
  184. // don't track shared pointers
  185. template<class T>
  186. struct tracking_level< ::std::shared_ptr< T > > {
  187. typedef mpl::integral_c_tag tag;
  188. typedef mpl::int_< ::boost::serialization::track_never> type;
  189. BOOST_STATIC_CONSTANT(int, value = type::value);
  190. };
  191. }}
  192. // the following just keeps older programs from breaking
  193. #define BOOST_SERIALIZATION_SHARED_PTR(T)
  194. namespace boost {
  195. namespace serialization{
  196. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  197. // serialization for std::shared_ptr
  198. template<class Archive, class T>
  199. inline void save(
  200. Archive & ar,
  201. const std::shared_ptr< T > &t,
  202. const unsigned int /* file_version */
  203. ){
  204. // The most common cause of trapping here would be serializing
  205. // something like shared_ptr<int>. This occurs because int
  206. // is never tracked by default. Wrap int in a trackable type
  207. BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
  208. const T * t_ptr = t.get();
  209. ar << boost::serialization::make_nvp("px", t_ptr);
  210. }
  211. template<class Archive, class T>
  212. inline void load(
  213. Archive & ar,
  214. std::shared_ptr< T > &t,
  215. const unsigned int /*file_version*/
  216. ){
  217. // The most common cause of trapping here would be serializing
  218. // something like shared_ptr<int>. This occurs because int
  219. // is never tracked by default. Wrap int in a trackable type
  220. BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
  221. T* r;
  222. ar >> boost::serialization::make_nvp("px", r);
  223. //void (* const id)(Archive &, std::shared_ptr< T > &, const unsigned int) = & load;
  224. boost::serialization::shared_ptr_helper<std::shared_ptr> & h =
  225. ar.template get_helper<
  226. shared_ptr_helper<std::shared_ptr>
  227. >(
  228. shared_ptr_helper_id
  229. );
  230. h.reset(t,r);
  231. }
  232. template<class Archive, class T>
  233. inline void serialize(
  234. Archive & ar,
  235. std::shared_ptr< T > &t,
  236. const unsigned int file_version
  237. ){
  238. // correct shared_ptr serialization depends upon object tracking
  239. // being used.
  240. BOOST_STATIC_ASSERT(
  241. boost::serialization::tracking_level< T >::value
  242. != boost::serialization::track_never
  243. );
  244. boost::serialization::split_free(ar, t, file_version);
  245. }
  246. } // namespace serialization
  247. } // namespace boost
  248. #endif // BOOST_NO_CXX11_SMART_PTR
  249. #endif // BOOST_SERIALIZATION_SHARED_PTR_HPP