local_shared_ptr.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. #ifndef BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED
  2. #define BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED
  3. // local_shared_ptr.hpp
  4. //
  5. // Copyright 2017 Peter Dimov
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See
  8. // accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // See http://www.boost.org/libs/smart_ptr/ for documentation.
  12. #include <boost/smart_ptr/shared_ptr.hpp>
  13. namespace boost
  14. {
  15. template<class T> class local_shared_ptr;
  16. namespace detail
  17. {
  18. template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
  19. {
  20. boost::detail::sp_assert_convertible< Y, E >();
  21. typedef boost::detail::local_sp_deleter< boost::checked_deleter<Y> > D;
  22. boost::shared_ptr<E> p2( p, D() );
  23. D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
  24. pd->pn_ = p2._internal_count();
  25. pn = pd;
  26. }
  27. template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[] > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
  28. {
  29. boost::detail::sp_assert_convertible< Y[], E[] >();
  30. typedef boost::detail::local_sp_deleter< boost::checked_array_deleter<E> > D;
  31. boost::shared_ptr<E[]> p2( p, D() );
  32. D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
  33. pd->pn_ = p2._internal_count();
  34. pn = pd;
  35. }
  36. template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[N] > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn )
  37. {
  38. boost::detail::sp_assert_convertible< Y[N], E[N] >();
  39. typedef boost::detail::local_sp_deleter< boost::checked_array_deleter<E> > D;
  40. boost::shared_ptr<E[N]> p2( p, D() );
  41. D * pd = static_cast< D * >( p2._internal_get_untyped_deleter() );
  42. pd->pn_ = p2._internal_count();
  43. pn = pd;
  44. }
  45. template< class E, class P, class D > inline void lsp_deleter_construct( boost::local_shared_ptr< E > * /*ppx*/, P p, D const& d, boost::detail::local_counted_base * & pn )
  46. {
  47. typedef boost::detail::local_sp_deleter<D> D2;
  48. boost::shared_ptr<E> p2( p, D2( d ) );
  49. D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
  50. pd->pn_ = p2._internal_count();
  51. pn = pd;
  52. }
  53. template< class E, class P, class D, class A > inline void lsp_allocator_construct( boost::local_shared_ptr< E > * /*ppx*/, P p, D const& d, A const& a, boost::detail::local_counted_base * & pn )
  54. {
  55. typedef boost::detail::local_sp_deleter<D> D2;
  56. boost::shared_ptr<E> p2( p, D2( d ), a );
  57. D2 * pd = static_cast< D2 * >( p2._internal_get_untyped_deleter() );
  58. pd->pn_ = p2._internal_count();
  59. pn = pd;
  60. }
  61. struct lsp_internal_constructor_tag
  62. {
  63. };
  64. } // namespace detail
  65. //
  66. // local_shared_ptr
  67. //
  68. // as shared_ptr, but local to a thread.
  69. // reference count manipulations are non-atomic.
  70. //
  71. template<class T> class local_shared_ptr
  72. {
  73. private:
  74. typedef local_shared_ptr this_type;
  75. public:
  76. typedef typename boost::detail::sp_element<T>::type element_type;
  77. private:
  78. element_type * px;
  79. boost::detail::local_counted_base * pn;
  80. template<class Y> friend class local_shared_ptr;
  81. public:
  82. // destructor
  83. ~local_shared_ptr() BOOST_SP_NOEXCEPT
  84. {
  85. if( pn )
  86. {
  87. pn->release();
  88. }
  89. }
  90. // constructors
  91. BOOST_CONSTEXPR local_shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn( 0 )
  92. {
  93. }
  94. #if !defined( BOOST_NO_CXX11_NULLPTR )
  95. BOOST_CONSTEXPR local_shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn( 0 )
  96. {
  97. }
  98. #endif
  99. // internal constructor, used by make_shared
  100. BOOST_CONSTEXPR local_shared_ptr( boost::detail::lsp_internal_constructor_tag, element_type * px_, boost::detail::local_counted_base * pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( pn_ )
  101. {
  102. }
  103. template<class Y>
  104. explicit local_shared_ptr( Y * p ): px( p ), pn( 0 )
  105. {
  106. boost::detail::lsp_pointer_construct( this, p, pn );
  107. }
  108. template<class Y, class D> local_shared_ptr( Y * p, D d ): px( p ), pn( 0 )
  109. {
  110. boost::detail::lsp_deleter_construct( this, p, d, pn );
  111. }
  112. #if !defined( BOOST_NO_CXX11_NULLPTR )
  113. template<class D> local_shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( 0 )
  114. {
  115. boost::detail::lsp_deleter_construct( this, p, d, pn );
  116. }
  117. #endif
  118. template<class Y, class D, class A> local_shared_ptr( Y * p, D d, A a ): px( p ), pn( 0 )
  119. {
  120. boost::detail::lsp_allocator_construct( this, p, d, a, pn );
  121. }
  122. #if !defined( BOOST_NO_CXX11_NULLPTR )
  123. template<class D, class A> local_shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( 0 )
  124. {
  125. boost::detail::lsp_allocator_construct( this, p, d, a, pn );
  126. }
  127. #endif
  128. // construction from shared_ptr
  129. template<class Y> local_shared_ptr( shared_ptr<Y> const & r,
  130. typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
  131. : px( r.get() ), pn( 0 )
  132. {
  133. boost::detail::sp_assert_convertible< Y, T >();
  134. if( r.use_count() != 0 )
  135. {
  136. pn = new boost::detail::local_counted_impl( r._internal_count() );
  137. }
  138. }
  139. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  140. template<class Y> local_shared_ptr( shared_ptr<Y> && r,
  141. typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
  142. : px( r.get() ), pn( 0 )
  143. {
  144. boost::detail::sp_assert_convertible< Y, T >();
  145. if( r.use_count() != 0 )
  146. {
  147. pn = new boost::detail::local_counted_impl( r._internal_count() );
  148. r.reset();
  149. }
  150. }
  151. #endif
  152. // construction from unique_ptr
  153. #if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  154. template< class Y, class D >
  155. local_shared_ptr( std::unique_ptr< Y, D > && r,
  156. typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() )
  157. : px( r.get() ), pn( 0 )
  158. {
  159. boost::detail::sp_assert_convertible< Y, T >();
  160. if( px )
  161. {
  162. pn = new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) )._internal_count() );
  163. }
  164. }
  165. #endif
  166. template< class Y, class D >
  167. local_shared_ptr( boost::movelib::unique_ptr< Y, D > r ); // !
  168. // : px( r.get() ), pn( new boost::detail::local_counted_impl( shared_ptr<T>( std::move(r) ) ) )
  169. //{
  170. // boost::detail::sp_assert_convertible< Y, T >();
  171. //}
  172. // copy constructor
  173. local_shared_ptr( local_shared_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
  174. {
  175. if( pn )
  176. {
  177. pn->add_ref();
  178. }
  179. }
  180. // move constructor
  181. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  182. local_shared_ptr( local_shared_ptr && r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
  183. {
  184. r.px = 0;
  185. r.pn = 0;
  186. }
  187. #endif
  188. // converting copy constructor
  189. template<class Y> local_shared_ptr( local_shared_ptr<Y> const & r,
  190. typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() ) BOOST_SP_NOEXCEPT
  191. : px( r.px ), pn( r.pn )
  192. {
  193. boost::detail::sp_assert_convertible< Y, T >();
  194. if( pn )
  195. {
  196. pn->add_ref();
  197. }
  198. }
  199. // converting move constructor
  200. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  201. template<class Y> local_shared_ptr( local_shared_ptr<Y> && r,
  202. typename boost::detail::sp_enable_if_convertible<Y, T>::type = boost::detail::sp_empty() ) BOOST_SP_NOEXCEPT
  203. : px( r.px ), pn( r.pn )
  204. {
  205. boost::detail::sp_assert_convertible< Y, T >();
  206. r.px = 0;
  207. r.pn = 0;
  208. }
  209. #endif
  210. // aliasing
  211. template<class Y>
  212. local_shared_ptr( local_shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
  213. {
  214. if( pn )
  215. {
  216. pn->add_ref();
  217. }
  218. }
  219. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  220. template<class Y>
  221. local_shared_ptr( local_shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
  222. {
  223. r.px = 0;
  224. r.pn = 0;
  225. }
  226. #endif
  227. // assignment
  228. local_shared_ptr & operator=( local_shared_ptr const & r ) BOOST_SP_NOEXCEPT
  229. {
  230. local_shared_ptr( r ).swap( *this );
  231. return *this;
  232. }
  233. template<class Y> local_shared_ptr & operator=( local_shared_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
  234. {
  235. local_shared_ptr( r ).swap( *this );
  236. return *this;
  237. }
  238. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  239. local_shared_ptr & operator=( local_shared_ptr && r ) BOOST_SP_NOEXCEPT
  240. {
  241. local_shared_ptr( std::move( r ) ).swap( *this );
  242. return *this;
  243. }
  244. template<class Y>
  245. local_shared_ptr & operator=( local_shared_ptr<Y> && r ) BOOST_SP_NOEXCEPT
  246. {
  247. local_shared_ptr( std::move( r ) ).swap( *this );
  248. return *this;
  249. }
  250. #endif
  251. #if !defined( BOOST_NO_CXX11_NULLPTR )
  252. local_shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
  253. {
  254. local_shared_ptr().swap(*this);
  255. return *this;
  256. }
  257. #endif
  258. #if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  259. template<class Y, class D>
  260. local_shared_ptr & operator=( std::unique_ptr<Y, D> && r )
  261. {
  262. local_shared_ptr( std::move(r) ).swap( *this );
  263. return *this;
  264. }
  265. #endif
  266. template<class Y, class D>
  267. local_shared_ptr & operator=( boost::movelib::unique_ptr<Y, D> r ); // !
  268. // reset
  269. void reset() BOOST_SP_NOEXCEPT
  270. {
  271. local_shared_ptr().swap( *this );
  272. }
  273. template<class Y> void reset( Y * p ) // Y must be complete
  274. {
  275. local_shared_ptr( p ).swap( *this );
  276. }
  277. template<class Y, class D> void reset( Y * p, D d )
  278. {
  279. local_shared_ptr( p, d ).swap( *this );
  280. }
  281. template<class Y, class D, class A> void reset( Y * p, D d, A a )
  282. {
  283. local_shared_ptr( p, d, a ).swap( *this );
  284. }
  285. template<class Y> void reset( local_shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT
  286. {
  287. local_shared_ptr( r, p ).swap( *this );
  288. }
  289. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  290. template<class Y> void reset( local_shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT
  291. {
  292. local_shared_ptr( std::move( r ), p ).swap( *this );
  293. }
  294. #endif
  295. // accessors
  296. typename boost::detail::sp_dereference< T >::type operator* () const BOOST_SP_NOEXCEPT
  297. {
  298. return *px;
  299. }
  300. typename boost::detail::sp_member_access< T >::type operator-> () const BOOST_SP_NOEXCEPT
  301. {
  302. return px;
  303. }
  304. typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const BOOST_SP_NOEXCEPT_WITH_ASSERT
  305. {
  306. BOOST_ASSERT( px != 0 );
  307. BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
  308. return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
  309. }
  310. element_type * get() const BOOST_SP_NOEXCEPT
  311. {
  312. return px;
  313. }
  314. // implicit conversion to "bool"
  315. #include <boost/smart_ptr/detail/operator_bool.hpp>
  316. long local_use_count() const BOOST_SP_NOEXCEPT
  317. {
  318. return pn? pn->local_use_count(): 0;
  319. }
  320. // conversions to shared_ptr, weak_ptr
  321. #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
  322. template<class Y, class E = typename boost::detail::sp_enable_if_convertible<T,Y>::type> operator shared_ptr<Y>() const BOOST_SP_NOEXCEPT
  323. #else
  324. template<class Y> operator shared_ptr<Y>() const BOOST_SP_NOEXCEPT
  325. #endif
  326. {
  327. boost::detail::sp_assert_convertible<T, Y>();
  328. if( pn )
  329. {
  330. return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
  331. }
  332. else
  333. {
  334. return shared_ptr<Y>();
  335. }
  336. }
  337. #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
  338. template<class Y, class E = typename boost::detail::sp_enable_if_convertible<T,Y>::type> operator weak_ptr<Y>() const BOOST_SP_NOEXCEPT
  339. #else
  340. template<class Y> operator weak_ptr<Y>() const BOOST_SP_NOEXCEPT
  341. #endif
  342. {
  343. boost::detail::sp_assert_convertible<T, Y>();
  344. if( pn )
  345. {
  346. return shared_ptr<Y>( boost::detail::sp_internal_constructor_tag(), px, pn->local_cb_get_shared_count() );
  347. }
  348. else
  349. {
  350. return weak_ptr<Y>();
  351. }
  352. }
  353. // swap
  354. void swap( local_shared_ptr & r ) BOOST_SP_NOEXCEPT
  355. {
  356. std::swap( px, r.px );
  357. std::swap( pn, r.pn );
  358. }
  359. // owner_before
  360. template<class Y> bool owner_before( local_shared_ptr<Y> const & r ) const BOOST_SP_NOEXCEPT
  361. {
  362. return std::less< boost::detail::local_counted_base* >()( pn, r.pn );
  363. }
  364. // owner_equals
  365. template<class Y> bool owner_equals( local_shared_ptr<Y> const & r ) const BOOST_SP_NOEXCEPT
  366. {
  367. return pn == r.pn;
  368. }
  369. };
  370. template<class T, class U> inline bool operator==( local_shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
  371. {
  372. return a.get() == b.get();
  373. }
  374. template<class T, class U> inline bool operator!=( local_shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
  375. {
  376. return a.get() != b.get();
  377. }
  378. #if !defined( BOOST_NO_CXX11_NULLPTR )
  379. template<class T> inline bool operator==( local_shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
  380. {
  381. return p.get() == 0;
  382. }
  383. template<class T> inline bool operator==( boost::detail::sp_nullptr_t, local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  384. {
  385. return p.get() == 0;
  386. }
  387. template<class T> inline bool operator!=( local_shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
  388. {
  389. return p.get() != 0;
  390. }
  391. template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  392. {
  393. return p.get() != 0;
  394. }
  395. #endif
  396. template<class T, class U> inline bool operator==( local_shared_ptr<T> const & a, shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
  397. {
  398. return a.get() == b.get();
  399. }
  400. template<class T, class U> inline bool operator!=( local_shared_ptr<T> const & a, shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
  401. {
  402. return a.get() != b.get();
  403. }
  404. template<class T, class U> inline bool operator==( shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
  405. {
  406. return a.get() == b.get();
  407. }
  408. template<class T, class U> inline bool operator!=( shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
  409. {
  410. return a.get() != b.get();
  411. }
  412. template<class T, class U> inline bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) BOOST_SP_NOEXCEPT
  413. {
  414. return a.owner_before( b );
  415. }
  416. template<class T> inline void swap( local_shared_ptr<T> & a, local_shared_ptr<T> & b ) BOOST_SP_NOEXCEPT
  417. {
  418. a.swap( b );
  419. }
  420. template<class T, class U> local_shared_ptr<T> static_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
  421. {
  422. (void) static_cast< T* >( static_cast< U* >( 0 ) );
  423. typedef typename local_shared_ptr<T>::element_type E;
  424. E * p = static_cast< E* >( r.get() );
  425. return local_shared_ptr<T>( r, p );
  426. }
  427. template<class T, class U> local_shared_ptr<T> const_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
  428. {
  429. (void) const_cast< T* >( static_cast< U* >( 0 ) );
  430. typedef typename local_shared_ptr<T>::element_type E;
  431. E * p = const_cast< E* >( r.get() );
  432. return local_shared_ptr<T>( r, p );
  433. }
  434. template<class T, class U> local_shared_ptr<T> dynamic_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
  435. {
  436. (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
  437. typedef typename local_shared_ptr<T>::element_type E;
  438. E * p = dynamic_cast< E* >( r.get() );
  439. return p? local_shared_ptr<T>( r, p ): local_shared_ptr<T>();
  440. }
  441. template<class T, class U> local_shared_ptr<T> reinterpret_pointer_cast( local_shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT
  442. {
  443. (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
  444. typedef typename local_shared_ptr<T>::element_type E;
  445. E * p = reinterpret_cast< E* >( r.get() );
  446. return local_shared_ptr<T>( r, p );
  447. }
  448. #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  449. template<class T, class U> local_shared_ptr<T> static_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
  450. {
  451. (void) static_cast< T* >( static_cast< U* >( 0 ) );
  452. typedef typename local_shared_ptr<T>::element_type E;
  453. E * p = static_cast< E* >( r.get() );
  454. return local_shared_ptr<T>( std::move(r), p );
  455. }
  456. template<class T, class U> local_shared_ptr<T> const_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
  457. {
  458. (void) const_cast< T* >( static_cast< U* >( 0 ) );
  459. typedef typename local_shared_ptr<T>::element_type E;
  460. E * p = const_cast< E* >( r.get() );
  461. return local_shared_ptr<T>( std::move(r), p );
  462. }
  463. template<class T, class U> local_shared_ptr<T> dynamic_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
  464. {
  465. (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
  466. typedef typename local_shared_ptr<T>::element_type E;
  467. E * p = dynamic_cast< E* >( r.get() );
  468. return p? local_shared_ptr<T>( std::move(r), p ): local_shared_ptr<T>();
  469. }
  470. template<class T, class U> local_shared_ptr<T> reinterpret_pointer_cast( local_shared_ptr<U> && r ) BOOST_SP_NOEXCEPT
  471. {
  472. (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
  473. typedef typename local_shared_ptr<T>::element_type E;
  474. E * p = reinterpret_cast< E* >( r.get() );
  475. return local_shared_ptr<T>( std::move(r), p );
  476. }
  477. #endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  478. // get_pointer() enables boost::mem_fn to recognize local_shared_ptr
  479. template<class T> inline typename local_shared_ptr<T>::element_type * get_pointer( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  480. {
  481. return p.get();
  482. }
  483. // operator<<
  484. #if !defined(BOOST_NO_IOSTREAM)
  485. template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< ( std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p )
  486. {
  487. os << p.get();
  488. return os;
  489. }
  490. #endif // !defined(BOOST_NO_IOSTREAM)
  491. // get_deleter
  492. template<class D, class T> D * get_deleter( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  493. {
  494. return get_deleter<D>( shared_ptr<T>( p ) );
  495. }
  496. // hash_value
  497. template< class T > struct hash;
  498. template< class T > std::size_t hash_value( local_shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
  499. {
  500. return boost::hash< typename local_shared_ptr<T>::element_type* >()( p.get() );
  501. }
  502. } // namespace boost
  503. // std::hash
  504. #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
  505. namespace std
  506. {
  507. template<class T> struct hash< ::boost::local_shared_ptr<T> >
  508. {
  509. std::size_t operator()( ::boost::local_shared_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
  510. {
  511. return std::hash< typename ::boost::local_shared_ptr<T>::element_type* >()( p.get() );
  512. }
  513. };
  514. } // namespace std
  515. #endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
  516. #endif // #ifndef BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED