Warning, file /include/boost/smart_ptr/shared_ptr.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <boost/smart_ptr/detail/shared_count.hpp>
0018 #include <boost/smart_ptr/detail/sp_convertible.hpp>
0019 #include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
0020 #include <boost/smart_ptr/detail/sp_noexcept.hpp>
0021 #include <boost/core/checked_delete.hpp>
0022 #include <boost/throw_exception.hpp>
0023 #include <boost/assert.hpp>
0024 #include <boost/config.hpp>
0025 #include <boost/config/workaround.hpp>
0026
0027 #if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
0028 #include <boost/smart_ptr/detail/spinlock_pool.hpp>
0029 #endif
0030
0031 #include <algorithm> // for std::swap
0032 #include <functional> // for std::less
0033 #include <typeinfo> // for std::bad_cast
0034 #include <cstddef> // for std::size_t
0035 #include <memory> // for std::auto_ptr
0036 #include <iosfwd> // for std::basic_ostream
0037
0038 #if defined( BOOST_SP_DISABLE_DEPRECATED )
0039 #pragma GCC diagnostic push
0040 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0041 #endif
0042
0043 namespace boost
0044 {
0045
0046 template<class T> class shared_ptr;
0047 template<class T> class weak_ptr;
0048 template<class T> class enable_shared_from_this;
0049 class enable_shared_from_raw;
0050
0051 namespace movelib
0052 {
0053
0054 template< class T, class D > class unique_ptr;
0055
0056 }
0057
0058 namespace detail
0059 {
0060
0061
0062
0063 template< class T > struct sp_element
0064 {
0065 typedef T type;
0066 };
0067
0068 template< class T > struct sp_element< T[] >
0069 {
0070 typedef T type;
0071 };
0072
0073 template< class T, std::size_t N > struct sp_element< T[N] >
0074 {
0075 typedef T type;
0076 };
0077
0078
0079
0080 template< class T > struct sp_dereference
0081 {
0082 typedef T & type;
0083 };
0084
0085 template<> struct sp_dereference< void >
0086 {
0087 typedef void type;
0088 };
0089
0090 template<> struct sp_dereference< void const >
0091 {
0092 typedef void type;
0093 };
0094
0095 template<> struct sp_dereference< void volatile >
0096 {
0097 typedef void type;
0098 };
0099
0100 template<> struct sp_dereference< void const volatile >
0101 {
0102 typedef void type;
0103 };
0104
0105 template< class T > struct sp_dereference< T[] >
0106 {
0107 typedef void type;
0108 };
0109
0110 template< class T, std::size_t N > struct sp_dereference< T[N] >
0111 {
0112 typedef void type;
0113 };
0114
0115
0116
0117 template< class T > struct sp_member_access
0118 {
0119 typedef T * type;
0120 };
0121
0122 template< class T > struct sp_member_access< T[] >
0123 {
0124 typedef void type;
0125 };
0126
0127 template< class T, std::size_t N > struct sp_member_access< T[N] >
0128 {
0129 typedef void type;
0130 };
0131
0132
0133
0134 template< class T > struct sp_array_access
0135 {
0136 typedef void type;
0137 };
0138
0139 template< class T > struct sp_array_access< T[] >
0140 {
0141 typedef T & type;
0142 };
0143
0144 template< class T, std::size_t N > struct sp_array_access< T[N] >
0145 {
0146 typedef T & type;
0147 };
0148
0149
0150
0151 template< class T > struct sp_extent
0152 {
0153 enum _vt { value = 0 };
0154 };
0155
0156 template< class T, std::size_t N > struct sp_extent< T[N] >
0157 {
0158 enum _vt { value = N };
0159 };
0160
0161
0162
0163 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 )
0164 {
0165 if( pe != 0 )
0166 {
0167 pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
0168 }
0169 }
0170
0171 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 );
0172
0173 #ifdef _MANAGED
0174
0175
0176
0177 struct sp_any_pointer
0178 {
0179 template<class T> sp_any_pointer( T* ) {}
0180 };
0181
0182 inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer )
0183 {
0184 }
0185
0186 #else
0187
0188 inline void sp_enable_shared_from_this( ... )
0189 {
0190 }
0191
0192 #endif
0193
0194
0195
0196 template< class Y, class T > inline void sp_assert_convertible() noexcept
0197 {
0198 static_assert( sp_convertible< Y, T >::value, "incompatible pointer type" );
0199 }
0200
0201
0202
0203 template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
0204 {
0205 boost::detail::shared_count( p ).swap( pn );
0206 boost::detail::sp_enable_shared_from_this( ppx, p, p );
0207 }
0208
0209 template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * , Y * p, boost::detail::shared_count & pn )
0210 {
0211 sp_assert_convertible< Y[], T[] >();
0212 boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
0213 }
0214
0215 template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * , Y * p, boost::detail::shared_count & pn )
0216 {
0217 sp_assert_convertible< Y[N], T[N] >();
0218 boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
0219 }
0220
0221
0222
0223 template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p )
0224 {
0225 boost::detail::sp_enable_shared_from_this( ppx, p, p );
0226 }
0227
0228 template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * , Y * )
0229 {
0230 sp_assert_convertible< Y[], T[] >();
0231 }
0232
0233 template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * , Y * )
0234 {
0235 sp_assert_convertible< Y[N], T[N] >();
0236 }
0237
0238 struct sp_internal_constructor_tag
0239 {
0240 };
0241
0242 }
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253 template<class T> class shared_ptr
0254 {
0255 private:
0256
0257
0258 typedef shared_ptr<T> this_type;
0259
0260 public:
0261
0262 typedef typename boost::detail::sp_element< T >::type element_type;
0263
0264 constexpr shared_ptr() noexcept : px( 0 ), pn()
0265 {
0266 }
0267
0268 constexpr shared_ptr( std::nullptr_t ) noexcept : px( 0 ), pn()
0269 {
0270 }
0271
0272 constexpr shared_ptr( boost::detail::sp_internal_constructor_tag, element_type * px_, boost::detail::shared_count const & pn_ ) noexcept : px( px_ ), pn( pn_ )
0273 {
0274 }
0275
0276 constexpr shared_ptr( boost::detail::sp_internal_constructor_tag, element_type * px_, boost::detail::shared_count && pn_ ) noexcept : px( px_ ), pn( std::move( pn_ ) )
0277 {
0278 }
0279
0280 template<class Y>
0281 explicit shared_ptr( Y * p ): px( p ), pn()
0282 {
0283 boost::detail::sp_pointer_construct( this, p, pn );
0284 }
0285
0286
0287
0288
0289
0290
0291
0292 template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, static_cast< D&& >( d ) )
0293 {
0294 boost::detail::sp_deleter_construct( this, p );
0295 }
0296
0297 template<class D> shared_ptr( std::nullptr_t p, D d ): px( p ), pn( p, static_cast< D&& >( d ) )
0298 {
0299 }
0300
0301
0302
0303 template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, static_cast< D&& >( d ), a )
0304 {
0305 boost::detail::sp_deleter_construct( this, p );
0306 }
0307
0308 template<class D, class A> shared_ptr( std::nullptr_t p, D d, A a ): px( p ), pn( p, static_cast< D&& >( d ), a )
0309 {
0310 }
0311
0312
0313
0314
0315 shared_ptr( shared_ptr const & r ) noexcept : px( r.px ), pn( r.pn )
0316 {
0317 }
0318
0319 template<class Y>
0320 explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn )
0321 {
0322 boost::detail::sp_assert_convertible< Y, T >();
0323
0324
0325 px = r.px;
0326 }
0327
0328 template<class Y>
0329 shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag )
0330 noexcept : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
0331 {
0332 if( !pn.empty() )
0333 {
0334 px = r.px;
0335 }
0336 }
0337
0338 template<class Y>
0339 shared_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
0340 noexcept : px( r.px ), pn( r.pn )
0341 {
0342 boost::detail::sp_assert_convertible< Y, T >();
0343 }
0344
0345
0346 template< class Y >
0347 shared_ptr( shared_ptr<Y> const & r, element_type * p ) noexcept : px( p ), pn( r.pn )
0348 {
0349 }
0350
0351 #ifndef BOOST_NO_AUTO_PTR
0352
0353 template<class Y>
0354 explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn()
0355 {
0356 boost::detail::sp_assert_convertible< Y, T >();
0357
0358 Y * tmp = r.get();
0359 pn = boost::detail::shared_count( r );
0360
0361 boost::detail::sp_deleter_construct( this, tmp );
0362 }
0363
0364 template<class Y>
0365 shared_ptr( std::auto_ptr<Y> && r ): px(r.get()), pn()
0366 {
0367 boost::detail::sp_assert_convertible< Y, T >();
0368
0369 Y * tmp = r.get();
0370 pn = boost::detail::shared_count( r );
0371
0372 boost::detail::sp_deleter_construct( this, tmp );
0373 }
0374
0375 #endif
0376
0377 template< class Y, class D >
0378 shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
0379 {
0380 boost::detail::sp_assert_convertible< Y, T >();
0381
0382 typename std::unique_ptr< Y, D >::pointer tmp = r.get();
0383
0384 if( tmp != 0 )
0385 {
0386 pn = boost::detail::shared_count( r );
0387 boost::detail::sp_deleter_construct( this, tmp );
0388 }
0389 }
0390
0391 template< class Y, class D >
0392 shared_ptr( boost::movelib::unique_ptr< Y, D > r ): px( r.get() ), pn()
0393 {
0394 boost::detail::sp_assert_convertible< Y, T >();
0395
0396 typename boost::movelib::unique_ptr< Y, D >::pointer tmp = r.get();
0397
0398 if( tmp != 0 )
0399 {
0400 pn = boost::detail::shared_count( r );
0401 boost::detail::sp_deleter_construct( this, tmp );
0402 }
0403 }
0404
0405
0406
0407 shared_ptr & operator=( shared_ptr const & r ) noexcept
0408 {
0409 this_type(r).swap(*this);
0410 return *this;
0411 }
0412
0413 template<class Y>
0414 shared_ptr & operator=(shared_ptr<Y> const & r) noexcept
0415 {
0416 this_type(r).swap(*this);
0417 return *this;
0418 }
0419
0420 #ifndef BOOST_NO_AUTO_PTR
0421
0422 template<class Y>
0423 shared_ptr & operator=( std::auto_ptr<Y> & r )
0424 {
0425 this_type( r ).swap( *this );
0426 return *this;
0427 }
0428
0429 template<class Y>
0430 shared_ptr & operator=( std::auto_ptr<Y> && r )
0431 {
0432 this_type( static_cast< std::auto_ptr<Y> && >( r ) ).swap( *this );
0433 return *this;
0434 }
0435
0436 #endif
0437
0438 template<class Y, class D>
0439 shared_ptr & operator=( std::unique_ptr<Y, D> && r )
0440 {
0441 this_type( static_cast< std::unique_ptr<Y, D> && >( r ) ).swap(*this);
0442 return *this;
0443 }
0444
0445 template<class Y, class D>
0446 shared_ptr & operator=( boost::movelib::unique_ptr<Y, D> r )
0447 {
0448
0449
0450 boost::detail::sp_assert_convertible< Y, T >();
0451
0452 typename boost::movelib::unique_ptr< Y, D >::pointer p = r.get();
0453
0454 shared_ptr tmp;
0455
0456 if( p != 0 )
0457 {
0458 tmp.px = p;
0459 tmp.pn = boost::detail::shared_count( r );
0460
0461 boost::detail::sp_deleter_construct( &tmp, p );
0462 }
0463
0464 tmp.swap( *this );
0465
0466 return *this;
0467 }
0468
0469
0470
0471 shared_ptr( shared_ptr && r ) noexcept : px( r.px ), pn( static_cast< boost::detail::shared_count && >( r.pn ) )
0472 {
0473 r.px = 0;
0474 }
0475
0476 template<class Y>
0477 shared_ptr( shared_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
0478 noexcept : px( r.px ), pn( static_cast< boost::detail::shared_count && >( r.pn ) )
0479 {
0480 boost::detail::sp_assert_convertible< Y, T >();
0481 r.px = 0;
0482 }
0483
0484 shared_ptr & operator=( shared_ptr && r ) noexcept
0485 {
0486 this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
0487 return *this;
0488 }
0489
0490 template<class Y>
0491 shared_ptr & operator=( shared_ptr<Y> && r ) noexcept
0492 {
0493 this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
0494 return *this;
0495 }
0496
0497
0498 template<class Y>
0499 shared_ptr( shared_ptr<Y> && r, element_type * p ) noexcept : px( p ), pn()
0500 {
0501 pn.swap( r.pn );
0502 r.px = 0;
0503 }
0504
0505 shared_ptr & operator=( std::nullptr_t ) noexcept
0506 {
0507 this_type().swap(*this);
0508 return *this;
0509 }
0510
0511 void reset() noexcept
0512 {
0513 this_type().swap(*this);
0514 }
0515
0516 template<class Y> void reset( Y * p )
0517 {
0518 BOOST_ASSERT( p == 0 || p != px );
0519 this_type( p ).swap( *this );
0520 }
0521
0522 template<class Y, class D> void reset( Y * p, D d )
0523 {
0524 this_type( p, static_cast< D&& >( d ) ).swap( *this );
0525 }
0526
0527 template<class Y, class D, class A> void reset( Y * p, D d, A a )
0528 {
0529 this_type( p, static_cast< D&& >( d ), a ).swap( *this );
0530 }
0531
0532 template<class Y> void reset( shared_ptr<Y> const & r, element_type * p ) noexcept
0533 {
0534 this_type( r, p ).swap( *this );
0535 }
0536
0537 template<class Y> void reset( shared_ptr<Y> && r, element_type * p ) noexcept
0538 {
0539 this_type( static_cast< shared_ptr<Y> && >( r ), p ).swap( *this );
0540 }
0541
0542 typename boost::detail::sp_dereference< T >::type operator* () const BOOST_SP_NOEXCEPT_WITH_ASSERT
0543 {
0544 BOOST_ASSERT( px != 0 );
0545 return *px;
0546 }
0547
0548 typename boost::detail::sp_member_access< T >::type operator-> () const BOOST_SP_NOEXCEPT_WITH_ASSERT
0549 {
0550 BOOST_ASSERT( px != 0 );
0551 return px;
0552 }
0553
0554 typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const BOOST_SP_NOEXCEPT_WITH_ASSERT
0555 {
0556 BOOST_ASSERT( px != 0 );
0557 BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
0558
0559 return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
0560 }
0561
0562 element_type * get() const noexcept
0563 {
0564 return px;
0565 }
0566
0567 explicit operator bool () const noexcept
0568 {
0569 return px != 0;
0570 }
0571
0572 bool unique() const noexcept
0573 {
0574 return pn.unique();
0575 }
0576
0577 long use_count() const noexcept
0578 {
0579 return pn.use_count();
0580 }
0581
0582 void swap( shared_ptr & other ) noexcept
0583 {
0584 std::swap(px, other.px);
0585 pn.swap(other.pn);
0586 }
0587
0588 template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const noexcept
0589 {
0590 return pn < rhs.pn;
0591 }
0592
0593 template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const noexcept
0594 {
0595 return pn < rhs.pn;
0596 }
0597
0598 template<class Y> bool owner_equals( shared_ptr<Y> const & rhs ) const noexcept
0599 {
0600 return pn == rhs.pn;
0601 }
0602
0603 template<class Y> bool owner_equals( weak_ptr<Y> const & rhs ) const noexcept
0604 {
0605 return pn == rhs.pn;
0606 }
0607
0608 std::size_t owner_hash_value() const noexcept
0609 {
0610 return pn.hash_value();
0611 }
0612
0613 void * _internal_get_deleter( boost::detail::sp_typeinfo_ const & ti ) const noexcept
0614 {
0615 return pn.get_deleter( ti );
0616 }
0617
0618 void * _internal_get_local_deleter( boost::detail::sp_typeinfo_ const & ti ) const noexcept
0619 {
0620 return pn.get_local_deleter( ti );
0621 }
0622
0623 void * _internal_get_untyped_deleter() const noexcept
0624 {
0625 return pn.get_untyped_deleter();
0626 }
0627
0628 bool _internal_equiv( shared_ptr const & r ) const noexcept
0629 {
0630 return px == r.px && pn == r.pn;
0631 }
0632
0633 boost::detail::shared_count _internal_count() const noexcept
0634 {
0635 return pn;
0636 }
0637
0638 private:
0639
0640 template<class Y> friend class shared_ptr;
0641 template<class Y> friend class weak_ptr;
0642
0643
0644 element_type * px;
0645 boost::detail::shared_count pn;
0646
0647 };
0648
0649 template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept
0650 {
0651 return a.get() == b.get();
0652 }
0653
0654 template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept
0655 {
0656 return a.get() != b.get();
0657 }
0658
0659 template<class T> inline bool operator==( shared_ptr<T> const & p, std::nullptr_t ) noexcept
0660 {
0661 return p.get() == 0;
0662 }
0663
0664 template<class T> inline bool operator==( std::nullptr_t, shared_ptr<T> const & p ) noexcept
0665 {
0666 return p.get() == 0;
0667 }
0668
0669 template<class T> inline bool operator!=( shared_ptr<T> const & p, std::nullptr_t ) noexcept
0670 {
0671 return p.get() != 0;
0672 }
0673
0674 template<class T> inline bool operator!=( std::nullptr_t, shared_ptr<T> const & p ) noexcept
0675 {
0676 return p.get() != 0;
0677 }
0678
0679 template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept
0680 {
0681 return a.owner_before( b );
0682 }
0683
0684 template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) noexcept
0685 {
0686 a.swap(b);
0687 }
0688
0689 template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) noexcept
0690 {
0691 (void) static_cast< T* >( static_cast< U* >( 0 ) );
0692
0693 typedef typename shared_ptr<T>::element_type E;
0694
0695 E * p = static_cast< E* >( r.get() );
0696 return shared_ptr<T>( r, p );
0697 }
0698
0699 template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) noexcept
0700 {
0701 (void) const_cast< T* >( static_cast< U* >( 0 ) );
0702
0703 typedef typename shared_ptr<T>::element_type E;
0704
0705 E * p = const_cast< E* >( r.get() );
0706 return shared_ptr<T>( r, p );
0707 }
0708
0709 template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) noexcept
0710 {
0711 (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
0712
0713 typedef typename shared_ptr<T>::element_type E;
0714
0715 E * p = dynamic_cast< E* >( r.get() );
0716 return p? shared_ptr<T>( r, p ): shared_ptr<T>();
0717 }
0718
0719 template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) noexcept
0720 {
0721 (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
0722
0723 typedef typename shared_ptr<T>::element_type E;
0724
0725 E * p = reinterpret_cast< E* >( r.get() );
0726 return shared_ptr<T>( r, p );
0727 }
0728
0729 template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> && r ) noexcept
0730 {
0731 (void) static_cast< T* >( static_cast< U* >( 0 ) );
0732
0733 typedef typename shared_ptr<T>::element_type E;
0734
0735 E * p = static_cast< E* >( r.get() );
0736 return shared_ptr<T>( std::move(r), p );
0737 }
0738
0739 template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> && r ) noexcept
0740 {
0741 (void) const_cast< T* >( static_cast< U* >( 0 ) );
0742
0743 typedef typename shared_ptr<T>::element_type E;
0744
0745 E * p = const_cast< E* >( r.get() );
0746 return shared_ptr<T>( std::move(r), p );
0747 }
0748
0749 template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> && r ) noexcept
0750 {
0751 (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
0752
0753 typedef typename shared_ptr<T>::element_type E;
0754
0755 E * p = dynamic_cast< E* >( r.get() );
0756 return p? shared_ptr<T>( std::move(r), p ): shared_ptr<T>();
0757 }
0758
0759 template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> && r ) noexcept
0760 {
0761 (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
0762
0763 typedef typename shared_ptr<T>::element_type E;
0764
0765 E * p = reinterpret_cast< E* >( r.get() );
0766 return shared_ptr<T>( std::move(r), p );
0767 }
0768
0769
0770
0771 template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) noexcept
0772 {
0773 return p.get();
0774 }
0775
0776
0777
0778 template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
0779 {
0780 os << p.get();
0781 return os;
0782 }
0783
0784
0785
0786 namespace detail
0787 {
0788
0789 template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) noexcept
0790 {
0791 return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID_(D)) );
0792 }
0793
0794 template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) noexcept;
0795 template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) noexcept;
0796
0797 class esft2_deleter_wrapper
0798 {
0799 private:
0800
0801 shared_ptr<void const volatile> deleter_;
0802
0803 public:
0804
0805 esft2_deleter_wrapper() noexcept
0806 {
0807 }
0808
0809 template< class T > void set_deleter( shared_ptr<T> const & deleter ) noexcept
0810 {
0811 deleter_ = deleter;
0812 }
0813
0814 template<typename D> D* get_deleter() const noexcept
0815 {
0816 return boost::detail::basic_get_deleter<D>( deleter_ );
0817 }
0818
0819 template< class T> void operator()( T* ) BOOST_SP_NOEXCEPT_WITH_ASSERT
0820 {
0821 BOOST_ASSERT( deleter_.use_count() <= 1 );
0822 deleter_.reset();
0823 }
0824 };
0825
0826 }
0827
0828 template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) noexcept
0829 {
0830 D * d = boost::detail::basic_get_deleter<D>( p );
0831
0832 if( d == 0 )
0833 {
0834 d = boost::detail::basic_get_local_deleter( d, p );
0835 }
0836
0837 if( d == 0 )
0838 {
0839 boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter<boost::detail::esft2_deleter_wrapper>(p);
0840
0841
0842 if(del_wrapper) d = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>();
0843 }
0844
0845 return d;
0846 }
0847
0848
0849
0850 #if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
0851
0852 template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * ) noexcept
0853 {
0854 return false;
0855 }
0856
0857 template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ) noexcept
0858 {
0859 boost::detail::spinlock_pool<2>::scoped_lock lock( p );
0860 return *p;
0861 }
0862
0863 template<class T, class M> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, M ) noexcept
0864 {
0865 return atomic_load( p );
0866 }
0867
0868 template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ) noexcept
0869 {
0870 boost::detail::spinlock_pool<2>::scoped_lock lock( p );
0871 p->swap( r );
0872 }
0873
0874 template<class T, class M> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, M ) noexcept
0875 {
0876 atomic_store( p, r );
0877 }
0878
0879 template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ) noexcept
0880 {
0881 boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
0882
0883 sp.lock();
0884 p->swap( r );
0885 sp.unlock();
0886
0887 return r;
0888 }
0889
0890 template<class T, class M> shared_ptr<T> inline atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, M ) noexcept
0891 {
0892 return atomic_exchange( p, r );
0893 }
0894
0895 template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ) noexcept
0896 {
0897 boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
0898
0899 sp.lock();
0900
0901 if( p->_internal_equiv( *v ) )
0902 {
0903 p->swap( w );
0904
0905 sp.unlock();
0906
0907 return true;
0908 }
0909 else
0910 {
0911 shared_ptr<T> tmp( *p );
0912
0913 sp.unlock();
0914
0915 tmp.swap( *v );
0916 return false;
0917 }
0918 }
0919
0920 template<class T, class M> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, M, M ) noexcept
0921 {
0922 return atomic_compare_exchange( p, v, w );
0923 }
0924
0925 #endif
0926
0927
0928
0929 template< class T > struct hash;
0930
0931 template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) noexcept
0932 {
0933 return boost::hash< typename boost::shared_ptr<T>::element_type* >()( p.get() );
0934 }
0935
0936 }
0937
0938
0939
0940 namespace std
0941 {
0942
0943 template<class T> struct hash< ::boost::shared_ptr<T> >
0944 {
0945 std::size_t operator()( ::boost::shared_ptr<T> const & p ) const noexcept
0946 {
0947 return std::hash< typename ::boost::shared_ptr<T>::element_type* >()( p.get() );
0948 }
0949 };
0950
0951 }
0952
0953 #include <boost/smart_ptr/detail/local_sp_deleter.hpp>
0954
0955 namespace boost
0956 {
0957
0958 namespace detail
0959 {
0960
0961 template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) noexcept
0962 {
0963 return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID_(local_sp_deleter<D>) ) );
0964 }
0965
0966 template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) noexcept
0967 {
0968 return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID_(local_sp_deleter<D>) ) );
0969 }
0970
0971 }
0972
0973 #if defined(__cpp_deduction_guides)
0974
0975 template<class T> shared_ptr( weak_ptr<T> ) -> shared_ptr<T>;
0976 template<class T, class D> shared_ptr( std::unique_ptr<T, D> ) -> shared_ptr<T>;
0977
0978 #endif
0979
0980 }
0981
0982 #if defined( BOOST_SP_DISABLE_DEPRECATED )
0983 #pragma GCC diagnostic pop
0984 #endif
0985
0986 #endif