diff options
Diffstat (limited to 'cutl/details/boost/smart_ptr/detail/shared_count.hpp')
-rw-r--r-- | cutl/details/boost/smart_ptr/detail/shared_count.hpp | 165 |
1 files changed, 162 insertions, 3 deletions
diff --git a/cutl/details/boost/smart_ptr/detail/shared_count.hpp b/cutl/details/boost/smart_ptr/detail/shared_count.hpp index 16d6527..77aea5c 100644 --- a/cutl/details/boost/smart_ptr/detail/shared_count.hpp +++ b/cutl/details/boost/smart_ptr/detail/shared_count.hpp @@ -35,7 +35,14 @@ // rather than including <memory> directly: #include <cutl/details/boost/config/no_tr1/memory.hpp> // std::auto_ptr #include <functional> // std::less -#include <new> // std::bad_alloc + +#ifdef BOOST_NO_EXCEPTIONS +# include <new> // std::bad_alloc +#endif + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) +# include <cutl/details/boost/utility/addressof.hpp> +#endif namespace cutl_details_boost { @@ -52,6 +59,42 @@ int const weak_count_id = 0x298C38A4; struct sp_nothrow_tag {}; +template< class D > struct sp_inplace_tag +{ +}; + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) + +template< class T > class sp_reference_wrapper +{ +public: + + explicit sp_reference_wrapper( T & t): t_( cutl_details_boost::addressof( t ) ) + { + } + + template< class Y > void operator()( Y * p ) const + { + (*t_)( p ); + } + +private: + + T * t_; +}; + +template< class D > struct sp_convert_reference +{ + typedef D type; +}; + +template< class D > struct sp_convert_reference< D& > +{ + typedef sp_reference_wrapper< D > type; +}; + +#endif + class weak_count; class shared_count @@ -142,6 +185,40 @@ public: #endif } +#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) + + template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_impl_pd< P, D >( p ); + } + catch( ... ) + { + D::operator_fn( p ); // delete p + throw; + } + +#else + + pi_ = new sp_counted_impl_pd< P, D >( p ); + + if( pi_ == 0 ) + { + D::operator_fn( p ); // delete p + cutl_details_boost::throw_exception( std::bad_alloc() ); + } + +#endif // #ifndef BOOST_NO_EXCEPTIONS + } + +#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) + template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 ) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) @@ -188,6 +265,56 @@ public: #endif } +#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) + + template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + typedef sp_counted_impl_pda< P, D, A > impl_type; + typedef typename A::template rebind< impl_type >::other A2; + + A2 a2( a ); + +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + new( static_cast< void* >( pi_ ) ) impl_type( p, a ); + } + catch(...) + { + D::operator_fn( p ); + + if( pi_ != 0 ) + { + a2.deallocate( static_cast< impl_type* >( pi_ ), 1 ); + } + + throw; + } + +#else + + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + + if( pi_ != 0 ) + { + new( static_cast< void* >( pi_ ) ) impl_type( p, a ); + } + else + { + D::operator_fn( p ); + cutl_details_boost::throw_exception( std::bad_alloc() ); + } + +#endif // #ifndef BOOST_NO_EXCEPTIONS + } + +#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) + #ifndef BOOST_NO_AUTO_PTR // auto_ptr<Y> is special cased to provide the strong guarantee @@ -212,6 +339,33 @@ public: #endif +#if !defined( BOOST_NO_CXX11_SMART_PTR ) + + template<class Y, class D> + explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + typedef typename sp_convert_reference<D>::type D2; + + D2 d2( r.get_deleter() ); + pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 ); + +#ifdef BOOST_NO_EXCEPTIONS + + if( pi_ == 0 ) + { + cutl_details_boost::throw_exception( std::bad_alloc() ); + } + +#endif + + r.release(); + } + +#endif + ~shared_count() // nothrow { if( pi_ != 0 ) pi_->release(); @@ -228,7 +382,7 @@ public: if( pi_ != 0 ) pi_->add_ref_copy(); } -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) shared_count(shared_count && r): pi_(r.pi_) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) @@ -293,6 +447,11 @@ public: { return pi_? pi_->get_deleter( ti ): 0; } + + void * get_untyped_deleter() const + { + return pi_? pi_->get_untyped_deleter(): 0; + } }; @@ -335,7 +494,7 @@ public: // Move support -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) weak_count(weak_count && r): pi_(r.pi_) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) |