diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp new file mode 100644 index 0000000..b2aa826 --- /dev/null +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP +#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP + +#include +#include +#include +#include +#include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +namespace boost { + template + inline typename detail::sp_if_array::type + allocate_shared(const A& allocator, std::size_t size) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = size * detail::array_total::size; + detail::allocate_array_helper a1(allocator, n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, n1); + return shared_ptr(s1, p1); + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + template + inline typename detail::sp_if_array::type + allocate_shared(const A& allocator, std::size_t size, Args&&... args) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = size * detail::array_total::size; + detail::allocate_array_helper a1(allocator, n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, n1, std::forward(args)...); + return shared_ptr(s1, p1); + } + template + inline typename detail::sp_if_size_array::type + allocate_shared(const A& allocator, Args&&... args) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = detail::array_total::size; + detail::allocate_array_helper a1(allocator, n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, n1, std::forward(args)...); + return shared_ptr(s1, p1); + } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + inline typename detail::sp_if_array::type + allocate_shared(const A& allocator, + std::initializer_list::type> list) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + typedef const T2 T3; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n1 = list.size() * detail::array_total::size; + detail::allocate_array_helper a1(allocator, n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p3 = reinterpret_cast(list.begin()); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, n1, p3); + return shared_ptr(s1, p1); + } + template + inline typename detail::sp_if_size_array::type + allocate_shared(const A& allocator, + std::initializer_list::type> list) { + BOOST_ASSERT(list.size() == detail::array_size::size); + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + typedef const T2 T3; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n1 = detail::array_total::size; + detail::allocate_array_helper a1(allocator, n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p3 = reinterpret_cast(list.begin()); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, n1, p3); + return shared_ptr(s1, p1); + } + template + inline typename detail::sp_if_array::type + allocate_shared(const A& allocator, std::size_t size, + std::initializer_list::type> list) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + typedef const T2 T3; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n0 = detail::array_total::size; + std::size_t n1 = n0 * list.size(); + detail::allocate_array_helper a1(allocator, n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p3 = reinterpret_cast(list.begin()); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, n1, p3, n0); + return shared_ptr(s1, p1); + } +#endif +} + +#endif diff --git a/include/boost/smart_ptr/detail/allocate_array_helper.hpp b/include/boost/smart_ptr/detail/allocate_array_helper.hpp new file mode 100644 index 0000000..bfb4dec --- /dev/null +++ b/include/boost/smart_ptr/detail/allocate_array_helper.hpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP +#define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP + +#include + +namespace boost { + namespace detail { + template + class allocate_array_helper { + template + friend class allocate_array_helper; + typedef typename A::template rebind ::other A2; + typedef typename A::template rebind::other A3; + public: + typedef typename A2::value_type value_type; + typedef typename A2::pointer pointer; + typedef typename A2::const_pointer const_pointer; + typedef typename A2::reference reference; + typedef typename A2::const_reference const_reference; + typedef typename A2::size_type size_type; + typedef typename A2::difference_type difference_type; + template + struct rebind { + typedef allocate_array_helper other; + }; + allocate_array_helper(const A& allocator, std::size_t size, T** data) + : allocator(allocator), + size(sizeof(T) * size), + data(data) { + } + allocate_array_helper(const allocate_array_helper& other) + : allocator(other.allocator), + size(other.size), + data(other.data) { + } + template + allocate_array_helper(const allocate_array_helper& other) + : allocator(other.allocator), + size(other.size), + data(other.data) { + } + pointer address(reference value) const { + return allocator.address(value); + } + const_pointer address(const_reference value) const { + return allocator.address(value); + } + size_type max_size() const { + return allocator.max_size(); + } + pointer allocate(size_type count, const void* value = 0) { + std::size_t a1 = alignment_of::value; + std::size_t n1 = count * sizeof(Y) + a1 - 1; + char* p1 = A3(allocator).allocate(n1 + size, value); + char* p2 = p1 + n1; + while (std::size_t(p2) % a1 != 0) { + p2--; + } + *data = reinterpret_cast(p2); + return reinterpret_cast(p1); + } + void deallocate(pointer memory, size_type count) { + std::size_t a1 = alignment_of::value; + std::size_t n1 = count * sizeof(Y) + a1 - 1; + char* p1 = reinterpret_cast(memory); + A3(allocator).deallocate(p1, n1 + size); + } + void construct(pointer memory, const Y& value) { + allocator.construct(memory, value); + } + void destroy(pointer memory) { + allocator.destroy(memory); + } + template + bool operator==(const allocate_array_helper& other) const { + return allocator == other.allocator; + } + template + bool operator!=(const allocate_array_helper& other) const { + return !(*this == other); + } + private: + A2 allocator; + std::size_t size; + T** data; + }; + } +} + +#endif diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp new file mode 100644 index 0000000..273dcac --- /dev/null +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP +#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP + +#include +#include + +namespace boost { + namespace detail { + template + class array_deleter { + public: + array_deleter() + : size(0) { + } + ~array_deleter() { + destroy(); + } + void construct(T* memory, std::size_t count) { + for (object = memory; size < count; size++) { + void* p1 = object + size; + ::new(p1) T(); + } + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + template + void construct(T* memory, std::size_t count, Args&&... args) { + for (object = memory; size < count; size++) { + void* p1 = object + size; + ::new(p1) T(args...); + } + } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void construct_list(T* memory, std::size_t count, const T* list) { + for (object = memory; size < count; size++) { + void* p1 = object + size; + ::new(p1) T(list[size]); + } + } + void construct_list(T* memory, std::size_t count, const T* list, std::size_t n) { + for (object = memory; size < count; size++) { + void* p1 = object + size; + ::new(p1) T(list[size % n]); + } + } +#endif + void construct_noinit(T* memory, std::size_t count) { + for (object = memory; size < count; size++) { + void* p1 = object + size; + ::new(p1) T; + } + } + void operator()(const void*) { + destroy(); + } + private: + void destroy() { + while (size > 0) { + object[--size].~T(); + } + } + std::size_t size; + T* object; + }; + } +} + +#endif diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp new file mode 100644 index 0000000..068629a --- /dev/null +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP +#define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP + +#include + +namespace boost { + namespace detail { + template + struct array_base { + typedef typename boost::remove_cv::type type; + }; + template + struct array_base { + typedef typename array_base::type type; + }; + template + struct array_size { + }; + template + struct array_size { + enum { + size = N + }; + }; + template + struct array_total { + enum { + size = 1 + }; + }; + template + struct array_total { + enum { + size = N * array_total::size + }; + }; + template + struct array_inner { + }; + template + struct array_inner { + typedef T type; + }; + template + struct array_inner { + typedef T type; + }; + template + struct arrays_inner { + }; + template + struct arrays_inner { + typedef T type; + }; + } +} + +#endif diff --git a/include/boost/smart_ptr/detail/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp new file mode 100644 index 0000000..96fa3f9 --- /dev/null +++ b/include/boost/smart_ptr/detail/make_array_helper.hpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#ifndef BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP +#define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP + +#include + +namespace boost { + namespace detail { + template + class make_array_helper { + template + friend class make_array_helper; + public: + typedef Y value_type; + typedef Y* pointer; + typedef const Y* const_pointer; + typedef Y& reference; + typedef const Y& const_reference; + typedef std::size_t size_type; + typedef ptrdiff_t difference_type; + template + struct rebind { + typedef make_array_helper other; + }; + make_array_helper(std::size_t size, T** data) + : size(sizeof(T) * size), + data(data) { + } + make_array_helper(const make_array_helper& other) + : size(other.size), + data(other.data) { + } + template + make_array_helper(const make_array_helper& other) + : size(other.size), + data(other.data) { + } + pointer address(reference value) const { + return &value; + } + const_pointer address(const_reference value) const { + return &value; + } + size_type max_size() const { + return static_cast(-1) / sizeof(Y); + } + pointer allocate(size_type count, const void* = 0) { + std::size_t a1 = alignment_of::value; + std::size_t n1 = count * sizeof(Y) + a1 - 1; + void* p1 = ::operator new(n1 + size); + char* p2 = static_cast(p1) + n1; + while (std::size_t(p2) % a1 != 0) { + p2--; + } + *data = reinterpret_cast(p2); + return reinterpret_cast(p1); + } + void deallocate(pointer memory, size_type) { + void* p1 = memory; + ::operator delete(p1); + } + void construct(pointer memory, const Y& value) { + void* p1 = memory; + ::new(p1) Y(value); + } + void destroy(pointer memory) { + memory->~Y(); + } + template + bool operator==(const make_array_helper& other) const { + return true; + } + template + bool operator!=(const make_array_helper& other) const { + return !(*this == other); + } + private: + std::size_t size; + T** data; + }; + } +} + +#endif diff --git a/include/boost/smart_ptr/detail/operator_bool.hpp b/include/boost/smart_ptr/detail/operator_bool.hpp index 842a05d..1d5be11 100644 --- a/include/boost/smart_ptr/detail/operator_bool.hpp +++ b/include/boost/smart_ptr/detail/operator_bool.hpp @@ -31,7 +31,7 @@ ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \ ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) ) - typedef T * (this_type::*unspecified_bool_type)() const; + typedef element_type * (this_type::*unspecified_bool_type)() const; operator unspecified_bool_type() const // never throws { @@ -40,7 +40,7 @@ #else - typedef T * this_type::*unspecified_bool_type; + typedef element_type * this_type::*unspecified_bool_type; operator unspecified_bool_type() const // never throws { diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index 2c99f02..be4f65b 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -347,7 +347,7 @@ public: typedef typename sp_convert_reference::type D2; D2 d2( r.get_deleter() ); - pi_ = new sp_counted_impl_pd< Y*, D2 >( r.get(), d2 ); + pi_ = new sp_counted_impl_pd< typename std::unique_ptr::pointer, D2 >( r.get(), d2 ); #ifdef BOOST_NO_EXCEPTIONS diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp index eb39797..31b2627 100644 --- a/include/boost/smart_ptr/detail/sp_convertible.hpp +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp @@ -48,6 +48,21 @@ template< class Y, class T > struct sp_convertible enum _vt { value = sizeof( (f)( static_cast(0) ) ) == sizeof(yes) }; }; +template< class Y, class T > struct sp_convertible< Y, T[] > +{ + enum _vt { value = false }; +}; + +template< class Y, class T > struct sp_convertible< Y[], T[] > +{ + enum _vt { value = sp_convertible< Y[1], T[1] >::value }; +}; + +template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] > +{ + enum _vt { value = sp_convertible< Y[1], T[1] >::value }; +}; + struct sp_empty { }; diff --git a/include/boost/smart_ptr/detail/sp_if_array.hpp b/include/boost/smart_ptr/detail/sp_if_array.hpp new file mode 100644 index 0000000..3ba3a0e --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_if_array.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#ifndef BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP +#define BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP + +#include + +namespace boost { + namespace detail { + template + struct sp_if_array { + }; + template + struct sp_if_array { + typedef boost::shared_ptr type; + }; + template + struct sp_if_size_array { + }; + template + struct sp_if_size_array { + typedef boost::shared_ptr type; + }; + } +} + +#endif diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp index 7b605e2..8d0e3ea 100644 --- a/include/boost/smart_ptr/make_shared.hpp +++ b/include/boost/smart_ptr/make_shared.hpp @@ -3,7 +3,7 @@ // make_shared.hpp // -// Copyright (c) 2007, 2008 Peter Dimov +// Copyright (c) 2007, 2008, 2012 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at @@ -12,970 +12,11 @@ // See http://www.boost.org/libs/smart_ptr/make_shared.html // for documentation. -#include -#include -#include -#include -#include -#include - -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_; - }; -}; - -template< class T > class sp_ms_deleter -{ -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(); - -#else - - reinterpret_cast< T* >( storage_.data_ )->~T(); +#include +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE ) +# include +# include #endif - initialized_ = false; - } - } - -public: - - 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; - } -}; - -#if defined( BOOST_HAS_RVALUE_REFS ) - -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() -{ - 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 ); -} - -template< class T, class A > boost::shared_ptr< T > 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 ); -} - -#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS ) - -// Variadic templates, rvalue reference - -template< class T, class Arg1, class... Args > boost::shared_ptr< T > 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 ); -} - -template< class T, class A, class Arg1, class... Args > boost::shared_ptr< T > 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 ); -} - -#elif defined( BOOST_HAS_RVALUE_REFS ) - -// For example MSVC 10.0 - -template< class T, class A1 > -boost::shared_ptr< T > 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 ); -} - -template< class T, class A, class A1 > -boost::shared_ptr< T > 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 ) - ); - - 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 ); -} - -template< class T, class A1, class A2 > -boost::shared_ptr< T > make_shared( 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 ) - ); - - 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 ); -} - -template< class T, class A, class A1, class A2 > -boost::shared_ptr< T > allocate_shared( A const & a, 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 ), - 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 ); -} - -template< class T, class A1, class A2, class A3 > -boost::shared_ptr< T > 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 ), - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -#else - -// C++03 version - -template< class T, class A1 > -boost::shared_ptr< T > 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 ); -} - -template< class T, class A, class A1 > -boost::shared_ptr< T > 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 ); - 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 ); -} - -template< class T, class A1, class A2 > -boost::shared_ptr< T > make_shared( 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 ); - 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 ); -} - -template< class T, class A, class A1, class A2 > -boost::shared_ptr< T > allocate_shared( A const & a, 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, 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 ); -} - -template< class T, class A1, class A2, class A3 > -boost::shared_ptr< T > 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, 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -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 ) -{ - 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 ); -} - -#endif - -#undef BOOST_SP_MSD - -} // namespace boost - #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp new file mode 100644 index 0000000..f9a39ff --- /dev/null +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP +#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP + +#include +#include +#include +#include +#include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +namespace boost { + template + inline typename detail::sp_if_array::type + make_shared(std::size_t size) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = size * detail::array_total::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, n1); + return shared_ptr(s1, p1); + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + template + inline typename detail::sp_if_array::type + make_shared(std::size_t size, Args&&... args) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = size * detail::array_total::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, n1, std::forward(args)...); + return shared_ptr(s1, p1); + } + template + inline typename detail::sp_if_size_array::type + make_shared(Args&&... args) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = detail::array_total::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, n1, std::forward(args)...); + return shared_ptr(s1, p1); + } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + inline typename detail::sp_if_array::type + make_shared(std::initializer_list::type> list) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + typedef const T2 T3; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n1 = list.size() * detail::array_total::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p3 = reinterpret_cast(list.begin()); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, n1, p3); + return shared_ptr(s1, p1); + } + template + inline typename detail::sp_if_size_array::type + make_shared(std::initializer_list::type> list) { + BOOST_ASSERT(list.size() == detail::array_size::size); + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + typedef const T2 T3; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n1 = detail::array_total::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p3 = reinterpret_cast(list.begin()); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, n1, p3); + return shared_ptr(s1, p1); + } + template + inline typename detail::sp_if_array::type + make_shared(std::size_t size, + std::initializer_list::type> list) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + typedef const T2 T3; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n0 = detail::array_total::size; + std::size_t n1 = n0 * size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p3 = reinterpret_cast(list.begin()); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, n1, p3, n0); + return shared_ptr(s1, p1); + } +#endif + template + inline typename detail::sp_if_array::type + make_shared_noinit(std::size_t size) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = size * detail::array_total::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_noinit(p2, n1); + return shared_ptr(s1, p1); + } + template + inline typename detail::sp_if_size_array::type + make_shared_noinit() { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = detail::array_total::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_noinit(p2, n1); + return shared_ptr(s1, p1); + } +} + +#endif diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp new file mode 100644 index 0000000..3872909 --- /dev/null +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -0,0 +1,998 @@ +#ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED +#define BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED + +// make_shared_object.hpp +// +// Copyright (c) 2007, 2008, 2012 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. + +#include +#include +#include +#include +#include +#include + +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_; + }; +}; + +template< class T > class sp_ms_deleter +{ +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(); + +#else + + reinterpret_cast< T* >( storage_.data_ )->~T(); + +#endif + + initialized_ = false; + } + } + +public: + + 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; + } +}; + +#if defined( BOOST_HAS_RVALUE_REFS ) + +template< class T > T&& sp_forward( T & t ) +{ + return static_cast< T&& >( t ); +} + +#endif + +template< class T > struct sp_if_not_array +{ + typedef boost::shared_ptr< T > type; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T > struct sp_if_not_array< T[] > +{ +}; + +template< class T, std::size_t N > struct sp_if_not_array< T[N] > +{ +}; + +#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 > typename boost::detail::sp_if_not_array< T >::type 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 ); +} + +template< class T, class A > typename boost::detail::sp_if_not_array< T >::type 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 ); +} + +#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS ) + +// Variadic templates, rvalue reference + +template< class T, class Arg1, class... Args > typename boost::detail::sp_if_not_array< T >::type 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 ); +} + +template< class T, class A, class Arg1, class... Args > typename boost::detail::sp_if_not_array< T >::type 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 ); +} + +#elif defined( BOOST_HAS_RVALUE_REFS ) + +// For example MSVC 10.0 + +template< class T, class A1 > +typename boost::detail::sp_if_not_array< T >::type 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 ); +} + +template< class T, class A, class A1 > +typename boost::detail::sp_if_not_array< T >::type 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 ) + ); + + 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 ); +} + +template< class T, class A1, class A2 > +typename boost::detail::sp_if_not_array< T >::type make_shared( 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 ) + ); + + 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 ); +} + +template< class T, class A, class A1, class A2 > +typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, 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 ), + 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 ); +} + +template< class T, class A1, class A2, class A3 > +typename boost::detail::sp_if_not_array< T >::type 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 ), + 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 ); +} + +template< class T, class A, class A1, class A2, class A3 > +typename boost::detail::sp_if_not_array< T >::type 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 ) + ); + + 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 ); +} + +template< class T, class A1, class A2, class A3, class A4 > +typename boost::detail::sp_if_not_array< T >::type make_shared( 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 ) + ); + + 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4 > +typename boost::detail::sp_if_not_array< T >::type 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 ), 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 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5 > +typename boost::detail::sp_if_not_array< T >::type 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 ), + 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5 > +typename boost::detail::sp_if_not_array< T >::type 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 ) + ); + + 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 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > +typename boost::detail::sp_if_not_array< T >::type 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 ) ); + + 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 > +typename boost::detail::sp_if_not_array< T >::type 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 ), 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 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > +typename boost::detail::sp_if_not_array< T >::type 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 ), + 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > +typename boost::detail::sp_if_not_array< T >::type 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 ) + ); + + 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 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > +typename boost::detail::sp_if_not_array< T >::type 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 ) ); + + 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > +typename boost::detail::sp_if_not_array< T >::type 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 ), 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 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > +typename boost::detail::sp_if_not_array< T >::type 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 ), + 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > +typename boost::detail::sp_if_not_array< T >::type 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 ); +} + +#else + +// C++03 version + +template< class T, class A1 > +typename boost::detail::sp_if_not_array< T >::type 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 ); +} + +template< class T, class A, class A1 > +typename boost::detail::sp_if_not_array< T >::type 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 ); + 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 ); +} + +template< class T, class A1, class A2 > +typename boost::detail::sp_if_not_array< T >::type make_shared( 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 ); + 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 ); +} + +template< class T, class A, class A1, class A2 > +typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, 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, 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 ); +} + +template< class T, class A1, class A2, class A3 > +typename boost::detail::sp_if_not_array< T >::type 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, 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 ); +} + +template< class T, class A, class A1, class A2, class A3 > +typename boost::detail::sp_if_not_array< T >::type 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 ); + 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 ); +} + +template< class T, class A1, class A2, class A3, class A4 > +typename boost::detail::sp_if_not_array< T >::type 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 ) ); + + 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4 > +typename boost::detail::sp_if_not_array< T >::type 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 ), 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 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5 > +typename boost::detail::sp_if_not_array< T >::type 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, 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5 > +typename boost::detail::sp_if_not_array< T >::type 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 ); + 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 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > +typename boost::detail::sp_if_not_array< T >::type 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 ) ); + + 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 > +typename boost::detail::sp_if_not_array< T >::type 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 ), 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 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > +typename boost::detail::sp_if_not_array< T >::type 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, 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > +typename boost::detail::sp_if_not_array< T >::type 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 ); + 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 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > +typename boost::detail::sp_if_not_array< T >::type 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 ) ); + + 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > +typename boost::detail::sp_if_not_array< T >::type 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 ), 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 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > +typename boost::detail::sp_if_not_array< T >::type 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, 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 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > +typename boost::detail::sp_if_not_array< T >::type 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 ); +} + +#endif + +#undef BOOST_SP_MSD + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED diff --git a/include/boost/smart_ptr/shared_array.hpp b/include/boost/smart_ptr/shared_array.hpp index 36799e6..3e79582 100644 --- a/include/boost/smart_ptr/shared_array.hpp +++ b/include/boost/smart_ptr/shared_array.hpp @@ -5,7 +5,7 @@ // shared_array.hpp // // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. -// Copyright (c) 2001, 2002 Peter Dimov +// Copyright (c) 2001, 2002, 2012 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -55,18 +56,32 @@ public: typedef T element_type; - explicit shared_array(T * p = 0): px(p), pn(p, deleter()) + shared_array(): px( 0 ), pn() // never throws { } + template + explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter() ) + { + boost::detail::sp_assert_convertible< Y[], T[] >(); + } + // // Requirements: D's copy constructor must not throw // // shared_array will release p by calling d(p) // - template shared_array(T * p, D d): px(p), pn(p, d) + template shared_array( Y * p, D d ): px( p ), pn( p, d ) { + boost::detail::sp_assert_convertible< Y[], T[] >(); + } + + // As above, but with allocator. A's copy constructor shall not throw. + + template shared_array( Y * p, D d, A a ): px( p ), pn( p, d, a ) + { + boost::detail::sp_assert_convertible< Y[], T[] >(); } // generated copy constructor, destructor are fine... @@ -79,8 +94,38 @@ public: { } + shared_array( shared_array && r ): px( r.px ), pn() // never throws + { + pn.swap( r.pn ); + r.px = 0; + } + #endif + // conversion + + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + shared_array( shared_array const & r, typename boost::detail::sp_enable_if_convertible< Y[], T[] >::type = boost::detail::sp_empty() ) + +#else + + shared_array( shared_array const & r ) + +#endif + : px( r.px ), pn( r.pn ) // never throws + { + boost::detail::sp_assert_convertible< Y[], T[] >(); + } + + // aliasing + + template< class Y > + shared_array( shared_array const & r, element_type * p ): px( p ), pn( r.pn ) // never throws + { + } + // assignment shared_array & operator=( shared_array const & r ) // never throws @@ -89,15 +134,58 @@ public: return *this; } - void reset(T * p = 0) +#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400) + + template + shared_array & operator=( shared_array const & r ) // never throws { - BOOST_ASSERT(p == 0 || p != px); - this_type(p).swap(*this); + this_type( r ).swap( *this ); + return *this; } - template void reset(T * p, D d) +#endif + +#if defined( BOOST_HAS_RVALUE_REFS ) + + shared_array & operator=( shared_array && r ) // never throws { - this_type(p, d).swap(*this); + this_type( static_cast< shared_array && >( r ) ).swap( *this ); + return *this; + } + + template + shared_array & operator=( shared_array && r ) // never throws + { + this_type( static_cast< shared_array && >( r ) ).swap( *this ); + return *this; + } + +#endif + + void reset() // never throws + { + this_type().swap( *this ); + } + + template void reset( Y * p ) // Y must be complete + { + BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors + this_type( p ).swap( *this ); + } + + template void reset( Y * p, D d ) + { + this_type( p, d ).swap( *this ); + } + + template void reset( Y * p, D d, A a ) + { + this_type( p, d, a ).swap( *this ); + } + + template void reset( shared_array const & r, element_type * p ) + { + this_type( r, p ).swap( *this ); } T & operator[] (std::ptrdiff_t i) const // never throws @@ -138,6 +226,8 @@ public: private: + template friend class shared_array; + T * px; // contained pointer detail::shared_count pn; // reference counter diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 08cf3fe..f9fe0d3 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -67,34 +67,129 @@ struct const_cast_tag {}; struct dynamic_cast_tag {}; struct polymorphic_cast_tag {}; -template struct shared_ptr_traits +// sp_element, element_type + +template< class T > struct sp_element { - typedef T & reference; + typedef T type; }; -template<> struct shared_ptr_traits +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T > struct sp_element< T[] > { - typedef void reference; + typedef T type; +}; + +template< class T, std::size_t N > struct sp_element< T[N] > +{ + typedef T type; +}; + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// sp_dereference, return type of operator* + +template< class T > struct sp_dereference +{ + typedef T & type; +}; + +template<> struct sp_dereference< void > +{ + typedef void type; }; #if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) -template<> struct shared_ptr_traits +template<> struct sp_dereference< void const > { - typedef void reference; + typedef void type; }; -template<> struct shared_ptr_traits +template<> struct sp_dereference< void volatile > { - typedef void reference; + typedef void type; }; -template<> struct shared_ptr_traits +template<> struct sp_dereference< void const volatile > { - typedef void reference; + typedef void type; }; -#endif +#endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T > struct sp_dereference< T[] > +{ + typedef void type; +}; + +template< class T, std::size_t N > struct sp_dereference< T[N] > +{ + typedef void type; +}; + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// sp_member_access, return type of operator-> + +template< class T > struct sp_member_access +{ + typedef T * type; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T > struct sp_member_access< T[] > +{ + typedef void type; +}; + +template< class T, std::size_t N > struct sp_member_access< T[N] > +{ + typedef void type; +}; + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// sp_array_access, return type of operator[] + +template< class T > struct sp_array_access +{ + typedef void type; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T > struct sp_array_access< T[] > +{ + typedef T & type; +}; + +template< class T, std::size_t N > struct sp_array_access< T[N] > +{ + typedef T & type; +}; + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// sp_extent, for operator[] index check + +template< class T > struct sp_extent +{ + enum _vt { value = 0 }; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T, std::size_t N > struct sp_extent< T[N] > +{ + enum _vt { value = N }; +}; + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // enable_shared_from_this support @@ -144,6 +239,69 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R #endif +// sp_assert_convertible + +template< class Y, class T > inline void sp_assert_convertible() +{ +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + // static_assert( sp_convertible< Y, T >::value ); + typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ]; + (void)sizeof( tmp ); + +#else + + T* p = static_cast< Y* >( 0 ); + (void)p; + +#endif +} + +// pointer constructor helper + +template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn ) +{ + boost::detail::shared_count( p ).swap( pn ); + boost::detail::sp_enable_shared_from_this( ppx, p, p ); +} + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn ) +{ + sp_assert_convertible< Y[], T[] >(); + boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); +} + +template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * p, boost::detail::shared_count & pn ) +{ + sp_assert_convertible< Y[N], T[N] >(); + boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); +} + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// deleter constructor helper + +template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p ) +{ + boost::detail::sp_enable_shared_from_this( ppx, p, p ); +} + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ ) +{ + sp_assert_convertible< Y[], T[] >(); +} + +template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ ) +{ + sp_assert_convertible< Y[N], T[N] >(); +} + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + } // namespace detail @@ -164,19 +322,16 @@ private: public: - typedef T element_type; - typedef T value_type; - typedef T * pointer; - typedef typename boost::detail::shared_ptr_traits::reference reference; + typedef typename boost::detail::sp_element< T >::type element_type; - shared_ptr(): px(0), pn() // never throws in 1.30+ + shared_ptr(): px( 0 ), pn() // never throws in 1.30+ { } template - explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete + explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete { - boost::detail::sp_enable_shared_from_this( this, p, p ); + boost::detail::sp_pointer_construct( this, p, pn ); } // @@ -185,16 +340,16 @@ public: // shared_ptr will release p by calling d(p) // - template shared_ptr(Y * p, D d): px(p), pn(p, d) + template shared_ptr( Y * p, D d ): px( p ), pn( p, d ) { - boost::detail::sp_enable_shared_from_this( this, p, p ); + boost::detail::sp_deleter_construct( this, p ); } // As above, but with allocator. A's copy constructor shall not throw. template shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a ) { - boost::detail::sp_enable_shared_from_this( this, p, p ); + boost::detail::sp_deleter_construct( this, p ); } // generated copy constructor, destructor are fine... @@ -210,8 +365,10 @@ public: #endif template - explicit shared_ptr(weak_ptr const & r): pn(r.pn) // may throw + explicit shared_ptr( weak_ptr const & r ): pn( r.pn ) // may throw { + boost::detail::sp_assert_convertible< Y, T >(); + // it is now safe to copy r.px, as pn(r.pn) did not throw px = r.px; } @@ -237,11 +394,12 @@ public: #endif : px( r.px ), pn( r.pn ) // never throws { + boost::detail::sp_assert_convertible< Y, T >(); } // aliasing template< class Y > - shared_ptr( shared_ptr const & r, T * p ): px( p ), pn( r.pn ) // never throws + shared_ptr( shared_ptr const & r, element_type * p ): px( p ), pn( r.pn ) // never throws { } @@ -278,9 +436,12 @@ public: template explicit shared_ptr(std::auto_ptr & r): px(r.get()), pn() { + boost::detail::sp_assert_convertible< Y, T >(); + Y * tmp = r.get(); pn = boost::detail::shared_count(r); - boost::detail::sp_enable_shared_from_this( this, tmp, tmp ); + + boost::detail::sp_deleter_construct( this, tmp ); } #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) @@ -288,11 +449,15 @@ public: template explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr::type = 0 ): px( r.get() ), pn() { - typename Ap::element_type * tmp = r.get(); - pn = boost::detail::shared_count( r ); - boost::detail::sp_enable_shared_from_this( this, tmp, tmp ); - } + typedef typename Ap::element_type Y; + boost::detail::sp_assert_convertible< Y, T >(); + + Y * tmp = r.get(); + pn = boost::detail::shared_count( r ); + + boost::detail::sp_deleter_construct( this, tmp ); + } #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -301,11 +466,14 @@ public: #if !defined( BOOST_NO_CXX11_SMART_PTR ) template< class Y, class D > - shared_ptr( std::unique_ptr< Y, D > && r): px( r.get() ), pn() + shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn() { - Y * tmp = r.get(); + 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_enable_shared_from_this( this, tmp, tmp ); + + boost::detail::sp_deleter_construct( this, tmp ); } #endif @@ -347,7 +515,6 @@ public: return *this; } - #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #endif // BOOST_NO_AUTO_PTR @@ -374,6 +541,8 @@ public: #endif : px( r.px ), pn() // never throws { + boost::detail::sp_assert_convertible< Y, T >(); + pn.swap( r.pn ); r.px = 0; } @@ -398,10 +567,10 @@ public: this_type().swap(*this); } - template void reset(Y * p) // Y must be complete + template void reset( Y * p ) // Y must be complete { - BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors - this_type(p).swap(*this); + BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors + this_type( p ).swap( *this ); } template void reset( Y * p, D d ) @@ -414,24 +583,32 @@ public: this_type( p, d, a ).swap( *this ); } - template void reset( shared_ptr const & r, T * p ) + template void reset( shared_ptr const & r, element_type * p ) { this_type( r, p ).swap( *this ); } - reference operator* () const // never throws + typename boost::detail::sp_dereference< T >::type operator* () const // never throws { - BOOST_ASSERT(px != 0); + BOOST_ASSERT( px != 0 ); return *px; } - T * operator-> () const // never throws + typename boost::detail::sp_member_access< T >::type operator-> () const // never throws { - BOOST_ASSERT(px != 0); + BOOST_ASSERT( px != 0 ); return px; } - T * get() const // never throws + typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const // never throws + { + BOOST_ASSERT( px != 0 ); + BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) ); + + return px[ i ]; + } + + element_type * get() const // never throws { return px; } @@ -449,7 +626,7 @@ public: return pn.use_count(); } - void swap(shared_ptr & other) // never throws + void swap( shared_ptr & other ) // never throws { std::swap(px, other.px); pn.swap(other.pn); @@ -488,7 +665,7 @@ private: #endif - T * px; // contained pointer + element_type * px; // contained pointer boost::detail::shared_count pn; // reference counter }; // shared_ptr diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index 5391910..62b6afe 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -29,7 +29,7 @@ private: public: - typedef T element_type; + typedef typename boost::detail::sp_element< T >::type element_type; weak_ptr(): px(0), pn() // never throws in 1.30+ { @@ -83,6 +83,7 @@ public: #endif : px(r.lock().get()), pn(r.pn) // never throws { + boost::detail::sp_assert_convertible< Y, T >(); } #if defined( BOOST_HAS_RVALUE_REFS ) @@ -99,6 +100,7 @@ public: #endif : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws { + boost::detail::sp_assert_convertible< Y, T >(); r.px = 0; } @@ -130,15 +132,19 @@ public: #endif : px( r.px ), pn( r.pn ) // never throws { + boost::detail::sp_assert_convertible< Y, T >(); } #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) template - weak_ptr & operator=(weak_ptr const & r) // never throws + weak_ptr & operator=( weak_ptr const & r ) // never throws { + boost::detail::sp_assert_convertible< Y, T >(); + px = r.lock().get(); pn = r.pn; + return *this; } @@ -154,10 +160,13 @@ public: #endif template - weak_ptr & operator=(shared_ptr const & r) // never throws + weak_ptr & operator=( shared_ptr const & r ) // never throws { + boost::detail::sp_assert_convertible< Y, T >(); + px = r.px; pn = r.pn; + return *this; } @@ -165,7 +174,7 @@ public: shared_ptr lock() const // never throws { - return shared_ptr( *this, boost::detail::sp_nothrow_tag() ); + return shared_ptr( *this, boost::detail::sp_nothrow_tag() ); } long use_count() const // never throws @@ -195,7 +204,7 @@ public: } template - void _internal_aliasing_assign(weak_ptr const & r, T * px2) + void _internal_aliasing_assign(weak_ptr const & r, element_type * px2) { px = px2; pn = r.pn; @@ -223,7 +232,7 @@ private: #endif - T * px; // contained pointer + element_type * px; // contained pointer boost::detail::weak_count pn; // reference counter }; // weak_ptr diff --git a/make_shared_array.html b/make_shared_array.html new file mode 100644 index 0000000..4739b3a --- /dev/null +++ b/make_shared_array.html @@ -0,0 +1,129 @@ + + + + make_shared and allocate_shared + + + +

boost.png (6897 bytes)make_shared and allocate_shared + for arrays

+

Introduction
+ Synopsis
+ Free Functions
+ Example
+

Introduction

+

One criticism of Boost shared_array is + the lack of utility similar to make_shared + which ensures only a single allocation for an array. A second criticism + is Boost shared_array does not support custom allocators + and so also lacks an allocate_shared utility.

+

The header files <boost/smart_ptr/make_shared_array.hpp> and + <boost/smart_ptr/allocate_shared_array.hpp> provide new function + templates, make_shared and allocate_shared, + to address this need. make_shared uses the global + operator new to allocate memory, whereas + allocate_shared uses an user-supplied allocator, + allowing finer control.

+

Synopsis

+
namespace boost {
+    template<typename T>
+    shared_ptr<T[]> make_shared(size_t size);
+
+    template<typename T, typename A>
+    shared_ptr<T[]> allocate_shared(const A& allocator, size_t size);
+    
+#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+    template<typename T, typename... Args>
+    shared_ptr<T[]> make_shared(size_t size, Args&&... args);
+    
+    template<typename T, typename... Args>
+    shared_ptr<T[N]> make_shared(Args&&... args);
+    
+    template<typename T, typename A, typename... Args>
+    shared_ptr<T> allocate_shared(const A& allocator, size_t size, Args&&... args);
+    
+    template<typename T, typename A, typename... Args>
+    shared_ptr<T[N]> allocate_shared(const A& allocator, Args&&... args);
+#endif
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+    template<typename T, typename... Args>
+    shared_ptr<T[]> make_shared(initializer_list<T> list);
+    
+    template<typename T, typename... Args>
+    shared_ptr<T[N]> make_shared(initializer_list<T> list);
+    
+    template<typename T, typename... Args>
+    shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T> list);
+        
+    template<typename T, typename A, typename... Args>
+    shared_ptr<T[]> allocate_shared(const A& allocator, initializer_list<T> list);
+    
+    template<typename T, typename A, typename... Args>
+    shared_ptr<T[N]> allocate_shared(const A& allocator, initializer_list<T> list);
+    
+    template<typename T, typename A, typename... Args>
+    shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list);
+#endif
+
+    template<typename T>
+    shared_ptr<T> make_shared_noinit(size_t size);
+    
+    template<typename T>
+    shared_ptr<T[N]> make_shared_noinit();
+}
+

Free Functions

+
template<typename T, typename... Args>
+    shared_ptr<T> make_shared(size_t size, Args&&... args);
+template<typename T, typename A, typename... Args>
+    shared_ptr<T> allocate_shared(const A& allocator, size_t size, Args&&... args);
+
+

Requires: The expression + new(pointer) T(forward<Args>(args)...), where + pointer is a void* pointing to storage + suitable to hold an object of type T, shall be + well-formed. A shall be an Allocator, as + described in section 20.1.5 (Allocator requirements) + of the C++ Standard. The copy constructor and destructor of + A shall not throw.

+

Effects: Allocates memory suitable for an array of type + T and size size and constructs an array + of objects in it via the placement new expression + new(pointer) T() or + new(pointer) T(forward<Args>(args)...). + allocate_shared uses a copy of + allocator to allocate memory. If an exception is thrown, + has no effect.

+

Returns: A shared_ptr instance that stores and + owns the address of the newly constructed array of type T + and size size.

+

Postconditions: + get() != 0 && use_count() == 1.

+

Throws: bad_alloc, or an exception thrown from + A::allocate or the constructor of T.

+

Notes: This implementation allocates the memory required for + the returned shared_ptr and an array of type + T of size size in a single allocation. This + provides efficiency to equivalent to an intrusive smart array + pointer.

+

The prototypes shown above are used if your compiler supports r-value + references and variadic templates. They perfectly forward the + args parameters to the constructors of + T for each array element.

+

Otherwise, you can use the overloads which take only the array size + (and the allocator in case of allocate_shared) and do not + take any constructor arguments. These overloads invoke the default + constructor of T for each array element.

+
+

Example

+
boost::shared_ptr<int[]> array = boost::make_shared<int[]>(size);
+
+

$Date: 2012-10-30 10:12:25 -0800 (Tue, 30 Oct 2012) $

+

Copyright 2012 Glen Fernandes. 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.

+ + diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 1df2a3e..e3b41c0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -46,7 +46,7 @@ import testing ; [ run spinlock_pool_test.cpp ] [ run make_shared_test.cpp ] [ run make_shared_perfect_forwarding_test.cpp ] - [ run sp_convertible_test.cpp ] + [ run shared_ptr_convertible_test.cpp ] [ run wp_convertible_test.cpp ] [ run ip_convertible_test.cpp ] [ run allocate_shared_test.cpp ] @@ -70,5 +70,82 @@ import testing ; [ run ip_hash_test.cpp ] [ run owner_less_test.cpp ] [ run sp_unique_ptr_test.cpp ] + [ run sp_array_test.cpp ] + [ compile sp_array_cv_test.cpp ] + [ run sp_convertible_test.cpp ] + [ run sp_array_n_test.cpp ] + + [ compile-fail array_fail_spa_sp_c.cpp ] + [ compile-fail array_fail_sp_spa_c.cpp ] + [ compile-fail array_fail_spa_spa_c.cpp ] + [ compile-fail array_fail_spa_wp_c.cpp ] + [ compile-fail array_fail_sp_wpa_c.cpp ] + [ compile-fail array_fail_spa_wpa_c.cpp ] + [ compile-fail array_fail_wpa_wp_c.cpp ] + [ compile-fail array_fail_wp_wpa_c.cpp ] + [ compile-fail array_fail_wpa_wpa_c.cpp ] + [ compile-fail array_fail_ap_spa_c.cpp ] + [ compile-fail array_fail_upa_sp_c.cpp ] + [ compile-fail array_fail_up_spa_c.cpp ] + + [ compile-fail array_fail_spa_sp_mc.cpp ] + [ compile-fail array_fail_sp_spa_mc.cpp ] + [ compile-fail array_fail_spa_spa_mc.cpp ] + [ compile-fail array_fail_spa_wp_mc.cpp ] + [ compile-fail array_fail_sp_wpa_mc.cpp ] + [ compile-fail array_fail_spa_wpa_mc.cpp ] + [ compile-fail array_fail_wpa_wp_mc.cpp ] + [ compile-fail array_fail_wp_wpa_mc.cpp ] + [ compile-fail array_fail_wpa_wpa_mc.cpp ] + [ compile-fail array_fail_ap_spa_mc.cpp ] + [ compile-fail array_fail_upa_sp_mc.cpp ] + [ compile-fail array_fail_up_spa_mc.cpp ] + + [ compile-fail array_fail_spa_sp_a.cpp ] + [ compile-fail array_fail_sp_spa_a.cpp ] + [ compile-fail array_fail_spa_spa_a.cpp ] + [ compile-fail array_fail_spa_wp_a.cpp ] + [ compile-fail array_fail_sp_wpa_a.cpp ] + [ compile-fail array_fail_spa_wpa_a.cpp ] + [ compile-fail array_fail_wpa_wp_a.cpp ] + [ compile-fail array_fail_wp_wpa_a.cpp ] + [ compile-fail array_fail_wpa_wpa_a.cpp ] + [ compile-fail array_fail_ap_spa_a.cpp ] + [ compile-fail array_fail_upa_sp_a.cpp ] + [ compile-fail array_fail_up_spa_a.cpp ] + + [ compile-fail array_fail_spa_sp_ma.cpp ] + [ compile-fail array_fail_sp_spa_ma.cpp ] + [ compile-fail array_fail_spa_spa_ma.cpp ] + [ compile-fail array_fail_spa_wp_ma.cpp ] + [ compile-fail array_fail_sp_wpa_ma.cpp ] + [ compile-fail array_fail_spa_wpa_ma.cpp ] + [ compile-fail array_fail_wpa_wp_ma.cpp ] + [ compile-fail array_fail_wp_wpa_ma.cpp ] + [ compile-fail array_fail_wpa_wpa_ma.cpp ] + [ compile-fail array_fail_ap_spa_ma.cpp ] + [ compile-fail array_fail_upa_sp_ma.cpp ] + [ compile-fail array_fail_up_spa_ma.cpp ] + + [ compile-fail array_fail_dereference.cpp ] + [ compile-fail array_fail_member_access.cpp ] + [ compile-fail array_fail_array_access.cpp ] + + [ run make_shared_array_test.cpp ] + [ run make_shared_arrays_test.cpp ] + [ run make_shared_array_create_test.cpp ] + [ run make_shared_array_init_test.cpp ] + [ run make_shared_arrays_create_test.cpp ] + [ run make_shared_array_throws_test.cpp ] + [ run make_shared_array_esft_test.cpp ] + [ run make_shared_array_args_test.cpp ] + [ run allocate_shared_array_test.cpp ] + [ run allocate_shared_arrays_test.cpp ] + [ run allocate_shared_array_create_test.cpp ] + [ run allocate_shared_array_init_test.cpp ] + [ run allocate_shared_arrays_create_test.cpp ] + [ run allocate_shared_array_throws_test.cpp ] + [ run allocate_shared_array_esft_test.cpp ] + [ run allocate_shared_array_args_test.cpp ] ; } diff --git a/test/allocate_shared_array_args_test.cpp b/test/allocate_shared_array_args_test.cpp new file mode 100644 index 0000000..1226b94 --- /dev/null +++ b/test/allocate_shared_array_args_test.cpp @@ -0,0 +1,173 @@ +// allocate_shared_array_args_test.cpp +// +// Copyright 2007-2009, 2012 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 + +#include +#include +#include +#include +#include + +class X +{ +private: + + X( X const & ); + X & operator=( X const & ); + + void * operator new[]( std::size_t n ); + void operator delete[]( void * p ); + +public: + + static int instances; + + int v; + + explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 ) + { + ++instances; + } + + ~X() + { + --instances; + } +}; + +int X::instances = 0; + +int main() +{ + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 0 ); + BOOST_TEST( px[1].v == 0 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + + { + boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1 ); + BOOST_TEST( px[1].v == 1 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1, 2 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2 ); + BOOST_TEST( px[1].v == 1+2 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1, 2, 3 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3 ); + BOOST_TEST( px[1].v == 1+2+3 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1, 2, 3, 4 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4 ); + BOOST_TEST( px[1].v == 1+2+3+4 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1, 2, 3, 4, 5 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4+5 ); + BOOST_TEST( px[1].v == 1+2+3+4+5 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1, 2, 3, 4, 5, 6 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4+5+6 ); + BOOST_TEST( px[1].v == 1+2+3+4+5+6 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1, 2, 3, 4, 5, 6, 7 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4+5+6+7 ); + BOOST_TEST( px[1].v == 1+2+3+4+5+6+7 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1, 2, 3, 4, 5, 6, 7, 8 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4+5+6+7+8 ); + BOOST_TEST( px[1].v == 1+2+3+4+5+6+7+8 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1, 2, 3, 4, 5, 6, 7, 8, 9 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4+5+6+7+8+9 ); + BOOST_TEST( px[1].v == 1+2+3+4+5+6+7+8+9 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + +#endif + + return boost::report_errors(); +} diff --git a/test/allocate_shared_array_create_test.cpp b/test/allocate_shared_array_create_test.cpp new file mode 100644 index 0000000..2e03be6 --- /dev/null +++ b/test/allocate_shared_array_create_test.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include + +class type { +public: + static int instances; + explicit type(int a=0, int b=0, int c=0, int d=0, int e=0, int f=0, int g=0, int h=0, int i=0) + : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h), i(i) { + instances++; + } + ~type() { + instances--; + } + const int a; + const int b; + const int c; + const int d; + const int e; + const int f; + const int g; + const int h; + const int i; +private: + type(const type&); + type& operator=(const type&); +}; + +int type::instances = 0; + +int main() { +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, 1, 2, 3, 4, 5, 6, 7, 8, 9); + BOOST_TEST(type::instances == 2); + BOOST_TEST(a1[0].a == 1); + BOOST_TEST(a1[0].d == 4); + BOOST_TEST(a1[1].f == 6); + BOOST_TEST(a1[1].i == 9); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 1, 2, 3, 4, 5, 6, 7, 8, 9); + BOOST_TEST(type::instances == 2); + BOOST_TEST(a1[0].a == 1); + BOOST_TEST(a1[0].d == 4); + BOOST_TEST(a1[1].f == 6); + BOOST_TEST(a1[1].i == 9); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, 1, 2, 3, 4, 5, 6, 7); + BOOST_TEST(type::instances == 4); + BOOST_TEST(a1[0][0].a == 1); + BOOST_TEST(a1[0][1].d == 4); + BOOST_TEST(a1[1][0].f == 6); + BOOST_TEST(a1[1][1].i == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 1, 2, 3, 4, 5, 6, 7); + BOOST_TEST(type::instances == 4); + BOOST_TEST(a1[0][0].a == 1); + BOOST_TEST(a1[0][1].d == 4); + BOOST_TEST(a1[1][0].f == 6); + BOOST_TEST(a1[1][1].i == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, 1, 2, 3, 4, 5); + BOOST_TEST(type::instances == 8); + BOOST_TEST(a1[0][0][0].a == 1); + BOOST_TEST(a1[0][1][0].c == 3); + BOOST_TEST(a1[1][0][1].e == 5); + BOOST_TEST(a1[1][1][1].i == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 1, 2, 3, 4, 5); + BOOST_TEST(type::instances == 8); + BOOST_TEST(a1[0][0][0].a == 1); + BOOST_TEST(a1[0][1][0].c == 3); + BOOST_TEST(a1[1][0][1].e == 5); + BOOST_TEST(a1[1][1][1].i == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, 1, 2, 3); + BOOST_TEST(type::instances == 16); + BOOST_TEST(a1[0][0][0][1].a == 1); + BOOST_TEST(a1[0][0][1][0].c == 3); + BOOST_TEST(a1[0][1][0][0].f == 0); + BOOST_TEST(a1[1][0][0][0].i == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 1, 2, 3); + BOOST_TEST(type::instances == 16); + BOOST_TEST(a1[0][0][0][1].a == 1); + BOOST_TEST(a1[0][0][1][0].c == 3); + BOOST_TEST(a1[0][1][0][0].f == 0); + BOOST_TEST(a1[1][0][0][0].i == 0); + } +#endif + return boost::report_errors(); +} diff --git a/test/allocate_shared_array_esft_test.cpp b/test/allocate_shared_array_esft_test.cpp new file mode 100644 index 0000000..2315421 --- /dev/null +++ b/test/allocate_shared_array_esft_test.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include +#include + +class type + : public boost::enable_shared_from_this { +public: + static unsigned int instances; + explicit type() { + instances++; + } + ~type() { + instances--; + } +private: + type(const type&); + type& operator=(const type&); +}; + +unsigned int type::instances = 0; + +int main() { + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); + try { + a1[0].shared_from_this(); + BOOST_ERROR("shared_from_this did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 3); + } + } + return boost::report_errors(); +} diff --git a/test/allocate_shared_array_init_test.cpp b/test/allocate_shared_array_init_test.cpp new file mode 100644 index 0000000..6411aa8 --- /dev/null +++ b/test/allocate_shared_array_init_test.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include + +class type { +public: + type(int value) + : value(value) { + } + const int value; +private: + type& operator=(const type&); +}; + +int main() { +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 3 }); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 1); + BOOST_TEST(a1[2] == 2); + BOOST_TEST(a1[3] == 3); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 3 }); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 1); + BOOST_TEST(a1[2] == 2); + BOOST_TEST(a1[3] == 3); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 3 }); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 1); + BOOST_TEST(a1[2] == 2); + BOOST_TEST(a1[3] == 3); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 3 }); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 1); + BOOST_TEST(a1[2] == 2); + BOOST_TEST(a1[3] == 3); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 3 }); + BOOST_TEST(a1[0].value == 0); + BOOST_TEST(a1[1].value == 1); + BOOST_TEST(a1[2].value == 2); + BOOST_TEST(a1[3].value == 3); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 3 }); + BOOST_TEST(a1[0].value == 0); + BOOST_TEST(a1[1].value == 1); + BOOST_TEST(a1[2].value == 2); + BOOST_TEST(a1[3].value == 3); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 3 }); + BOOST_TEST(a1[0].value == 0); + BOOST_TEST(a1[1].value == 1); + BOOST_TEST(a1[2].value == 2); + BOOST_TEST(a1[3].value == 3); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 3 }); + BOOST_TEST(a1[0].value == 0); + BOOST_TEST(a1[1].value == 1); + BOOST_TEST(a1[2].value == 2); + BOOST_TEST(a1[3].value == 3); + } +#endif + return boost::report_errors(); +} diff --git a/test/allocate_shared_array_test.cpp b/test/allocate_shared_array_test.cpp new file mode 100644 index 0000000..91f3fb5 --- /dev/null +++ b/test/allocate_shared_array_test.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include +#include +#include + +class type { +public: + static unsigned int instances; + explicit type(int = 0, int = 0) + : member() { + instances++; + } + ~type() { + instances--; + } +private: + type(const type&); + type& operator=(const type&); + double member; +}; + +unsigned int type::instances = 0; + +int main() { + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); + int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 0); + BOOST_TEST(a1[2] == 0); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); + const int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 0); + BOOST_TEST(a1[2] == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); + type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = a1; + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); + const type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + a1.reset(); + BOOST_TEST(type::instances == 0); + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3, 1, 5); + type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = a1; + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 1, 5); + type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = a1; + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3, 1, 5); + const type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 1, 5); + const type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + a1.reset(); + BOOST_TEST(type::instances == 0); + } +#endif + return boost::report_errors(); +} diff --git a/test/allocate_shared_array_throws_test.cpp b/test/allocate_shared_array_throws_test.cpp new file mode 100644 index 0000000..d52104c --- /dev/null +++ b/test/allocate_shared_array_throws_test.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include + +class type { +public: + static unsigned int instances; + explicit type() { + if (instances == 5) { + throw true; + } + instances++; + } + ~type() { + instances--; + } +private: + type(const type&); + type& operator=(const type&); +}; + +unsigned int type::instances = 0; + +int main() { + BOOST_TEST(type::instances == 0); + try { + boost::allocate_shared(std::allocator(), 6); + BOOST_ERROR("allocate_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + try { + boost::allocate_shared(std::allocator(), 3); + BOOST_ERROR("allocate_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp new file mode 100644 index 0000000..fd44aa0 --- /dev/null +++ b/test/allocate_shared_arrays_create_test.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include + +int main() { +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { {0, 1}, {2, 3} }); + BOOST_TEST(a1[0][0] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 2); + BOOST_TEST(a1[1][1] == 3); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { {0, 1}, {2, 3} }); + BOOST_TEST(a1[0][0] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 2); + BOOST_TEST(a1[1][1] == 3); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, {0, 1}); + BOOST_TEST(a1[0][0] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 0); + BOOST_TEST(a1[1][1] == 1); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, { {0, 1}, {2, 3} }); + BOOST_TEST(a1[0][0][0] == 0); + BOOST_TEST(a1[0][0][1] == 1); + BOOST_TEST(a1[1][1][0] == 2); + BOOST_TEST(a1[1][1][1] == 3); + } +#endif + return boost::report_errors(); +} diff --git a/test/allocate_shared_arrays_test.cpp b/test/allocate_shared_arrays_test.cpp new file mode 100644 index 0000000..ab22c23 --- /dev/null +++ b/test/allocate_shared_arrays_test.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include + +class type { +public: + static unsigned int instances; + explicit type(int = 0, int = 0) + : member() { + instances++; + } + ~type() { + instances--; + } +private: + type(const type&); + type& operator=(const type&); + double member; +}; + +unsigned int type::instances = 0; + +int main() { + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a1[0][0][1] == 0); + BOOST_TEST(a1[0][1][0] == 0); + BOOST_TEST(a1[1][0][0] == 0); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a1[0][0][1] == 0); + BOOST_TEST(a1[0][1][0] == 0); + BOOST_TEST(a1[1][0][0] == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, 1, 5); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 1, 5); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, 1, 5); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 1, 5); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } +#endif + return boost::report_errors(); +} diff --git a/test/array_fail_ap_spa_a.cpp b/test/array_fail_ap_spa_a.cpp new file mode 100644 index 0000000..0524827 --- /dev/null +++ b/test/array_fail_ap_spa_a.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + std::auto_ptr px; + boost::shared_ptr px2; px2 = px; +} diff --git a/test/array_fail_ap_spa_c.cpp b/test/array_fail_ap_spa_c.cpp new file mode 100644 index 0000000..bc76316 --- /dev/null +++ b/test/array_fail_ap_spa_c.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + std::auto_ptr px; + boost::shared_ptr px2( px ); +} diff --git a/test/array_fail_ap_spa_ma.cpp b/test/array_fail_ap_spa_ma.cpp new file mode 100644 index 0000000..e26a548 --- /dev/null +++ b/test/array_fail_ap_spa_ma.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px2; px2 = std::auto_ptr(); +} diff --git a/test/array_fail_ap_spa_mc.cpp b/test/array_fail_ap_spa_mc.cpp new file mode 100644 index 0000000..d53eeff --- /dev/null +++ b/test/array_fail_ap_spa_mc.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px2(( std::auto_ptr() )); +} diff --git a/test/array_fail_array_access.cpp b/test/array_fail_array_access.cpp new file mode 100644 index 0000000..abfacbe --- /dev/null +++ b/test/array_fail_array_access.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px( new X ); + px[ 0 ]; +} diff --git a/test/array_fail_dereference.cpp b/test/array_fail_dereference.cpp new file mode 100644 index 0000000..081d5b4 --- /dev/null +++ b/test/array_fail_dereference.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px( new X[ 1 ] ); + *px; +} diff --git a/test/array_fail_member_access.cpp b/test/array_fail_member_access.cpp new file mode 100644 index 0000000..8051ad1 --- /dev/null +++ b/test/array_fail_member_access.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ + int m; +}; + +int main() +{ + boost::shared_ptr px( new X[ 1 ] ); + px->m = 0; +} diff --git a/test/array_fail_sp_spa_a.cpp b/test/array_fail_sp_spa_a.cpp new file mode 100644 index 0000000..e1e2bb6 --- /dev/null +++ b/test/array_fail_sp_spa_a.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::shared_ptr px2; px2 = px; +} diff --git a/test/array_fail_sp_spa_c.cpp b/test/array_fail_sp_spa_c.cpp new file mode 100644 index 0000000..c65df88 --- /dev/null +++ b/test/array_fail_sp_spa_c.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::shared_ptr px2( px ); +} diff --git a/test/array_fail_sp_spa_ma.cpp b/test/array_fail_sp_spa_ma.cpp new file mode 100644 index 0000000..a1253a0 --- /dev/null +++ b/test/array_fail_sp_spa_ma.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px2; px2 = boost::shared_ptr(); +} diff --git a/test/array_fail_sp_spa_mc.cpp b/test/array_fail_sp_spa_mc.cpp new file mode 100644 index 0000000..75c014c --- /dev/null +++ b/test/array_fail_sp_spa_mc.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px2(( boost::shared_ptr() )); +} diff --git a/test/array_fail_sp_wpa_a.cpp b/test/array_fail_sp_wpa_a.cpp new file mode 100644 index 0000000..8b88512 --- /dev/null +++ b/test/array_fail_sp_wpa_a.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::weak_ptr px2; px2 = px; +} diff --git a/test/array_fail_sp_wpa_c.cpp b/test/array_fail_sp_wpa_c.cpp new file mode 100644 index 0000000..fc7cd5b --- /dev/null +++ b/test/array_fail_sp_wpa_c.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::weak_ptr px2( px ); +} diff --git a/test/array_fail_sp_wpa_ma.cpp b/test/array_fail_sp_wpa_ma.cpp new file mode 100644 index 0000000..578e10b --- /dev/null +++ b/test/array_fail_sp_wpa_ma.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px2; px2 = boost::shared_ptr(); +} diff --git a/test/array_fail_sp_wpa_mc.cpp b/test/array_fail_sp_wpa_mc.cpp new file mode 100644 index 0000000..ca62eaf --- /dev/null +++ b/test/array_fail_sp_wpa_mc.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px2(( boost::shared_ptr() )); +} diff --git a/test/array_fail_spa_sp_a.cpp b/test/array_fail_spa_sp_a.cpp new file mode 100644 index 0000000..4d6d323 --- /dev/null +++ b/test/array_fail_spa_sp_a.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::shared_ptr px2; px2 = px; +} diff --git a/test/array_fail_spa_sp_c.cpp b/test/array_fail_spa_sp_c.cpp new file mode 100644 index 0000000..9015483 --- /dev/null +++ b/test/array_fail_spa_sp_c.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::shared_ptr px2( px ); +} diff --git a/test/array_fail_spa_sp_ma.cpp b/test/array_fail_spa_sp_ma.cpp new file mode 100644 index 0000000..6511887 --- /dev/null +++ b/test/array_fail_spa_sp_ma.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px2; px2 = boost::shared_ptr(); +} diff --git a/test/array_fail_spa_sp_mc.cpp b/test/array_fail_spa_sp_mc.cpp new file mode 100644 index 0000000..46f6e30 --- /dev/null +++ b/test/array_fail_spa_sp_mc.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px2(( boost::shared_ptr() )); +} diff --git a/test/array_fail_spa_spa_a.cpp b/test/array_fail_spa_spa_a.cpp new file mode 100644 index 0000000..edb248d --- /dev/null +++ b/test/array_fail_spa_spa_a.cpp @@ -0,0 +1,23 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::shared_ptr px2; px2 = px; +} diff --git a/test/array_fail_spa_spa_c.cpp b/test/array_fail_spa_spa_c.cpp new file mode 100644 index 0000000..a1833ee --- /dev/null +++ b/test/array_fail_spa_spa_c.cpp @@ -0,0 +1,23 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::shared_ptr px2( px ); +} diff --git a/test/array_fail_spa_spa_ma.cpp b/test/array_fail_spa_spa_ma.cpp new file mode 100644 index 0000000..8c81693 --- /dev/null +++ b/test/array_fail_spa_spa_ma.cpp @@ -0,0 +1,22 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::shared_ptr px2; px2 = boost::shared_ptr(); +} diff --git a/test/array_fail_spa_spa_mc.cpp b/test/array_fail_spa_spa_mc.cpp new file mode 100644 index 0000000..606d937 --- /dev/null +++ b/test/array_fail_spa_spa_mc.cpp @@ -0,0 +1,22 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::shared_ptr px2(( boost::shared_ptr() )); +} diff --git a/test/array_fail_spa_wp_a.cpp b/test/array_fail_spa_wp_a.cpp new file mode 100644 index 0000000..14c122e --- /dev/null +++ b/test/array_fail_spa_wp_a.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::weak_ptr px2; px2 = px; +} diff --git a/test/array_fail_spa_wp_c.cpp b/test/array_fail_spa_wp_c.cpp new file mode 100644 index 0000000..9c22a5b --- /dev/null +++ b/test/array_fail_spa_wp_c.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::weak_ptr px2( px ); +} diff --git a/test/array_fail_spa_wp_ma.cpp b/test/array_fail_spa_wp_ma.cpp new file mode 100644 index 0000000..49c1eb0 --- /dev/null +++ b/test/array_fail_spa_wp_ma.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px2; px2 = boost::shared_ptr(); +} diff --git a/test/array_fail_spa_wp_mc.cpp b/test/array_fail_spa_wp_mc.cpp new file mode 100644 index 0000000..738946c --- /dev/null +++ b/test/array_fail_spa_wp_mc.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px2(( boost::shared_ptr() )); +} diff --git a/test/array_fail_spa_wpa_a.cpp b/test/array_fail_spa_wpa_a.cpp new file mode 100644 index 0000000..9c65f1c --- /dev/null +++ b/test/array_fail_spa_wpa_a.cpp @@ -0,0 +1,24 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::weak_ptr px2; px2 = px; +} diff --git a/test/array_fail_spa_wpa_c.cpp b/test/array_fail_spa_wpa_c.cpp new file mode 100644 index 0000000..ff2ae22 --- /dev/null +++ b/test/array_fail_spa_wpa_c.cpp @@ -0,0 +1,24 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::shared_ptr px; + boost::weak_ptr px2( px ); +} diff --git a/test/array_fail_spa_wpa_ma.cpp b/test/array_fail_spa_wpa_ma.cpp new file mode 100644 index 0000000..cb2725e --- /dev/null +++ b/test/array_fail_spa_wpa_ma.cpp @@ -0,0 +1,23 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::weak_ptr px2; px2 = boost::shared_ptr(); +} diff --git a/test/array_fail_spa_wpa_mc.cpp b/test/array_fail_spa_wpa_mc.cpp new file mode 100644 index 0000000..9b07933 --- /dev/null +++ b/test/array_fail_spa_wpa_mc.cpp @@ -0,0 +1,23 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::weak_ptr px2(( boost::shared_ptr() )); +} diff --git a/test/array_fail_up_spa_a.cpp b/test/array_fail_up_spa_a.cpp new file mode 100644 index 0000000..8b9f246 --- /dev/null +++ b/test/array_fail_up_spa_a.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + std::unique_ptr px; + boost::shared_ptr px2; px2 = px; +} diff --git a/test/array_fail_up_spa_c.cpp b/test/array_fail_up_spa_c.cpp new file mode 100644 index 0000000..1bbc5c0 --- /dev/null +++ b/test/array_fail_up_spa_c.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + std::unique_ptr px; + boost::shared_ptr px2( px ); +} diff --git a/test/array_fail_up_spa_ma.cpp b/test/array_fail_up_spa_ma.cpp new file mode 100644 index 0000000..fcd612d --- /dev/null +++ b/test/array_fail_up_spa_ma.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px2; px2 = std::unique_ptr(); +} diff --git a/test/array_fail_up_spa_mc.cpp b/test/array_fail_up_spa_mc.cpp new file mode 100644 index 0000000..6a20d6e --- /dev/null +++ b/test/array_fail_up_spa_mc.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px2(( std::unique_ptr() )); +} diff --git a/test/array_fail_upa_sp_a.cpp b/test/array_fail_upa_sp_a.cpp new file mode 100644 index 0000000..b44e07e --- /dev/null +++ b/test/array_fail_upa_sp_a.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + std::unique_ptr px; + boost::shared_ptr px2; px2 = px; +} diff --git a/test/array_fail_upa_sp_c.cpp b/test/array_fail_upa_sp_c.cpp new file mode 100644 index 0000000..fe62044 --- /dev/null +++ b/test/array_fail_upa_sp_c.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + std::unique_ptr px; + boost::shared_ptr px2( px ); +} diff --git a/test/array_fail_upa_sp_ma.cpp b/test/array_fail_upa_sp_ma.cpp new file mode 100644 index 0000000..1b2a2b2 --- /dev/null +++ b/test/array_fail_upa_sp_ma.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px2; px2 = std::unique_ptr(); +} diff --git a/test/array_fail_upa_sp_mc.cpp b/test/array_fail_upa_sp_mc.cpp new file mode 100644 index 0000000..d314a01 --- /dev/null +++ b/test/array_fail_upa_sp_mc.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include +#include + +struct X +{ +}; + +int main() +{ + boost::shared_ptr px2(( std::unique_ptr() )); +} diff --git a/test/array_fail_wp_wpa_a.cpp b/test/array_fail_wp_wpa_a.cpp new file mode 100644 index 0000000..ea82eb9 --- /dev/null +++ b/test/array_fail_wp_wpa_a.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px; + boost::weak_ptr px2; px2 = px; +} diff --git a/test/array_fail_wp_wpa_c.cpp b/test/array_fail_wp_wpa_c.cpp new file mode 100644 index 0000000..9f5609c --- /dev/null +++ b/test/array_fail_wp_wpa_c.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px; + boost::weak_ptr px2( px ); +} diff --git a/test/array_fail_wp_wpa_ma.cpp b/test/array_fail_wp_wpa_ma.cpp new file mode 100644 index 0000000..79af4d7 --- /dev/null +++ b/test/array_fail_wp_wpa_ma.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px2; px2 = boost::weak_ptr(); +} diff --git a/test/array_fail_wp_wpa_mc.cpp b/test/array_fail_wp_wpa_mc.cpp new file mode 100644 index 0000000..18a9d8a --- /dev/null +++ b/test/array_fail_wp_wpa_mc.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px2(( boost::weak_ptr() )); +} diff --git a/test/array_fail_wpa_wp_a.cpp b/test/array_fail_wpa_wp_a.cpp new file mode 100644 index 0000000..19d0026 --- /dev/null +++ b/test/array_fail_wpa_wp_a.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px; + boost::weak_ptr px2; px2 = px; +} diff --git a/test/array_fail_wpa_wp_c.cpp b/test/array_fail_wpa_wp_c.cpp new file mode 100644 index 0000000..d4b75dd --- /dev/null +++ b/test/array_fail_wpa_wp_c.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px; + boost::weak_ptr px2( px ); +} diff --git a/test/array_fail_wpa_wp_ma.cpp b/test/array_fail_wpa_wp_ma.cpp new file mode 100644 index 0000000..5c33c8b --- /dev/null +++ b/test/array_fail_wpa_wp_ma.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px2; px2 = boost::weak_ptr(); +} diff --git a/test/array_fail_wpa_wp_mc.cpp b/test/array_fail_wpa_wp_mc.cpp new file mode 100644 index 0000000..8375e6b --- /dev/null +++ b/test/array_fail_wpa_wp_mc.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +int main() +{ + boost::weak_ptr px2(( boost::weak_ptr() )); +} diff --git a/test/array_fail_wpa_wpa_a.cpp b/test/array_fail_wpa_wpa_a.cpp new file mode 100644 index 0000000..29aeaa6 --- /dev/null +++ b/test/array_fail_wpa_wpa_a.cpp @@ -0,0 +1,23 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::weak_ptr px; + boost::weak_ptr px2; px2 = px; +} diff --git a/test/array_fail_wpa_wpa_c.cpp b/test/array_fail_wpa_wpa_c.cpp new file mode 100644 index 0000000..98a574e --- /dev/null +++ b/test/array_fail_wpa_wpa_c.cpp @@ -0,0 +1,23 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::weak_ptr px; + boost::weak_ptr px2( px ); +} diff --git a/test/array_fail_wpa_wpa_ma.cpp b/test/array_fail_wpa_wpa_ma.cpp new file mode 100644 index 0000000..eb638de --- /dev/null +++ b/test/array_fail_wpa_wpa_ma.cpp @@ -0,0 +1,22 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::weak_ptr px2; px2 = boost::weak_ptr(); +} diff --git a/test/array_fail_wpa_wpa_mc.cpp b/test/array_fail_wpa_wpa_mc.cpp new file mode 100644 index 0000000..77d4f75 --- /dev/null +++ b/test/array_fail_wpa_wpa_mc.cpp @@ -0,0 +1,22 @@ +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + boost::weak_ptr px2(( boost::weak_ptr() )); +} diff --git a/test/make_shared_array_args_test.cpp b/test/make_shared_array_args_test.cpp new file mode 100644 index 0000000..c308c7a --- /dev/null +++ b/test/make_shared_array_args_test.cpp @@ -0,0 +1,172 @@ +// make_shared_array_args_test.cpp +// +// Copyright 2007-2009, 2012 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 + +#include +#include +#include +#include + +class X +{ +private: + + X( X const & ); + X & operator=( X const & ); + + void * operator new[]( std::size_t n ); + void operator delete[]( void * p ); + +public: + + static int instances; + + int v; + + explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 ) + { + ++instances; + } + + ~X() + { + --instances; + } +}; + +int X::instances = 0; + +int main() +{ + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 0 ); + BOOST_TEST( px[1].v == 0 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + + { + boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1 ); + BOOST_TEST( px[1].v == 1 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1, 2 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2 ); + BOOST_TEST( px[1].v == 1+2 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1, 2, 3 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3 ); + BOOST_TEST( px[1].v == 1+2+3 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1, 2, 3, 4 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4 ); + BOOST_TEST( px[1].v == 1+2+3+4 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1, 2, 3, 4, 5 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4+5 ); + BOOST_TEST( px[1].v == 1+2+3+4+5 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1, 2, 3, 4, 5, 6 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4+5+6 ); + BOOST_TEST( px[1].v == 1+2+3+4+5+6 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1, 2, 3, 4, 5, 6, 7 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4+5+6+7 ); + BOOST_TEST( px[1].v == 1+2+3+4+5+6+7 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1, 2, 3, 4, 5, 6, 7, 8 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4+5+6+7+8 ); + BOOST_TEST( px[1].v == 1+2+3+4+5+6+7+8 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1, 2, 3, 4, 5, 6, 7, 8, 9 ); + + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( px[0].v == 1+2+3+4+5+6+7+8+9 ); + BOOST_TEST( px[1].v == 1+2+3+4+5+6+7+8+9 ); + + px.reset(); + + BOOST_TEST( X::instances == 0 ); + } + +#endif + + return boost::report_errors(); +} diff --git a/test/make_shared_array_create_test.cpp b/test/make_shared_array_create_test.cpp new file mode 100644 index 0000000..46db862 --- /dev/null +++ b/test/make_shared_array_create_test.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include + +class type { +public: + static int instances; + explicit type(int a=0, int b=0, int c=0, int d=0, int e=0, int f=0, int g=0, int h=0, int i=0) + : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h), i(i) { + instances++; + } + ~type() { + instances--; + } + const int a; + const int b; + const int c; + const int d; + const int e; + const int f; + const int g; + const int h; + const int i; +private: + type(const type&); + type& operator=(const type&); +}; + +int type::instances = 0; + +int main() { +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(2, 1, 2, 3, 4, 5, 6, 7, 8, 9); + BOOST_TEST(type::instances == 2); + BOOST_TEST(a1[0].a == 1); + BOOST_TEST(a1[0].d == 4); + BOOST_TEST(a1[1].f == 6); + BOOST_TEST(a1[1].i == 9); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(1, 2, 3, 4, 5, 6, 7, 8, 9); + BOOST_TEST(type::instances == 2); + BOOST_TEST(a1[0].a == 1); + BOOST_TEST(a1[0].d == 4); + BOOST_TEST(a1[1].f == 6); + BOOST_TEST(a1[1].i == 9); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(2, 1, 2, 3, 4, 5, 6, 7); + BOOST_TEST(type::instances == 4); + BOOST_TEST(a1[0][0].a == 1); + BOOST_TEST(a1[0][1].d == 4); + BOOST_TEST(a1[1][0].f == 6); + BOOST_TEST(a1[1][1].i == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(1, 2, 3, 4, 5, 6, 7); + BOOST_TEST(type::instances == 4); + BOOST_TEST(a1[0][0].a == 1); + BOOST_TEST(a1[0][1].d == 4); + BOOST_TEST(a1[1][0].f == 6); + BOOST_TEST(a1[1][1].i == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(2, 1, 2, 3, 4, 5); + BOOST_TEST(type::instances == 8); + BOOST_TEST(a1[0][0][0].a == 1); + BOOST_TEST(a1[0][1][0].c == 3); + BOOST_TEST(a1[1][0][1].e == 5); + BOOST_TEST(a1[1][1][1].i == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(1, 2, 3, 4, 5); + BOOST_TEST(type::instances == 8); + BOOST_TEST(a1[0][0][0].a == 1); + BOOST_TEST(a1[0][1][0].c == 3); + BOOST_TEST(a1[1][0][1].e == 5); + BOOST_TEST(a1[1][1][1].i == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(2, 1, 2, 3); + BOOST_TEST(type::instances == 16); + BOOST_TEST(a1[0][0][0][1].a == 1); + BOOST_TEST(a1[0][0][1][0].c == 3); + BOOST_TEST(a1[0][1][0][0].f == 0); + BOOST_TEST(a1[1][0][0][0].i == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(1, 2, 3); + BOOST_TEST(type::instances == 16); + BOOST_TEST(a1[0][0][0][1].a == 1); + BOOST_TEST(a1[0][0][1][0].c == 3); + BOOST_TEST(a1[0][1][0][0].f == 0); + BOOST_TEST(a1[1][0][0][0].i == 0); + } +#endif + return boost::report_errors(); +} diff --git a/test/make_shared_array_esft_test.cpp b/test/make_shared_array_esft_test.cpp new file mode 100644 index 0000000..9d0adb1 --- /dev/null +++ b/test/make_shared_array_esft_test.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include +#include + +class type + : public boost::enable_shared_from_this { +public: + static unsigned int instances; + explicit type() { + instances++; + } + ~type() { + instances--; + } +private: + type(const type&); + type& operator=(const type&); +}; + +unsigned int type::instances = 0; + +int main() { + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(3); + try { + a1[0].shared_from_this(); + BOOST_ERROR("shared_from_this did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 3); + } + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared_noinit(3); + try { + a1[0].shared_from_this(); + BOOST_ERROR("shared_from_this did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 3); + } + } + return boost::report_errors(); +} diff --git a/test/make_shared_array_init_test.cpp b/test/make_shared_array_init_test.cpp new file mode 100644 index 0000000..6a4c5d5 --- /dev/null +++ b/test/make_shared_array_init_test.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include + +class type { +public: + type(int value) + : value(value) { + } + const int value; +private: + type& operator=(const type&); +}; + +int main() { +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + { + boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 3 }); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 1); + BOOST_TEST(a1[2] == 2); + BOOST_TEST(a1[3] == 3); + } + { + boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 3 }); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 1); + BOOST_TEST(a1[2] == 2); + BOOST_TEST(a1[3] == 3); + } + { + boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 3 }); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 1); + BOOST_TEST(a1[2] == 2); + BOOST_TEST(a1[3] == 3); + } + { + boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 3 }); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 1); + BOOST_TEST(a1[2] == 2); + BOOST_TEST(a1[3] == 3); + } + { + boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 3 }); + BOOST_TEST(a1[0].value == 0); + BOOST_TEST(a1[1].value == 1); + BOOST_TEST(a1[2].value == 2); + BOOST_TEST(a1[3].value == 3); + } + { + boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 3 }); + BOOST_TEST(a1[0].value == 0); + BOOST_TEST(a1[1].value == 1); + BOOST_TEST(a1[2].value == 2); + BOOST_TEST(a1[3].value == 3); + } + { + boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 3 }); + BOOST_TEST(a1[0].value == 0); + BOOST_TEST(a1[1].value == 1); + BOOST_TEST(a1[2].value == 2); + BOOST_TEST(a1[3].value == 3); + } + { + boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 3 }); + BOOST_TEST(a1[0].value == 0); + BOOST_TEST(a1[1].value == 1); + BOOST_TEST(a1[2].value == 2); + BOOST_TEST(a1[3].value == 3); + } +#endif + return boost::report_errors(); +} diff --git a/test/make_shared_array_test.cpp b/test/make_shared_array_test.cpp new file mode 100644 index 0000000..d9b9134 --- /dev/null +++ b/test/make_shared_array_test.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include +#include +#include + +class type { +public: + static unsigned int instances; + explicit type(int = 0, int = 0) + : member() { + instances++; + } + ~type() { + instances--; + } +private: + type(const type&); + type& operator=(const type&); + double member; +}; + +unsigned int type::instances = 0; + +int main() { + { + boost::shared_ptr a1 = boost::make_shared(3); + int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 0); + BOOST_TEST(a1[2] == 0); + } + { + boost::shared_ptr a1 = boost::make_shared(3); + const int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 0); + BOOST_TEST(a1[2] == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(3); + type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = a1; + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(3); + const type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + a1.reset(); + BOOST_TEST(type::instances == 0); + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(3, 1, 5); + type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = a1; + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(1, 5); + type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = a1; + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(3, 1, 5); + const type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(1, 5); + const type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + a1.reset(); + BOOST_TEST(type::instances == 0); + } +#endif + { + boost::shared_ptr a1 = boost::make_shared_noinit(3); + int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + } + { + boost::shared_ptr a1 = boost::make_shared_noinit(); + int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + } + { + boost::shared_ptr a1 = boost::make_shared_noinit(3); + const int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + } + { + boost::shared_ptr a1 = boost::make_shared_noinit(); + const int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared_noinit(3); + type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = a1; + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared_noinit(); + type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = a1; + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared_noinit(3); + const type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared_noinit(); + const type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} diff --git a/test/make_shared_array_throws_test.cpp b/test/make_shared_array_throws_test.cpp new file mode 100644 index 0000000..7e06d41 --- /dev/null +++ b/test/make_shared_array_throws_test.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include + +class type { +public: + static unsigned int instances; + explicit type() { + if (instances == 5) { + throw true; + } + instances++; + } + ~type() { + instances--; + } +private: + type(const type&); + type& operator=(const type&); +}; + +unsigned int type::instances = 0; + +int main() { + BOOST_TEST(type::instances == 0); + try { + boost::make_shared(6); + BOOST_ERROR("make_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + try { + boost::make_shared(3); + BOOST_ERROR("make_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + try { + boost::make_shared_noinit(6); + BOOST_ERROR("make_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + try { + boost::make_shared_noinit(3); + BOOST_ERROR("make_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp new file mode 100644 index 0000000..b5b96d5 --- /dev/null +++ b/test/make_shared_arrays_create_test.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include +#include + +int main() { +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + { + boost::shared_ptr a1 = boost::make_shared({ {0, 1}, {2, 3} }); + BOOST_TEST(a1[0][0] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 2); + BOOST_TEST(a1[1][1] == 3); + } + { + boost::shared_ptr a1 = boost::make_shared({ {0, 1}, {2, 3} }); + BOOST_TEST(a1[0][0] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 2); + BOOST_TEST(a1[1][1] == 3); + } + { + boost::shared_ptr a1 = boost::make_shared(2, {0, 1}); + BOOST_TEST(a1[0][0] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 0); + BOOST_TEST(a1[1][1] == 1); + } + { + boost::shared_ptr a1 = boost::make_shared(2, { {0, 1}, {2, 3} }); + BOOST_TEST(a1[0][0][0] == 0); + BOOST_TEST(a1[0][0][1] == 1); + BOOST_TEST(a1[1][1][0] == 2); + BOOST_TEST(a1[1][1][1] == 3); + } +#endif + return boost::report_errors(); +} diff --git a/test/make_shared_arrays_test.cpp b/test/make_shared_arrays_test.cpp new file mode 100644 index 0000000..eb79d4f --- /dev/null +++ b/test/make_shared_arrays_test.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2012 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include + +class type { +public: + static unsigned int instances; + explicit type(int = 0, int = 0) + : member() { + instances++; + } + ~type() { + instances--; + } +private: + type(const type&); + type& operator=(const type&); + double member; +}; + +unsigned int type::instances = 0; + +int main() { + { + boost::shared_ptr a1 = boost::make_shared(2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a1[0][0][1] == 0); + BOOST_TEST(a1[0][1][0] == 0); + BOOST_TEST(a1[1][0][0] == 0); + } + { + boost::shared_ptr a1 = boost::make_shared(2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a1[0][0][1] == 0); + BOOST_TEST(a1[0][1][0] == 0); + BOOST_TEST(a1[1][0][0] == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(2, 1, 5); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(1, 5); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(2, 1, 5); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared(1, 5); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } +#endif + { + boost::shared_ptr a1 = boost::make_shared_noinit(2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + { + boost::shared_ptr a1 = boost::make_shared_noinit(); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + { + boost::shared_ptr a1 = boost::make_shared_noinit(2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + { + boost::shared_ptr a1 = boost::make_shared_noinit(); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared_noinit(2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared_noinit(); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared_noinit(2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::make_shared_noinit(); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} diff --git a/test/shared_ptr_convertible_test.cpp b/test/shared_ptr_convertible_test.cpp new file mode 100644 index 0000000..7f49e1f --- /dev/null +++ b/test/shared_ptr_convertible_test.cpp @@ -0,0 +1,71 @@ +#include + +// sp_convertible_test.cpp +// +// Copyright (c) 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 + +#include +#include + +// + +class incomplete; + +struct X +{ +}; + +struct Y +{ +}; + +struct Z: public X +{ +}; + +int f( boost::shared_ptr ) +{ + return 1; +} + +int f( boost::shared_ptr ) +{ + return 2; +} + +int f( boost::shared_ptr ) +{ + return 3; +} + +int g( boost::shared_ptr ) +{ + return 4; +} + +int g( boost::shared_ptr ) +{ + return 5; +} + +int g( boost::shared_ptr ) +{ + return 6; +} + +int main() +{ + boost::shared_ptr p1; + BOOST_TEST( 1 == f( p1 ) ); + BOOST_TEST( 1 == f( boost::shared_ptr() ) ); + + boost::shared_ptr p2; + BOOST_TEST( 4 == g( p2 ) ); + BOOST_TEST( 4 == g( boost::shared_ptr() ) ); + + return boost::report_errors(); +} diff --git a/test/smart_ptr_test.cpp b/test/smart_ptr_test.cpp index 7b4de34..656a42a 100644 --- a/test/smart_ptr_test.cpp +++ b/test/smart_ptr_test.cpp @@ -236,7 +236,7 @@ void test() ca2.reset(); BOOST_TEST( ca.use_count() == 2 ); BOOST_TEST( ca3.use_count() == 2 ); - BOOST_TEST( ca2.use_count() == 1 ); + BOOST_TEST( ca2.use_count() == 0 ); ca.reset(); BOOST_TEST( ca.get() == 0 ); @@ -269,7 +269,7 @@ void test() udta2.reset(); BOOST_TEST( udta2.get() == 0 ); BOOST_TEST( udta.use_count() == 1 ); - BOOST_TEST( udta2.use_count() == 1 ); + BOOST_TEST( udta2.use_count() == 0 ); BOOST_TEST( UDT_use_count == 4 ); // reality check diff --git a/test/sp_array_cv_test.cpp b/test/sp_array_cv_test.cpp new file mode 100644 index 0000000..8618fb0 --- /dev/null +++ b/test/sp_array_cv_test.cpp @@ -0,0 +1,60 @@ +// +// sp_array_cv_test.cpp +// +// Copyright (c) 2012 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 +// + +#include + +struct X +{ +}; + +class B +{ +}; + +class D: public B +{ +}; + +#define TEST_CONV( T, U ) \ + { \ + boost::shared_ptr< T > p1; \ + boost::shared_ptr< U > p2( p1 ); \ + p2 = p1; \ + boost::shared_ptr< U > p3 = boost::shared_ptr< T >(); \ + p3 = boost::shared_ptr< T >(); \ + } + +#define TEST_CV_TRUE( T, U ) \ + TEST_CONV( T, U ) \ + TEST_CONV( T, const U ) \ + TEST_CONV( T, volatile U ) \ + TEST_CONV( T, const volatile U ) \ + TEST_CONV( const T, const U ) \ + TEST_CONV( const T, const volatile U ) \ + TEST_CONV( volatile T, volatile U ) \ + TEST_CONV( volatile T, const volatile U ) \ + TEST_CONV( const volatile T, const volatile U ) + +int main() +{ + TEST_CV_TRUE( X, X ) + TEST_CV_TRUE( X, void ) + TEST_CV_TRUE( D, B ) + + TEST_CV_TRUE( X[], X[] ) + TEST_CV_TRUE( X[3], X[3] ) + + TEST_CV_TRUE( X[3], X[] ) + + TEST_CV_TRUE( X[], void ) + TEST_CV_TRUE( X[3], void ) + + return 0; +} diff --git a/test/sp_array_n_test.cpp b/test/sp_array_n_test.cpp new file mode 100644 index 0000000..ccbcc26 --- /dev/null +++ b/test/sp_array_n_test.cpp @@ -0,0 +1,248 @@ +// +// sp_array_n_test.cpp +// +// Copyright (c) 2012 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 +// + +#include +#include +#include +#include +#include +#include + +class X: public boost::enable_shared_from_this< X > +{ +public: + + static int allocations; + static int instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + + void* operator new[]( std::size_t n ) + { + ++allocations; + return ::operator new[]( n ); + } + + void operator delete[]( void* p ) + { + --allocations; + ::operator delete[]( p ); + } + +private: + + X( X const& ); + X& operator=( X const& ); +}; + +int X::allocations = 0; +int X::instances = 0; + +template< class T> class array_deleter +{ +public: + + static int calls; + + void operator()( T * p ) const + { + ++calls; + delete[] p; + } + +private: + + template< class Y > void operator()( Y * p ) const; +}; + +template< class T > int array_deleter< T >::calls = 0; + +int main() +{ + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr px; + BOOST_TEST( !px ); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + boost::shared_ptr px2( new X[ 3 ] ); + BOOST_TEST( px2 ); + + try + { + px2[0].shared_from_this(); + BOOST_ERROR( "px2[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 3 ); + + { + X & rx = px2[ 0 ]; + BOOST_TEST( &rx == px2.get() ); + } + + boost::shared_ptr px3( px2 ); + BOOST_TEST( px3 == px2 ); + BOOST_TEST( !( px2 < px3 ) && !( px3 < px2 ) ); + + { + X const & rx = px3[ 1 ]; + BOOST_TEST( &rx == px3.get() + 1 ); + } + + px3.reset(); + px3 = px2; + BOOST_TEST( px3 == px2 ); + BOOST_TEST( !( px2 < px3 ) && !( px3 < px2 ) ); + + boost::shared_ptr px4( px2 ); + BOOST_TEST( px4 == px2 ); + BOOST_TEST( !( px2 < px4 ) && !( px4 < px2 ) ); + + { + X volatile & rx = px4[ 2 ]; + BOOST_TEST( &rx == px4.get() + 2 ); + } + + px4.reset(); + px4 = px2; + BOOST_TEST( px4 == px2 ); + BOOST_TEST( !( px2 < px4 ) && !( px4 < px2 ) ); + + boost::shared_ptr px5( px2 ); + BOOST_TEST( px5 == px2 ); + BOOST_TEST( !( px2 < px5 ) && !( px5 < px2 ) ); + + px5.reset(); + px5 = px2; + BOOST_TEST( px5 == px2 ); + BOOST_TEST( !( px2 < px5 ) && !( px5 < px2 ) ); + + boost::weak_ptr wp( px ); + BOOST_TEST( wp.lock() == px ); + + boost::weak_ptr wp2( px2 ); + BOOST_TEST( wp2.lock() == px2 ); + + wp2.reset(); + wp2 = px2; + BOOST_TEST( wp2.lock() == px2 ); + + boost::weak_ptr wp3( px2 ); + BOOST_TEST( wp3.lock() == px2 ); + + wp3.reset(); + wp3 = px2; + BOOST_TEST( wp3.lock() == px2 ); + + boost::weak_ptr wp4( px2 ); + BOOST_TEST( wp4.lock() == px2 ); + + wp4.reset(); + wp4 = px2; + BOOST_TEST( wp4.lock() == px2 ); + + boost::weak_ptr wp5( px2 ); + BOOST_TEST( wp5.lock() == px2 ); + + wp5.reset(); + wp5 = px2; + BOOST_TEST( wp5.lock() == px2 ); + + px2.reset(); + + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 3 ); + + px3.reset(); + px4.reset(); + px5.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + BOOST_TEST( wp2.lock() == 0 ); + BOOST_TEST( wp3.lock() == 0 ); + BOOST_TEST( wp4.lock() == 0 ); + BOOST_TEST( wp5.lock() == 0 ); + } + + { + boost::shared_ptr px( new X[ 5 ], array_deleter< X >() ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 5 ); + + try + { + px[0].shared_from_this(); + BOOST_ERROR( "px[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( array_deleter< X >::calls == 1 ); + } + + { + boost::shared_ptr px( new X[ 6 ], array_deleter< X >(), std::allocator< X >() ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 6 ); + + try + { + px[0].shared_from_this(); + BOOST_ERROR( "px[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( array_deleter< X >::calls == 2 ); + } + + return boost::report_errors(); +} diff --git a/test/sp_array_test.cpp b/test/sp_array_test.cpp new file mode 100644 index 0000000..0c7f597 --- /dev/null +++ b/test/sp_array_test.cpp @@ -0,0 +1,311 @@ +// +// sp_array_test.cpp +// +// Copyright (c) 2012 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 +// + +#include +#include +#include +#include +#include +#include + +class X: public boost::enable_shared_from_this< X > +{ +public: + + static int allocations; + static int instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + + void* operator new[]( std::size_t n ) + { + ++allocations; + return ::operator new[]( n ); + } + + void operator delete[]( void* p ) + { + --allocations; + ::operator delete[]( p ); + } + +private: + + X( X const& ); + X& operator=( X const& ); +}; + +int X::allocations = 0; +int X::instances = 0; + +template< class T> class array_deleter +{ +public: + + static int calls; + + void operator()( T * p ) const + { + ++calls; + delete[] p; + } + +private: + + template< class Y > void operator()( Y * p ) const; +}; + +template< class T > int array_deleter< T >::calls = 0; + +int main() +{ + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr px; + BOOST_TEST( !px ); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + boost::shared_ptr px2( new X[ 3 ] ); + BOOST_TEST( px2 ); + + try + { + px2[0].shared_from_this(); + BOOST_ERROR( "px2[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 3 ); + + { + X & rx = px2[ 0 ]; + BOOST_TEST( &rx == px2.get() ); + } + + boost::shared_ptr px3( px2 ); + BOOST_TEST( px3 == px2 ); + BOOST_TEST( !( px2 < px3 ) && !( px3 < px2 ) ); + + { + X const & rx = px3[ 1 ]; + BOOST_TEST( &rx == px3.get() + 1 ); + } + + px3.reset(); + px3 = px2; + BOOST_TEST( px3 == px2 ); + BOOST_TEST( !( px2 < px3 ) && !( px3 < px2 ) ); + + boost::shared_ptr px4( px2 ); + BOOST_TEST( px4 == px2 ); + BOOST_TEST( !( px2 < px4 ) && !( px4 < px2 ) ); + + { + X volatile & rx = px4[ 2 ]; + BOOST_TEST( &rx == px4.get() + 2 ); + } + + px4.reset(); + px4 = px2; + BOOST_TEST( px4 == px2 ); + BOOST_TEST( !( px2 < px4 ) && !( px4 < px2 ) ); + + boost::shared_ptr px5( px2 ); + BOOST_TEST( px5 == px2 ); + BOOST_TEST( !( px2 < px5 ) && !( px5 < px2 ) ); + + px5.reset(); + px5 = px2; + BOOST_TEST( px5 == px2 ); + BOOST_TEST( !( px2 < px5 ) && !( px5 < px2 ) ); + + boost::weak_ptr wp( px ); + BOOST_TEST( wp.lock() == px ); + + boost::weak_ptr wp2( px2 ); + BOOST_TEST( wp2.lock() == px2 ); + + wp2.reset(); + wp2 = px2; + BOOST_TEST( wp2.lock() == px2 ); + + boost::weak_ptr wp3( px2 ); + BOOST_TEST( wp3.lock() == px2 ); + + wp3.reset(); + wp3 = px2; + BOOST_TEST( wp3.lock() == px2 ); + + boost::weak_ptr wp4( px2 ); + BOOST_TEST( wp4.lock() == px2 ); + + wp4.reset(); + wp4 = px2; + BOOST_TEST( wp4.lock() == px2 ); + + boost::weak_ptr wp5( px2 ); + BOOST_TEST( wp5.lock() == px2 ); + + wp5.reset(); + wp5 = px2; + BOOST_TEST( wp5.lock() == px2 ); + + px2.reset(); + + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 3 ); + + px3.reset(); + px4.reset(); + px5.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + BOOST_TEST( wp2.lock() == 0 ); + BOOST_TEST( wp3.lock() == 0 ); + BOOST_TEST( wp4.lock() == 0 ); + BOOST_TEST( wp5.lock() == 0 ); + } + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) + + { + std::unique_ptr px( new X[ 4 ] ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 4 ); + + boost::shared_ptr px2( std::move( px ) ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 4 ); + BOOST_TEST( px.get() == 0 ); + + try + { + px2[0].shared_from_this(); + BOOST_ERROR( "px2[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px2.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + } + + { + std::unique_ptr px( new X[ 4 ] ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 4 ); + + boost::shared_ptr px2; + px2 = std::move( px ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 4 ); + BOOST_TEST( px.get() == 0 ); + + try + { + px2[0].shared_from_this(); + BOOST_ERROR( "px2[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px2.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + } + +#endif + + { + boost::shared_ptr px( new X[ 5 ], array_deleter< X >() ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 5 ); + + try + { + px[0].shared_from_this(); + BOOST_ERROR( "px[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( array_deleter< X >::calls == 1 ); + } + + { + boost::shared_ptr px( new X[ 6 ], array_deleter< X >(), std::allocator< X >() ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 6 ); + + try + { + px[0].shared_from_this(); + BOOST_ERROR( "px[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( array_deleter< X >::calls == 2 ); + } + + return boost::report_errors(); +} diff --git a/test/sp_convertible_test.cpp b/test/sp_convertible_test.cpp index 7f49e1f..05b15c1 100644 --- a/test/sp_convertible_test.cpp +++ b/test/sp_convertible_test.cpp @@ -2,70 +2,92 @@ // sp_convertible_test.cpp // -// Copyright (c) 2008 Peter Dimov +// Copyright (c) 2012 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 #include -#include +#include // -class incomplete; +class X; -struct X +class B { }; -struct Y +class D: public B { }; -struct Z: public X -{ -}; +#define TEST_CV_TRUE( T, U ) \ + BOOST_TEST(( sp_convertible< T, U >::value == true )); \ + BOOST_TEST(( sp_convertible< T, const U >::value == true )); \ + BOOST_TEST(( sp_convertible< T, volatile U >::value == true )); \ + BOOST_TEST(( sp_convertible< T, const volatile U >::value == true )); \ + BOOST_TEST(( sp_convertible< const T, U >::value == false )); \ + BOOST_TEST(( sp_convertible< const T, const U >::value == true )); \ + BOOST_TEST(( sp_convertible< const T, volatile U >::value == false )); \ + BOOST_TEST(( sp_convertible< const T, const volatile U >::value == true )); \ + BOOST_TEST(( sp_convertible< volatile T, U >::value == false )); \ + BOOST_TEST(( sp_convertible< volatile T, const U >::value == false )); \ + BOOST_TEST(( sp_convertible< volatile T, volatile U >::value == true )); \ + BOOST_TEST(( sp_convertible< volatile T, const volatile U >::value == true )); \ + BOOST_TEST(( sp_convertible< const volatile T, U >::value == false )); \ + BOOST_TEST(( sp_convertible< const volatile T, const U >::value == false )); \ + BOOST_TEST(( sp_convertible< const volatile T, volatile U >::value == false )); \ + BOOST_TEST(( sp_convertible< const volatile T, const volatile U >::value == true )); -int f( boost::shared_ptr ) -{ - return 1; -} - -int f( boost::shared_ptr ) -{ - return 2; -} - -int f( boost::shared_ptr ) -{ - return 3; -} - -int g( boost::shared_ptr ) -{ - return 4; -} - -int g( boost::shared_ptr ) -{ - return 5; -} - -int g( boost::shared_ptr ) -{ - return 6; -} +#define TEST_CV_FALSE( T, U ) \ + BOOST_TEST(( sp_convertible< T, U >::value == false )); \ + BOOST_TEST(( sp_convertible< T, const U >::value == false )); \ + BOOST_TEST(( sp_convertible< T, volatile U >::value == false )); \ + BOOST_TEST(( sp_convertible< T, const volatile U >::value == false )); \ + BOOST_TEST(( sp_convertible< const T, U >::value == false )); \ + BOOST_TEST(( sp_convertible< const T, const U >::value == false )); \ + BOOST_TEST(( sp_convertible< const T, volatile U >::value == false )); \ + BOOST_TEST(( sp_convertible< const T, const volatile U >::value == false )); \ + BOOST_TEST(( sp_convertible< volatile T, U >::value == false )); \ + BOOST_TEST(( sp_convertible< volatile T, const U >::value == false )); \ + BOOST_TEST(( sp_convertible< volatile T, volatile U >::value == false )); \ + BOOST_TEST(( sp_convertible< volatile T, const volatile U >::value == false )); \ + BOOST_TEST(( sp_convertible< const volatile T, U >::value == false )); \ + BOOST_TEST(( sp_convertible< const volatile T, const U >::value == false )); \ + BOOST_TEST(( sp_convertible< const volatile T, volatile U >::value == false )); \ + BOOST_TEST(( sp_convertible< const volatile T, const volatile U >::value == false )); int main() { - boost::shared_ptr p1; - BOOST_TEST( 1 == f( p1 ) ); - BOOST_TEST( 1 == f( boost::shared_ptr() ) ); +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) - boost::shared_ptr p2; - BOOST_TEST( 4 == g( p2 ) ); - BOOST_TEST( 4 == g( boost::shared_ptr() ) ); + using boost::detail::sp_convertible; + + TEST_CV_TRUE( X, X ) + TEST_CV_TRUE( X, void ) + TEST_CV_FALSE( void, X ) + TEST_CV_TRUE( D, B ) + TEST_CV_FALSE( B, D ) + + TEST_CV_TRUE( X[], X[] ) + TEST_CV_FALSE( D[], B[] ) + + TEST_CV_TRUE( X[3], X[3] ) + TEST_CV_FALSE( X[3], X[4] ) + TEST_CV_FALSE( D[3], B[3] ) + + TEST_CV_TRUE( X[3], X[] ) + TEST_CV_FALSE( X[], X[3] ) + + TEST_CV_TRUE( X[], void ) + TEST_CV_FALSE( void, X[] ) + + TEST_CV_TRUE( X[3], void ) + TEST_CV_FALSE( void, X[3] ) + +#endif return boost::report_errors(); }