diff options
Diffstat (limited to 'boost/smart_ptr/shared_ptr.hpp')
-rw-r--r-- | boost/smart_ptr/shared_ptr.hpp | 225 |
1 files changed, 135 insertions, 90 deletions
diff --git a/boost/smart_ptr/shared_ptr.hpp b/boost/smart_ptr/shared_ptr.hpp index e33707b3bc..e8a302c74a 100644 --- a/boost/smart_ptr/shared_ptr.hpp +++ b/boost/smart_ptr/shared_ptr.hpp @@ -11,7 +11,7 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// See http://www.boost.org/libs/smart_ptr/ for documentation. // #include <boost/config.hpp> // for broken compiler workarounds @@ -262,7 +262,7 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R // sp_assert_convertible -template< class Y, class T > inline void sp_assert_convertible() +template< class Y, class T > inline void sp_assert_convertible() BOOST_SP_NOEXCEPT { #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) @@ -323,6 +323,10 @@ template< class T, std::size_t N, class Y > inline void sp_deleter_construct( bo #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) +struct sp_internal_constructor_tag +{ +}; + } // namespace detail @@ -345,13 +349,25 @@ public: typedef typename boost::detail::sp_element< T >::type element_type; - shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+ + BOOST_CONSTEXPR shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn() { } #if !defined( BOOST_NO_CXX11_NULLPTR ) - shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn() // never throws + BOOST_CONSTEXPR shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn() + { + } + +#endif + + 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_ ) + { + } + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + 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_ ) ) { } @@ -420,7 +436,7 @@ public: template<class Y> shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ) - BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) + BOOST_SP_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) { if( !pn.empty() ) { @@ -438,14 +454,14 @@ public: shared_ptr( shared_ptr<Y> const & r ) #endif - BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) + BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn ) { boost::detail::sp_assert_convertible< Y, T >(); } // aliasing template< class Y > - shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn ) + shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn ) { } @@ -502,9 +518,12 @@ public: boost::detail::sp_assert_convertible< Y, T >(); typename std::unique_ptr< Y, D >::pointer tmp = r.get(); - pn = boost::detail::shared_count( r ); - boost::detail::sp_deleter_construct( this, tmp ); + if( tmp != 0 ) + { + pn = boost::detail::shared_count( r ); + boost::detail::sp_deleter_construct( this, tmp ); + } } #endif @@ -515,9 +534,12 @@ public: boost::detail::sp_assert_convertible< Y, T >(); typename boost::movelib::unique_ptr< Y, D >::pointer tmp = r.get(); - pn = boost::detail::shared_count( r ); - boost::detail::sp_deleter_construct( this, tmp ); + if( tmp != 0 ) + { + pn = boost::detail::shared_count( r ); + boost::detail::sp_deleter_construct( this, tmp ); + } } // assignment @@ -531,7 +553,7 @@ public: #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400) template<class Y> - shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_NOEXCEPT + shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_SP_NOEXCEPT { this_type(r).swap(*this); return *this; @@ -592,10 +614,13 @@ public: shared_ptr tmp; - tmp.px = p; - tmp.pn = boost::detail::shared_count( r ); + if( p != 0 ) + { + tmp.px = p; + tmp.pn = boost::detail::shared_count( r ); - boost::detail::sp_deleter_construct( &tmp, p ); + boost::detail::sp_deleter_construct( &tmp, p ); + } tmp.swap( *this ); @@ -622,7 +647,7 @@ public: shared_ptr( shared_ptr<Y> && r ) #endif - BOOST_NOEXCEPT : px( r.px ), pn() + BOOST_SP_NOEXCEPT : px( r.px ), pn() { boost::detail::sp_assert_convertible< Y, T >(); @@ -637,7 +662,7 @@ public: } template<class Y> - shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_NOEXCEPT + shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_SP_NOEXCEPT { this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this ); return *this; @@ -645,7 +670,7 @@ public: // aliasing move template<class Y> - shared_ptr( shared_ptr<Y> && r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn() + shared_ptr( shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn() { pn.swap( r.pn ); r.px = 0; @@ -655,7 +680,7 @@ public: #if !defined( BOOST_NO_CXX11_NULLPTR ) - shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT // never throws + shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT { this_type().swap(*this); return *this; @@ -663,7 +688,7 @@ public: #endif - void reset() BOOST_NOEXCEPT // never throws in 1.30+ + void reset() BOOST_SP_NOEXCEPT { this_type().swap(*this); } @@ -684,36 +709,33 @@ public: this_type( p, d, a ).swap( *this ); } - template<class Y> void reset( shared_ptr<Y> const & r, element_type * p ) + template<class Y> void reset( shared_ptr<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT { this_type( r, p ).swap( *this ); } #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - template<class Y> void reset( shared_ptr<Y> && r, element_type * p ) + template<class Y> void reset( shared_ptr<Y> && r, element_type * p ) BOOST_SP_NOEXCEPT { this_type( static_cast< shared_ptr<Y> && >( r ), p ).swap( *this ); } #endif - // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) - typename boost::detail::sp_dereference< T >::type operator* () const + typename boost::detail::sp_dereference< T >::type operator* () const BOOST_SP_NOEXCEPT_WITH_ASSERT { BOOST_ASSERT( px != 0 ); return *px; } - // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) - typename boost::detail::sp_member_access< T >::type operator-> () const + typename boost::detail::sp_member_access< T >::type operator-> () const BOOST_SP_NOEXCEPT_WITH_ASSERT { BOOST_ASSERT( px != 0 ); return px; } - // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) - typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const + typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const BOOST_SP_NOEXCEPT_WITH_ASSERT { BOOST_ASSERT( px != 0 ); BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) ); @@ -721,7 +743,7 @@ public: return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] ); } - element_type * get() const BOOST_NOEXCEPT + element_type * get() const BOOST_SP_NOEXCEPT { return px; } @@ -729,47 +751,57 @@ public: // implicit conversion to "bool" #include <boost/smart_ptr/detail/operator_bool.hpp> - bool unique() const BOOST_NOEXCEPT + bool unique() const BOOST_SP_NOEXCEPT { return pn.unique(); } - long use_count() const BOOST_NOEXCEPT + long use_count() const BOOST_SP_NOEXCEPT { return pn.use_count(); } - void swap( shared_ptr & other ) BOOST_NOEXCEPT + void swap( shared_ptr & other ) BOOST_SP_NOEXCEPT { std::swap(px, other.px); pn.swap(other.pn); } - template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT + template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT { return pn < rhs.pn; } - template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT + template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT { return pn < rhs.pn; } - void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT + void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT { return pn.get_deleter( ti ); } - void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT + void * _internal_get_local_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT + { + return pn.get_local_deleter( ti ); + } + + void * _internal_get_untyped_deleter() const BOOST_SP_NOEXCEPT { return pn.get_untyped_deleter(); } - bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT + bool _internal_equiv( shared_ptr const & r ) const BOOST_SP_NOEXCEPT { return px == r.px && pn == r.pn; } + boost::detail::shared_count _internal_count() const BOOST_NOEXCEPT + { + return pn; + } + // Tasteless as this may seem, making all members public allows member templates // to work in the absence of member template friends. (Matthew Langston) @@ -788,12 +820,12 @@ private: }; // shared_ptr -template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT +template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPT { return a.get() == b.get(); } -template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT +template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPT { return a.get() != b.get(); } @@ -802,7 +834,7 @@ template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, share // Resolve the ambiguity between our op!= and the one in rel_ops -template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_NOEXCEPT +template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_SP_NOEXCEPT { return a.get() != b.get(); } @@ -811,39 +843,39 @@ template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> #if !defined( BOOST_NO_CXX11_NULLPTR ) -template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT +template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT { return p.get() == 0; } -template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT +template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT { return p.get() == 0; } -template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT +template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT { return p.get() != 0; } -template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT +template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT { return p.get() != 0; } #endif -template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT +template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_SP_NOEXCEPT { return a.owner_before( b ); } -template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_NOEXCEPT +template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_SP_NOEXCEPT { a.swap(b); } -template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT +template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT { (void) static_cast< T* >( static_cast< U* >( 0 ) ); @@ -853,7 +885,7 @@ template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> cons return shared_ptr<T>( r, p ); } -template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT +template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT { (void) const_cast< T* >( static_cast< U* >( 0 ) ); @@ -863,7 +895,7 @@ template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const return shared_ptr<T>( r, p ); } -template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT +template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT { (void) dynamic_cast< T* >( static_cast< U* >( 0 ) ); @@ -873,7 +905,7 @@ template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> con return p? shared_ptr<T>( r, p ): shared_ptr<T>(); } -template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT +template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_SP_NOEXCEPT { (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); @@ -885,7 +917,7 @@ template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) -template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> && r ) BOOST_NOEXCEPT +template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT { (void) static_cast< T* >( static_cast< U* >( 0 ) ); @@ -895,7 +927,7 @@ template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> && r return shared_ptr<T>( std::move(r), p ); } -template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> && r ) BOOST_NOEXCEPT +template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT { (void) const_cast< T* >( static_cast< U* >( 0 ) ); @@ -905,7 +937,7 @@ template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> && r return shared_ptr<T>( std::move(r), p ); } -template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> && r ) BOOST_NOEXCEPT +template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT { (void) dynamic_cast< T* >( static_cast< U* >( 0 ) ); @@ -915,7 +947,7 @@ template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> && return p? shared_ptr<T>( std::move(r), p ): shared_ptr<T>(); } -template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> && r ) BOOST_NOEXCEPT +template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> && r ) BOOST_SP_NOEXCEPT { (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); @@ -929,7 +961,7 @@ template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> // get_pointer() enables boost::mem_fn to recognize shared_ptr -template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_NOEXCEPT +template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_SP_NOEXCEPT { return p.get(); } @@ -974,27 +1006,13 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std:: namespace detail { -#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \ - ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \ - ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) ) - -// g++ 2.9x doesn't allow static_cast<X const *>(void *) -// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it - -template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p) -{ - void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D)); - return const_cast<D *>(static_cast<D const *>(q)); -} - -#else - -template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT +template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT { return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID(D)) ); } -#endif +template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT; +template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT; class esft2_deleter_wrapper { @@ -1008,17 +1026,17 @@ public: { } - template< class T > void set_deleter( shared_ptr<T> const & deleter ) + template< class T > void set_deleter( shared_ptr<T> const & deleter ) BOOST_SP_NOEXCEPT { deleter_ = deleter; } - template<typename D> D* get_deleter() const BOOST_NOEXCEPT + template<typename D> D* get_deleter() const BOOST_SP_NOEXCEPT { return boost::detail::basic_get_deleter<D>( deleter_ ); } - template< class T> void operator()( T* ) + template< class T> void operator()( T* ) BOOST_SP_NOEXCEPT_WITH_ASSERT { BOOST_ASSERT( deleter_.use_count() <= 1 ); deleter_.reset(); @@ -1027,53 +1045,58 @@ public: } // namespace detail -template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT +template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT { - D *del = boost::detail::basic_get_deleter<D>(p); + D * d = boost::detail::basic_get_deleter<D>( p ); + + if( d == 0 ) + { + d = boost::detail::basic_get_local_deleter( d, p ); + } - if(del == 0) + if( d == 0 ) { boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter<boost::detail::esft2_deleter_wrapper>(p); // The following get_deleter method call is fully qualified because // older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>() - if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>(); + if(del_wrapper) d = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>(); } - return del; + return d; } // atomic access #if !defined(BOOST_SP_NO_ATOMIC_ACCESS) -template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_NOEXCEPT +template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_SP_NOEXCEPT { return false; } -template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ) +template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ) BOOST_SP_NOEXCEPT { boost::detail::spinlock_pool<2>::scoped_lock lock( p ); return *p; } -template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, /*memory_order mo*/ int ) +template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, /*memory_order mo*/ int ) BOOST_SP_NOEXCEPT { return atomic_load( p ); } -template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ) +template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ) BOOST_SP_NOEXCEPT { boost::detail::spinlock_pool<2>::scoped_lock lock( p ); p->swap( r ); } -template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int ) +template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int ) BOOST_SP_NOEXCEPT { atomic_store( p, r ); // std::move( r ) } -template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ) +template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ) BOOST_SP_NOEXCEPT { boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p ); @@ -1084,12 +1107,12 @@ template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T return r; // return std::move( r ) } -template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int ) +template<class T> shared_ptr<T> inline atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int ) BOOST_SP_NOEXCEPT { return atomic_exchange( p, r ); // std::move( r ) } -template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ) +template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT { boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p ); @@ -1114,7 +1137,7 @@ template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> } } -template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, /*memory_order success*/ int, /*memory_order failure*/ int ) +template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, /*memory_order success*/ int, /*memory_order failure*/ int ) BOOST_SP_NOEXCEPT { return atomic_compare_exchange( p, v, w ); // std::move( w ) } @@ -1125,13 +1148,35 @@ template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * template< class T > struct hash; -template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_NOEXCEPT +template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT { return boost::hash< typename boost::shared_ptr<T>::element_type* >()( p.get() ); } } // namespace boost +#include <boost/smart_ptr/detail/local_sp_deleter.hpp> + +namespace boost +{ + +namespace detail +{ + +template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT +{ + return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID(local_sp_deleter<D>) ) ); +} + +template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT +{ + return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID(local_sp_deleter<D>) ) ); +} + +} // namespace detail + +} // namespace boost + #if defined( BOOST_SP_DISABLE_DEPRECATED ) #pragma GCC diagnostic pop #endif |