diff --git boost/smart_ptr/detail/shared_count.hpp boost/smart_ptr/detail/shared_count.hpp index f96a220..ff8e8a4 100644 --- boost/smart_ptr/detail/shared_count.hpp +++ boost/smart_ptr/detail/shared_count.hpp @@ -79,6 +79,13 @@ public: { } + shared_count(sp_counted_base* counter): pi_(counter) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + } + template explicit shared_count( Y * p ): pi_( 0 ) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) diff --git boost/smart_ptr/detail/sp_counted_impl_ms.hpp boost/smart_ptr/detail/sp_counted_impl_ms.hpp new file mode 100644 index 0000000..634f8b9 --- /dev/null +++ boost/smart_ptr/detail/sp_counted_impl_ms.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_MS_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_MS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +template +class sp_counted_base_ms : public sp_counted_base +{ +public: + T* get_pointer() + { + return reinterpret_cast(p_.address()); + } + + virtual void dispose() // nothrow + { + get_pointer()->~T(); + } + + virtual void* get_deleter(detail::sp_typeinfo const &) + { + return NULL; + } + +private: + typedef boost::aligned_storage::value> storage_t; + storage_t p_; +}; + +template +class sp_counted_impl_ms : public sp_counted_base_ms +{ +}; + +template +class sp_counted_impl_ms_a : public sp_counted_base_ms, private A // use empty base optimization +{ +public: + sp_counted_impl_ms_a(A a) : A(a) // can throw if A's copy ctor throws + { + } + + virtual void destroy() + { + typename A::template rebind::other a2(static_cast(*this)); + this->sp_counted_impl_ms_a::~sp_counted_impl_ms_a(); + a2.deallocate(this, 1); + } +}; + +} // namespace boost::detail + +} // namespace boost + +#endif // BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_MS_HPP_INCLUDED diff --git boost/smart_ptr/make_shared.hpp boost/smart_ptr/make_shared.hpp index 7b605e2..95c8180 100644 --- boost/smart_ptr/make_shared.hpp +++ boost/smart_ptr/make_shared.hpp @@ -1,22 +1,20 @@ #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED #define BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED -// make_shared.hpp -// -// Copyright (c) 2007, 2008 Peter Dimov -// -// Distributed under the Boost Software License, Version 1.0. -// See 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/make_shared.html -// for documentation. +// MS compatible compilers support #pragma once + +#if defined( _MSC_VER ) && ( _MSC_VER >= 1020 ) +# pragma once +#endif #include #include -#include -#include -#include +#include +#include +#include + +#include // std::auto_ptr +#include // std::bad_alloc #include namespace boost @@ -25,956 +23,479 @@ namespace boost namespace detail { -template< std::size_t N, std::size_t A > struct sp_aligned_storage -{ - union type - { - char data_[ N ]; - typename boost::type_with_alignment< A >::type align_; - }; -}; +#ifdef BOOST_NO_EXCEPTIONS -template< class T > class sp_ms_deleter +template +void verify_allocation(T* p) { -private: - - typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type; - - bool initialized_; - storage_type storage_; - -private: - - void destroy() - { - if( initialized_ ) - { -#if defined( __GNUC__ ) - - // fixes incorrect aliasing warning - T * p = reinterpret_cast< T* >( storage_.data_ ); - p->~T(); + if (!p) + { + boost::throw_exception(std::bad_alloc()); + } +} #else - reinterpret_cast< T* >( storage_.data_ )->~T(); +template +void verify_allocation(T*) {} -#endif +#endif // BOOST_NO_EXCEPTIONS - initialized_ = false; - } - } +// scoped holder of sp counter object allocated with custom allocator +template +class scoped_sp_counter : private boost::noncopyable +{ + typedef typename Alloc::template rebind::other sp_counter_alloc_t; public: + scoped_sp_counter(const Alloc& a) : a_(a) + { + p_ = a_.allocate(1, NULL); + boost::detail::verify_allocation(p_); + new (p_) SpCounter(a); // nothrow if a's copy ctor doesn't throw + } + + ~scoped_sp_counter() + { + if (p_) + { + p_->~SpCounter(); + a_.deallocate(p_, 1); + } + } + + SpCounter* operator->() const { return p_; } + SpCounter* release() { SpCounter* released = p_; p_ = NULL; return released; } - sp_ms_deleter(): initialized_( false ) - { - } - - // optimization: do not copy storage_ - sp_ms_deleter( sp_ms_deleter const & ): initialized_( false ) - { - } - - ~sp_ms_deleter() - { - destroy(); - } - - void operator()( T * ) - { - destroy(); - } - - void * address() - { - return storage_.data_; - } - - void set_initialized() - { - initialized_ = true; - } +private: + SpCounter* p_; + sp_counter_alloc_t a_; }; -#if defined( BOOST_HAS_RVALUE_REFS ) +} // namespace boost::detail -template< class T > T&& sp_forward( T & t ) -{ - return static_cast< T&& >( t ); -} - -#endif - -} // namespace detail - -#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) -# define BOOST_SP_MSD( T ) boost::detail::sp_inplace_tag< boost::detail::sp_ms_deleter< T > >() -#else -# define BOOST_SP_MSD( T ) boost::detail::sp_ms_deleter< T >() -#endif -// Zero-argument versions -// -// Used even when variadic templates are available because of the new T() vs new T issue - -template< class T > boost::shared_ptr< T > make_shared() +template +boost::shared_ptr make_shared() { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T(); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a ) +template +boost::shared_ptr allocate_shared(A const & a) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T(); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS ) - -// Variadic templates, rvalue reference +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) -template< class T, class Arg1, class... Args > boost::shared_ptr< T > make_shared( Arg1 && arg1, Args && ... args ) +template +boost::shared_ptr make_shared(Arg1&& arg1, Args&&... args) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( boost::detail::sp_forward( arg1 ), boost::detail::sp_forward( args )... ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(std::forward(arg1), std::forward(args)...); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class Arg1, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Arg1 && arg1, Args && ... args ) +template +boost::shared_ptr allocate_shared(A const & a, Arg1&& arg1, Args&&... args) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( boost::detail::sp_forward( arg1 ), boost::detail::sp_forward( args )... ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(std::forward(arg1), std::forward(args)...); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -#elif defined( BOOST_HAS_RVALUE_REFS ) +#elif defined(BOOST_HAS_RVALUE_REFS) -// For example MSVC 10.0 - -template< class T, class A1 > -boost::shared_ptr< T > make_shared( A1 && a1 ) +template +boost::shared_ptr make_shared(A1&& a1) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(std::forward(a1)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1 ) +template +boost::shared_ptr make_shared(A1&& a1, A2&& a2) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2 > -boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2 ) +template +boost::shared_ptr make_shared(A1&& a1, A2&& a2, A3&& a3) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2 ) +template +boost::shared_ptr make_shared(A1&& a1, A2&& a2, A3&& a3, A4&& a4) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3 > -boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3 ) +template +boost::shared_ptr make_shared(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4), std::forward(a5)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3 ) +template +boost::shared_ptr make_shared(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4), std::forward(a5), std::forward(a6)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4 > -boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4 ) +template +boost::shared_ptr make_shared(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4), std::forward(a5), std::forward(a6), + std::forward(a7)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4 ) +template +boost::shared_ptr make_shared(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, A8&& a8) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4), std::forward(a5), std::forward(a6), + std::forward(a7), std::forward(a8)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4, class A5 > -boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 ) +template +boost::shared_ptr make_shared(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, A8&& a8, A9&& a9) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ), - boost::detail::sp_forward( a5 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4), std::forward(a5), std::forward(a6), + std::forward(a7), std::forward(a8), std::forward(a9)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4, class A5 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 ) +template +boost::shared_ptr allocate_shared(A const & a, A1&& a1) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ), - boost::detail::sp_forward( a5 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(std::forward(a1)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > -boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 ) +template +boost::shared_ptr allocate_shared(A const & a, A1&& a1, A2&& a2) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ), - boost::detail::sp_forward( a5 ), - boost::detail::sp_forward( a6 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 ) +template +boost::shared_ptr allocate_shared(A const & a, A1&& a1, A2&& a2, A3&& a3) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ), - boost::detail::sp_forward( a5 ), - boost::detail::sp_forward( a6 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > -boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 ) +template +boost::shared_ptr allocate_shared(A const & a, A1&& a1, A2&& a2, A3&& a3, A4&& a4) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ), - boost::detail::sp_forward( a5 ), - boost::detail::sp_forward( a6 ), - boost::detail::sp_forward( a7 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 ) +template +boost::shared_ptr allocate_shared(A const & a, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ), - boost::detail::sp_forward( a5 ), - boost::detail::sp_forward( a6 ), - boost::detail::sp_forward( a7 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4), std::forward(a5)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > -boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 ) +template +boost::shared_ptr allocate_shared(A const & a, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ), - boost::detail::sp_forward( a5 ), - boost::detail::sp_forward( a6 ), - boost::detail::sp_forward( a7 ), - boost::detail::sp_forward( a8 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4), std::forward(a5), std::forward(a6)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 ) +template +boost::shared_ptr allocate_shared(A const & a, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ), - boost::detail::sp_forward( a5 ), - boost::detail::sp_forward( a6 ), - boost::detail::sp_forward( a7 ), - boost::detail::sp_forward( a8 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4), std::forward(a5), std::forward(a6), + std::forward(a7)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > -boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 ) +template +boost::shared_ptr allocate_shared(A const & a, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, A8&& a8) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ), - boost::detail::sp_forward( a5 ), - boost::detail::sp_forward( a6 ), - boost::detail::sp_forward( a7 ), - boost::detail::sp_forward( a8 ), - boost::detail::sp_forward( a9 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4), std::forward(a5), std::forward(a6), + std::forward(a7), std::forward(a8)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 ) +template +boost::shared_ptr allocate_shared(A const & a, A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, A8&& a8, A9&& a9) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( - boost::detail::sp_forward( a1 ), - boost::detail::sp_forward( a2 ), - boost::detail::sp_forward( a3 ), - boost::detail::sp_forward( a4 ), - boost::detail::sp_forward( a5 ), - boost::detail::sp_forward( a6 ), - boost::detail::sp_forward( a7 ), - boost::detail::sp_forward( a8 ), - boost::detail::sp_forward( a9 ) - ); - - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T( + std::forward(a1), std::forward(a2), std::forward(a3), + std::forward(a4), std::forward(a5), std::forward(a6), + std::forward(a7), std::forward(a8), std::forward(a9)); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -#else - -// C++03 version +#else // C++03 -template< class T, class A1 > -boost::shared_ptr< T > make_shared( A1 const & a1 ) +template +boost::shared_ptr make_shared(A1 const & a1) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(a1); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 ) +template +boost::shared_ptr make_shared(A1 const & a1, A2 const & a2) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(a1, a2); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2 > -boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 ) +template +boost::shared_ptr make_shared(A1 const & a1, A2 const & a2, A3 const & a3) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(a1, a2, a3); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 ) +template +boost::shared_ptr make_shared(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(a1, a2, a3, a4); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3 > -boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 ) +template +boost::shared_ptr make_shared(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(a1, a2, a3, a4, a5); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 ) +template +boost::shared_ptr make_shared(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(a1, a2, a3, a4, a5, a6); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4 > -boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 ) +template +boost::shared_ptr make_shared(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(a1, a2, a3, a4, a5, a6, a7); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 ) +template +boost::shared_ptr make_shared(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(a1, a2, a3, a4, a5, a6, a7, a8); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4, class A5 > -boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 ) +template +boost::shared_ptr make_shared(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4, a5 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + std::auto_ptr > counter(new boost::detail::sp_counted_impl_ms()); + boost::detail::verify_allocation(counter.get()); + ::new (counter->get_pointer()) T(a1, a2, a3, a4, a5, a6, a7, a8, a9); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4, class A5 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 ) +template +boost::shared_ptr allocate_shared(A const & a, A1 const & a1) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4, a5 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(a1); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > -boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 ) +template +boost::shared_ptr allocate_shared(A const & a, A1 const & a1, A2 const & a2) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4, a5, a6 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(a1, a2); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 ) +template +boost::shared_ptr allocate_shared(A const & a, A1 const & a1, A2 const & a2, A3 const & a3) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4, a5, a6 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(a1, a2, a3); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > -boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 ) +template +boost::shared_ptr allocate_shared(A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(a1, a2, a3, a4); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 ) +template +boost::shared_ptr allocate_shared(A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(a1, a2, a3, a4, a5); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > -boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 ) +template +boost::shared_ptr allocate_shared(A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(a1, a2, a3, a4, a5, a6); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 ) +template +boost::shared_ptr allocate_shared(A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(a1, a2, a3, a4, a5, a6, a7); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > -boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 ) +template +boost::shared_ptr allocate_shared(A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(a1, a2, a3, a4, a5, a6, a7, a8); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 ) +template +boost::shared_ptr allocate_shared(A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) { - boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); - - boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt ); - - void * pv = pd->address(); - - ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); - pd->set_initialized(); - - T * pt2 = static_cast< T* >( pv ); - - boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); - return boost::shared_ptr< T >( pt, pt2 ); + boost::detail::scoped_sp_counter, A> counter(a); + ::new (counter->get_pointer()) T(a1, a2, a3, a4, a5, a6, a7, a8, a9); + boost::detail::sp_counted_base_ms* c = counter.release(); + return boost::shared_ptr(c->get_pointer(), static_cast(c)); } -#endif - -#undef BOOST_SP_MSD +#endif // C++03 } // namespace boost diff --git boost/smart_ptr/shared_ptr.hpp boost/smart_ptr/shared_ptr.hpp index 0932cc3..8412747 100644 --- boost/smart_ptr/shared_ptr.hpp +++ boost/smart_ptr/shared_ptr.hpp @@ -108,9 +108,11 @@ template< class X, class Y, class T > inline void sp_enable_shared_from_this( bo template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); -#ifdef _MANAGED +#if defined(_MANAGED) || defined(BOOST_MSVC) // Avoid C4793, ... causes native code generation +// Also, function with (...) isn't inlined (bug?), so compiler generates call of empty function +// instead of throwing it out. struct sp_any_pointer { @@ -121,13 +123,13 @@ inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_p { } -#else // _MANAGED +#else // defined(_MANAGED) || defined(BOOST_MSVC) inline void sp_enable_shared_from_this( ... ) { } -#endif // _MANAGED +#endif // defined(_MANAGED) || defined(BOOST_MSVC) #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR ) @@ -273,6 +275,12 @@ public: } } + template + shared_ptr(Y* p, boost::detail::sp_counted_base* counter): px(p), pn(counter) // never throws + { + boost::detail::sp_enable_shared_from_this( this, p, p ); + } + #ifndef BOOST_NO_AUTO_PTR template