shared_ptr.hpp 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
  2. #define BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
  3. //
  4. // shared_ptr.hpp
  5. //
  6. // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
  7. // Copyright (c) 2001-2008 Peter Dimov
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See
  10. // accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. //
  13. // See http://www.boost.org/libs/smart_ptr/ for documentation.
  14. //
  15. #include <boost/smart_ptr/detail/shared_count.hpp>
  16. #include <boost/smart_ptr/detail/sp_convertible.hpp>
  17. #include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
  18. #include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
  19. #include <boost/smart_ptr/detail/sp_noexcept.hpp>
  20. #include <boost/checked_delete.hpp>
  21. #include <boost/throw_exception.hpp>
  22. #include <boost/assert.hpp>
  23. #include <boost/config.hpp>
  24. #include <boost/config/workaround.hpp>
  25. #if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
  26. #include <boost/smart_ptr/detail/spinlock_pool.hpp>
  27. #endif
  28. #include <algorithm> // for std::swap
  29. #include <functional> // for std::less
  30. #include <typeinfo> // for std::bad_cast
  31. #include <cstddef> // for std::size_t
  32. #include <memory> // for std::auto_ptr
  33. #if !defined(BOOST_NO_IOSTREAM)
  34. #if !defined(BOOST_NO_IOSFWD)
  35. #include <iosfwd> // for std::basic_ostream
  36. #else
  37. #include <ostream>
  38. #endif
  39. #endif
  40. #if defined( BOOST_SP_DISABLE_DEPRECATED )
  41. #pragma GCC diagnostic push
  42. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  43. #endif
  44. namespace boost
  45. {
  46. template<class T> class shared_ptr;
  47. template<class T> class weak_ptr;
  48. template<class T> class enable_shared_from_this;
  49. class enable_shared_from_raw;
  50. namespace movelib
  51. {
  52. template< class T, class D > class unique_ptr;
  53. } // namespace movelib
  54. namespace detail
  55. {
  56. // sp_element, element_type
  57. template< class T > struct sp_element
  58. {
  59. typedef T type;
  60. };
  61. #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  62. template< class T > struct sp_element< T[] >
  63. {
  64. typedef T type;
  65. };
  66. #if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
  67. template< class T, std::size_t N > struct sp_element< T[N] >
  68. {
  69. typedef T type;
  70. };
  71. #endif
  72. #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  73. // sp_dereference, return type of operator*
  74. template< class T > struct sp_dereference
  75. {
  76. typedef T & type;
  77. };
  78. template<> struct sp_dereference< void >
  79. {
  80. typedef void type;
  81. };
  82. #if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
  83. template<> struct sp_dereference< void const >
  84. {
  85. typedef void type;
  86. };
  87. template<> struct sp_dereference< void volatile >
  88. {
  89. typedef void type;
  90. };
  91. template<> struct sp_dereference< void const volatile >
  92. {
  93. typedef void type;
  94. };
  95. #endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
  96. #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  97. template< class T > struct sp_dereference< T[] >
  98. {
  99. typedef void type;
  100. };
  101. #if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
  102. template< class T, std::size_t N > struct sp_dereference< T[N] >
  103. {
  104. typedef void type;
  105. };
  106. #endif
  107. #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  108. // sp_member_access, return type of operator->
  109. template< class T > struct sp_member_access
  110. {
  111. typedef T * type;
  112. };
  113. #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  114. template< class T > struct sp_member_access< T[] >
  115. {
  116. typedef void type;
  117. };
  118. #if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
  119. template< class T, std::size_t N > struct sp_member_access< T[N] >
  120. {
  121. typedef void type;
  122. };
  123. #endif
  124. #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  125. // sp_array_access, return type of operator[]
  126. template< class T > struct sp_array_access
  127. {
  128. typedef void type;
  129. };
  130. #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  131. template< class T > struct sp_array_access< T[] >
  132. {
  133. typedef T & type;
  134. };
  135. #if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
  136. template< class T, std::size_t N > struct sp_array_access< T[N] >
  137. {
  138. typedef T & type;
  139. };
  140. #endif
  141. #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  142. // sp_extent, for operator[] index check
  143. template< class T > struct sp_extent
  144. {
  145. enum _vt { value = 0 };
  146. };
  147. #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  148. template< class T, std::size_t N > struct sp_extent< T[N] >
  149. {
  150. enum _vt { value = N };
  151. };
  152. #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  153. // enable_shared_from_this support
  154. template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
  155. {
  156. if( pe != 0 )
  157. {
  158. pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
  159. }
  160. }
  161. template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
  162. #ifdef _MANAGED
  163. // Avoid C4793, ... causes native code generation
  164. struct sp_any_pointer
  165. {
  166. template<class T> sp_any_pointer( T* ) {}
  167. };
  168. inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer )
  169. {
  170. }
  171. #else // _MANAGED
  172. inline void sp_enable_shared_from_this( ... )
  173. {
  174. }
  175. #endif // _MANAGED
  176. #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
  177. // rvalue auto_ptr support based on a technique by Dave Abrahams
  178. template< class T, class R > struct sp_enable_if_auto_ptr
  179. {
  180. };
  181. template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
  182. {
  183. typedef R type;
  184. };
  185. #endif
  186. // sp_assert_convertible
  187. template< class Y, class T > inline void sp_assert_convertible() BOOST_SP_NOEXCEPT
  188. {
  189. #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
  190. // static_assert( sp_convertible< Y, T >::value );
  191. typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ];
  192. (void)sizeof( tmp );
  193. #else
  194. T* p = static_cast< Y* >( 0 );
  195. (void)p;
  196. #endif
  197. }
  198. // pointer constructor helper
  199. template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
  200. {
  201. boost::detail::shared_count( p ).swap( pn );
  202. boost::detail::sp_enable_shared_from_this( ppx, p, p );
  203. }
  204. #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  205. template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
  206. {
  207. sp_assert_convertible< Y[], T[] >();
  208. boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
  209. }
  210. template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
  211. {
  212. sp_assert_convertible< Y[N], T[N] >();
  213. boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
  214. }
  215. #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  216. // deleter constructor helper
  217. template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p )
  218. {
  219. boost::detail::sp_enable_shared_from_this( ppx, p, p );
  220. }
  221. #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  222. template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ )
  223. {
  224. sp_assert_convertible< Y[], T[] >();
  225. }
  226. template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ )
  227. {
  228. sp_assert_convertible< Y[N], T[N] >();
  229. }
  230. #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  231. struct sp_internal_constructor_tag
  232. {
  233. };
  234. } // namespace detail
  235. //
  236. // shared_ptr
  237. //
  238. // An enhanced relative of scoped_ptr with reference counted copy semantics.
  239. // The object pointed to is deleted when the last shared_ptr pointing to it
  240. // is destroyed or reset.
  241. //
  242. template<class T> class shared_ptr
  243. {
  244. private:
  245. // Borland 5.5.1 specific workaround
  246. typedef shared_ptr<T> this_type;
  247. public:
  248. typedef typename boost::detail::sp_element< T >::type element_type;
  249. BOOST_CONSTEXPR shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn()
  250. {
  251. }
  252. #if !defined( BOOST_NO_CXX11_NULLPTR )
  253. BOOST_CONSTEXPR shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn()
  254. {
  255. }
  256. #endif
  257. BOOST_CONSTEXPR shared_ptr( boost::detail::sp_internal_constructor_tag, element_type * px_, boost::detail::shared_count const & pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( pn_ )
  258. {
  259. }
  260. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  261. BOOST_CONSTEXPR shared_ptr( boost::detail::sp_internal_constructor_tag, element_type * px_, boost::detail::shared_count && pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( std::move( pn_ ) )
  262. {
  263. }
  264. #endif
  265. template<class Y>
  266. explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
  267. {
  268. boost::detail::sp_pointer_construct( this, p, pn );
  269. }
  270. //
  271. // Requirements: D's copy constructor must not throw
  272. //
  273. // shared_ptr will release p by calling d(p)
  274. //
  275. template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
  276. {
  277. boost::detail::sp_deleter_construct( this, p );
  278. }
  279. #if !defined( BOOST_NO_CXX11_NULLPTR )
  280. template<class D> shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d )
  281. {
  282. }
  283. #endif
  284. // As above, but with allocator. A's copy constructor shall not throw.
  285. template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
  286. {
  287. boost::detail::sp_deleter_construct( this, p );
  288. }
  289. #if !defined( BOOST_NO_CXX11_NULLPTR )
  290. template<class D, class A> shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a )
  291. {
  292. }
  293. #endif
  294. // generated copy constructor, destructor are fine...
  295. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  296. // ... except in C++0x, move disables the implicit copy
  297. shared_ptr( shared_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
  298. {
  299. }
  300. #endif
  301. template<class Y>
  302. explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
  303. {
  304. boost::detail::sp_assert_convertible< Y, T >();
  305. // it is now safe to copy r.px, as pn(r.pn) did not throw
  306. px = r.px;
  307. }
  308. template<class Y>
  309. shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag )
  310. BOOST_SP_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
  311. {
  312. if( !pn.empty() )
  313. {
  314. px = r.px;
  315. }
  316. }
  317. template<class Y>
  318. #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
  319. shared_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
  320. #else
  321. shared_ptr( shared_ptr<Y> const & r )
  322. #endif
  323. BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
  324. {
  325. boost::detail::sp_assert_convertible< Y, T >();
  326. }
  327. // aliasing
  328. template< class Y >
  329. shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
  330. {
  331. }
  332. #ifndef BOOST_NO_AUTO_PTR
  333. template<class Y>
  334. explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn()
  335. {
  336. boost::detail::sp_assert_convertible< Y, T >();
  337. Y * tmp = r.get();
  338. pn = boost::detail::shared_count( r );
  339. boost::detail::sp_deleter_construct( this, tmp );
  340. }
  341. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  342. template<class Y>
  343. shared_ptr( std::auto_ptr<Y> && r ): px(r.get()), pn()
  344. {
  345. boost::detail::sp_assert_convertible< Y, T >();
  346. Y * tmp = r.get();
  347. pn = boost::detail::shared_count( r );
  348. boost::detail::sp_deleter_construct( this, tmp );
  349. }
  350. #elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  351. template<class Ap>
  352. explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
  353. {
  354. typedef typename Ap::element_type Y;
  355. boost::detail::sp_assert_convertible< Y, T >();
  356. Y * tmp = r.get();
  357. pn = boost::detail::shared_count( r );
  358. boost::detail::sp_deleter_construct( this, tmp );
  359. }
  360. #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  361. #endif // BOOST_NO_AUTO_PTR
  362. #if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  363. template< class Y, class D >
  364. shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
  365. {
  366. boost::detail::sp_assert_convertible< Y, T >();
  367. typename std::unique_ptr< Y, D >::pointer tmp = r.get();
  368. if( tmp != 0 )
  369. {
  370. pn = boost::detail::shared_count( r );
  371. boost::detail::sp_deleter_construct( this, tmp );
  372. }
  373. }
  374. #endif
  375. template< class Y, class D >
  376. shared_ptr( boost::movelib::unique_ptr< Y, D > r ): px( r.get() ), pn()
  377. {
  378. boost::detail::sp_assert_convertible< Y, T >();
  379. typename boost::movelib::unique_ptr< Y, D >::pointer tmp = r.get();
  380. if( tmp != 0 )
  381. {
  382. pn = boost::detail::shared_count( r );
  383. boost::detail::sp_deleter_construct( this, tmp );
  384. }
  385. }
  386. // assignment
  387. shared_ptr & operator=( shared_ptr const & r ) BOOST_SP_NOEXCEPT
  388. {
  389. this_type(r).swap(*this);
  390. return *this;
  391. }
  392. #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
  393. template<class Y>
  394. shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_SP_NOEXCEPT
  395. {
  396. this_type(r).swap(*this);
  397. return *this;
  398. }
  399. #endif
  400. #ifndef BOOST_NO_AUTO_PTR
  401. template<class Y>
  402. shared_ptr & operator=( std::auto_ptr<Y> & r )
  403. {
  404. this_type( r ).swap( *this );
  405. return *this;
  406. }
  407. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  408. template<class Y>
  409. shared_ptr & operator=( std::auto_ptr<Y> && r )
  410. {
  411. this_type( static_cast< std::auto_ptr<Y> && >( r ) ).swap( *this );
  412. return *this;
  413. }
  414. #elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  415. template<class Ap>
  416. typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
  417. {
  418. this_type( r ).swap( *this );
  419. return *this;
  420. }
  421. #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  422. #endif // BOOST_NO_AUTO_PTR
  423. #if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  424. template<class Y, class D>
  425. shared_ptr & operator=( std::unique_ptr<Y, D> && r )
  426. {
  427. this_type( static_cast< std::unique_ptr<Y, D> && >( r ) ).swap(*this);
  428. return *this;
  429. }
  430. #endif
  431. template<class Y, class D>
  432. shared_ptr & operator=( boost::movelib::unique_ptr<Y, D> r )
  433. {
  434. // this_type( static_cast< unique_ptr<Y, D> && >( r ) ).swap( *this );
  435. boost::detail::sp_assert_convertible< Y, T >();
  436. typename boost::movelib::unique_ptr< Y, D >::pointer p = r.get();
  437. shared_ptr tmp;
  438. if( p != 0 )
  439. {
  440. tmp.px = p;
  441. tmp.pn = boost::detail::shared_count( r );
  442. boost::detail::sp_deleter_construct( &tmp, p );
  443. }
  444. tmp.swap( *this );
  445. return *this;
  446. }
  447. // Move support
  448. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  449. shared_ptr( shared_ptr && r ) BOOST_SP_NOEXCEPT : px( r.px ), pn()
  450. {
  451. pn.swap( r.pn );
  452. r.px = 0;
  453. }
  454. template<class Y>
  455. #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
  456. shared_ptr( shared_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
  457. #else
  458. shared_ptr( shared_ptr<Y> && r )
  459. #endif
  460. BOOST_SP_NOEXCEPT : px( r.px ), pn()
  461. {
  462. boost::detail::sp_assert_convertible< Y, T >();
  463. pn.swap( r.pn );
  464. r.px = 0;
  465. }
  466. shared_ptr & operator=( shared_ptr && r ) BOOST_SP_NOEXCEPT
  467. {
  468. this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
  469. return *this;
  470. }
  471. template<class Y>
  472. shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_SP_NOEXCEPT
  473. {
  474. this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
  475. return *this;
  476. }
  477. // aliasing move
  478. template<class Y>
  479. shared_ptr( shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn()
  480. {
  481. pn.swap( r.pn );
  482. r.px = 0;
  483. }
  484. #endif
  485. #if !defined( BOOST_NO_CXX11_NULLPTR )
  486. shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
  487. {
  488. this_type().swap(*this);
  489. return *this;
  490. }
  491. #endif
  492. void reset() BOOST_SP_NOEXCEPT
  493. {
  494. this_type().swap(*this);
  495. }
  496. template<class Y> void reset( Y * p ) // Y must be complete
  497. {
  498. BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
  499. this_type( p ).swap( *this );
  500. }
  501. template<class Y, class D> void reset( Y * p, D d )
  502. {
  503. this_type( p, d ).swap( *this );
  504. }
  505. template<class Y, class D, class A> void reset( Y * p, D d, A a )
  506. {
  507. this_type( p, d, a ).swap( *this );
  508. }
  509. template<class Y> void reset( shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT
  510. {
  511. this_type( r, p ).swap( *this );
  512. }
  513. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  514. template<class Y> void reset( shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT
  515. {
  516. this_type( static_cast< shared_ptr<Y> && >( r ), p ).swap( *this );
  517. }
  518. #endif
  519. typename boost::detail::sp_dereference< T >::type operator* () const BOOST_SP_NOEXCEPT_WITH_ASSERT
  520. {
  521. BOOST_ASSERT( px != 0 );
  522. return *px;
  523. }
  524. typename boost::detail::sp_member_access< T >::type operator-> () const BOOST_SP_NOEXCEPT_WITH_ASSERT
  525. {
  526. BOOST_ASSERT( px != 0 );
  527. return px;
  528. }
  529. typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const BOOST_SP_NOEXCEPT_WITH_ASSERT
  530. {
  531. BOOST_ASSERT( px != 0 );
  532. BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
  533. return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
  534. }
  535. element_type * get() const BOOST_SP_NOEXCEPT
  536. {
  537. return px;
  538. }
  539. // implicit conversion to "bool"
  540. #include <boost/smart_ptr/detail/operator_bool.hpp>
  541. bool unique() const BOOST_SP_NOEXCEPT
  542. {
  543. return pn.unique();
  544. }
  545. long use_count() const BOOST_SP_NOEXCEPT
  546. {
  547. return pn.use_count();
  548. }
  549. void swap( shared_ptr & other ) BOOST_SP_NOEXCEPT
  550. {
  551. std::swap(px, other.px);
  552. pn.swap(other.pn);
  553. }
  554. template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
  555. {
  556. return pn < rhs.pn;
  557. }
  558. template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
  559. {
  560. return pn < rhs.pn;
  561. }
  562. template<class Y> bool owner_equals( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
  563. {
  564. return pn == rhs.pn;
  565. }
  566. template<class Y> bool owner_equals( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
  567. {
  568. return pn == rhs.pn;
  569. }
  570. std::size_t owner_hash_value() const BOOST_SP_NOEXCEPT
  571. {
  572. return pn.hash_value();
  573. }
  574. void * _internal_get_deleter( boost::detail::sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
  575. {
  576. return pn.get_deleter( ti );
  577. }
  578. void * _internal_get_local_deleter( boost::detail::sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
  579. {
  580. return pn.get_local_deleter( ti );
  581. }
  582. void * _internal_get_untyped_deleter() const BOOST_SP_NOEXCEPT
  583. {
  584. return pn.get_untyped_deleter();
  585. }
  586. bool _internal_equiv( shared_ptr const & r ) const BOOST_SP_NOEXCEPT
  587. {
  588. return px == r.px && pn == r.pn;
  589. }
  590. boost::detail::shared_count _internal_count() const BOOST_SP_NOEXCEPT
  591. {
  592. return pn;
  593. }
  594. // Tasteless as this may seem, making all members public allows member templates
  595. // to work in the absence of member template friends. (Matthew Langston)
  596. #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
  597. private:
  598. template<class Y> friend class shared_ptr;
  599. template<class Y> friend class weak_ptr;
  600. #endif
  601. element_type * px; // contained pointer
  602. boost::detail::shared_count pn; // reference counter
  603. }; // shared_ptr
  604. template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPT
  605. {
  606. return a.get() == b.get();
  607. }
  608. template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPT
  609. {
  610. return a.get() != b.get();
  611. }
  612. #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
  613. // Resolve the ambiguity between our op!= and the one in rel_ops
  614. template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_SP_NOEXCEPT
  615. {
  616. return a.get() != b.get();
  617. }
  618. #endif
  619. #if !defined( BOOST_NO_CXX11_NULLPTR )
  620. template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
  621. {
  622. return p.get() == 0;
  623. }
  624. template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  625. {
  626. return p.get() == 0;
  627. }
  628. template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
  629. {
  630. return p.get() != 0;
  631. }
  632. template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  633. {
  634. return p.get() != 0;
  635. }
  636. #endif
  637. template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPT
  638. {
  639. return a.owner_before( b );
  640. }
  641. template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_SP_NOEXCEPT
  642. {
  643. a.swap(b);
  644. }
  645. template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
  646. {
  647. (void) static_cast< T* >( static_cast< U* >( 0 ) );
  648. typedef typename shared_ptr<T>::element_type E;
  649. E * p = static_cast< E* >( r.get() );
  650. return shared_ptr<T>( r, p );
  651. }
  652. template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
  653. {
  654. (void) const_cast< T* >( static_cast< U* >( 0 ) );
  655. typedef typename shared_ptr<T>::element_type E;
  656. E * p = const_cast< E* >( r.get() );
  657. return shared_ptr<T>( r, p );
  658. }
  659. template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
  660. {
  661. (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
  662. typedef typename shared_ptr<T>::element_type E;
  663. E * p = dynamic_cast< E* >( r.get() );
  664. return p? shared_ptr<T>( r, p ): shared_ptr<T>();
  665. }
  666. template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
  667. {
  668. (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
  669. typedef typename shared_ptr<T>::element_type E;
  670. E * p = reinterpret_cast< E* >( r.get() );
  671. return shared_ptr<T>( r, p );
  672. }
  673. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  674. template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
  675. {
  676. (void) static_cast< T* >( static_cast< U* >( 0 ) );
  677. typedef typename shared_ptr<T>::element_type E;
  678. E * p = static_cast< E* >( r.get() );
  679. return shared_ptr<T>( std::move(r), p );
  680. }
  681. template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
  682. {
  683. (void) const_cast< T* >( static_cast< U* >( 0 ) );
  684. typedef typename shared_ptr<T>::element_type E;
  685. E * p = const_cast< E* >( r.get() );
  686. return shared_ptr<T>( std::move(r), p );
  687. }
  688. template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
  689. {
  690. (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
  691. typedef typename shared_ptr<T>::element_type E;
  692. E * p = dynamic_cast< E* >( r.get() );
  693. return p? shared_ptr<T>( std::move(r), p ): shared_ptr<T>();
  694. }
  695. template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
  696. {
  697. (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
  698. typedef typename shared_ptr<T>::element_type E;
  699. E * p = reinterpret_cast< E* >( r.get() );
  700. return shared_ptr<T>( std::move(r), p );
  701. }
  702. #endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  703. // get_pointer() enables boost::mem_fn to recognize shared_ptr
  704. template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_SP_NOEXCEPT
  705. {
  706. return p.get();
  707. }
  708. // operator<<
  709. #if !defined(BOOST_NO_IOSTREAM)
  710. #if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
  711. template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
  712. {
  713. os << p.get();
  714. return os;
  715. }
  716. #else
  717. // in STLport's no-iostreams mode no iostream symbols can be used
  718. #ifndef _STLP_NO_IOSTREAMS
  719. # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
  720. // MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
  721. using std::basic_ostream;
  722. template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
  723. # else
  724. template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
  725. # endif
  726. {
  727. os << p.get();
  728. return os;
  729. }
  730. #endif // _STLP_NO_IOSTREAMS
  731. #endif // __GNUC__ < 3
  732. #endif // !defined(BOOST_NO_IOSTREAM)
  733. // get_deleter
  734. namespace detail
  735. {
  736. template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  737. {
  738. return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID_(D)) );
  739. }
  740. template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT;
  741. template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT;
  742. class esft2_deleter_wrapper
  743. {
  744. private:
  745. shared_ptr<void const volatile> deleter_;
  746. public:
  747. esft2_deleter_wrapper() BOOST_SP_NOEXCEPT
  748. {
  749. }
  750. template< class T > void set_deleter( shared_ptr<T> const & deleter ) BOOST_SP_NOEXCEPT
  751. {
  752. deleter_ = deleter;
  753. }
  754. template<typename D> D* get_deleter() const BOOST_SP_NOEXCEPT
  755. {
  756. return boost::detail::basic_get_deleter<D>( deleter_ );
  757. }
  758. template< class T> void operator()( T* ) BOOST_SP_NOEXCEPT_WITH_ASSERT
  759. {
  760. BOOST_ASSERT( deleter_.use_count() <= 1 );
  761. deleter_.reset();
  762. }
  763. };
  764. } // namespace detail
  765. template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  766. {
  767. D * d = boost::detail::basic_get_deleter<D>( p );
  768. if( d == 0 )
  769. {
  770. d = boost::detail::basic_get_local_deleter( d, p );
  771. }
  772. if( d == 0 )
  773. {
  774. boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter<boost::detail::esft2_deleter_wrapper>(p);
  775. // The following get_deleter method call is fully qualified because
  776. // older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>()
  777. if(del_wrapper) d = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>();
  778. }
  779. return d;
  780. }
  781. // atomic access
  782. #if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
  783. template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_SP_NOEXCEPT
  784. {
  785. return false;
  786. }
  787. template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ) BOOST_SP_NOEXCEPT
  788. {
  789. boost::detail::spinlock_pool<2>::scoped_lock lock( p );
  790. return *p;
  791. }
  792. template<class T, class M> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, /*memory_order mo*/ M ) BOOST_SP_NOEXCEPT
  793. {
  794. return atomic_load( p );
  795. }
  796. template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ) BOOST_SP_NOEXCEPT
  797. {
  798. boost::detail::spinlock_pool<2>::scoped_lock lock( p );
  799. p->swap( r );
  800. }
  801. template<class T, class M> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ M ) BOOST_SP_NOEXCEPT
  802. {
  803. atomic_store( p, r ); // std::move( r )
  804. }
  805. template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ) BOOST_SP_NOEXCEPT
  806. {
  807. boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
  808. sp.lock();
  809. p->swap( r );
  810. sp.unlock();
  811. return r; // return std::move( r )
  812. }
  813. template<class T, class M> shared_ptr<T> inline atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ M ) BOOST_SP_NOEXCEPT
  814. {
  815. return atomic_exchange( p, r ); // std::move( r )
  816. }
  817. template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
  818. {
  819. boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
  820. sp.lock();
  821. if( p->_internal_equiv( *v ) )
  822. {
  823. p->swap( w );
  824. sp.unlock();
  825. return true;
  826. }
  827. else
  828. {
  829. shared_ptr<T> tmp( *p );
  830. sp.unlock();
  831. tmp.swap( *v );
  832. return false;
  833. }
  834. }
  835. template<class T, class M> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, /*memory_order success*/ M, /*memory_order failure*/ M ) BOOST_SP_NOEXCEPT
  836. {
  837. return atomic_compare_exchange( p, v, w ); // std::move( w )
  838. }
  839. #endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS)
  840. // hash_value
  841. template< class T > struct hash;
  842. template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  843. {
  844. return boost::hash< typename boost::shared_ptr<T>::element_type* >()( p.get() );
  845. }
  846. } // namespace boost
  847. // std::hash
  848. #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
  849. namespace std
  850. {
  851. template<class T> struct hash< ::boost::shared_ptr<T> >
  852. {
  853. std::size_t operator()( ::boost::shared_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
  854. {
  855. return std::hash< typename ::boost::shared_ptr<T>::element_type* >()( p.get() );
  856. }
  857. };
  858. } // namespace std
  859. #endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
  860. #include <boost/smart_ptr/detail/local_sp_deleter.hpp>
  861. namespace boost
  862. {
  863. namespace detail
  864. {
  865. template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  866. {
  867. return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID_(local_sp_deleter<D>) ) );
  868. }
  869. template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  870. {
  871. return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID_(local_sp_deleter<D>) ) );
  872. }
  873. } // namespace detail
  874. #if defined(__cpp_deduction_guides)
  875. template<class T> shared_ptr( weak_ptr<T> ) -> shared_ptr<T>;
  876. template<class T, class D> shared_ptr( std::unique_ptr<T, D> ) -> shared_ptr<T>;
  877. #endif
  878. } // namespace boost
  879. #if defined( BOOST_SP_DISABLE_DEPRECATED )
  880. #pragma GCC diagnostic pop
  881. #endif
  882. #endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED