From ad1b34440501fc9984cbcfd55ab1e45c03aba879 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 1 Mar 2009 17:10:49 +0000 Subject: [PATCH 001/210] Refs #2394 (fixed in trunk.) [SVN r51514] --- include/boost/smart_ptr/detail/shared_count.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index 3384faa..b968bba 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -319,7 +319,7 @@ public: weak_count(shared_count const & r): pi_(r.pi_) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) + , id_(weak_count_id) #endif { if(pi_ != 0) pi_->weak_add_ref(); @@ -327,7 +327,7 @@ public: weak_count(weak_count const & r): pi_(r.pi_) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) + , id_(weak_count_id) #endif { if(pi_ != 0) pi_->weak_add_ref(); From eb0ff40d621a620bfca945ca62c52d66033f542a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 1 Mar 2009 17:18:17 +0000 Subject: [PATCH 002/210] Refs #2675 (fixed in trunk.) [SVN r51515] --- include/boost/smart_ptr/detail/lightweight_mutex.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/smart_ptr/detail/lightweight_mutex.hpp b/include/boost/smart_ptr/detail/lightweight_mutex.hpp index a2fc281..d46b193 100644 --- a/include/boost/smart_ptr/detail/lightweight_mutex.hpp +++ b/include/boost/smart_ptr/detail/lightweight_mutex.hpp @@ -32,7 +32,7 @@ # include #elif defined(BOOST_HAS_PTHREADS) # include -#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +#elif defined(BOOST_HAS_WINTHREADS) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # include #else // Use #define BOOST_DISABLE_THREADS to avoid the error From ed32efcc5133175cafb96223e1d35955a025a37f Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 1 Mar 2009 17:27:35 +0000 Subject: [PATCH 003/210] Refs #2662 (applied to trunk.) [SVN r51516] --- include/boost/smart_ptr/make_shared.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp index 58e38d2..25b9cf0 100644 --- a/include/boost/smart_ptr/make_shared.hpp +++ b/include/boost/smart_ptr/make_shared.hpp @@ -60,6 +60,11 @@ public: { } + // optimization: do not copy storage_ + sp_ms_deleter( sp_ms_deleter const & ): initialized_( false ) + { + } + ~sp_ms_deleter() { destroy(); From 905a3711dbca8321b32a2dcf5478b5f0e75ac784 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 1 Mar 2009 18:01:19 +0000 Subject: [PATCH 004/210] Refs #2525 (fixed in trunk.) [SVN r51517] --- .../boost/smart_ptr/detail/atomic_count.hpp | 5 +- .../smart_ptr/detail/atomic_count_gcc.hpp | 6 ++- .../smart_ptr/detail/sp_counted_base.hpp | 5 +- .../boost/smart_ptr/detail/sp_has_sync.hpp | 49 +++++++++++++++++++ include/boost/smart_ptr/detail/spinlock.hpp | 8 ++- 5 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 include/boost/smart_ptr/detail/sp_has_sync.hpp diff --git a/include/boost/smart_ptr/detail/atomic_count.hpp b/include/boost/smart_ptr/detail/atomic_count.hpp index 91236e4..a6ddea3 100644 --- a/include/boost/smart_ptr/detail/atomic_count.hpp +++ b/include/boost/smart_ptr/detail/atomic_count.hpp @@ -74,6 +74,7 @@ // #include +#include #ifndef BOOST_HAS_THREADS @@ -95,10 +96,10 @@ typedef long atomic_count; #elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) # include -#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # include -#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) ) +#elif defined( BOOST_SP_HAS_SYNC ) # include #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) diff --git a/include/boost/smart_ptr/detail/atomic_count_gcc.hpp b/include/boost/smart_ptr/detail/atomic_count_gcc.hpp index 6abfdf2..1305632 100644 --- a/include/boost/smart_ptr/detail/atomic_count_gcc.hpp +++ b/include/boost/smart_ptr/detail/atomic_count_gcc.hpp @@ -17,7 +17,11 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include +#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402 +# include +#else +# include +#endif namespace boost { diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp index 1352346..df8be5b 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp @@ -18,6 +18,7 @@ // #include +#include #if defined( BOOST_SP_DISABLE_THREADS ) # include @@ -46,13 +47,13 @@ #elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) # include -#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) ) +#elif defined( BOOST_SP_HAS_SYNC ) # include #elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) ) # include -#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__) # include #elif !defined( BOOST_HAS_THREADS ) diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp new file mode 100644 index 0000000..cb0282d --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp @@ -0,0 +1,49 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/smart_ptr/detail/sp_has_sync.hpp +// +// Copyright (c) 2008, 2009 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) +// +// Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics +// are available. +// + +#if defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) + +#define BOOST_SP_HAS_SYNC + +#if defined( __arm__ ) || defined( __armel__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __hppa ) || defined( __hppa__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __m68k__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __sparc__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401 + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/spinlock.hpp b/include/boost/smart_ptr/detail/spinlock.hpp index 9c6cb9f..1640a38 100644 --- a/include/boost/smart_ptr/detail/spinlock.hpp +++ b/include/boost/smart_ptr/detail/spinlock.hpp @@ -29,17 +29,23 @@ // #include +#include #if defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ ) # include -#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) ) + +#elif defined( BOOST_SP_HAS_SYNC ) # include + #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # include + #elif defined(BOOST_HAS_PTHREADS) # include + #elif !defined(BOOST_HAS_THREADS) # include + #else # error Unrecognized threading platform #endif From a378c8c27818eee7c0c8602181c90098a90d08e5 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 1 Mar 2009 18:42:44 +0000 Subject: [PATCH 005/210] Refs #2814 (fixed in trunk.) [SVN r51518] --- .../boost/smart_ptr/detail/operator_bool.hpp | 56 ++++++++++++++++ include/boost/smart_ptr/intrusive_ptr.hpp | 67 ++++++------------- include/boost/smart_ptr/scoped_array.hpp | 61 +++++------------ include/boost/smart_ptr/scoped_ptr.hpp | 65 +++++------------- include/boost/smart_ptr/shared_array.hpp | 50 +------------- include/boost/smart_ptr/shared_ptr.hpp | 53 +-------------- 6 files changed, 112 insertions(+), 240 deletions(-) create mode 100644 include/boost/smart_ptr/detail/operator_bool.hpp diff --git a/include/boost/smart_ptr/detail/operator_bool.hpp b/include/boost/smart_ptr/detail/operator_bool.hpp new file mode 100644 index 0000000..842a05d --- /dev/null +++ b/include/boost/smart_ptr/detail/operator_bool.hpp @@ -0,0 +1,56 @@ +// This header intentionally has no include guards. +// +// Copyright (c) 2001-2009 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 + +#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__) + + operator bool () const + { + return px != 0; + } + +#elif defined( _MANAGED ) + + static void unspecified_bool( this_type*** ) + { + } + + typedef void (*unspecified_bool_type)( this_type*** ); + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: unspecified_bool; + } + +#elif \ + ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \ + ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \ + ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) ) + + typedef T * (this_type::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::get; + } + +#else + + typedef T * this_type::*unspecified_bool_type; + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::px; + } + +#endif + + // operator! is redundant, but some compilers need it + bool operator! () const // never throws + { + return px == 0; + } diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index f5acae3..d3bd02b 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -63,13 +63,13 @@ public: typedef T element_type; - intrusive_ptr(): p_(0) + intrusive_ptr(): px( 0 ) { } - intrusive_ptr(T * p, bool add_ref = true): p_(p) + intrusive_ptr( T * p, bool add_ref = true ): px( p ) { - if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_); + if( px != 0 && add_ref ) intrusive_ptr_add_ref( px ); } #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) @@ -84,21 +84,21 @@ public: intrusive_ptr( intrusive_ptr const & rhs ) #endif - : p_( rhs.get() ) + : px( rhs.get() ) { - if( p_ != 0 ) intrusive_ptr_add_ref( p_ ); + if( px != 0 ) intrusive_ptr_add_ref( px ); } #endif - intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_) + intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px ) { - if(p_ != 0) intrusive_ptr_add_ref(p_); + if( px != 0 ) intrusive_ptr_add_ref( px ); } ~intrusive_ptr() { - if(p_ != 0) intrusive_ptr_release(p_); + if( px != 0 ) intrusive_ptr_release( px ); } #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) @@ -135,63 +135,34 @@ public: T * get() const { - return p_; + return px; } T & operator*() const { - BOOST_ASSERT( p_ != 0 ); - return *p_; + BOOST_ASSERT( px != 0 ); + return *px; } T * operator->() const { - BOOST_ASSERT( p_ != 0 ); - return p_; + BOOST_ASSERT( px != 0 ); + return px; } -#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) - - operator bool () const - { - return p_ != 0; - } - -#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) - typedef T * (this_type::*unspecified_bool_type)() const; - - operator unspecified_bool_type() const // never throws - { - return p_ == 0? 0: &this_type::get; - } - -#else - - typedef T * this_type::*unspecified_bool_type; - - operator unspecified_bool_type () const - { - return p_ == 0? 0: &this_type::p_; - } - -#endif - - // operator! is a Borland-specific workaround - bool operator! () const - { - return p_ == 0; - } +// implicit conversion to "bool" +#include void swap(intrusive_ptr & rhs) { - T * tmp = p_; - p_ = rhs.p_; - rhs.p_ = tmp; + T * tmp = px; + px = rhs.px; + rhs.px = tmp; } private: - T * p_; + T * px; }; template inline bool operator==(intrusive_ptr const & a, intrusive_ptr const & b) diff --git a/include/boost/smart_ptr/scoped_array.hpp b/include/boost/smart_ptr/scoped_array.hpp index 23c2f87..483460f 100644 --- a/include/boost/smart_ptr/scoped_array.hpp +++ b/include/boost/smart_ptr/scoped_array.hpp @@ -39,7 +39,7 @@ template class scoped_array // noncopyable { private: - T * ptr; + T * px; scoped_array(scoped_array const &); scoped_array & operator=(scoped_array const &); @@ -53,79 +53,48 @@ public: typedef T element_type; - explicit scoped_array(T * p = 0) : ptr(p) // never throws + explicit scoped_array( T * p = 0 ) : px( p ) // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - boost::sp_array_constructor_hook(ptr); + boost::sp_array_constructor_hook( px ); #endif } ~scoped_array() // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - boost::sp_array_destructor_hook(ptr); + boost::sp_array_destructor_hook( px ); #endif - boost::checked_array_delete(ptr); + boost::checked_array_delete( px ); } void reset(T * p = 0) // never throws { - BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors + BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors this_type(p).swap(*this); } T & operator[](std::ptrdiff_t i) const // never throws { - BOOST_ASSERT(ptr != 0); - BOOST_ASSERT(i >= 0); - return ptr[i]; + BOOST_ASSERT( px != 0 ); + BOOST_ASSERT( i >= 0 ); + return px[i]; } T * get() const // never throws { - return ptr; + return px; } - // implicit conversion to "bool" - -#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) - - operator bool () const - { - return ptr != 0; - } - -#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) - typedef T * (this_type::*unspecified_bool_type)() const; - - operator unspecified_bool_type() const // never throws - { - return ptr == 0? 0: &this_type::get; - } - -#else - - typedef T * this_type::*unspecified_bool_type; - - operator unspecified_bool_type() const // never throws - { - return ptr == 0? 0: &this_type::ptr; - } - -#endif - - bool operator! () const // never throws - { - return ptr == 0; - } +// implicit conversion to "bool" +#include void swap(scoped_array & b) // never throws { - T * tmp = b.ptr; - b.ptr = ptr; - ptr = tmp; + T * tmp = b.px; + b.px = px; + px = tmp; } - }; template inline void swap(scoped_array & a, scoped_array & b) // never throws diff --git a/include/boost/smart_ptr/scoped_ptr.hpp b/include/boost/smart_ptr/scoped_ptr.hpp index 518a254..df479e5 100644 --- a/include/boost/smart_ptr/scoped_ptr.hpp +++ b/include/boost/smart_ptr/scoped_ptr.hpp @@ -40,7 +40,7 @@ template class scoped_ptr // noncopyable { private: - T * ptr; + T * px; scoped_ptr(scoped_ptr const &); scoped_ptr & operator=(scoped_ptr const &); @@ -54,19 +54,19 @@ public: typedef T element_type; - explicit scoped_ptr(T * p = 0): ptr(p) // never throws + explicit scoped_ptr( T * p = 0 ): px( p ) // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - boost::sp_scalar_constructor_hook(ptr); + boost::sp_scalar_constructor_hook( px ); #endif } #ifndef BOOST_NO_AUTO_PTR - explicit scoped_ptr(std::auto_ptr p): ptr(p.release()) // never throws + explicit scoped_ptr( std::auto_ptr p ): px( p.release() ) // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - boost::sp_scalar_constructor_hook(ptr); + boost::sp_scalar_constructor_hook( px ); #endif } @@ -75,71 +75,42 @@ public: ~scoped_ptr() // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - boost::sp_scalar_destructor_hook(ptr); + boost::sp_scalar_destructor_hook( px ); #endif - boost::checked_delete(ptr); + boost::checked_delete( px ); } void reset(T * p = 0) // never throws { - BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors + BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors this_type(p).swap(*this); } T & operator*() const // never throws { - BOOST_ASSERT(ptr != 0); - return *ptr; + BOOST_ASSERT( px != 0 ); + return *px; } T * operator->() const // never throws { - BOOST_ASSERT(ptr != 0); - return ptr; + BOOST_ASSERT( px != 0 ); + return px; } T * get() const // never throws { - return ptr; + return px; } - // implicit conversion to "bool" - -#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) - - operator bool () const - { - return ptr != 0; - } - -#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) - typedef T * (this_type::*unspecified_bool_type)() const; - - operator unspecified_bool_type() const // never throws - { - return ptr == 0? 0: &this_type::get; - } - -#else - typedef T * this_type::*unspecified_bool_type; - - operator unspecified_bool_type() const // never throws - { - return ptr == 0? 0: &this_type::ptr; - } - -#endif - - bool operator! () const // never throws - { - return ptr == 0; - } +// implicit conversion to "bool" +#include void swap(scoped_ptr & b) // never throws { - T * tmp = b.ptr; - b.ptr = ptr; - ptr = tmp; + T * tmp = b.px; + b.px = px; + px = tmp; } }; diff --git a/include/boost/smart_ptr/shared_array.hpp b/include/boost/smart_ptr/shared_array.hpp index 7d68aa2..1f50403 100644 --- a/include/boost/smart_ptr/shared_array.hpp +++ b/include/boost/smart_ptr/shared_array.hpp @@ -94,54 +94,8 @@ public: return px; } - // implicit conversion to "bool" - -#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) - - operator bool () const - { - return px != 0; - } - -#elif defined( _MANAGED ) - - static void unspecified_bool( this_type*** ) - { - } - - typedef void (*unspecified_bool_type)( this_type*** ); - - operator unspecified_bool_type() const // never throws - { - return px == 0? 0: unspecified_bool; - } - -#elif \ - ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \ - ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) - - typedef T * (this_type::*unspecified_bool_type)() const; - - operator unspecified_bool_type() const // never throws - { - return px == 0? 0: &this_type::get; - } - -#else - - typedef T * this_type::*unspecified_bool_type; - - operator unspecified_bool_type() const // never throws - { - return px == 0? 0: &this_type::px; - } - -#endif - - bool operator! () const // never throws - { - return px == 0; - } +// implicit conversion to "bool" +#include bool unique() const // never throws { diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 78711ed..c7cdaf7 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -425,57 +425,8 @@ public: return px; } - // implicit conversion to "bool" - -#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__) - - operator bool () const - { - return px != 0; - } - -#elif defined( _MANAGED ) - - static void unspecified_bool( this_type*** ) - { - } - - typedef void (*unspecified_bool_type)( this_type*** ); - - operator unspecified_bool_type() const // never throws - { - return px == 0? 0: unspecified_bool; - } - -#elif \ - ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \ - ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \ - ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) ) - - typedef T * (this_type::*unspecified_bool_type)() const; - - operator unspecified_bool_type() const // never throws - { - return px == 0? 0: &this_type::get; - } - -#else - - typedef T * this_type::*unspecified_bool_type; - - operator unspecified_bool_type() const // never throws - { - return px == 0? 0: &this_type::px; - } - -#endif - - // operator! is redundant, but some compilers need it - - bool operator! () const // never throws - { - return px == 0; - } +// implicit conversion to "bool" +#include bool unique() const // never throws { From 68c939ec5a633fa69e92682c4eee4ec17726cf4c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 1 Mar 2009 18:54:51 +0000 Subject: [PATCH 006/210] Fix #includes in spinlock_test.cpp, spinlock_try_test.cpp, yield_k_test.cpp. [SVN r51519] --- test/spinlock_test.cpp | 2 +- test/spinlock_try_test.cpp | 2 +- test/yield_k_test.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/spinlock_test.cpp b/test/spinlock_test.cpp index 0820b96..d2c66c0 100644 --- a/test/spinlock_test.cpp +++ b/test/spinlock_test.cpp @@ -8,7 +8,7 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include +#include // Sanity check only diff --git a/test/spinlock_try_test.cpp b/test/spinlock_try_test.cpp index 59e3390..008b60e 100644 --- a/test/spinlock_try_test.cpp +++ b/test/spinlock_try_test.cpp @@ -8,7 +8,7 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include +#include #include // Sanity check only diff --git a/test/yield_k_test.cpp b/test/yield_k_test.cpp index 1e6ab13..593c13d 100644 --- a/test/yield_k_test.cpp +++ b/test/yield_k_test.cpp @@ -8,7 +8,7 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include +#include // Sanity check only From 9c55fbc6c22533e034d9d9877066fc047755d812 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 3 Mar 2009 19:25:26 +0000 Subject: [PATCH 007/210] Fix enable_shared_from_this-related tickets in trunk. Refs #2126. Refs #2584. [SVN r51581] --- .../smart_ptr/enable_shared_from_this.hpp | 36 ++- include/boost/smart_ptr/make_shared.hpp | 154 +++++++--- include/boost/smart_ptr/shared_ptr.hpp | 31 +- test/Jamfile.v2 | 4 + test/allocate_shared_esft_test.cpp | 264 ++++++++++++++++++ test/allocate_shared_test.cpp | 9 + test/esft_constructor_test.cpp | 169 ----------- test/esft_second_ptr_test.cpp | 51 ++++ test/esft_void_test.cpp | 41 +++ test/make_shared_esft_test.cpp | 263 +++++++++++++++++ test/make_shared_test.cpp | 9 + test/shared_from_this_test.cpp | 43 ++- test/shared_ptr_move_test.cpp | 11 + test/sp_accept_owner_test.cpp | 146 ---------- 14 files changed, 824 insertions(+), 407 deletions(-) create mode 100644 test/allocate_shared_esft_test.cpp delete mode 100644 test/esft_constructor_test.cpp create mode 100644 test/esft_second_ptr_test.cpp create mode 100644 test/esft_void_test.cpp create mode 100644 test/make_shared_esft_test.cpp delete mode 100644 test/sp_accept_owner_test.cpp diff --git a/include/boost/smart_ptr/enable_shared_from_this.hpp b/include/boost/smart_ptr/enable_shared_from_this.hpp index ed9aadd..f7b1445 100644 --- a/include/boost/smart_ptr/enable_shared_from_this.hpp +++ b/include/boost/smart_ptr/enable_shared_from_this.hpp @@ -4,11 +4,11 @@ // // enable_shared_from_this.hpp // -// Copyright (c) 2002 Peter Dimov +// Copyright 2002, 2009 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) +// 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 // // http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html // @@ -46,26 +46,32 @@ public: shared_ptr shared_from_this() { - shared_ptr p(_internal_weak_this); - BOOST_ASSERT(p.get() == this); + shared_ptr p( weak_this_ ); + BOOST_ASSERT( p.get() == this ); return p; } shared_ptr shared_from_this() const { - shared_ptr p(_internal_weak_this); - BOOST_ASSERT(p.get() == this); + shared_ptr p( weak_this_ ); + BOOST_ASSERT( p.get() == this ); return p; } -// Note: No, you don't need to initialize _internal_weak_this -// -// Please read the documentation, not the code -// -// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html +public: // actually private, but avoids compiler template friendship issues - typedef T _internal_element_type; // for bcc 5.5.1 - mutable weak_ptr<_internal_element_type> _internal_weak_this; + // Note: invoked automatically by shared_ptr; do not call + template void _internal_accept_owner( shared_ptr const * ppx, Y * py ) const + { + if( weak_this_.expired() ) + { + weak_this_ = shared_ptr( *ppx, py ); + } + } + +private: + + mutable weak_ptr weak_this_; }; } // namespace boost diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp index 25b9cf0..7e1e793 100644 --- a/include/boost/smart_ptr/make_shared.hpp +++ b/include/boost/smart_ptr/make_shared.hpp @@ -105,10 +105,13 @@ template< class T > boost::shared_ptr< T > make_shared() void * pv = pd->address(); - new( pv ) T(); + ::new( pv ) T(); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 ) @@ -119,10 +122,13 @@ template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a void * pv = pd->address(); - new( pv ) T(); + ::new( pv ) T(); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 ) @@ -137,10 +143,13 @@ template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && . void * pv = pd->address(); - new( pv ) T( detail::forward( args )... ); + ::new( pv ) T( detail::forward( args )... ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args ) @@ -151,10 +160,13 @@ template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shar void * pv = pd->address(); - new( pv ) T( detail::forward( args )... ); + ::new( pv ) T( detail::forward( args )... ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); } #else @@ -170,10 +182,13 @@ boost::shared_ptr< T > make_shared( A1 const & a1 ) void * pv = pd->address(); - new( pv ) T( a1 ); + ::new( pv ) T( a1 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -185,10 +200,13 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 ) void * pv = pd->address(); - new( pv ) T( a1 ); + ::new( pv ) T( a1 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -200,10 +218,13 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 ) void * pv = pd->address(); - new( pv ) T( a1, a2 ); + ::new( pv ) T( a1, a2 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -215,10 +236,13 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a void * pv = pd->address(); - new( pv ) T( a1, a2 ); + ::new( pv ) T( a1, a2 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -230,10 +254,13 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 void * pv = pd->address(); - new( pv ) T( a1, a2, a3 ); + ::new( pv ) T( a1, a2, a3 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -245,10 +272,13 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a void * pv = pd->address(); - new( pv ) T( a1, a2, a3 ); + ::new( pv ) T( a1, a2, a3 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -260,10 +290,13 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4 ); + ::new( pv ) T( a1, a2, a3, a4 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -275,10 +308,13 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4 ); + ::new( pv ) T( a1, a2, a3, a4 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -290,10 +326,13 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4, a5 ); + ::new( pv ) T( a1, a2, a3, a4, a5 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -305,10 +344,13 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4, a5 ); + ::new( pv ) T( a1, a2, a3, a4, a5 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -320,10 +362,13 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4, a5, a6 ); + ::new( pv ) T( a1, a2, a3, a4, a5, a6 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -335,10 +380,13 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4, a5, a6 ); + ::new( pv ) T( a1, a2, a3, a4, a5, a6 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -350,10 +398,13 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -365,10 +416,13 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -380,10 +434,13 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -395,10 +452,13 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -410,10 +470,13 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + 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 > @@ -425,10 +488,13 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a void * pv = pd->address(); - new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); pd->set_initialized(); - return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) ); + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); } #endif diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index c7cdaf7..0812c04 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -58,6 +58,7 @@ namespace boost { +template class shared_ptr; template class weak_ptr; template class enable_shared_from_this; @@ -100,9 +101,12 @@ template<> struct shared_ptr_traits // enable_shared_from_this support -template void sp_enable_shared_from_this( shared_count const & pn, boost::enable_shared_from_this const * pe, Y const * px ) +template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe ) { - if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast(px), pn); + if( pe != 0 ) + { + pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); + } } #ifdef _MANAGED @@ -114,25 +118,16 @@ struct sp_any_pointer template sp_any_pointer( T* ) {} }; -inline void sp_enable_shared_from_this( shared_count const & /*pn*/, sp_any_pointer, sp_any_pointer ) +inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer ) { } #else // _MANAGED -#ifdef sgi -// Turn off: the last argument of the varargs function "sp_enable_shared_from_this" is unnamed -# pragma set woff 3506 -#endif - -inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) +inline void sp_enable_shared_from_this( ... ) { } -#ifdef sgi -# pragma reset woff 3506 -#endif - #endif // _MANAGED #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR ) @@ -182,7 +177,7 @@ public: template explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete { - boost::detail::sp_enable_shared_from_this( pn, p, p ); + boost::detail::sp_enable_shared_from_this( this, p, p ); } // @@ -193,14 +188,14 @@ public: template shared_ptr(Y * p, D d): px(p), pn(p, d) { - boost::detail::sp_enable_shared_from_this( pn, p, p ); + boost::detail::sp_enable_shared_from_this( this, p, 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( pn, p, p ); + boost::detail::sp_enable_shared_from_this( this, p, p ); } // generated copy constructor, assignment, destructor are fine... @@ -288,7 +283,7 @@ public: { Y * tmp = r.get(); pn = boost::detail::shared_count(r); - boost::detail::sp_enable_shared_from_this( pn, tmp, tmp ); + boost::detail::sp_enable_shared_from_this( this, tmp, tmp ); } #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) @@ -298,7 +293,7 @@ public: { typename Ap::element_type * tmp = r.get(); pn = boost::detail::shared_count( r ); - boost::detail::sp_enable_shared_from_this( pn, tmp, tmp ); + boost::detail::sp_enable_shared_from_this( this, tmp, tmp ); } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 5f68e20..34cd5f1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -48,5 +48,9 @@ import testing ; [ run ip_convertible_test.cpp ] [ run allocate_shared_test.cpp ] [ run sp_atomic_test.cpp ] + [ run esft_void_test.cpp ] + [ run esft_second_ptr_test.cpp ] + [ run make_shared_esft_test.cpp ] + [ run allocate_shared_esft_test.cpp ] ; } diff --git a/test/allocate_shared_esft_test.cpp b/test/allocate_shared_esft_test.cpp new file mode 100644 index 0000000..2bb8ccc --- /dev/null +++ b/test/allocate_shared_esft_test.cpp @@ -0,0 +1,264 @@ +// allocate_shared_esft_test.cpp +// +// Copyright 2007-2009 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: public boost::enable_shared_from_this +{ +private: + + X( X const & ); + X & operator=( X const & ); + +public: + + static int instances; + + explicit X( int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0 ) + { + ++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() ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator(), 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator(), 1, 2 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator(), 1, 2, 3 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator(), 1, 2, 3, 4 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator(), 1, 2, 3, 4, 5 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator(), 1, 2, 3, 4, 5, 6 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator(), 1, 2, 3, 4, 5, 6, 7 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator(), 1, 2, 3, 4, 5, 6, 7, 8 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator(), 1, 2, 3, 4, 5, 6, 7, 8, 9 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + return boost::report_errors(); +} diff --git a/test/allocate_shared_test.cpp b/test/allocate_shared_test.cpp index 71ee948..97808c2 100644 --- a/test/allocate_shared_test.cpp +++ b/test/allocate_shared_test.cpp @@ -10,6 +10,7 @@ #include #include #include +#include class X { @@ -18,6 +19,14 @@ private: X( X const & ); X & operator=( X const & ); + void * operator new( std::size_t ); + + void operator delete( void * p ) + { + // lack of this definition causes link errors on MSVC + ::operator delete( p ); + } + public: static int instances; diff --git a/test/esft_constructor_test.cpp b/test/esft_constructor_test.cpp deleted file mode 100644 index 737123e..0000000 --- a/test/esft_constructor_test.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// -// esft_constructor_test.cpp -// -// A test for the new enable_shared_from_this support for calling -// shared_from_this from constructors (that is, prior to the -// object's ownership being passed to an external shared_ptr). -// -// Copyright (c) 2008 Frank Mori Hess -// 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 -#include -#include -#include - -class X: public boost::enable_shared_from_this< X > -{ -private: - - int destroyed_; - int deleted_; - int expected_; - -private: - - X( X const& ); - X& operator=( X const& ); - -public: - - static int instances; - -public: - - explicit X( int expected, boost::shared_ptr *early_px = 0 ): destroyed_( 0 ), deleted_( 0 ), expected_( expected ) - { - ++instances; - if( early_px ) *early_px = shared_from_this(); - } - - ~X() - { - BOOST_TEST( deleted_ == expected_ ); - BOOST_TEST( destroyed_ == 0 ); - ++destroyed_; - --instances; - } - - typedef void (*deleter_type)( X* ); - - static void deleter( X * px ) - { - ++px->deleted_; - } - - static void deleter2( X * px ) - { - ++px->deleted_; - delete px; - } -}; - -int X::instances = 0; - -template -bool are_shared_owners(const boost::shared_ptr &a, const boost::shared_ptr &b) -{ - return !(a < b) && !(b < a); -} - -struct Y: public boost::enable_shared_from_this -{}; - -int main() -{ - BOOST_TEST( X::instances == 0 ); - - { - boost::shared_ptr early_px; - X* x = new X( 1, &early_px ); - BOOST_TEST( early_px.use_count() > 0 ); - BOOST_TEST( boost::get_deleter(early_px) == 0 ); - boost::shared_ptr px( x, &X::deleter2 ); - BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 ); - BOOST_TEST(are_shared_owners(early_px, px)); - px.reset(); - BOOST_TEST( early_px.use_count() == 1 ); - BOOST_TEST( X::instances == 1 ); - X::deleter_type *pd = boost::get_deleter(early_px); - BOOST_TEST(pd && *pd == &X::deleter2 ); - } - - BOOST_TEST( X::instances == 0 ); - - { - boost::shared_ptr early_px; - X* x = new X( 1, &early_px ); - boost::weak_ptr early_weak_px = early_px; - early_px.reset(); - BOOST_TEST( !early_weak_px.expired() ); - boost::shared_ptr px( x, &X::deleter2 ); - BOOST_TEST( px.use_count() == 1 ); - BOOST_TEST( X::instances == 1 ); - BOOST_TEST(are_shared_owners(early_weak_px.lock(), px)); - px.reset(); - BOOST_TEST( early_weak_px.expired() ); - } - - BOOST_TEST( X::instances == 0 ); - - { - boost::shared_ptr early_px; - X x( 1, &early_px ); - BOOST_TEST( early_px.use_count() > 0 ); - boost::shared_ptr px( &x, &X::deleter ); - BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 ); - early_px.reset(); - BOOST_TEST( px.use_count() == 1 ); - BOOST_TEST( X::instances == 1 ); - px.reset(); - try - { - x.shared_from_this(); - BOOST_ERROR("x did not throw bad_weak_ptr"); - } - catch( const boost::bad_weak_ptr &err) - {} - } - - BOOST_TEST( X::instances == 0 ); - - { - boost::weak_ptr early_weak_px; - { - boost::shared_ptr early_px; - X x( 0, &early_px ); - early_weak_px = early_px; - early_px.reset(); - BOOST_TEST( !early_weak_px.expired() ); - BOOST_TEST( X::instances == 1 ); - } - BOOST_TEST( early_weak_px.expired() ); - } - - BOOST_TEST( X::instances == 0 ); - - { - boost::shared_ptr px(new Y()); - Y y(*px); - px.reset(); - try - { - y.shared_from_this(); - } - catch( const boost::bad_weak_ptr &err) - { - BOOST_ERROR("y threw bad_weak_ptr"); - } - } - - return boost::report_errors(); -} diff --git a/test/esft_second_ptr_test.cpp b/test/esft_second_ptr_test.cpp new file mode 100644 index 0000000..0600667 --- /dev/null +++ b/test/esft_second_ptr_test.cpp @@ -0,0 +1,51 @@ +// +// esft_second_ptr_test.cpp +// +// This test has been extracted from a real +// scenario that occurs in Boost.Python +// +// Copyright 2009 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 X: public boost::enable_shared_from_this +{ +}; + +void null_deleter( void const* ) +{ +} + +int main() +{ + boost::shared_ptr px( new X ); + + { + boost::shared_ptr px2( px.get(), null_deleter ); + BOOST_TEST( px == px2 ); + } + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + + return boost::report_errors(); +} diff --git a/test/esft_void_test.cpp b/test/esft_void_test.cpp new file mode 100644 index 0000000..b28c669 --- /dev/null +++ b/test/esft_void_test.cpp @@ -0,0 +1,41 @@ +// +// esft_void_test.cpp +// +// Copyright 2009 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 X: public boost::enable_shared_from_this +{ +}; + +int main() +{ + boost::shared_ptr< void const volatile > pv( new X ); + boost::shared_ptr< void > pv2 = boost::const_pointer_cast< void >( pv ); + boost::shared_ptr< X > px = boost::static_pointer_cast< X >( pv2 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + + return boost::report_errors(); +} diff --git a/test/make_shared_esft_test.cpp b/test/make_shared_esft_test.cpp new file mode 100644 index 0000000..1956cba --- /dev/null +++ b/test/make_shared_esft_test.cpp @@ -0,0 +1,263 @@ +// make_shared_esft_test.cpp +// +// Copyright 2007-2009 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: public boost::enable_shared_from_this +{ +private: + + X( X const & ); + X & operator=( X const & ); + +public: + + static int instances; + + explicit X( int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0 ) + { + ++instances; + } + + ~X() + { + --instances; + } +}; + +int X::instances = 0; + +int main() +{ + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared< X >(); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared< X >( 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + return boost::report_errors(); +} diff --git a/test/make_shared_test.cpp b/test/make_shared_test.cpp index 9930e31..474d1c5 100644 --- a/test/make_shared_test.cpp +++ b/test/make_shared_test.cpp @@ -10,6 +10,7 @@ #include #include #include +#include class X { @@ -18,6 +19,14 @@ private: X( X const & ); X & operator=( X const & ); + void * operator new( std::size_t ); + + void operator delete( void * p ) + { + // lack of this definition causes link errors on MSVC + ::operator delete( p ); + } + public: static int instances; diff --git a/test/shared_from_this_test.cpp b/test/shared_from_this_test.cpp index 61515bd..68d6098 100644 --- a/test/shared_from_this_test.cpp +++ b/test/shared_from_this_test.cpp @@ -55,16 +55,23 @@ void test() BOOST_TEST(py.get() != 0); BOOST_TEST(py.use_count() == 1); - boost::shared_ptr px = py->getX(); - BOOST_TEST(px.get() != 0); - BOOST_TEST(py.use_count() == 2); + try + { + boost::shared_ptr px = py->getX(); + BOOST_TEST(px.get() != 0); + BOOST_TEST(py.use_count() == 2); - px->f(); + px->f(); - boost::shared_ptr py2 = boost::dynamic_pointer_cast(px); - BOOST_TEST(py.get() == py2.get()); - BOOST_TEST(!(py < py2 || py2 < py)); - BOOST_TEST(py.use_count() == 3); + boost::shared_ptr py2 = boost::dynamic_pointer_cast(px); + BOOST_TEST(py.get() == py2.get()); + BOOST_TEST(!(py < py2 || py2 < py)); + BOOST_TEST(py.use_count() == 3); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "py->getX() failed" ); + } } void test2(); @@ -124,19 +131,25 @@ void test3() { boost::shared_ptr p(new V); - boost::shared_ptr q = p->shared_from_this(); - BOOST_TEST(p == q); - BOOST_TEST(!(p < q) && !(q < p)); + try + { + boost::shared_ptr q = p->shared_from_this(); + BOOST_TEST(p == q); + BOOST_TEST(!(p < q) && !(q < p)); + } + catch( boost::bad_weak_ptr const & ) + { + BOOST_ERROR( "p->shared_from_this() failed" ); + } V v2(*p); try { boost::shared_ptr r = v2.shared_from_this(); - BOOST_TEST( p < r || r < p ); - BOOST_TEST( r.get() == &v2 ); + BOOST_ERROR("v2.shared_from_this() failed to throw"); } - catch(boost::bad_weak_ptr const &) + catch( boost::bad_weak_ptr const & ) { } @@ -147,7 +160,7 @@ void test3() BOOST_TEST(p == r); BOOST_TEST(!(p < r) && !(r < p)); } - catch(boost::bad_weak_ptr const &) + catch( boost::bad_weak_ptr const & ) { BOOST_ERROR("p->shared_from_this() threw bad_weak_ptr after *p = V()"); } diff --git a/test/shared_ptr_move_test.cpp b/test/shared_ptr_move_test.cpp index 8814d3d..bd785e4 100644 --- a/test/shared_ptr_move_test.cpp +++ b/test/shared_ptr_move_test.cpp @@ -8,6 +8,8 @@ // http://www.boost.org/LICENSE_1_0.txt // +#if defined( BOOST_HAS_RVALUE_REFS ) + #include #include @@ -93,3 +95,12 @@ int main() return boost::report_errors(); } + +#else // !defined( BOOST_HAS_RVALUE_REFS ) + +int main() +{ + return 0; +} + +#endif diff --git a/test/sp_accept_owner_test.cpp b/test/sp_accept_owner_test.cpp deleted file mode 100644 index e8d1b32..0000000 --- a/test/sp_accept_owner_test.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// -// sp_accept_owner_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 -#include - -namespace N -{ - -struct D; - -struct X -{ - X * px_; - - D * pd_; - void * pv_; - - X(): px_( 0 ), pd_( 0 ), pv_( 0 ) - { - } -}; - -struct D -{ - template void operator()( T * p ) const { delete p; } -}; - -} // namespace N - -#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) - -namespace N -{ - -#else - -namespace boost -{ - -#endif - -template inline void sp_accept_owner( boost::shared_ptr * ps, ::N::X * px ) -{ - std::cout << "sp_accept_owner( " << ps << ", " << px << " )\n"; - - BOOST_TEST( ps->get() == px ); - - if( px != 0 ) - { - px->px_ = px; - } -} - -template inline void sp_accept_owner( boost::shared_ptr * ps, ::N::X * px, ::N::D * pd ) -{ - std::cout << "sp_accept_owner( " << ps << ", " << px << ", (D*)" << pd << " )\n"; - - BOOST_TEST( ps->get() == px ); - - if( px != 0 ) - { - px->px_ = px; - px->pd_ = pd; - } -} - -template inline void sp_accept_owner( boost::shared_ptr * ps, ::N::X * px, void * pv ) -{ - std::cout << "sp_accept_owner( " << ps << ", " << px << ", (void*)" << pv << " )\n"; - - BOOST_TEST( ps->get() == px ); - - if( px != 0 ) - { - px->px_ = px; - px->pv_ = pv; - } -} - -} // namespace N or boost - -struct D2 -{ - template void operator()( T * p ) const { delete p; } -}; - -template void test( T* = 0 ) -{ - { - boost::shared_ptr p( static_cast< T* >( 0 ) ); - } - - { - T * p = new T; - boost::shared_ptr q( p ); - - BOOST_TEST( q->px_ == p ); - BOOST_TEST( q->pd_ == 0 ); - BOOST_TEST( q->pv_ == 0 ); - } - - { - T * p = new T; - boost::shared_ptr q( p, N::D() ); - - BOOST_TEST( q->px_ == p ); - BOOST_TEST( q->pd_ != 0 ); - BOOST_TEST( q->pv_ == 0 ); - } - - { - T * p = new T; - boost::shared_ptr q( p, D2() ); - - BOOST_TEST( q->px_ == p ); - BOOST_TEST( q->pd_ == 0 ); - BOOST_TEST( q->pv_ != 0 ); - } -} - -namespace N2 -{ - -struct Y: public virtual N::X -{ -}; - -} // namespace N2 - -int main() -{ - test(); - test(); - - return boost::report_errors(); -} From 0610947c4a7141e209b2ac6caca0790da17d06f3 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 7 Mar 2009 22:21:56 +0000 Subject: [PATCH 008/210] De-optimize assignment into this_type(r).swap(*this) - turns out that they were not equivalent, leading to leaks in contrived cases. Refs #2813. [SVN r51643] --- include/boost/smart_ptr/shared_ptr.hpp | 27 +++--- test/Jamfile.v2 | 4 + test/sp_recursive_assign2_rv_test.cpp | 114 +++++++++++++++++++++++ test/sp_recursive_assign2_test.cpp | 122 +++++++++++++++++++++++++ test/sp_recursive_assign_rv_test.cpp | 114 +++++++++++++++++++++++ test/sp_recursive_assign_test.cpp | 122 +++++++++++++++++++++++++ 6 files changed, 487 insertions(+), 16 deletions(-) create mode 100644 test/sp_recursive_assign2_rv_test.cpp create mode 100644 test/sp_recursive_assign2_test.cpp create mode 100644 test/sp_recursive_assign_rv_test.cpp create mode 100644 test/sp_recursive_assign_test.cpp diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 0812c04..0ce3b97 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -198,19 +198,7 @@ public: boost::detail::sp_enable_shared_from_this( this, p, p ); } -// generated copy constructor, assignment, destructor are fine... - -// except that Borland C++ has a bug, and g++ with -Wsynth warns -#if defined(__BORLANDC__) || defined(__GNUC__) - - shared_ptr & operator=(shared_ptr const & r) // never throws - { - px = r.px; - pn = r.pn; // shared_count::op= doesn't throw - return *this; - } - -#endif +// generated copy constructor, destructor are fine template explicit shared_ptr(weak_ptr const & r): pn(r.pn) // may throw @@ -301,13 +289,20 @@ public: #endif // BOOST_NO_AUTO_PTR -#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) + // assignment + + shared_ptr & operator=( shared_ptr const & r ) // never throws + { + this_type(r).swap(*this); + return *this; + } + +#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400) template shared_ptr & operator=(shared_ptr const & r) // never throws { - px = r.px; - pn = r.pn; // shared_count::op= doesn't throw + this_type(r).swap(*this); return *this; } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 34cd5f1..c862197 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -52,5 +52,9 @@ import testing ; [ run esft_second_ptr_test.cpp ] [ run make_shared_esft_test.cpp ] [ run allocate_shared_esft_test.cpp ] + [ run sp_recursive_assign_test.cpp ] + [ run sp_recursive_assign2_test.cpp ] + [ run sp_recursive_assign_rv_test.cpp ] + [ run sp_recursive_assign2_rv_test.cpp ] ; } diff --git a/test/sp_recursive_assign2_rv_test.cpp b/test/sp_recursive_assign2_rv_test.cpp new file mode 100644 index 0000000..e450c72 --- /dev/null +++ b/test/sp_recursive_assign2_rv_test.cpp @@ -0,0 +1,114 @@ +// +// sp_recursive_assign2_rv_test.cpp +// +// Copyright 2009 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 X +{ +public: + + static int instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + +private: + + X( X const& ); +}; + +int X::instances = 0; + +class Y +{ +public: + + static int instances; + + Y() + { + ++instances; + } + + ~Y() + { + --instances; + } + +private: + + Y( Y const& ); +}; + +int Y::instances = 0; + +static boost::shared_ptr s_pv; + +class Z +{ +public: + + static int instances; + + Z() + { + ++instances; + } + + ~Z() + { + --instances; + s_pv = boost::shared_ptr( new Y ); + } + +private: + + Z( Z const& ); +}; + +int Z::instances = 0; + +int main() +{ + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 0 ); + + s_pv = boost::shared_ptr( new Z ); + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 1 ); + + s_pv = boost::shared_ptr( new X ); + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 1 ); + BOOST_TEST( Z::instances == 0 ); + + s_pv = boost::shared_ptr(); + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 0 ); + + return boost::report_errors(); +} diff --git a/test/sp_recursive_assign2_test.cpp b/test/sp_recursive_assign2_test.cpp new file mode 100644 index 0000000..ef6fa52 --- /dev/null +++ b/test/sp_recursive_assign2_test.cpp @@ -0,0 +1,122 @@ +// +// sp_recursive_assign2_test.cpp +// +// Copyright 2009 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 X +{ +public: + + static int instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + +private: + + X( X const& ); +}; + +int X::instances = 0; + +class Y +{ +public: + + static int instances; + + Y() + { + ++instances; + } + + ~Y() + { + --instances; + } + +private: + + Y( Y const& ); +}; + +int Y::instances = 0; + +static boost::shared_ptr s_pv; + +class Z +{ +public: + + static int instances; + + Z() + { + ++instances; + } + + ~Z() + { + --instances; + + boost::shared_ptr pv( new Y ); + s_pv = pv; + } + +private: + + Z( Z const& ); +}; + +int Z::instances = 0; + +int main() +{ + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 0 ); + + { + boost::shared_ptr pv( new Z ); + s_pv = pv; + } + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 1 ); + + { + boost::shared_ptr pv( new X ); + s_pv = pv; + } + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 1 ); + BOOST_TEST( Z::instances == 0 ); + + s_pv.reset(); + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 0 ); + + return boost::report_errors(); +} diff --git a/test/sp_recursive_assign_rv_test.cpp b/test/sp_recursive_assign_rv_test.cpp new file mode 100644 index 0000000..8d80e72 --- /dev/null +++ b/test/sp_recursive_assign_rv_test.cpp @@ -0,0 +1,114 @@ +// +// sp_recursive_assign_rv_test.cpp +// +// Copyright 2009 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 X +{ +public: + + static int instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + +private: + + X( X const& ); +}; + +int X::instances = 0; + +class Y +{ +public: + + static int instances; + + Y() + { + ++instances; + } + + ~Y() + { + --instances; + } + +private: + + Y( Y const& ); +}; + +int Y::instances = 0; + +static boost::shared_ptr s_pv; + +class Z +{ +public: + + static int instances; + + Z() + { + ++instances; + } + + ~Z() + { + --instances; + s_pv = boost::shared_ptr( new Y ); + } + +private: + + Z( Z const& ); +}; + +int Z::instances = 0; + +int main() +{ + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 0 ); + + s_pv = boost::shared_ptr( new Z ); + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 1 ); + + s_pv = boost::shared_ptr( new X ); + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 1 ); + BOOST_TEST( Z::instances == 0 ); + + s_pv = boost::shared_ptr(); + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 0 ); + + return boost::report_errors(); +} diff --git a/test/sp_recursive_assign_test.cpp b/test/sp_recursive_assign_test.cpp new file mode 100644 index 0000000..0f36891 --- /dev/null +++ b/test/sp_recursive_assign_test.cpp @@ -0,0 +1,122 @@ +// +// sp_recursive_assign_test.cpp +// +// Copyright 2009 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 X +{ +public: + + static int instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + +private: + + X( X const& ); +}; + +int X::instances = 0; + +class Y +{ +public: + + static int instances; + + Y() + { + ++instances; + } + + ~Y() + { + --instances; + } + +private: + + Y( Y const& ); +}; + +int Y::instances = 0; + +static boost::shared_ptr s_pv; + +class Z +{ +public: + + static int instances; + + Z() + { + ++instances; + } + + ~Z() + { + --instances; + + boost::shared_ptr pv( new Y ); + s_pv = pv; + } + +private: + + Z( Z const& ); +}; + +int Z::instances = 0; + +int main() +{ + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 0 ); + + { + boost::shared_ptr pv( new Z ); + s_pv = pv; + } + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 1 ); + + { + boost::shared_ptr pv( new X ); + s_pv = pv; + } + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 1 ); + BOOST_TEST( Z::instances == 0 ); + + s_pv.reset(); + + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( Y::instances == 0 ); + BOOST_TEST( Z::instances == 0 ); + + return boost::report_errors(); +} From dc3ffc5f4b3cc82ab6cf0a6ea2dae5ab3d249c9f Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 10 Mar 2009 18:07:13 +0000 Subject: [PATCH 009/210] Attempt to fix como link failure. [SVN r51686] --- test/allocate_shared_test.cpp | 12 +++++++++--- test/make_shared_test.cpp | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/test/allocate_shared_test.cpp b/test/allocate_shared_test.cpp index 97808c2..bdae793 100644 --- a/test/allocate_shared_test.cpp +++ b/test/allocate_shared_test.cpp @@ -1,6 +1,6 @@ -// allocate_shared_test.cpp +// allocate_shared_test.cpp // -// Copyright (c) 2007, 2008 Peter Dimov +// Copyright 2007-2009 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at @@ -19,11 +19,17 @@ private: X( X const & ); X & operator=( X const & ); - void * operator new( std::size_t ); + void * operator new( std::size_t n ) + { + // lack of this definition causes link errors on Comeau C++ + BOOST_ERROR( "private X::new called" ); + return ::operator new( n ); + } void operator delete( void * p ) { // lack of this definition causes link errors on MSVC + BOOST_ERROR( "private X::delete called" ); ::operator delete( p ); } diff --git a/test/make_shared_test.cpp b/test/make_shared_test.cpp index 474d1c5..9ebc3fa 100644 --- a/test/make_shared_test.cpp +++ b/test/make_shared_test.cpp @@ -1,6 +1,6 @@ -// make_shared_test.cpp +// make_shared_test.cpp // -// Copyright (c) 2007, 2008 Peter Dimov +// Copyright 2007-2009 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at @@ -19,11 +19,17 @@ private: X( X const & ); X & operator=( X const & ); - void * operator new( std::size_t ); + void * operator new( std::size_t n ) + { + // lack of this definition causes link errors on Comeau C++ + BOOST_ERROR( "private X::new called" ); + return ::operator new( n ); + } void operator delete( void * p ) { // lack of this definition causes link errors on MSVC + BOOST_ERROR( "private X::delete called" ); ::operator delete( p ); } From fbc6919eae7bbdc0a4b8924ebcc582c6df782102 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Wed, 11 Mar 2009 13:48:51 +0000 Subject: [PATCH 010/210] Adding documentation for make_shared and allocate_shared to smart_ptr docs. It is adopted from n2351 "Improving shared_ptr for C++0x, Revision 2". Also includes some minor corrections. Refs #1897 [SVN r51699] --- make_shared.html | 119 ++++++++++++++++++ shared_ptr.htm | 309 ++++++++++++++++++++++++----------------------- smart_ptr.htm | 159 ++++++++++++------------ 3 files changed, 361 insertions(+), 226 deletions(-) create mode 100644 make_shared.html diff --git a/make_shared.html b/make_shared.html new file mode 100644 index 0000000..e47fe2a --- /dev/null +++ b/make_shared.html @@ -0,0 +1,119 @@ + + + + make_shared and allocate_shared + + + +

boost.png (6897 bytes)make_shared and allocate_shared function templates

+

Introduction
+ Synopsis
+ Free Functions
+ Example
+

Introduction

+

Consistent use of shared_ptr + can eliminate the need to use an explicit delete, + but alone it provides no support in avoiding explicit new. + There have been repeated requests from users for a factory function that creates + an object of a given type and returns a shared_ptr to it. + Besides convenience and style, such a function is also exception safe and + considerably faster because it can use a single allocation for both the object + and its corresponding control block, eliminating a significant portion of + shared_ptr's construction overhead. + This eliminates one of the major efficiency complaints about shared_ptr. +

+

The header file <boost/make_shared.hpp> provides a family of overloaded 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.

+

+ The rationale for choosing the name make_shared is that the expression + make_shared<Widget>() can be read aloud and conveys the intended meaning.

+

Synopsis

+
namespace boost {
+
+  template<typename T> class shared_ptr;
+
+  template<typename T>
+    shared_ptr<T> make_shared();
+
+  template<typename T, typename A>
+    shared_ptr<T> allocate_shared( A const & );
+
+#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )	// C++0x prototypes
+
+  template<typename T, typename... Args>
+    shared_ptr<T> make_shared( Args && ... args );
+
+  template<typename T, typename A, typename... Args>
+    shared_ptr<T> allocate_shared( A const & a, Args && ... args );
+
+#else // no C++0X support
+
+  template<typename T, typename Arg1 >
+    shared_ptr<T> make_shared( Arg1 const & arg1 );
+  template<typename T, typename Arg1, typename Arg2 >
+    shared_ptr<T> make_shared( Arg1 const & arg1, Arg2 const & arg2 );
+// ...
+  template<typename T, typename Arg1, typename Arg2, ..., typename ArgN >
+    shared_ptr<T> make_shared( Arg1 const & arg1, Arg2 const & arg2, ..., ArgN const & argN );
+
+  template<typename T, typename A, typename Arg1 >
+    shared_ptr<T> allocate_shared( A const & a, Arg1 const & arg1 );
+  template<typename T, typename A, typename Arg1, typename Arg2 >
+    shared_ptr<T> allocate_shared( Arg1 const & arg1, Arg2 const & arg2 );
+// ...
+  template<typename T, typename A, typename Arg1, typename Arg2, ..., typename ArgN >
+    shared_ptr<T> allocate_shared( A const & a, Arg1 const & arg1, Arg2 const & arg2, ..., ArgN const & argN );
+
+#endif
+}
+

Free Functions

+
template<class T, class... Args>
+    shared_ptr<T> make_shared( Args && ... args );
+template<class T, class A, class... Args>
+    shared_ptr<T> allocate_shared( A const & a, Args && ... args );
+
+

Requires: The expression new( pv ) T( std::forward<Args>(args)... ), + where pv 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 object of type T + and constructs an object in it via the placement new expression new( pv ) T() + or new( pv ) T( std::forward<Args>(args)... ). + allocate_shared uses a copy of a 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 object of type T.

+

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 object of type T in a single + allocation. This provides efficiency equivalent to an intrusive smart pointer.

+

The prototypes shown above are used if your compiler supports rvalue references + and variadic templates. They perfectly forward the args parameters to + the constructors of T.

+

Otherwise, the implementation will fall back on + forwarding the arguments to the constructors of T as const references. + If you need to pass a non-const reference to a constructor of T, + you may do so by wrapping the parameter in a call to boost::ref. + In addition, you will be + limited to a maximum of 9 arguments (not counting the allocator argument of + allocate_shared).

+
+

Example

+
boost::shared_ptr<std::string> x = boost::make_shared<std::string>("hello, world!");
+std::cout << *x;
+
+

+ $Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $

+

Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess. + 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/shared_ptr.htm b/shared_ptr.htm index 5b4444f..77e1fa8 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -19,54 +19,54 @@ Smart Pointer Timings
Programming Techniques

Introduction

-

The shared_ptr class template stores a pointer to a dynamically allocated - object, typically with a C++ new-expression. The object pointed to is - guaranteed to be deleted when the last shared_ptr pointing to it is +

The shared_ptr class template stores a pointer to a dynamically allocated + object, typically with a C++ new-expression. The object pointed to is + guaranteed to be deleted when the last shared_ptr pointing to it is destroyed or reset. See the example.

-

Every shared_ptr meets the CopyConstructible and Assignable - requirements of the C++ Standard Library, and so can be used in standard - library containers. Comparison operators are supplied so that shared_ptr +

Every shared_ptr meets the CopyConstructible and Assignable + requirements of the C++ Standard Library, and so can be used in standard + library containers. Comparison operators are supplied so that shared_ptr works with the standard library's associative containers.

-

Normally, a shared_ptr cannot correctly hold a pointer to a dynamically - allocated array. See shared_array for +

Normally, a shared_ptr cannot correctly hold a pointer to a dynamically + allocated array. See shared_array for that usage.

-

Because the implementation uses reference counting, cycles of shared_ptr instances +

Because the implementation uses reference counting, cycles of shared_ptr instances will not be reclaimed. For example, if main() holds a shared_ptr to A, which directly or indirectly holds a shared_ptr back to A, - A's use count will be 2. Destruction of the original shared_ptr will + A's use count will be 2. Destruction of the original shared_ptr will leave A dangling with a use count of 1. Use weak_ptr to "break cycles."

-

The class template is parameterized on T, the type of the object pointed - to. shared_ptr and most of its member functions place no +

The class template is parameterized on T, the type of the object pointed + to. shared_ptr and most of its member functions place no requirements on T; it is allowed to be an incomplete type, or void. Member functions that do place additional requirements (constructors, reset) are explicitly documented below.

shared_ptr<T> can be implicitly converted to shared_ptr<U> - whenever T* can be implicitly converted to U*. - In particular, shared_ptr<T> is implicitly convertible + whenever T* can be implicitly converted to U*. + In particular, shared_ptr<T> is implicitly convertible to shared_ptr<T const>, to shared_ptr<U> where U is an accessible base of T, and to shared_ptr<void>.

-

shared_ptr is now part of TR1, the first C++ - Library Technical Report. The latest draft of TR1 is available +

shared_ptr is now part of TR1, the first C++ + Library Technical Report. The latest draft of TR1 is available at the following location:

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf (1.36Mb PDF)

-

This implementation conforms to the TR1 specification, with the only exception +

This implementation conforms to the TR1 specification, with the only exception that it resides in namespace boost instead of std::tr1.

Best Practices

-

A simple guideline that nearly eliminates the possibility of memory leaks is: +

A simple guideline that nearly eliminates the possibility of memory leaks is: always use a named smart pointer variable to hold the result of new. - Every occurence of the new keyword in the code should have the + Every occurence of the new keyword in the code should have the form:

shared_ptr<T> p(new Y);

It is, of course, acceptable to use another smart pointer in place of shared_ptr - above; having T and Y be the same type, or + above; having T and Y be the same type, or passing arguments to Y's constructor is also OK.

-

If you observe this guideline, it naturally follows that you will have no - explicit deletes; try/catch constructs will +

If you observe this guideline, it naturally follows that you will have no + explicit deletes; try/catch constructs will be rare.

-

Avoid using unnamed shared_ptr temporaries to save typing; to +

Avoid using unnamed shared_ptr temporaries to save typing; to see why this is dangerous, consider this example:

void f(shared_ptr<int>, int);
 int g();
@@ -83,13 +83,18 @@ void bad()
 }
 

The function ok follows the guideline to the letter, whereas - bad constructs the temporary shared_ptr in place, - admitting the possibility of a memory leak. Since function arguments are - evaluated in unspecified order, it is possible for new int(2) to + bad constructs the temporary shared_ptr in place, + admitting the possibility of a memory leak. Since function arguments are + evaluated in unspecified order, it is possible for new int(2) to be evaluated first, g() second, and we may never get to the - shared_ptr constructor if g throws an exception. + shared_ptr constructor if g throws an exception. See Herb Sutter's treatment (also here) of the issue for more information.

+

The exception safety problem described above may also be eliminated by using + the make_shared + or allocate_shared + factory functions defined in boost/make_shared.hpp. These factory functions also provide + an efficiency benefit by consolidating allocations.

Synopsis

namespace boost {
 
@@ -115,7 +120,7 @@ void bad()
       template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);
       template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r);
 
-      shared_ptr & operator=(shared_ptr const & r); // never throws  
+      shared_ptr & operator=(shared_ptr const & r); // never throws
       template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws
       template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);
 
@@ -178,32 +183,32 @@ void bad()
 			

Postconditions: use_count() == 0 && get() == 0.

Throws: nothing.

-

[The nothrow guarantee is important, since reset() is specified - in terms of the default constructor; this implies that the constructor must not +

[The nothrow guarantee is important, since reset() is specified + in terms of the default constructor; this implies that the constructor must not allocate memory.]

template<class Y> explicit shared_ptr(Y * p);

Requirements: p must be convertible to T *. Y - must be a complete type. The expression delete p must be + must be a complete type. The expression delete p must be well-formed, must not invoke undefined behavior, and must not throw exceptions.

Effects: Constructs a shared_ptr that owns the pointer p.

Postconditions: use_count() == 1 && get() == p.

-

Throws: std::bad_alloc, or an implementation-defined +

Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

-

Exception safety: If an exception is thrown, delete p is +

Exception safety: If an exception is thrown, delete p is called.

-

Notes: p must be a pointer to an object that was +

Notes: p must be a pointer to an object that was allocated via a C++ new expression or be 0. The postcondition that use count is 1 holds even if p is 0; invoking delete on a pointer that has a value of 0 is harmless.

-

[This constructor has been changed to a template in order to remember the actual - pointer type passed. The destructor will call delete with the - same pointer, complete with its original type, even when T does +

[This constructor has been changed to a template in order to remember the actual + pointer type passed. The destructor will call delete with the + same pointer, complete with its original type, even when T does not have a virtual destructor, or is void.

-

The optional intrusive counting support has been dropped as it exposes too much - implementation details and doesn't interact well with weak_ptr. +

The optional intrusive counting support has been dropped as it exposes too much + implementation details and doesn't interact well with weak_ptr. The current implementation uses a different mechanism, enable_shared_from_this, to solve the "shared_ptr from this" problem.]

@@ -212,46 +217,46 @@ void bad() template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);

Requirements: p must be convertible to T *. D - must be CopyConstructible. The copy constructor and destructor - of D must not throw. The expression d(p) must be + must be CopyConstructible. The copy constructor and destructor + of D must not throw. The expression d(p) must be well-formed, must not invoke undefined behavior, and must not throw exceptions. - A must be an Allocator, as described in section 20.1.5 (Allocator + A must be an Allocator, as described in section 20.1.5 (Allocator requirements) of the C++ Standard.

Effects: Constructs a shared_ptr that owns the pointer - p and the deleter d. The second constructor allocates + p and the deleter d. The second constructor allocates memory using a copy of a.

Postconditions: use_count() == 1 && get() == p.

-

Throws: std::bad_alloc, or an implementation-defined +

Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

Exception safety: If an exception is thrown, d(p) is called.

-

Notes: When the the time comes to delete the object pointed to by p, +

Notes: When the the time comes to delete the object pointed to by p, the stored copy of d is invoked with the stored copy of p as an argument.

[Custom deallocators allow a factory function returning a shared_ptr - to insulate the user from its memory allocation strategy. Since the deallocator - is not part of the type, changing the allocation strategy does not break source - or binary compatibility, and does not require a client recompilation. For + to insulate the user from its memory allocation strategy. Since the deallocator + is not part of the type, changing the allocation strategy does not break source + or binary compatibility, and does not require a client recompilation. For example, a "no-op" deallocator is useful when returning a shared_ptr to a statically allocated object, and other variations allow a shared_ptr to be used as a wrapper for another smart pointer, easing interoperability.

The support for custom deallocators does not impose significant overhead. Other shared_ptr features still require a deallocator to be kept.

-

The requirement that the copy constructor of D does not throw comes from - the pass by value. If the copy constructor throws, the pointer is leaked. +

The requirement that the copy constructor of D does not throw comes from + the pass by value. If the copy constructor throws, the pointer is leaked. Removing the requirement requires a pass by (const) reference.

-

The main problem with pass by reference lies in its interaction with rvalues. A - const reference may still cause a copy, and will require a const operator(). A - non-const reference won't bind to an rvalue at all. A good solution to this +

The main problem with pass by reference lies in its interaction with rvalues. A + const reference may still cause a copy, and will require a const operator(). A + non-const reference won't bind to an rvalue at all. A good solution to this problem is the rvalue reference proposed in N1377/N1385.]

shared_ptr(shared_ptr const & r); // never throws
 template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
-

Effects: If r is empty, constructs an empty shared_ptr; +

Effects: If r is empty, constructs an empty shared_ptr; otherwise, constructs a shared_ptr that shares ownership with r.

-

Postconditions: get() == r.get() && use_count() == +

Postconditions: get() == r.get() && use_count() == r.use_count().

Throws: nothing.

@@ -268,21 +273,21 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never r and stores a copy of the pointer stored in r.

Postconditions: use_count() == r.use_count().

Throws: bad_weak_ptr when r.use_count() == 0.

-

Exception safety: If an exception is thrown, the constructor has no +

Exception safety: If an exception is thrown, the constructor has no effect.

template<class Y> shared_ptr(std::auto_ptr<Y> & r);

Effects: Constructs a shared_ptr, as if by storing a copy of r.release().

Postconditions: use_count() == 1.

-

Throws: std::bad_alloc, or an implementation-defined +

Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

-

Exception safety: If an exception is thrown, the constructor has no +

Exception safety: If an exception is thrown, the constructor has no effect.

-

[This constructor takes a the source auto_ptr by reference and - not by value, and cannot accept auto_ptr temporaries. This is - by design, as the constructor offers the strong guarantee; an rvalue reference +

[This constructor takes a the source auto_ptr by reference and + not by value, and cannot accept auto_ptr temporaries. This is + by design, as the constructor offers the strong guarantee; an rvalue reference would solve this problem, too.]

destructor

~shared_ptr(); // never throws
@@ -290,15 +295,15 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never

Effects:

  • - If *this is empty, or shares ownership with - another shared_ptr instance (use_count() > 1), + If *this is empty, or shares ownership with + another shared_ptr instance (use_count() > 1), there are no side effects.
  • - Otherwise, if *this owns a pointer p + Otherwise, if *this owns a pointer p and a deleter d, d(p) is called.
  • - Otherwise, *this owns a pointer p, + Otherwise, *this owns a pointer p, and delete p is called.

Throws: nothing.

@@ -309,9 +314,9 @@ template<class Y> shared_ptr & operator=(std::auto_ptr<Y> &

Effects: Equivalent to shared_ptr(r).swap(*this).

Returns: *this.

-

Notes: The use count updates caused by the temporary object construction - and destruction are not considered observable side effects, and the - implementation is free to meet the effects (and the implied guarantees) via +

Notes: The use count updates caused by the temporary object construction + and destruction are not considered observable side effects, and the + implementation is free to meet the effects (and the implied guarantees) via different means, without creating a temporary. In particular, in the example:

shared_ptr<int> p(new int);
 shared_ptr<void> q(p);
@@ -365,32 +370,32 @@ q = p;
 		

Returns: use_count() == 1.

Throws: nothing.

-

Notes: unique() may be faster than use_count(). - If you are using unique() to implement copy on write, do not rely +

Notes: unique() may be faster than use_count(). + If you are using unique() to implement copy on write, do not rely on a specific value when the stored pointer is zero.

use_count

long use_count() const; // never throws
-

Returns: the number of shared_ptr objects, *this included, +

Returns: the number of shared_ptr objects, *this included, that share ownership with *this, or 0 when *this is empty.

Throws: nothing.

-

Notes: use_count() is not necessarily efficient. Use only +

Notes: use_count() is not necessarily efficient. Use only for debugging and testing purposes, not for production code.

conversions

operator unspecified-bool-type () const; // never throws
-

Returns: an unspecified value that, when used in boolean contexts, is +

Returns: an unspecified value that, when used in boolean contexts, is equivalent to get() != 0.

Throws: nothing.

-

Notes: This conversion operator allows shared_ptr objects to be - used in boolean contexts, like if (p && p->valid()) {}. - The actual target type is typically a pointer to a member function, avoiding +

Notes: This conversion operator allows shared_ptr objects to be + used in boolean contexts, like if (p && p->valid()) {}. + The actual target type is typically a pointer to a member function, avoiding many of the implicit conversion pitfalls.

-

[The conversion to bool is not merely syntactic sugar. It allows shared_ptrs +

[The conversion to bool is not merely syntactic sugar. It allows shared_ptrs to be declared in conditions when using dynamic_pointer_cast or weak_ptr::lock.]

swap

@@ -422,19 +427,19 @@ q = p; operator< is a strict weak ordering as described in section 25.3 [lib.alg.sorting] of the C++ standard;
  • - under the equivalence relation defined by operator<, !(a - < b) && !(b < a), two shared_ptr instances + under the equivalence relation defined by operator<, !(a + < b) && !(b < a), two shared_ptr instances are equivalent if and only if they share ownership or are both empty.
  • Throws: nothing.

    -

    Notes: Allows shared_ptr objects to be used as keys in +

    Notes: Allows shared_ptr objects to be used as keys in associative containers.

    [Operator< has been preferred over a std::less specialization for consistency and legality reasons, as std::less - is required to return the results of operator<, and many + is required to return the results of operator<, and many standard algorithms use operator< instead of std::less - for comparisons when a predicate is not supplied. Composite objects, like std::pair, - also implement their operator< in terms of their contained + for comparisons when a predicate is not supplied. Composite objects, like std::pair, + also implement their operator< in terms of their contained subobjects' operator<.

    The rest of the comparison operators are omitted by design.]

    swap

    @@ -443,11 +448,11 @@ q = p;

    Effects: Equivalent to a.swap(b).

    Throws: nothing.

    -

    Notes: Matches the interface of std::swap. Provided as an aid to +

    Notes: Matches the interface of std::swap. Provided as an aid to generic programming.

    [swap is defined in the same namespace as shared_ptr - as this is currently the only legal way to supply a swap function + as this is currently the only legal way to supply a swap function that has a chance to be used by the standard library.]

    get_pointer

    template<class T>
    @@ -464,13 +469,13 @@ q = p;
     		

    Requires: The expression static_cast<T*>(r.get()) must be well-formed.

    -

    Returns: If r is empty, an empty shared_ptr<T>; +

    Returns: If r is empty, an empty shared_ptr<T>; otherwise, a shared_ptr<T> object that stores a copy of static_cast<T*>(r.get()) and shares ownership with r.

    Throws: nothing.

    Notes: the seemingly equivalent expression

    shared_ptr<T>(static_cast<T*>(r.get()))

    -

    will eventually result in undefined behavior, attempting to delete the same +

    will eventually result in undefined behavior, attempting to delete the same object twice.

    const_pointer_cast

    @@ -479,13 +484,13 @@ q = p;

    Requires: The expression const_cast<T*>(r.get()) must be well-formed.

    -

    Returns: If r is empty, an empty shared_ptr<T>; +

    Returns: If r is empty, an empty shared_ptr<T>; otherwise, a shared_ptr<T> object that stores a copy of const_cast<T*>(r.get()) and shares ownership with r.

    Throws: nothing.

    Notes: the seemingly equivalent expression

    shared_ptr<T>(const_cast<T*>(r.get()))

    -

    will eventually result in undefined behavior, attempting to delete the same +

    will eventually result in undefined behavior, attempting to delete the same object twice.

    dynamic_pointer_cast

    @@ -498,14 +503,14 @@ q = p;
    • When dynamic_cast<T*>(r.get()) returns a nonzero value, a - shared_ptr<T> object that stores a copy of it and shares + shared_ptr<T> object that stores a copy of it and shares ownership with r;
    • Otherwise, an empty shared_ptr<T> object.

    Throws: nothing.

    Notes: the seemingly equivalent expression

    shared_ptr<T>(dynamic_cast<T*>(r.get()))

    -

    will eventually result in undefined behavior, attempting to delete the same +

    will eventually result in undefined behavior, attempting to delete the same object twice.

    operator<<

    @@ -520,41 +525,41 @@ q = p; D * get_deleter(shared_ptr<T> const & p);

    Returns: If *this owns a deleter d - of type (cv-unqualified) D, returns &d; + of type (cv-unqualified) D, returns &d; otherwise returns 0.

    Throws: nothing.

    Example

    -

    See shared_ptr_example.cpp for a +

    See shared_ptr_example.cpp for a complete example program. The program builds a std::vector and std::set of shared_ptr objects.

    Note that after the containers have been populated, some of the shared_ptr - objects will have a use count of 1 rather than a use count of 2, since the set - is a std::set rather than a std::multiset, and thus does not - contain duplicate entries. Furthermore, the use count may be even higher at - various times while push_back and insert container operations are - performed. More complicated yet, the container operations may throw exceptions - under a variety of circumstances. Getting the memory management and exception + objects will have a use count of 1 rather than a use count of 2, since the set + is a std::set rather than a std::multiset, and thus does not + contain duplicate entries. Furthermore, the use count may be even higher at + various times while push_back and insert container operations are + performed. More complicated yet, the container operations may throw exceptions + under a variety of circumstances. Getting the memory management and exception handling in this example right without a smart pointer would be a nightmare.

    Handle/Body Idiom

    -

    One common usage of shared_ptr is to implement a handle/body (also called - pimpl) idiom which avoids exposing the body (implementation) in the header +

    One common usage of shared_ptr is to implement a handle/body (also called + pimpl) idiom which avoids exposing the body (implementation) in the header file.

    The shared_ptr_example2_test.cpp - sample program includes a header file, shared_ptr_example2.hpp, - which uses a shared_ptr<> to an incomplete type to hide the - implementation. The instantiation of member functions which require a complete + sample program includes a header file, shared_ptr_example2.hpp, + which uses a shared_ptr<> to an incomplete type to hide the + implementation. The instantiation of member functions which require a complete type occurs in the shared_ptr_example2.cpp - implementation file. Note that there is no need for an explicit destructor. - Unlike ~scoped_ptr, ~shared_ptr does not require that T be a complete + implementation file. Note that there is no need for an explicit destructor. + Unlike ~scoped_ptr, ~shared_ptr does not require that T be a complete type.

    Thread Safety

    -

    shared_ptr objects offer the same level of thread safety as - built-in types. A shared_ptr instance can be "read" (accessed +

    shared_ptr objects offer the same level of thread safety as + built-in types. A shared_ptr instance can be "read" (accessed using only const operations) simultaneously by multiple threads. Different shared_ptr instances can be "written to" (accessed using mutable operations such as operator= - or reset) simultaneosly by multiple threads (even - when these instances are copies, and share the same reference count + or reset) simultaneosly by multiple threads (even + when these instances are copies, and share the same reference count underneath.)

    Any other simultaneous accesses result in undefined behavior.

    Examples:

    @@ -601,7 +606,7 @@ p3.reset(new int(1)); p3.reset(new int(2)); // undefined, multiple writes

     

    -

    Starting with Boost release 1.33.0, shared_ptr uses a lock-free +

    Starting with Boost release 1.33.0, shared_ptr uses a lock-free implementation on the following platforms:

    • @@ -614,75 +619,75 @@ p3.reset(new int(2)); // undefined, multiple writes GNU GCC on PowerPC;
    • Windows.
    -

    If your program is single-threaded and does not link to any libraries that might +

    If your program is single-threaded and does not link to any libraries that might have used shared_ptr in its default configuration, you can - #define the macro BOOST_SP_DISABLE_THREADS on a + #define the macro BOOST_SP_DISABLE_THREADS on a project-wide basis to switch to ordinary non-atomic reference count updates.

    -

    (Defining BOOST_SP_DISABLE_THREADS in some, but not all, - translation units is technically a violation of the One Definition Rule and - undefined behavior. Nevertheless, the implementation attempts to do its best to - accommodate the request to use non-atomic updates in those translation units. +

    (Defining BOOST_SP_DISABLE_THREADS in some, but not all, + translation units is technically a violation of the One Definition Rule and + undefined behavior. Nevertheless, the implementation attempts to do its best to + accommodate the request to use non-atomic updates in those translation units. No guarantees, though.)

    -

    You can define the macro BOOST_SP_USE_PTHREADS to turn off the - lock-free platform-specific implementation and fall back to the generic pthread_mutex_t-based +

    You can define the macro BOOST_SP_USE_PTHREADS to turn off the + lock-free platform-specific implementation and fall back to the generic pthread_mutex_t-based code.

    Frequently Asked Questions

    -

    Q. There are several variations of shared pointers, with different - tradeoffs; why does the smart pointer library supply only a single - implementation? It would be useful to be able to experiment with each type so +

    Q. There are several variations of shared pointers, with different + tradeoffs; why does the smart pointer library supply only a single + implementation? It would be useful to be able to experiment with each type so as to find the most suitable for the job at hand?

    - A. An important goal of shared_ptr is to provide a - standard shared-ownership pointer. Having a single pointer type is important - for stable library interfaces, since different shared pointers typically cannot - interoperate, i.e. a reference counted pointer (used by library A) cannot share + A. An important goal of shared_ptr is to provide a + standard shared-ownership pointer. Having a single pointer type is important + for stable library interfaces, since different shared pointers typically cannot + interoperate, i.e. a reference counted pointer (used by library A) cannot share ownership with a linked pointer (used by library B.)

    -

    Q. Why doesn't shared_ptr have template parameters supplying +

    Q. Why doesn't shared_ptr have template parameters supplying traits or policies to allow extensive user customization?

    - A. Parameterization discourages users. The shared_ptr template is - carefully crafted to meet common needs without extensive parameterization. Some - day a highly configurable smart pointer may be invented that is also very easy - to use and very hard to misuse. Until then, shared_ptr is the smart - pointer of choice for a wide range of applications. (Those interested in policy + A. Parameterization discourages users. The shared_ptr template is + carefully crafted to meet common needs without extensive parameterization. Some + day a highly configurable smart pointer may be invented that is also very easy + to use and very hard to misuse. Until then, shared_ptr is the smart + pointer of choice for a wide range of applications. (Those interested in policy based smart pointers should read Modern C++ Design by Andrei Alexandrescu.)

    -

    Q. I am not convinced. Default parameters can be used where appropriate +

    Q. I am not convinced. Default parameters can be used where appropriate to hide the complexity. Again, why not policies?

    - A. Template parameters affect the type. See the answer to the first + A. Template parameters affect the type. See the answer to the first question above.

    Q. Why doesn't shared_ptr use a linked list implementation?

    - A. A linked list implementation does not offer enough advantages to + A. A linked list implementation does not offer enough advantages to offset the added cost of an extra pointer. See timings - page. In addition, it is expensive to make a linked list implementation thread + page. In addition, it is expensive to make a linked list implementation thread safe.

    -

    Q. Why doesn't shared_ptr (or any of the other Boost smart +

    Q. Why doesn't shared_ptr (or any of the other Boost smart pointers) supply an automatic conversion to T*?

    A. Automatic conversion is believed to be too error prone.

    Q. Why does shared_ptr supply use_count()?

    - A. As an aid to writing test cases and debugging displays. One of the - progenitors had use_count(), and it was useful in tracking down bugs in a + A. As an aid to writing test cases and debugging displays. One of the + progenitors had use_count(), and it was useful in tracking down bugs in a complex project that turned out to have cyclic-dependencies.

    Q. Why doesn't shared_ptr specify complexity requirements?

    - A. Because complexity requirements limit implementors and complicate the - specification without apparent benefit to shared_ptr users. For example, - error-checking implementations might become non-conforming if they had to meet + A. Because complexity requirements limit implementors and complicate the + specification without apparent benefit to shared_ptr users. For example, + error-checking implementations might become non-conforming if they had to meet stringent complexity requirements.

    Q. Why doesn't shared_ptr provide a release() function?

    - A. shared_ptr cannot give away ownership unless it's unique() + A. shared_ptr cannot give away ownership unless it's unique() because the other copy will still destroy the object.

    Consider:

    shared_ptr<int> a(new int);
    @@ -692,25 +697,25 @@ int * p = a.release();
     
     // Who owns p now? b will still call delete on it in its destructor.
    -

    Furthermore, the pointer returned by release() would be difficult - to deallocate reliably, as the source shared_ptr could have been created +

    Furthermore, the pointer returned by release() would be difficult + to deallocate reliably, as the source shared_ptr could have been created with a custom deleter.

    -

    Q. Why is operator->() const, but its return value is a +

    Q. Why is operator->() const, but its return value is a non-const pointer to the element type?

    - A. Shallow copy pointers, including raw pointers, typically don't - propagate constness. It makes little sense for them to do so, as you can always - obtain a non-const pointer from a const one and then proceed to modify the - object through it.shared_ptr is "as close to raw pointers as possible + A. Shallow copy pointers, including raw pointers, typically don't + propagate constness. It makes little sense for them to do so, as you can always + obtain a non-const pointer from a const one and then proceed to modify the + object through it.shared_ptr is "as close to raw pointers as possible but no closer".


    $Date$

    -

    Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, +

    Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. + Copyright 2002-2005 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.

    diff --git a/smart_ptr.htm b/smart_ptr.htm index 497c63f..9e2512e 100644 --- a/smart_ptr.htm +++ b/smart_ptr.htm @@ -14,15 +14,15 @@ History and Acknowledgements
    References

    Introduction

    -

    Smart pointers are objects which store pointers to dynamically allocated (heap) - objects. They behave much like built-in C++ pointers except that they - automatically delete the object pointed to at the appropriate time. Smart - pointers are particularly useful in the face of exceptions as they ensure - proper destruction of dynamically allocated objects. They can also be used to +

    Smart pointers are objects which store pointers to dynamically allocated (heap) + objects. They behave much like built-in C++ pointers except that they + automatically delete the object pointed to at the appropriate time. Smart + pointers are particularly useful in the face of exceptions as they ensure + proper destruction of dynamically allocated objects. They can also be used to keep track of dynamically allocated objects shared by multiple owners.

    -

    Conceptually, smart pointers are seen as owning the object pointed to, and thus +

    Conceptually, smart pointers are seen as owning the object pointed to, and thus responsible for deletion of the object when it is no longer needed.

    -

    The smart pointer library provides five smart pointer class templates:

    +

    The smart pointer library provides six smart pointer class templates:

    @@ -38,7 +38,7 @@ - + @@ -58,126 +58,137 @@
    shared_ptr <boost/shared_ptr.hpp>Object ownership shared among multiple pointersObject ownership shared among multiple pointers.
    shared_array

    These templates are designed to complement the std::auto_ptr template.

    -

    They are examples of the "resource acquisition is initialization" idiom - described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition, +

    They are examples of the "resource acquisition is initialization" idiom + described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition, Section 14.4, Resource Management.

    -

    A test program, smart_ptr_test.cpp, is +

    Additionally, the smart pointer library provides efficient factory functions + for creating shared_ptr objects:

    +
    + + + + + + +
    make_shared and allocate_shared<boost/make_shared.hpp>Efficient creation of shared_ptr objects.
    +
    +

    A test program, smart_ptr_test.cpp, is provided to verify correct operation.

    -

    A page on compatibility with older versions of - the Boost smart pointer library describes some of the changes since earlier +

    A page on compatibility with older versions of + the Boost smart pointer library describes some of the changes since earlier versions of the smart pointer implementation.

    -

    A page on smart pointer timings will be of interest +

    A page on smart pointer timings will be of interest to those curious about performance issues.

    -

    A page on smart pointer programming techniques lists +

    A page on smart pointer programming techniques lists some advanced applications of shared_ptr and weak_ptr.

    Common Requirements

    -

    These smart pointer class templates have a template parameter, T, which - specifies the type of the object pointed to by the smart pointer. The behavior +

    These smart pointer class templates have a template parameter, T, which + specifies the type of the object pointed to by the smart pointer. The behavior of the smart pointer templates is undefined if the destructor or operator delete for objects of type T throw exceptions.

    -

    T may be an incomplete type at the point of smart pointer declaration. - Unless otherwise specified, it is required that T be a complete type at - points of smart pointer instantiation. Implementations are required to diagnose - (treat as an error) all violations of this requirement, including deletion of +

    T may be an incomplete type at the point of smart pointer declaration. + Unless otherwise specified, it is required that T be a complete type at + points of smart pointer instantiation. Implementations are required to diagnose + (treat as an error) all violations of this requirement, including deletion of an incomplete type. See the description of the checked_delete function template.

    -

    Note that shared_ptr does not have this restriction, as most of +

    Note that shared_ptr does not have this restriction, as most of its member functions do not require T to be a complete type.

    Rationale

    -

    The requirements on T are carefully crafted to maximize safety yet allow - handle-body (also called pimpl) and similar idioms. In these idioms a smart - pointer may appear in translation units where T is an incomplete type. - This separates interface from implementation and hides implementation from - translation units which merely use the interface. Examples described in the - documentation for specific smart pointers illustrate use of smart pointers in +

    The requirements on T are carefully crafted to maximize safety yet allow + handle-body (also called pimpl) and similar idioms. In these idioms a smart + pointer may appear in translation units where T is an incomplete type. + This separates interface from implementation and hides implementation from + translation units which merely use the interface. Examples described in the + documentation for specific smart pointers illustrate use of smart pointers in these idioms.

    -

    Note that scoped_ptr requires that T be a complete type at +

    Note that scoped_ptr requires that T be a complete type at destruction time, but shared_ptr does not.

    Exception Safety

    -

    Several functions in these smart pointer classes are specified as having "no - effect" or "no effect except such-and-such" if an exception is thrown. This - means that when an exception is thrown by an object of one of these classes, - the entire program state remains the same as it was prior to the function call - which resulted in the exception being thrown. This amounts to a guarantee that - there are no detectable side effects. Other functions never throw exceptions. - The only exception ever thrown by functions which do throw (assuming T meets - the common requirements) is std::bad_alloc, - and that is thrown only by functions which are explicitly documented as +

    Several functions in these smart pointer classes are specified as having "no + effect" or "no effect except such-and-such" if an exception is thrown. This + means that when an exception is thrown by an object of one of these classes, + the entire program state remains the same as it was prior to the function call + which resulted in the exception being thrown. This amounts to a guarantee that + there are no detectable side effects. Other functions never throw exceptions. + The only exception ever thrown by functions which do throw (assuming T meets + the common requirements) is std::bad_alloc, + and that is thrown only by functions which are explicitly documented as possibly throwing std::bad_alloc.

    Exception-specifications

    Exception-specifications are not used; see exception-specification rationale.

    -

    All the smart pointer templates contain member functions which can never throw - exceptions, because they neither throw exceptions themselves nor call other +

    All the smart pointer templates contain member functions which can never throw + exceptions, because they neither throw exceptions themselves nor call other functions which may throw exceptions. These members are indicated by a comment: // never throws.

    -

    Functions which destroy objects of the pointed to type are prohibited from +

    Functions which destroy objects of the pointed to type are prohibited from throwing exceptions by the common requirements.

    History and Acknowledgements

    -

    January 2002. Peter Dimov reworked all four classes, adding features, fixing - bugs, and splitting them into four separate headers, and added weak_ptr. - See the compatibility page for a summary of the +

    January 2002. Peter Dimov reworked all four classes, adding features, fixing + bugs, and splitting them into four separate headers, and added weak_ptr. + See the compatibility page for a summary of the changes.

    -

    May 2001. Vladimir Prus suggested requiring a complete type on destruction. - Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman - Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and +

    May 2001. Vladimir Prus suggested requiring a complete type on destruction. + Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman + Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and others.

    November 1999. Darin Adler provided operator ==, operator !=, and std::swap and std::less specializations for shared types.

    September 1999. Luis Coelho provided shared_ptr::swap and shared_array::swap

    -

    May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a +

    May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a number of suggestions resulting in numerous improvements.

    -

    October 1998. Beman Dawes proposed reviving the original semantics under the - names safe_ptr and counted_ptr, meeting of Per Andersson, Matt - Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar Kühl, - Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new - class names were finalized, it was decided that there was no need to exactly - follow the std::auto_ptr interface, and various function signatures and +

    October 1998. Beman Dawes proposed reviving the original semantics under the + names safe_ptr and counted_ptr, meeting of Per Andersson, Matt + Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar Kühl, + Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new + class names were finalized, it was decided that there was no need to exactly + follow the std::auto_ptr interface, and various function signatures and semantics were finalized.

    -

    Over the next three months, several implementations were considered for shared_ptr, - and discussed on the boost.org mailing list. - The implementation questions revolved around the reference count which must be - kept, either attached to the pointed to object, or detached elsewhere. Each of +

    Over the next three months, several implementations were considered for shared_ptr, + and discussed on the boost.org mailing list. + The implementation questions revolved around the reference count which must be + kept, either attached to the pointed to object, or detached elsewhere. Each of those variants have themselves two major variants:

    • - Direct detached: the shared_ptr contains a pointer to the object, and a pointer + Direct detached: the shared_ptr contains a pointer to the object, and a pointer to the count.
    • - Indirect detached: the shared_ptr contains a pointer to a helper object, which + Indirect detached: the shared_ptr contains a pointer to a helper object, which in turn contains a pointer to the object and the count.
    • Embedded attached: the count is a member of the object pointed to.
    • Placement attached: the count is attached via operator new manipulations.
    -

    Each implementation technique has advantages and disadvantages. We went so far - as to run various timings of the direct and indirect approaches, and found that - at least on Intel Pentium chips there was very little measurable difference. - Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar - Kühl suggested an elegant partial template specialization technique to allow - users to choose which implementation they preferred, and that was also +

    Each implementation technique has advantages and disadvantages. We went so far + as to run various timings of the direct and indirect approaches, and found that + at least on Intel Pentium chips there was very little measurable difference. + Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar + Kühl suggested an elegant partial template specialization technique to allow + users to choose which implementation they preferred, and that was also experimented with.

    -

    But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage +

    But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage users", and in the end we choose to supply only the direct implementation.

    Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named auto_ptr and counted_ptr which were very similar to what we now call scoped_ptr - and shared_ptr. [Col-94] In one of the very few - cases where the Library Working Group's recommendations were not followed by - the full committee, counted_ptr was rejected and surprising + and shared_ptr. [Col-94] In one of the very few + cases where the Library Working Group's recommendations were not followed by + the full committee, counted_ptr was rejected and surprising transfer-of-ownership semantics were added to auto_ptr.

    References

    [Col-94] Gregory Colvin, - Exception Safe Smart Pointers, C++ committee document 94-168/N0555, + Exception Safe Smart Pointers, C++ committee document 94-168/N0555, July, 1994.

    [E&D-94] John R. Ellis & David L. Detlefs, - Safe, Efficient Garbage Collection for C++, Usenix Proceedings, - February, 1994. This paper includes an extensive discussion of weak pointers + Safe, Efficient Garbage Collection for C++, Usenix Proceedings, + February, 1994. This paper includes an extensive discussion of weak pointers and an extensive bibliography.


    $Date$

    -

    Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. +

    Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 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.

    From fa3c56747d0981bc9ab17220a50fb3f11616b125 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Wed, 11 Mar 2009 13:55:29 +0000 Subject: [PATCH 011/210] Added missing semicolon at end of ü [SVN r51700] --- smart_ptr.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smart_ptr.htm b/smart_ptr.htm index 9e2512e..92ad2be 100644 --- a/smart_ptr.htm +++ b/smart_ptr.htm @@ -167,7 +167,7 @@ as to run various timings of the direct and indirect approaches, and found that at least on Intel Pentium chips there was very little measurable difference. Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar - Kühl suggested an elegant partial template specialization technique to allow + Kühl suggested an elegant partial template specialization technique to allow users to choose which implementation they preferred, and that was also experimented with.

    But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage From e88dd9fc77b8c72b98b19055951e7067829a97a7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 22 Mar 2009 20:08:39 +0000 Subject: [PATCH 012/210] Bring back the new enable_shared_from_this. [SVN r51908] --- include/boost/enable_shared_from_this2.hpp | 134 +++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 include/boost/enable_shared_from_this2.hpp diff --git a/include/boost/enable_shared_from_this2.hpp b/include/boost/enable_shared_from_this2.hpp new file mode 100644 index 0000000..b624ee9 --- /dev/null +++ b/include/boost/enable_shared_from_this2.hpp @@ -0,0 +1,134 @@ +#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED +#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED + +// +// enable_shared_from_this.hpp +// +// Copyright (c) 2002 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) +// +// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html +// + +#include +#include +#include +#include + +namespace boost +{ + +#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) + +template< class T > class enable_shared_from_this; +template< class T, class Y > void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ); +template< class T, class Y > void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ); + +#endif + +template< class T > class enable_shared_from_this +{ +protected: + + enable_shared_from_this() + { + } + + enable_shared_from_this(enable_shared_from_this const &) + { + } + + enable_shared_from_this & operator=(enable_shared_from_this const &) + { + return *this; + } + +// virtual destructor because we need a vtable for dynamic_cast from base to derived to work + virtual ~enable_shared_from_this() + { + BOOST_ASSERT( _shared_count.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist + } + +public: + + shared_ptr shared_from_this() + { + init_weak_once(); + T * p = dynamic_cast( this ); + return shared_ptr( detail::shared_count( _weak_count ), p ); + } + + shared_ptr shared_from_this() const + { + init_weak_once(); + T const * p = dynamic_cast( this ); + return shared_ptr( detail::shared_count( _weak_count ), p ); + } + +private: + + mutable detail::weak_count _weak_count; + mutable detail::shared_count _shared_count; + + void init_weak_once() const + { + if( _weak_count.empty() ) + { + detail::shared_count( (void*)0, detail::sp_deleter_wrapper() ).swap( _shared_count ); + _weak_count = _shared_count; + } + } + +#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) + + template< class U, class Y > friend void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ); + template< class U, class Y > friend void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ); + +#else + +public: + +#endif + + template + void sp_accept_owner( shared_ptr & owner ) const + { + if( _weak_count.use_count() == 0 ) + { + _weak_count = owner.get_shared_count(); + } + else if( !_shared_count.empty() ) + { + BOOST_ASSERT( owner.unique() ); // no weak_ptrs to owner should exist either, but there's no way to check that + detail::sp_deleter_wrapper * pd = detail::basic_get_deleter( _shared_count ); + BOOST_ASSERT( pd != 0 ); + pd->set_deleter( owner.get_shared_count() ); + + owner.reset( _shared_count, owner.get() ); + detail::shared_count().swap( _shared_count ); + } + } +}; + +template< class T, class Y > inline void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ) +{ + if( pe != 0 ) + { + pe->sp_accept_owner( *ptr ); + } +} + +template< class T, class Y > inline void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ) +{ + if( pe != 0 ) + { + pe->sp_accept_owner( *ptr ); + } +} + +} // namespace boost + +#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED From 9227371881ae25bdcff33f1738d63e0841e26d7d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 22 Mar 2009 20:13:16 +0000 Subject: [PATCH 013/210] Move enable_shared_from_this2.hpp to boost/smart_ptr. [SVN r51909] --- .../smart_ptr/enable_shared_from_this2.hpp | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 include/boost/smart_ptr/enable_shared_from_this2.hpp diff --git a/include/boost/smart_ptr/enable_shared_from_this2.hpp b/include/boost/smart_ptr/enable_shared_from_this2.hpp new file mode 100644 index 0000000..b624ee9 --- /dev/null +++ b/include/boost/smart_ptr/enable_shared_from_this2.hpp @@ -0,0 +1,134 @@ +#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED +#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED + +// +// enable_shared_from_this.hpp +// +// Copyright (c) 2002 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) +// +// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html +// + +#include +#include +#include +#include + +namespace boost +{ + +#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) + +template< class T > class enable_shared_from_this; +template< class T, class Y > void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ); +template< class T, class Y > void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ); + +#endif + +template< class T > class enable_shared_from_this +{ +protected: + + enable_shared_from_this() + { + } + + enable_shared_from_this(enable_shared_from_this const &) + { + } + + enable_shared_from_this & operator=(enable_shared_from_this const &) + { + return *this; + } + +// virtual destructor because we need a vtable for dynamic_cast from base to derived to work + virtual ~enable_shared_from_this() + { + BOOST_ASSERT( _shared_count.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist + } + +public: + + shared_ptr shared_from_this() + { + init_weak_once(); + T * p = dynamic_cast( this ); + return shared_ptr( detail::shared_count( _weak_count ), p ); + } + + shared_ptr shared_from_this() const + { + init_weak_once(); + T const * p = dynamic_cast( this ); + return shared_ptr( detail::shared_count( _weak_count ), p ); + } + +private: + + mutable detail::weak_count _weak_count; + mutable detail::shared_count _shared_count; + + void init_weak_once() const + { + if( _weak_count.empty() ) + { + detail::shared_count( (void*)0, detail::sp_deleter_wrapper() ).swap( _shared_count ); + _weak_count = _shared_count; + } + } + +#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) + + template< class U, class Y > friend void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ); + template< class U, class Y > friend void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ); + +#else + +public: + +#endif + + template + void sp_accept_owner( shared_ptr & owner ) const + { + if( _weak_count.use_count() == 0 ) + { + _weak_count = owner.get_shared_count(); + } + else if( !_shared_count.empty() ) + { + BOOST_ASSERT( owner.unique() ); // no weak_ptrs to owner should exist either, but there's no way to check that + detail::sp_deleter_wrapper * pd = detail::basic_get_deleter( _shared_count ); + BOOST_ASSERT( pd != 0 ); + pd->set_deleter( owner.get_shared_count() ); + + owner.reset( _shared_count, owner.get() ); + detail::shared_count().swap( _shared_count ); + } + } +}; + +template< class T, class Y > inline void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ) +{ + if( pe != 0 ) + { + pe->sp_accept_owner( *ptr ); + } +} + +template< class T, class Y > inline void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ) +{ + if( pe != 0 ) + { + pe->sp_accept_owner( *ptr ); + } +} + +} // namespace boost + +#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED From 6f2bdddfa0253a411b4c00aec0e8750369559f2b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 22 Mar 2009 20:14:13 +0000 Subject: [PATCH 014/210] Delete enable_shared_from_this2.hpp from boost/. [SVN r51910] --- include/boost/enable_shared_from_this2.hpp | 134 --------------------- 1 file changed, 134 deletions(-) delete mode 100644 include/boost/enable_shared_from_this2.hpp diff --git a/include/boost/enable_shared_from_this2.hpp b/include/boost/enable_shared_from_this2.hpp deleted file mode 100644 index b624ee9..0000000 --- a/include/boost/enable_shared_from_this2.hpp +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED -#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED - -// -// enable_shared_from_this.hpp -// -// Copyright (c) 2002 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) -// -// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html -// - -#include -#include -#include -#include - -namespace boost -{ - -#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) - -template< class T > class enable_shared_from_this; -template< class T, class Y > void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ); -template< class T, class Y > void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ); - -#endif - -template< class T > class enable_shared_from_this -{ -protected: - - enable_shared_from_this() - { - } - - enable_shared_from_this(enable_shared_from_this const &) - { - } - - enable_shared_from_this & operator=(enable_shared_from_this const &) - { - return *this; - } - -// virtual destructor because we need a vtable for dynamic_cast from base to derived to work - virtual ~enable_shared_from_this() - { - BOOST_ASSERT( _shared_count.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist - } - -public: - - shared_ptr shared_from_this() - { - init_weak_once(); - T * p = dynamic_cast( this ); - return shared_ptr( detail::shared_count( _weak_count ), p ); - } - - shared_ptr shared_from_this() const - { - init_weak_once(); - T const * p = dynamic_cast( this ); - return shared_ptr( detail::shared_count( _weak_count ), p ); - } - -private: - - mutable detail::weak_count _weak_count; - mutable detail::shared_count _shared_count; - - void init_weak_once() const - { - if( _weak_count.empty() ) - { - detail::shared_count( (void*)0, detail::sp_deleter_wrapper() ).swap( _shared_count ); - _weak_count = _shared_count; - } - } - -#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) - - template< class U, class Y > friend void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ); - template< class U, class Y > friend void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ); - -#else - -public: - -#endif - - template - void sp_accept_owner( shared_ptr & owner ) const - { - if( _weak_count.use_count() == 0 ) - { - _weak_count = owner.get_shared_count(); - } - else if( !_shared_count.empty() ) - { - BOOST_ASSERT( owner.unique() ); // no weak_ptrs to owner should exist either, but there's no way to check that - detail::sp_deleter_wrapper * pd = detail::basic_get_deleter( _shared_count ); - BOOST_ASSERT( pd != 0 ); - pd->set_deleter( owner.get_shared_count() ); - - owner.reset( _shared_count, owner.get() ); - detail::shared_count().swap( _shared_count ); - } - } -}; - -template< class T, class Y > inline void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ) -{ - if( pe != 0 ) - { - pe->sp_accept_owner( *ptr ); - } -} - -template< class T, class Y > inline void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ) -{ - if( pe != 0 ) - { - pe->sp_accept_owner( *ptr ); - } -} - -} // namespace boost - -#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED From d34d63899896b66f50c46bbfd3a892a141eae102 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 22 Mar 2009 21:11:17 +0000 Subject: [PATCH 015/210] Bring back the constructor-enabled enable_shared_from_this as enable_shared_from_this2. [SVN r51912] --- .../smart_ptr/enable_shared_from_this2.hpp | 142 ++++++++------- include/boost/smart_ptr/shared_ptr.hpp | 9 + include/boost/smart_ptr/weak_ptr.hpp | 5 + test/Jamfile.v2 | 1 + test/esft_constructor_test.cpp | 169 ++++++++++++++++++ 5 files changed, 254 insertions(+), 72 deletions(-) create mode 100644 test/esft_constructor_test.cpp diff --git a/include/boost/smart_ptr/enable_shared_from_this2.hpp b/include/boost/smart_ptr/enable_shared_from_this2.hpp index b624ee9..a5bfcff 100644 --- a/include/boost/smart_ptr/enable_shared_from_this2.hpp +++ b/include/boost/smart_ptr/enable_shared_from_this2.hpp @@ -1,16 +1,15 @@ -#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED -#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED +#ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED +#define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED // -// enable_shared_from_this.hpp +// enable_shared_from_this2.hpp // -// Copyright (c) 2002 Peter Dimov +// Copyright 2002, 2009 Peter Dimov +// Copyright 2008 Frank Mori Hess // -// 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) -// -// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html +// 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 @@ -21,114 +20,113 @@ namespace boost { -#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) +namespace detail +{ -template< class T > class enable_shared_from_this; -template< class T, class Y > void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ); -template< class T, class Y > void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ); +class esft2_deleter_wrapper +{ +private: -#endif + shared_ptr deleter_; -template< class T > class enable_shared_from_this +public: + + esft2_deleter_wrapper() + { + } + + template< class T > void set_deleter( shared_ptr const & deleter ) + { + deleter_ = deleter; + } + + template< class T> void operator()( T* ) + { + BOOST_ASSERT( deleter_.use_count() <= 1 ); + deleter_.reset(); + } +}; + +} // namespace detail + +template< class T > class enable_shared_from_this2 { protected: - enable_shared_from_this() + enable_shared_from_this2() { } - enable_shared_from_this(enable_shared_from_this const &) + enable_shared_from_this2( enable_shared_from_this2 const & ) { } - enable_shared_from_this & operator=(enable_shared_from_this const &) + enable_shared_from_this2 & operator=( enable_shared_from_this2 const & ) { return *this; } -// virtual destructor because we need a vtable for dynamic_cast from base to derived to work - virtual ~enable_shared_from_this() + ~enable_shared_from_this2() { - BOOST_ASSERT( _shared_count.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist + BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist } +private: + + mutable weak_ptr weak_this_; + mutable shared_ptr shared_this_; + public: shared_ptr shared_from_this() { init_weak_once(); - T * p = dynamic_cast( this ); - return shared_ptr( detail::shared_count( _weak_count ), p ); + return shared_ptr( weak_this_ ); } shared_ptr shared_from_this() const { init_weak_once(); - T const * p = dynamic_cast( this ); - return shared_ptr( detail::shared_count( _weak_count ), p ); + return shared_ptr( weak_this_ ); } private: - mutable detail::weak_count _weak_count; - mutable detail::shared_count _shared_count; - void init_weak_once() const { - if( _weak_count.empty() ) + if( weak_this_._empty() ) { - detail::shared_count( (void*)0, detail::sp_deleter_wrapper() ).swap( _shared_count ); - _weak_count = _shared_count; + shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() ); + weak_this_ = shared_this_; } } -#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) +public: // actually private, but avoids compiler template friendship issues - template< class U, class Y > friend void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ); - template< class U, class Y > friend void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ); - -#else - -public: - -#endif - - template - void sp_accept_owner( shared_ptr & owner ) const + // Note: invoked automatically by shared_ptr; do not call + template void _internal_accept_owner( shared_ptr * ppx, Y * py ) const { - if( _weak_count.use_count() == 0 ) - { - _weak_count = owner.get_shared_count(); - } - else if( !_shared_count.empty() ) - { - BOOST_ASSERT( owner.unique() ); // no weak_ptrs to owner should exist either, but there's no way to check that - detail::sp_deleter_wrapper * pd = detail::basic_get_deleter( _shared_count ); - BOOST_ASSERT( pd != 0 ); - pd->set_deleter( owner.get_shared_count() ); + BOOST_ASSERT( ppx != 0 ); - owner.reset( _shared_count, owner.get() ); - detail::shared_count().swap( _shared_count ); + if( weak_this_.use_count() == 0 ) + { + weak_this_ = shared_ptr( *ppx, py ); + } + else if( shared_this_.use_count() != 0 ) + { + BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that + + detail::esft2_deleter_wrapper * pd = boost::get_deleter( shared_this_ ); + BOOST_ASSERT( pd != 0 ); + + pd->set_deleter( *ppx ); + + ppx->reset( shared_this_, ppx->get() ); + shared_this_.reset(); } } }; -template< class T, class Y > inline void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ) -{ - if( pe != 0 ) - { - pe->sp_accept_owner( *ptr ); - } -} - -template< class T, class Y > inline void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ) -{ - if( pe != 0 ) - { - pe->sp_accept_owner( *ptr ); - } -} - } // namespace boost -#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED +#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 0ce3b97..1cddc04 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -61,6 +61,7 @@ namespace boost template class shared_ptr; template class weak_ptr; template class enable_shared_from_this; +template class enable_shared_from_this2; namespace detail { @@ -109,6 +110,14 @@ template< class X, class Y, class T > inline void sp_enable_shared_from_this( bo } } +template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe ) +{ + if( pe != 0 ) + { + pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); + } +} + #ifdef _MANAGED // Avoid C4793, ... causes native code generation diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index bf5296a..d21b874 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -124,6 +124,11 @@ public: return pn.use_count() == 0; } + bool _empty() const // extension, not in std::weak_ptr + { + return pn.empty(); + } + void reset() // never throws in 1.30+ { this_type().swap(*this); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index c862197..eacee9a 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -56,5 +56,6 @@ import testing ; [ run sp_recursive_assign2_test.cpp ] [ run sp_recursive_assign_rv_test.cpp ] [ run sp_recursive_assign2_rv_test.cpp ] + [ run esft_constructor_test.cpp ] ; } diff --git a/test/esft_constructor_test.cpp b/test/esft_constructor_test.cpp new file mode 100644 index 0000000..ced24e2 --- /dev/null +++ b/test/esft_constructor_test.cpp @@ -0,0 +1,169 @@ +// +// esft_constructor_test.cpp +// +// A test for the new enable_shared_from_this support for calling +// shared_from_this from constructors (that is, prior to the +// object's ownership being passed to an external shared_ptr). +// +// Copyright (c) 2008 Frank Mori Hess +// 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 +#include +#include +#include + +class X: public boost::enable_shared_from_this2< X > +{ +private: + + int destroyed_; + int deleted_; + int expected_; + +private: + + X( X const& ); + X& operator=( X const& ); + +public: + + static int instances; + +public: + + explicit X( int expected, boost::shared_ptr *early_px = 0 ): destroyed_( 0 ), deleted_( 0 ), expected_( expected ) + { + ++instances; + if( early_px ) *early_px = shared_from_this(); + } + + ~X() + { + BOOST_TEST( deleted_ == expected_ ); + BOOST_TEST( destroyed_ == 0 ); + ++destroyed_; + --instances; + } + + typedef void (*deleter_type)( X* ); + + static void deleter( X * px ) + { + ++px->deleted_; + } + + static void deleter2( X * px ) + { + ++px->deleted_; + delete px; + } +}; + +int X::instances = 0; + +template +bool are_shared_owners(const boost::shared_ptr &a, const boost::shared_ptr &b) +{ + return !(a < b) && !(b < a); +} + +struct Y: public boost::enable_shared_from_this2 +{}; + +int main() +{ + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr early_px; + X* x = new X( 1, &early_px ); + BOOST_TEST( early_px.use_count() > 0 ); + BOOST_TEST( boost::get_deleter(early_px) == 0 ); + boost::shared_ptr px( x, &X::deleter2 ); + BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 ); + BOOST_TEST(are_shared_owners(early_px, px)); + px.reset(); + BOOST_TEST( early_px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + // X::deleter_type *pd = boost::get_deleter(early_px); + // BOOST_TEST(pd && *pd == &X::deleter2 ); + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr early_px; + X* x = new X( 1, &early_px ); + boost::weak_ptr early_weak_px = early_px; + early_px.reset(); + BOOST_TEST( !early_weak_px.expired() ); + boost::shared_ptr px( x, &X::deleter2 ); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + BOOST_TEST(are_shared_owners(early_weak_px.lock(), px)); + px.reset(); + BOOST_TEST( early_weak_px.expired() ); + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr early_px; + X x( 1, &early_px ); + BOOST_TEST( early_px.use_count() > 0 ); + boost::shared_ptr px( &x, &X::deleter ); + BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 ); + early_px.reset(); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + px.reset(); + try + { + x.shared_from_this(); + BOOST_ERROR("x did not throw bad_weak_ptr"); + } + catch( const boost::bad_weak_ptr & ) + {} + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::weak_ptr early_weak_px; + { + boost::shared_ptr early_px; + X x( 0, &early_px ); + early_weak_px = early_px; + early_px.reset(); + BOOST_TEST( !early_weak_px.expired() ); + BOOST_TEST( X::instances == 1 ); + } + BOOST_TEST( early_weak_px.expired() ); + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr px(new Y()); + Y y(*px); + px.reset(); + try + { + y.shared_from_this(); + } + catch( const boost::bad_weak_ptr & ) + { + BOOST_ERROR("y threw bad_weak_ptr"); + } + } + + return boost::report_errors(); +} From 287d3292761b3ab495e7e79277a5c98d3b62b17d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 26 Mar 2009 00:17:57 +0000 Subject: [PATCH 016/210] Added g++/MIPS support submitted by David Joyner. Refs #2885. [SVN r51978] --- .../smart_ptr/detail/sp_counted_base.hpp | 3 + .../detail/sp_counted_base_gcc_mips.hpp | 172 ++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp index df8be5b..cab45cc 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp @@ -47,6 +47,9 @@ #elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) # include +#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) +# include + #elif defined( BOOST_SP_HAS_SYNC ) # include diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp new file mode 100644 index 0000000..b60b80d --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -0,0 +1,172 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS +// +// Copyright (c) 2009, Spirent Communications, Inc. +// +// 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) +// +// +// Lock-free algorithm by Alexander Terekhov +// + +#include "sp_typeinfo.hpp" + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + int tmp; + + __asm__ __volatile__ + ( + "0:\n\t" + "ll %0, %1\n\t" + "addiu %0, 1\n\t" + "sc %0, %1\n\t" + "beqz %0, 0b": + "=&r"( tmp ), "=m"( *pw ): + "m"( *pw ) + ); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int rv, tmp; + + __asm__ __volatile__ + ( + "0:\n\t" + "ll %1, %2\n\t" + "addiu %0, %1, -1\n\t" + "sc %0, %2\n\t" + "beqz %0, 0b\n\t" + "addiu %0, %1, -1": + "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ): + "m"( *pw ): + "memory" + ); + + return rv; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int rv, tmp; + + __asm__ __volatile__ + ( + "0:\n\t" + "ll %0, %2\n\t" + "beqz %0, 1f\n\t" + "addiu %1, %0, 1\n\t" + "sc %1, %2\n\t" + "beqz %1, 0b\n\t" + "addiu %0, %0, 1\n\t" + "1:": + "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ): + "m"( *pw ): + "memory" + ); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED From 5758e519486b98c99b00065f58a639df3621589d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 26 Mar 2009 12:47:24 +0000 Subject: [PATCH 017/210] Fix sp_typeinfo.hpp include. Refs #2885. [SVN r51985] --- include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp index b60b80d..0c69b0b 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -20,7 +20,7 @@ // Lock-free algorithm by Alexander Terekhov // -#include "sp_typeinfo.hpp" +#include namespace boost { From 3dacec8e1dcb17b97bdb3e403cc9ea747a0fa1a3 Mon Sep 17 00:00:00 2001 From: David Deakins Date: Wed, 1 Apr 2009 14:42:11 +0000 Subject: [PATCH 018/210] Have config/select_stdlib_config.hpp and config/stdlib/stlport.hpp use instead of to determine which standard library is in use. For std lib implementations that rely on Boost components like TypeTraits, Bind, Function, or SmartPtr, this helps to avoid circular header dependency issues, since is much less likely to pull in Boost libraries than . In get_pointer.hpp, switched to using instead of using directly. As above, this helps avoid circular header dependency issues in Boost-supplemented std libs (specifically it avoids issues when pulls in pieces of Boost.SmartPtr). These two changes were made in response to testing done with STLport 5.2.1 using the _STLP_USE_BOOST_SUPPORT option. [SVN r52104] --- include/boost/get_pointer.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/boost/get_pointer.hpp b/include/boost/get_pointer.hpp index 17d11b8..a0cd5c0 100644 --- a/include/boost/get_pointer.hpp +++ b/include/boost/get_pointer.hpp @@ -5,7 +5,11 @@ #ifndef GET_POINTER_DWA20021219_HPP # define GET_POINTER_DWA20021219_HPP -# include +// In order to avoid circular dependencies with Boost.TR1 +// we make sure that our include of doesn't try to +// pull in the TR1 headers: that's why we use this header +// rather than including directly: +# include // std::auto_ptr namespace boost { From 0368a37fdeb23540de8fe35256c4566dca89d632 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 17 Apr 2009 19:51:18 +0000 Subject: [PATCH 019/210] Bring back "explicit" on the auto_ptr rvalue constructor. Refs #2951. [SVN r52454] --- include/boost/smart_ptr/shared_ptr.hpp | 2 +- test/Jamfile.v2 | 1 + test/auto_ptr_lv_fail.cpp | 32 ++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/auto_ptr_lv_fail.cpp diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 1cddc04..8256d00 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -286,7 +286,7 @@ public: #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) template - shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr::type = 0 ): px( r.get() ), pn() + 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 ); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index eacee9a..07f0840 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -57,5 +57,6 @@ import testing ; [ run sp_recursive_assign_rv_test.cpp ] [ run sp_recursive_assign2_rv_test.cpp ] [ run esft_constructor_test.cpp ] + [ compile-fail auto_ptr_lv_fail.cpp ] ; } diff --git a/test/auto_ptr_lv_fail.cpp b/test/auto_ptr_lv_fail.cpp new file mode 100644 index 0000000..b86832e --- /dev/null +++ b/test/auto_ptr_lv_fail.cpp @@ -0,0 +1,32 @@ +#include + +#if defined(BOOST_MSVC) +#pragma warning(disable: 4786) // identifier truncated in debug info +#pragma warning(disable: 4710) // function not inlined +#pragma warning(disable: 4711) // function selected for automatic inline expansion +#pragma warning(disable: 4514) // unreferenced inline removed +#endif + +// +// auto_ptr_lv_fail.cpp - a negative test for converting an auto_ptr to shared_ptr +// +// Copyright 2009 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 + +void f( boost::shared_ptr ) +{ +} + +int main() +{ + std::auto_ptr p; + f( p ); // must fail + return 0; +} From 4b4a62513f0bf33f86520fb737869fa269b61d3f Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 17 Apr 2009 20:24:01 +0000 Subject: [PATCH 020/210] Make ++a, where a is an atomic_count, return the new value. [SVN r52456] --- .../boost/smart_ptr/detail/atomic_count.hpp | 5 +- .../smart_ptr/detail/atomic_count_gcc.hpp | 10 ++-- .../smart_ptr/detail/atomic_count_gcc_x86.hpp | 11 +--- .../detail/atomic_count_pthreads.hpp | 4 +- .../smart_ptr/detail/atomic_count_sync.hpp | 4 +- test/Jamfile.v2 | 1 + test/atomic_count_test2.cpp | 55 +++++++++++++++++++ 7 files changed, 69 insertions(+), 21 deletions(-) create mode 100644 test/atomic_count_test2.cpp diff --git a/include/boost/smart_ptr/detail/atomic_count.hpp b/include/boost/smart_ptr/detail/atomic_count.hpp index a6ddea3..cc44ac2 100644 --- a/include/boost/smart_ptr/detail/atomic_count.hpp +++ b/include/boost/smart_ptr/detail/atomic_count.hpp @@ -31,13 +31,12 @@ // ++a; // // Effects: Atomically increments the value of a -// Returns: nothing +// Returns: (long) the new value of a // // --a; // // Effects: Atomically decrements the value of a -// Returns: (long) zero if the new value of a is zero, -// unspecified non-zero value otherwise (usually the new value) +// Returns: (long) the new value of a // // Important note: when --a returns zero, it must act as a // read memory barrier (RMB); i.e. the calling thread must diff --git a/include/boost/smart_ptr/detail/atomic_count_gcc.hpp b/include/boost/smart_ptr/detail/atomic_count_gcc.hpp index 1305632..54807e9 100644 --- a/include/boost/smart_ptr/detail/atomic_count_gcc.hpp +++ b/include/boost/smart_ptr/detail/atomic_count_gcc.hpp @@ -40,21 +40,21 @@ class atomic_count { public: - explicit atomic_count(long v) : value_(v) {} + explicit atomic_count( long v ) : value_( v ) {} - void operator++() + long operator++() { - __atomic_add(&value_, 1); + return __exchange_and_add( &value_, +1 ) + 1; } long operator--() { - return __exchange_and_add(&value_, -1) - 1; + return __exchange_and_add( &value_, -1 ) - 1; } operator long() const { - return __exchange_and_add(&value_, 0); + return __exchange_and_add( &value_, 0 ); } private: diff --git a/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp b/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp index 4fd1c57..5c44d7c 100644 --- a/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp +++ b/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp @@ -25,16 +25,9 @@ public: explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {} - void operator++() + long operator++() { - __asm__ - ( - "lock\n\t" - "incl %0": - "+m"( value_ ): // output (%0) - : // inputs - "cc" // clobbers - ); + return atomic_exchange_and_add( &value_, +1 ) + 1; } long operator--() diff --git a/include/boost/smart_ptr/detail/atomic_count_pthreads.hpp b/include/boost/smart_ptr/detail/atomic_count_pthreads.hpp index d8118f0..05f7867 100644 --- a/include/boost/smart_ptr/detail/atomic_count_pthreads.hpp +++ b/include/boost/smart_ptr/detail/atomic_count_pthreads.hpp @@ -62,10 +62,10 @@ public: pthread_mutex_destroy(&mutex_); } - void operator++() + long operator++() { scoped_lock lock(mutex_); - ++value_; + return ++value_; } long operator--() diff --git a/include/boost/smart_ptr/detail/atomic_count_sync.hpp b/include/boost/smart_ptr/detail/atomic_count_sync.hpp index f2d22fb..b6359b5 100644 --- a/include/boost/smart_ptr/detail/atomic_count_sync.hpp +++ b/include/boost/smart_ptr/detail/atomic_count_sync.hpp @@ -31,9 +31,9 @@ public: explicit atomic_count( long v ) : value_( v ) {} - void operator++() + long operator++() { - __sync_add_and_fetch( &value_, 1 ); + return __sync_add_and_fetch( &value_, 1 ); } long operator--() diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 07f0840..f52d641 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -58,5 +58,6 @@ import testing ; [ run sp_recursive_assign2_rv_test.cpp ] [ run esft_constructor_test.cpp ] [ compile-fail auto_ptr_lv_fail.cpp ] + [ run atomic_count_test2.cpp ] ; } diff --git a/test/atomic_count_test2.cpp b/test/atomic_count_test2.cpp new file mode 100644 index 0000000..7e6dd97 --- /dev/null +++ b/test/atomic_count_test2.cpp @@ -0,0 +1,55 @@ +// +// atomic_count_test2.cpp +// +// Copyright 2009 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 + +int main() +{ + boost::detail::atomic_count n( 4 ); + + BOOST_TEST( n == 4 ); + + BOOST_TEST( ++n == 5 ); + BOOST_TEST( ++n == 6 ); + + BOOST_TEST( n == 6 ); + + BOOST_TEST( --n == 5 ); + BOOST_TEST( --n == 4 ); + + BOOST_TEST( n == 4 ); + + boost::detail::atomic_count m( 0 ); + + BOOST_TEST( m == 0 ); + + BOOST_TEST( ++m == 1 ); + BOOST_TEST( ++m == 2 ); + + BOOST_TEST( m == 2 ); + + BOOST_TEST( --m == 1 ); + BOOST_TEST( --m == 0 ); + + BOOST_TEST( m == 0 ); + + BOOST_TEST( --m == -1 ); + BOOST_TEST( --m == -2 ); + + BOOST_TEST( m == -2 ); + + BOOST_TEST( ++m == -1 ); + BOOST_TEST( ++m == 0 ); + + BOOST_TEST( m == 0 ); + + return boost::report_errors(); +} From fc1254381487aa657b674ba626b273a822983ad0 Mon Sep 17 00:00:00 2001 From: Timothy Zachary Laine Date: Tue, 12 May 2009 16:18:15 +0000 Subject: [PATCH 021/210] Merged in smart_ptr changes from the sandbox/boost0x branch created for BoostCon '09. This adds move semantics to weak_ptr and intrusive_ptr. [SVN r52937] --- .../boost/smart_ptr/detail/shared_count.hpp | 14 ++ include/boost/smart_ptr/intrusive_ptr.hpp | 17 ++ include/boost/smart_ptr/shared_ptr.hpp | 4 +- include/boost/smart_ptr/weak_ptr.hpp | 47 ++++- test/Jamfile.v2 | 2 + test/intrusive_ptr_move_test.cpp | 184 ++++++++++++++++++ test/shared_ptr_move_test.cpp | 16 +- test/weak_ptr_move_test.cpp | 121 ++++++++++++ 8 files changed, 393 insertions(+), 12 deletions(-) create mode 100644 test/intrusive_ptr_move_test.cpp create mode 100644 test/weak_ptr_move_test.cpp diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index b968bba..4943e37 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -333,6 +333,20 @@ public: if(pi_ != 0) pi_->weak_add_ref(); } +// Move support + +#if defined( BOOST_HAS_RVALUE_REFS ) + + weak_count(weak_count && r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + r.pi_ = 0; + } + +#endif + ~weak_count() // nothrow { if(pi_ != 0) pi_->weak_release(); diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index d3bd02b..6927a59 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -109,6 +109,23 @@ public: return *this; } +#endif + +// Move support + +#if defined( BOOST_HAS_RVALUE_REFS ) + + intrusive_ptr(intrusive_ptr && rhs): px( rhs.px ) + { + rhs.px = 0; + } + + intrusive_ptr & operator=(intrusive_ptr && rhs) + { + this_type(std::move(rhs)).swap(*this); + return *this; + } + #endif intrusive_ptr & operator=(intrusive_ptr const & rhs) diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 8256d00..1b367f0 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -368,14 +368,14 @@ public: shared_ptr & operator=( shared_ptr && r ) // never throws { - this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); + this_type( std::move( r ) ).swap( *this ); return *this; } template shared_ptr & operator=( shared_ptr && r ) // never throws { - this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); + this_type( std::move( r ) ).swap( *this ); return *this; } diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index d21b874..621c433 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -70,11 +70,43 @@ public: weak_ptr( weak_ptr const & r ) #endif - : pn(r.pn) // never throws + : px(r.lock().get()), pn(r.pn) // never throws { - px = r.lock().get(); } +#if defined( BOOST_HAS_RVALUE_REFS ) + + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + weak_ptr( weak_ptr && r, typename detail::sp_enable_if_convertible::type = detail::sp_empty() ) + +#else + + weak_ptr( weak_ptr && r ) + +#endif + : px(r.lock().get()), pn(std::move(r.pn)) // never throws + { + r.px = 0; + } + + // for better efficiency in the T == Y case + weak_ptr( weak_ptr && r ): px( r.px ), pn(std::move(r.pn)) // never throws + { + r.px = 0; + } + + // for better efficiency in the T == Y case + weak_ptr & operator=( weak_ptr && r ) // never throws + { + this_type( std::move( r ) ).swap( *this ); + return *this; + } + + +#endif + template #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) @@ -99,6 +131,17 @@ public: return *this; } +#if defined( BOOST_HAS_RVALUE_REFS ) + + template + weak_ptr & operator=(weak_ptr && r) + { + this_type( std::move( r ) ).swap( *this ); + return *this; + } + +#endif + template weak_ptr & operator=(shared_ptr const & r) // never throws { diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f52d641..db4bfb1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -16,9 +16,11 @@ import testing ; [ run shared_ptr_basic_test.cpp : : : gcc:-Wno-non-virtual-dtor ] [ run shared_ptr_test.cpp : : : gcc:-Wno-non-virtual-dtor ] [ run weak_ptr_test.cpp ] + [ run weak_ptr_move_test.cpp ] [ run shared_from_this_test.cpp : : : gcc:-Wno-non-virtual-dtor ] [ run get_deleter_test.cpp ] [ run intrusive_ptr_test.cpp ] + [ run intrusive_ptr_move_test.cpp ] [ run atomic_count_test.cpp ] [ run lw_mutex_test.cpp ] [ compile-fail shared_ptr_assign_fail.cpp ] diff --git a/test/intrusive_ptr_move_test.cpp b/test/intrusive_ptr_move_test.cpp new file mode 100644 index 0000000..b5f0e65 --- /dev/null +++ b/test/intrusive_ptr_move_test.cpp @@ -0,0 +1,184 @@ +#include + +#if defined(BOOST_MSVC) + +#pragma warning(disable: 4786) // identifier truncated in debug info +#pragma warning(disable: 4710) // function not inlined +#pragma warning(disable: 4711) // function selected for automatic inline expansion +#pragma warning(disable: 4514) // unreferenced inline removed +#pragma warning(disable: 4355) // 'this' : used in base member initializer list +#pragma warning(disable: 4511) // copy constructor could not be generated +#pragma warning(disable: 4512) // assignment operator could not be generated + +#if (BOOST_MSVC >= 1310) +#pragma warning(disable: 4675) // resolved overload found with Koenig lookup +#endif + +#endif + +// +// intrusive_ptr_move_test.cpp +// +// Copyright (c) 2002-2005 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 + +#if defined( BOOST_HAS_RVALUE_REFS ) + +namespace N +{ + +class base +{ +private: + + boost::detail::atomic_count use_count_; + + base(base const &); + base & operator=(base const &); + +protected: + + base(): use_count_(0) + { + ++instances; + } + + virtual ~base() + { + --instances; + } + +public: + + static long instances; + + long use_count() const + { + return use_count_; + } + +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + + inline friend void intrusive_ptr_add_ref(base * p) + { + ++p->use_count_; + } + + inline friend void intrusive_ptr_release(base * p) + { + if(--p->use_count_ == 0) delete p; + } + +#else + + void add_ref() + { + ++use_count_; + } + + void release() + { + if(--use_count_ == 0) delete this; + } + +#endif +}; + +long base::instances = 0; + +} // namespace N + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + +namespace boost +{ + +inline void intrusive_ptr_add_ref(N::base * p) +{ + p->add_ref(); +} + +inline void intrusive_ptr_release(N::base * p) +{ + p->release(); +} + +} // namespace boost + +#endif + +// + +struct X: public virtual N::base +{ +}; + +struct Y: public X +{ +}; + +int main() +{ + BOOST_TEST( N::base::instances == 0 ); + + { + boost::intrusive_ptr p( new X ); + BOOST_TEST( N::base::instances == 1 ); + + boost::intrusive_ptr p2( std::move( p ) ); + BOOST_TEST( N::base::instances == 1 ); + BOOST_TEST( p.get() == 0 ); + + p2.reset(); + BOOST_TEST( N::base::instances == 0 ); + } + + { + boost::intrusive_ptr p( new X ); + BOOST_TEST( N::base::instances == 1 ); + + boost::intrusive_ptr p2; + p2 = std::move( p ); + BOOST_TEST( N::base::instances == 1 ); + BOOST_TEST( p.get() == 0 ); + + p2.reset(); + BOOST_TEST( N::base::instances == 0 ); + } + + { + boost::intrusive_ptr p( new X ); + BOOST_TEST( N::base::instances == 1 ); + + boost::intrusive_ptr p2( new X ); + BOOST_TEST( N::base::instances == 2 ); + p2 = std::move( p ); + BOOST_TEST( N::base::instances == 1 ); + BOOST_TEST( p.get() == 0 ); + + p2.reset(); + BOOST_TEST( N::base::instances == 0 ); + } + + return boost::report_errors(); +} + +#else // !defined( BOOST_HAS_RVALUE_REFS ) + +int main() +{ + return 0; +} + +#endif diff --git a/test/shared_ptr_move_test.cpp b/test/shared_ptr_move_test.cpp index bd785e4..c02ffa9 100644 --- a/test/shared_ptr_move_test.cpp +++ b/test/shared_ptr_move_test.cpp @@ -8,11 +8,11 @@ // http://www.boost.org/LICENSE_1_0.txt // -#if defined( BOOST_HAS_RVALUE_REFS ) - #include #include +#if defined( BOOST_HAS_RVALUE_REFS ) + struct X { static long instances; @@ -43,11 +43,11 @@ int main() boost::shared_ptr p( new X ); BOOST_TEST( X::instances == 1 ); - boost::shared_ptr p2( static_cast< boost::shared_ptr && >( p ) ); + boost::shared_ptr p2( std::move( p ) ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( p.get() == 0 ); - boost::shared_ptr p3( static_cast< boost::shared_ptr && >( p2 ) ); + boost::shared_ptr p3( std::move( p2 ) ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( p2.get() == 0 ); @@ -60,12 +60,12 @@ int main() BOOST_TEST( X::instances == 1 ); boost::shared_ptr p2; - p2 = static_cast< boost::shared_ptr && >( p ); + p2 = std::move( p ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( p.get() == 0 ); boost::shared_ptr p3; - p3 = static_cast< boost::shared_ptr && >( p2 ); + p3 = std::move( p2 ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( p2.get() == 0 ); @@ -79,13 +79,13 @@ int main() boost::shared_ptr p2( new X ); BOOST_TEST( X::instances == 2 ); - p2 = static_cast< boost::shared_ptr && >( p ); + p2 = std::move( p ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( p.get() == 0 ); boost::shared_ptr p3( new X ); BOOST_TEST( X::instances == 2 ); - p3 = static_cast< boost::shared_ptr && >( p2 ); + p3 = std::move( p2 ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( p2.get() == 0 ); diff --git a/test/weak_ptr_move_test.cpp b/test/weak_ptr_move_test.cpp new file mode 100644 index 0000000..572b13d --- /dev/null +++ b/test/weak_ptr_move_test.cpp @@ -0,0 +1,121 @@ +// +// weak_ptr_move_test.cpp +// +// Copyright (c) 2007 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 + +#if defined( BOOST_HAS_RVALUE_REFS ) + +struct X +{ + static long instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + +private: + + X( X const & ); + X & operator=( X const & ); +}; + +long X::instances = 0; + +int main() +{ + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr p_( new X ); + boost::weak_ptr p( p_ ); + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( p.use_count() == 1 ); + + boost::weak_ptr p2( std::move( p ) ); + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( p2.use_count() == 1 ); + BOOST_TEST( p.expired() ); + + boost::weak_ptr p3( std::move( p2 ) ); + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( p3.use_count() == 1 ); + BOOST_TEST( p2.expired() ); + + p_.reset(); + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( p3.expired() ); + } + + { + boost::shared_ptr p_( new X ); + boost::weak_ptr p( p_ ); + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( p.use_count() == 1 ); + + boost::weak_ptr p2; + p2 = static_cast< boost::weak_ptr && >( p ); + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( p2.use_count() == 1 ); + BOOST_TEST( p.expired() ); + + boost::weak_ptr p3; + p3 = std::move( p2 ); + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( p3.use_count() == 1 ); + BOOST_TEST( p2.expired() ); + + p_.reset(); + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( p3.expired() ); + } + + { + boost::shared_ptr p_( new X ); + boost::weak_ptr p( p_ ); + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( p.use_count() == 1 ); + + boost::shared_ptr p_2( new X ); + boost::weak_ptr p2( p_2 ); + BOOST_TEST( X::instances == 2 ); + p2 = std::move( p ); + BOOST_TEST( X::instances == 2 ); + BOOST_TEST( p2.use_count() == 1 ); + BOOST_TEST( p.expired() ); + BOOST_TEST( p2.lock() != p_2 ); + + boost::shared_ptr p_3( new X ); + boost::weak_ptr p3( p_3 ); + BOOST_TEST( X::instances == 3 ); + p3 = std::move( p2 ); + BOOST_TEST( X::instances == 3 ); + BOOST_TEST( p3.use_count() == 1 ); + BOOST_TEST( p2.expired() ); + BOOST_TEST( p3.lock() != p_3 ); + } + + return boost::report_errors(); +} + +#else // !defined( BOOST_HAS_RVALUE_REFS ) + +int main() +{ + return 0; +} + +#endif From 28d7e348c17d20c9ab25a5628da586d693cf14f3 Mon Sep 17 00:00:00 2001 From: Gennadiy Rozental Date: Sat, 6 Jun 2009 09:44:36 +0000 Subject: [PATCH 022/210] avoid C style casts [SVN r53672] --- include/boost/smart_ptr/detail/sp_convertible.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp index 7d9502d..66e5ec7 100644 --- a/include/boost/smart_ptr/detail/sp_convertible.hpp +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp @@ -45,7 +45,7 @@ template< class Y, class T > struct sp_convertible static yes f( T* ); static no f( ... ); - enum _vt { value = sizeof( f( (Y*)0 ) ) == sizeof(yes) }; + enum _vt { value = sizeof( f( static_cast(0) ) ) == sizeof(yes) }; }; struct sp_empty From f5cc79f58da49ebd1334e7e1439cf9f51620ada6 Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Sun, 26 Jul 2009 00:49:56 +0000 Subject: [PATCH 023/210] Copyrights on CMakeLists.txt to keep them from clogging up the inspect reports. This is essentially the same commit as r55095 on the release branch. [SVN r55159] --- CMakeLists.txt | 6 ++++++ test/CMakeLists.txt | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index abe2fc7..1c039fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# #---------------------------------------------------------------------------- # This file was automatically generated from the original CMakeLists.txt file # Add a variable to hold the headers for the library diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7ddae31..de59cfb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# boost_additional_test_dependencies(tokenizer BOOST_DEPENDS test intrusive) From e824e23ec26caa101fc28eabb4b34554a43a752b Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Sat, 17 Oct 2009 02:07:38 +0000 Subject: [PATCH 024/210] rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back [SVN r56942] --- CMakeLists.txt | 36 ------------------------------------ module.cmake | 1 - test/CMakeLists.txt | 24 ------------------------ 3 files changed, 61 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 module.cmake delete mode 100644 test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 1c039fc..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -#---------------------------------------------------------------------------- -# This file was automatically generated from the original CMakeLists.txt file -# Add a variable to hold the headers for the library -set (lib_headers - enable_shared_from_this.hpp - pointer_cast.hpp - scoped_array.hpp - scoped_ptr.hpp - shared_array.hpp - shared_ptr.hpp - weak_ptr.hpp -) - -# Add a library target to the build system -boost_library_project( - smart_ptr - # SRCDIRS - TESTDIRS test - HEADERS ${lib_headers} - # DOCDIRS - DESCRIPTION "Five smart pointer class templates." - MODULARIZED - AUTHORS "Greg Colvin" - "Beman Dawes " - "Peter Dimov " - "Darin Adler" - # MAINTAINERS -) - - diff --git a/module.cmake b/module.cmake deleted file mode 100644 index d83266c..0000000 --- a/module.cmake +++ /dev/null @@ -1 +0,0 @@ -boost_module(smart_ptr DEPENDS utility) \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index de59cfb..0000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -boost_additional_test_dependencies(tokenizer BOOST_DEPENDS test intrusive) - - -boost_test_run(smart_ptr_test) -boost_test_run(shared_ptr_basic_test) -boost_test_run(shared_ptr_test) -boost_test_run(weak_ptr_test) -boost_test_run(shared_from_this_test) -boost_test_run(get_deleter_test) -boost_test_run(intrusive_ptr_test) -boost_test_run(atomic_count_test) -boost_test_run(lw_mutex_test) -boost_test_compile_fail(shared_ptr_assign_fail) -boost_test_compile_fail(shared_ptr_delete_fail) -boost_test_run(shared_ptr_alloc2_test) -boost_test_run(pointer_cast_test) -boost_test_compile(pointer_to_other_test) -boost_test_run(auto_ptr_rv_test) From 32eb028e13de39ffccfdd9ae480aeda3a15c79a5 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Wed, 28 Oct 2009 19:10:47 +0000 Subject: [PATCH 025/210] Renamed enable_shared_from_this2 to enable_shared_from_raw and added shared_from_raw free function. These changes fix the pointer value in shared_ptr which were obtained before an external shared_ptr has taken ownership of the object (for example when a shared_ptr to this is obtained in an object's constructor). [SVN r57197] --- .../smart_ptr/enable_shared_from_raw.hpp | 157 ++++++++++++++++++ .../smart_ptr/enable_shared_from_this2.hpp | 132 --------------- include/boost/smart_ptr/shared_ptr.hpp | 10 +- test/esft_constructor_test.cpp | 26 ++- 4 files changed, 171 insertions(+), 154 deletions(-) create mode 100644 include/boost/smart_ptr/enable_shared_from_raw.hpp delete mode 100644 include/boost/smart_ptr/enable_shared_from_this2.hpp diff --git a/include/boost/smart_ptr/enable_shared_from_raw.hpp b/include/boost/smart_ptr/enable_shared_from_raw.hpp new file mode 100644 index 0000000..b5a03aa --- /dev/null +++ b/include/boost/smart_ptr/enable_shared_from_raw.hpp @@ -0,0 +1,157 @@ +#ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED +#define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED + +// +// enable_shared_from_raw.hpp +// +// Copyright 2002, 2009 Peter Dimov +// Copyright 2008-2009 Frank Mori Hess +// +// 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 + +namespace boost +{ +template boost::shared_ptr shared_from_raw(T *); + +namespace detail +{ +template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); + +class esft2_deleter_wrapper +{ +private: + + shared_ptr deleter_; + +public: + + esft2_deleter_wrapper() + { + } + + template< class T > void set_deleter( shared_ptr const & deleter ) + { + deleter_ = deleter; + } + + template< class T> void operator()( T* ) + { + BOOST_ASSERT( deleter_.use_count() <= 1 ); + deleter_.reset(); + } +}; + +} // namespace detail + +class enable_shared_from_raw +{ +protected: + + enable_shared_from_raw() + { + } + + enable_shared_from_raw( enable_shared_from_raw const & ) + { + } + + enable_shared_from_raw & operator=( enable_shared_from_raw const & ) + { + return *this; + } + + ~enable_shared_from_raw() + { + BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist + } + +private: + + mutable weak_ptr weak_this_; + mutable shared_ptr shared_this_; + +private: + + void init_weak_once() const + { + if( weak_this_.expired() ) + { + shared_this_.reset( static_cast(0), detail::esft2_deleter_wrapper() ); + weak_this_ = shared_this_; + } + } + +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +private: + template friend class shared_ptr; + template friend boost::shared_ptr shared_from_raw(T *); + template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); +#endif + + shared_ptr shared_from_this() + { + init_weak_once(); + return shared_ptr( weak_this_ ); + } + + shared_ptr shared_from_this() const + { + init_weak_once(); + return shared_ptr( weak_this_ ); + } + + // Note: invoked automatically by shared_ptr; do not call + template void _internal_accept_owner( shared_ptr * ppx, Y * py ) const + { + BOOST_ASSERT( ppx != 0 ); + + if( weak_this_.expired() ) + { + weak_this_ = *ppx; + } + else if( shared_this_.use_count() != 0 ) + { + BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that + + detail::esft2_deleter_wrapper * pd = boost::get_deleter( shared_this_ ); + BOOST_ASSERT( pd != 0 ); + + pd->set_deleter( *ppx ); + + ppx->reset( shared_this_, ppx->get() ); + shared_this_.reset(); + } + } +}; + +template +boost::shared_ptr shared_from_raw(T *p) +{ + return boost::shared_ptr(p->enable_shared_from_raw::shared_from_this(), p); +} + +namespace detail +{ + template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ) + { + if( pe != 0 ) + { + pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); + } + } +} // namepsace detail + +} // namespace boost + +#endif // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED diff --git a/include/boost/smart_ptr/enable_shared_from_this2.hpp b/include/boost/smart_ptr/enable_shared_from_this2.hpp deleted file mode 100644 index a5bfcff..0000000 --- a/include/boost/smart_ptr/enable_shared_from_this2.hpp +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED -#define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED - -// -// enable_shared_from_this2.hpp -// -// Copyright 2002, 2009 Peter Dimov -// Copyright 2008 Frank Mori Hess -// -// 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 - -namespace boost -{ - -namespace detail -{ - -class esft2_deleter_wrapper -{ -private: - - shared_ptr deleter_; - -public: - - esft2_deleter_wrapper() - { - } - - template< class T > void set_deleter( shared_ptr const & deleter ) - { - deleter_ = deleter; - } - - template< class T> void operator()( T* ) - { - BOOST_ASSERT( deleter_.use_count() <= 1 ); - deleter_.reset(); - } -}; - -} // namespace detail - -template< class T > class enable_shared_from_this2 -{ -protected: - - enable_shared_from_this2() - { - } - - enable_shared_from_this2( enable_shared_from_this2 const & ) - { - } - - enable_shared_from_this2 & operator=( enable_shared_from_this2 const & ) - { - return *this; - } - - ~enable_shared_from_this2() - { - BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist - } - -private: - - mutable weak_ptr weak_this_; - mutable shared_ptr shared_this_; - -public: - - shared_ptr shared_from_this() - { - init_weak_once(); - return shared_ptr( weak_this_ ); - } - - shared_ptr shared_from_this() const - { - init_weak_once(); - return shared_ptr( weak_this_ ); - } - -private: - - void init_weak_once() const - { - if( weak_this_._empty() ) - { - shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() ); - weak_this_ = shared_this_; - } - } - -public: // actually private, but avoids compiler template friendship issues - - // Note: invoked automatically by shared_ptr; do not call - template void _internal_accept_owner( shared_ptr * ppx, Y * py ) const - { - BOOST_ASSERT( ppx != 0 ); - - if( weak_this_.use_count() == 0 ) - { - weak_this_ = shared_ptr( *ppx, py ); - } - else if( shared_this_.use_count() != 0 ) - { - BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that - - detail::esft2_deleter_wrapper * pd = boost::get_deleter( shared_this_ ); - BOOST_ASSERT( pd != 0 ); - - pd->set_deleter( *ppx ); - - ppx->reset( shared_this_, ppx->get() ); - shared_this_.reset(); - } - } -}; - -} // namespace boost - -#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 1b367f0..e29c376 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -61,7 +61,7 @@ namespace boost template class shared_ptr; template class weak_ptr; template class enable_shared_from_this; -template class enable_shared_from_this2; +class enable_shared_from_raw; namespace detail { @@ -110,13 +110,7 @@ template< class X, class Y, class T > inline void sp_enable_shared_from_this( bo } } -template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe ) -{ - if( pe != 0 ) - { - pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); - } -} +template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); #ifdef _MANAGED diff --git a/test/esft_constructor_test.cpp b/test/esft_constructor_test.cpp index ced24e2..ad0fb11 100644 --- a/test/esft_constructor_test.cpp +++ b/test/esft_constructor_test.cpp @@ -13,14 +13,13 @@ // 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_this2< X > +class X: public boost::enable_shared_from_raw { private: @@ -42,7 +41,7 @@ public: explicit X( int expected, boost::shared_ptr *early_px = 0 ): destroyed_( 0 ), deleted_( 0 ), expected_( expected ) { ++instances; - if( early_px ) *early_px = shared_from_this(); + if( early_px ) *early_px = shared_from_raw(this); } ~X() @@ -75,7 +74,7 @@ bool are_shared_owners(const boost::shared_ptr &a, const boost::shared_ptr return !(a < b) && !(b < a); } -struct Y: public boost::enable_shared_from_this2 +struct Y: public boost::enable_shared_from_raw {}; int main() @@ -87,6 +86,7 @@ int main() X* x = new X( 1, &early_px ); BOOST_TEST( early_px.use_count() > 0 ); BOOST_TEST( boost::get_deleter(early_px) == 0 ); + BOOST_TEST( early_px.get() == x ); boost::shared_ptr px( x, &X::deleter2 ); BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 ); BOOST_TEST(are_shared_owners(early_px, px)); @@ -117,7 +117,7 @@ int main() { boost::shared_ptr early_px; - X x( 1, &early_px ); + X x( 2, &early_px ); BOOST_TEST( early_px.use_count() > 0 ); boost::shared_ptr px( &x, &X::deleter ); BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 ); @@ -125,13 +125,11 @@ int main() BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); px.reset(); - try - { - x.shared_from_this(); - BOOST_ERROR("x did not throw bad_weak_ptr"); - } - catch( const boost::bad_weak_ptr & ) - {} + // test reinitialization after all shared_ptr have expired + early_px = shared_from_raw(&x); + px.reset( &x, &X::deleter ); + BOOST_TEST(are_shared_owners(early_px, px)); + early_px.reset(); } BOOST_TEST( X::instances == 0 ); @@ -157,7 +155,7 @@ int main() px.reset(); try { - y.shared_from_this(); + shared_from_raw(&y); } catch( const boost::bad_weak_ptr & ) { From 2ee5eb70f3f0df0395916e84b700d126affd6607 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Wed, 28 Oct 2009 22:42:21 +0000 Subject: [PATCH 026/210] Brought back code which fixes get_deleter when it is called on a deleter which has been wrapped inside a deleter_wrapper by "shared_from_raw() in constructors" support. [SVN r57206] --- .../smart_ptr/enable_shared_from_raw.hpp | 24 --------- include/boost/smart_ptr/shared_ptr.hpp | 49 ++++++++++++++++++- test/esft_constructor_test.cpp | 4 +- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/include/boost/smart_ptr/enable_shared_from_raw.hpp b/include/boost/smart_ptr/enable_shared_from_raw.hpp index b5a03aa..5ce23d7 100644 --- a/include/boost/smart_ptr/enable_shared_from_raw.hpp +++ b/include/boost/smart_ptr/enable_shared_from_raw.hpp @@ -26,30 +26,6 @@ namespace detail { template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); -class esft2_deleter_wrapper -{ -private: - - shared_ptr deleter_; - -public: - - esft2_deleter_wrapper() - { - } - - template< class T > void set_deleter( shared_ptr const & deleter ) - { - deleter_ = deleter; - } - - template< class T> void operator()( T* ) - { - BOOST_ASSERT( deleter_.use_count() <= 1 ); - deleter_.reset(); - } -}; - } // namespace detail class enable_shared_from_raw diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index e29c376..3fcee9b 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -583,6 +583,9 @@ template std::basic_ostream & operator<< (std:: // get_deleter +namespace detail +{ + #if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \ ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \ ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) ) @@ -590,7 +593,7 @@ template std::basic_ostream & operator<< (std:: // g++ 2.9x doesn't allow static_cast(void *) // apparently EDG 2.38 and HP aCC A.03.35 also don't accept it -template D * get_deleter(shared_ptr const & p) +template D * basic_get_deleter(shared_ptr const & p) { void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D)); return const_cast(static_cast(q)); @@ -598,13 +601,55 @@ template D * get_deleter(shared_ptr const & p) #else -template D * get_deleter(shared_ptr const & p) +template D * basic_get_deleter(shared_ptr const & p) { return static_cast(p._internal_get_deleter(BOOST_SP_TYPEID(D))); } #endif +class esft2_deleter_wrapper +{ +private: + + shared_ptr deleter_; + +public: + + esft2_deleter_wrapper() + { + } + + template< class T > void set_deleter( shared_ptr const & deleter ) + { + deleter_ = deleter; + } + template D* get_deleter() const + { + return boost::detail::basic_get_deleter(deleter_); + } + template< class T> void operator()( T* ) + { + BOOST_ASSERT( deleter_.use_count() <= 1 ); + deleter_.reset(); + } +}; + +} // namespace detail + +template D * get_deleter(shared_ptr const & p) +{ + D *del = detail::basic_get_deleter(p); + if(del == 0) + { + detail::esft2_deleter_wrapper *del_wrapper = detail::basic_get_deleter(p); +// The following get_deleter method call is fully qualified because +// older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter() + if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter(); + } + return del; +} + // atomic access #if !defined(BOOST_SP_NO_ATOMIC_ACCESS) diff --git a/test/esft_constructor_test.cpp b/test/esft_constructor_test.cpp index ad0fb11..32a25b5 100644 --- a/test/esft_constructor_test.cpp +++ b/test/esft_constructor_test.cpp @@ -93,8 +93,8 @@ int main() px.reset(); BOOST_TEST( early_px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); - // X::deleter_type *pd = boost::get_deleter(early_px); - // BOOST_TEST(pd && *pd == &X::deleter2 ); + X::deleter_type *pd = boost::get_deleter(early_px); + BOOST_TEST(pd && *pd == &X::deleter2 ); } BOOST_TEST( X::instances == 0 ); From 9f49538b37e100a06708bf8d559901d956997dfa Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Thu, 5 Nov 2009 21:41:38 +0000 Subject: [PATCH 027/210] Added weak_from_raw(), for use in conjunction with enable_shared_from_raw base class. [SVN r57423] --- .../smart_ptr/enable_shared_from_raw.hpp | 12 ++++++ include/boost/smart_ptr/weak_ptr.hpp | 7 ++-- test/Jamfile.v2 | 1 + test/enable_shared_from_raw_test.cpp | 39 +++++++++++++++++++ 4 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 test/enable_shared_from_raw_test.cpp diff --git a/include/boost/smart_ptr/enable_shared_from_raw.hpp b/include/boost/smart_ptr/enable_shared_from_raw.hpp index 5ce23d7..b147a01 100644 --- a/include/boost/smart_ptr/enable_shared_from_raw.hpp +++ b/include/boost/smart_ptr/enable_shared_from_raw.hpp @@ -21,6 +21,7 @@ namespace boost { template boost::shared_ptr shared_from_raw(T *); +template boost::weak_ptr weak_from_raw(T *); namespace detail { @@ -72,6 +73,7 @@ public: private: template friend class shared_ptr; template friend boost::shared_ptr shared_from_raw(T *); + template friend boost::weak_ptr weak_from_raw(T *); template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); #endif @@ -114,9 +116,19 @@ private: template boost::shared_ptr shared_from_raw(T *p) { + BOOST_ASSERT(p != 0); return boost::shared_ptr(p->enable_shared_from_raw::shared_from_this(), p); } +template +boost::weak_ptr weak_from_raw(T *p) +{ + BOOST_ASSERT(p != 0); + boost::weak_ptr result; + result._internal_aliasing_assign(p->enable_shared_from_raw::weak_this_, p); + return result; +} + namespace detail { template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ) diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index 621c433..1ccbaf9 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -183,10 +183,11 @@ public: pn.swap(other.pn); } - void _internal_assign(T * px2, boost::detail::shared_count const & pn2) + template + void _internal_aliasing_assign(weak_ptr const & r, T * px2) { px = px2; - pn = pn2; + pn = r.pn; } template bool _internal_less(weak_ptr const & rhs) const @@ -225,6 +226,6 @@ template void swap(weak_ptr & a, weak_ptr & b) #ifdef BOOST_MSVC # pragma warning(pop) -#endif +#endif #endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index db4bfb1..815ac8f 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -59,6 +59,7 @@ import testing ; [ run sp_recursive_assign_rv_test.cpp ] [ run sp_recursive_assign2_rv_test.cpp ] [ run esft_constructor_test.cpp ] + [ run enable_shared_from_raw_test.cpp ] [ compile-fail auto_ptr_lv_fail.cpp ] [ run atomic_count_test2.cpp ] ; diff --git a/test/enable_shared_from_raw_test.cpp b/test/enable_shared_from_raw_test.cpp new file mode 100644 index 0000000..ba95ecc --- /dev/null +++ b/test/enable_shared_from_raw_test.cpp @@ -0,0 +1,39 @@ +#include + +// +// weak_from_raw_test.cpp +// +// Copyright (c) 2009 Frank Mori Hess +// +// 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: public boost::enable_shared_from_raw +{}; + +void basic_weak_from_raw_test() +{ + X *p(new X); + boost::weak_ptr weak = boost::weak_from_raw(p); + BOOST_TEST(weak.expired()); + boost::shared_ptr shared(p); + weak = boost::weak_from_raw(p); + BOOST_TEST(weak.expired() == false); + boost::shared_ptr shared2(weak); + BOOST_TEST((shared < shared2 || shared2 < shared) == false); + BOOST_TEST(shared.get() == p); +} + +int main() +{ + basic_weak_from_raw_test(); + return boost::report_errors(); +} From 502de325eed53bf8a78883ab007f6fe6e3e910ef Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Mon, 9 Nov 2009 16:33:35 +0000 Subject: [PATCH 028/210] Fixed access to enable_shared_from_raw::weak_this_ when BOOST_NO_MEMBER_TEMPLATE_FRIENDS is defined. [SVN r57518] --- include/boost/smart_ptr/enable_shared_from_raw.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/boost/smart_ptr/enable_shared_from_raw.hpp b/include/boost/smart_ptr/enable_shared_from_raw.hpp index b147a01..f659c04 100644 --- a/include/boost/smart_ptr/enable_shared_from_raw.hpp +++ b/include/boost/smart_ptr/enable_shared_from_raw.hpp @@ -51,11 +51,6 @@ protected: BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist } -private: - - mutable weak_ptr weak_this_; - mutable shared_ptr shared_this_; - private: void init_weak_once() const @@ -111,6 +106,10 @@ private: shared_this_.reset(); } } + + mutable weak_ptr weak_this_; +private: + mutable shared_ptr shared_this_; }; template From 18bfaea99669b3be8d4c5f59a1ef0169dd556283 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Mon, 9 Nov 2009 18:12:35 +0000 Subject: [PATCH 029/210] Fixed perfect forwarding for make_shared() in trunk, and added corresponding test. Refs #2962. [SVN r57520] --- include/boost/smart_ptr/make_shared.hpp | 4 +- test/Jamfile.v2 | 1 + test/make_shared_perfect_forwarding_test.cpp | 98 ++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 test/make_shared_perfect_forwarding_test.cpp diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp index 7e1e793..d477188 100644 --- a/include/boost/smart_ptr/make_shared.hpp +++ b/include/boost/smart_ptr/make_shared.hpp @@ -86,10 +86,12 @@ public: } }; -template< class T > T forward( T t ) +#if defined( BOOST_HAS_RVALUE_REFS ) +template< class T > T&& forward( T &&t ) { return t; } +#endif } // namespace detail diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 815ac8f..fee0107 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -45,6 +45,7 @@ import testing ; [ run spinlock_try_test.cpp : : : multi : spinlock_try_test.mt ] [ run spinlock_pool_test.cpp ] [ run make_shared_test.cpp ] + [ run make_shared_perfect_forwarding_test.cpp ] [ run sp_convertible_test.cpp ] [ run wp_convertible_test.cpp ] [ run ip_convertible_test.cpp ] diff --git a/test/make_shared_perfect_forwarding_test.cpp b/test/make_shared_perfect_forwarding_test.cpp new file mode 100644 index 0000000..45a111c --- /dev/null +++ b/test/make_shared_perfect_forwarding_test.cpp @@ -0,0 +1,98 @@ +// make_shared_perfect_forwarding_test.cpp - a test of make_shared +// perfect forwarding of constructor arguments when using a C++0x +// compiler. +// +// Copyright 2009 Frank Mori Hess +// +// 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 + +#ifndef BOOST_HAS_RVALUE_REFS + +int main() +{ + return 0; +} + +#else // BOOST_HAS_RVALUE_REFS + +class myarg +{ +public: + myarg() + {} +private: + myarg(myarg && other) + {} + myarg& operator=(myarg && other) + { + return *this; + } + myarg(const myarg & other) + {} + myarg& operator=(const myarg & other) + { + return *this; + } +}; + +class X +{ +public: + enum constructor_id + { + move_constructor, + const_ref_constructor, + ref_constructor + }; + + X(myarg &&arg): constructed_by_(move_constructor) + {} + X(const myarg &arg): constructed_by_(const_ref_constructor) + {} + X(myarg &arg): constructed_by_(ref_constructor) + {} + + constructor_id constructed_by_; +}; + +struct Y +{ + Y(int &value): ref(value) + {} + int &ref; +}; + +int main() +{ + { + myarg a; + boost::shared_ptr< X > x = boost::make_shared< X >(a); + BOOST_TEST( x->constructed_by_ == X::ref_constructor); + } + { + const myarg ca; + boost::shared_ptr< X > x = boost::make_shared< X >(ca); + BOOST_TEST( x->constructed_by_ == X::const_ref_constructor); + } + { + boost::shared_ptr< X > x = boost::make_shared< X >(myarg()); + BOOST_TEST( x->constructed_by_ == X::move_constructor); + } + { + int value = 1; + boost::shared_ptr< Y > y = boost::make_shared< Y >(value); + BOOST_TEST( y->ref == 1 && value == y->ref ); + ++y->ref; + BOOST_TEST( value == y->ref ); + } + + return boost::report_errors(); +} + +#endif // BOOST_HAS_RVALUE_REFS From 030a848c5f5b8778f654008378d95f865322ef1e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 26 Nov 2009 18:21:21 +0000 Subject: [PATCH 030/210] Fix SPARC asm operand failure. Refs #3678. Refs #3341. [SVN r57949] --- .../boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp index 8af6f0a..21fa59d 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @@ -30,9 +30,9 @@ namespace detail inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ ) { - __asm__ __volatile__( "cas %0, %2, %1" - : "+m" (*dest_), "+r" (swap_) - : "r" (compare_) + __asm__ __volatile__( "cas [%1], %2, %0" + : "+r" (swap_) + : "r" (dest_), "r" (compare_) : "memory" ); return swap_; From c97eebabf7e2b569fda8749b2136da676ff611c1 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 26 Nov 2009 20:11:05 +0000 Subject: [PATCH 031/210] Fix enable_shared_from_this example. Refs #3404. [SVN r57950] --- enable_shared_from_this.html | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/enable_shared_from_this.html b/enable_shared_from_this.html index 3f35665..c4caa25 100644 --- a/enable_shared_from_this.html +++ b/enable_shared_from_this.html @@ -29,20 +29,24 @@ and shared_ptr<T const>, depending on constness, to this.

    Example

    -class Y: public enable_shared_from_this<Y>
    +#include <boost/enable_shared_from_this.hpp>
    +#include <boost/shared_ptr.hpp>
    +#include <cassert>
    +
    +class Y: public boost::enable_shared_from_this<Y>
     {
     public:
     
    -    shared_ptr<Y> f()
    +    boost::shared_ptr<Y> f()
         {
             return shared_from_this();
         }
    -}
    +};
     
     int main()
     {
    -    shared_ptr<Y> p(new Y);
    -    shared_ptr<Y> q = p->f();
    +    boost::shared_ptr<Y> p(new Y);
    +    boost::shared_ptr<Y> q = p->f();
         assert(p == q);
         assert(!(p < q || q < p)); // p and q must share ownership
     }
    
    From 979e76b7e09b4b6281effa1af239559ba7876465 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 26 Nov 2009 20:17:55 +0000
    Subject: [PATCH 032/210] Enable __sync use on Intel 11.0 or later. Refs #3351.
    
    [SVN r57951]
    ---
     include/boost/smart_ptr/detail/sp_has_sync.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    index cb0282d..7fcd09e 100644
    --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp
    +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    @@ -40,7 +40,7 @@
     #undef BOOST_SP_HAS_SYNC
     #endif
     
    -#if defined( __INTEL_COMPILER ) && !defined( __ia64__ )
    +#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1100 )
     #undef BOOST_SP_HAS_SYNC
     #endif
     
    
    From d0a9d764944b3771fcfc538dc3796c1b78a18fab Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 26 Nov 2009 20:55:05 +0000
    Subject: [PATCH 033/210] Add error checking to lwm_pthreads.hpp. Refs #2681.
    
    [SVN r57953]
    ---
     include/boost/smart_ptr/detail/lwm_pthreads.hpp | 11 ++++++-----
     1 file changed, 6 insertions(+), 5 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/lwm_pthreads.hpp b/include/boost/smart_ptr/detail/lwm_pthreads.hpp
    index fc20dbb..8eda518 100644
    --- a/include/boost/smart_ptr/detail/lwm_pthreads.hpp
    +++ b/include/boost/smart_ptr/detail/lwm_pthreads.hpp
    @@ -17,6 +17,7 @@
     // http://www.boost.org/LICENSE_1_0.txt)
     //
     
    +#include 
     #include 
     
     namespace boost
    @@ -42,15 +43,15 @@ public:
     // HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
     
     #if defined(__hpux) && defined(_DECTHREADS_)
    -        pthread_mutex_init(&m_, pthread_mutexattr_default);
    +        BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
     #else
    -        pthread_mutex_init(&m_, 0);
    +        BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
     #endif
         }
     
         ~lightweight_mutex()
         {
    -        pthread_mutex_destroy(&m_);
    +        BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
         }
     
         class scoped_lock;
    @@ -69,12 +70,12 @@ public:
     
             scoped_lock(lightweight_mutex & m): m_(m.m_)
             {
    -            pthread_mutex_lock(&m_);
    +            BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
             }
     
             ~scoped_lock()
             {
    -            pthread_mutex_unlock(&m_);
    +            BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
             }
         };
     };
    
    From fa597b877e1453459df948c7b74e8cc71e907dff Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 26 Nov 2009 21:04:36 +0000
    Subject: [PATCH 034/210] Extend Borland workaround to 6.2.
    
    [SVN r57955]
    ---
     include/boost/smart_ptr/detail/sp_convertible.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp
    index 66e5ec7..b7f0ea8 100644
    --- a/include/boost/smart_ptr/detail/sp_convertible.hpp
    +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp
    @@ -25,7 +25,7 @@
     # define BOOST_SP_NO_SP_CONVERTIBLE
     #endif
     
    -#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ <= 0x610 )
    +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ <= 0x620 )
     # define BOOST_SP_NO_SP_CONVERTIBLE
     #endif
     
    
    From b691be0af982d4d1bd179fd40679899193e5b2a6 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 26 Nov 2009 21:20:47 +0000
    Subject: [PATCH 035/210] Remove std::move references. Refs #3570.
    
    [SVN r57957]
    ---
     include/boost/smart_ptr/intrusive_ptr.hpp |  2 +-
     include/boost/smart_ptr/shared_ptr.hpp    |  4 ++--
     include/boost/smart_ptr/weak_ptr.hpp      | 10 +++++-----
     3 files changed, 8 insertions(+), 8 deletions(-)
    
    diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp
    index 6927a59..0e30ece 100644
    --- a/include/boost/smart_ptr/intrusive_ptr.hpp
    +++ b/include/boost/smart_ptr/intrusive_ptr.hpp
    @@ -122,7 +122,7 @@ public:
     
         intrusive_ptr & operator=(intrusive_ptr && rhs)
         {
    -        this_type(std::move(rhs)).swap(*this);
    +        this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
             return *this;
         }
     
    diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp
    index 3fcee9b..d826783 100644
    --- a/include/boost/smart_ptr/shared_ptr.hpp
    +++ b/include/boost/smart_ptr/shared_ptr.hpp
    @@ -362,14 +362,14 @@ public:
     
         shared_ptr & operator=( shared_ptr && r ) // never throws
         {
    -        this_type( std::move( r ) ).swap( *this );
    +        this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
             return *this;
         }
     
         template
         shared_ptr & operator=( shared_ptr && r ) // never throws
         {
    -        this_type( std::move( r ) ).swap( *this );
    +        this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
             return *this;
         }
     
    diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp
    index 1ccbaf9..ceb026b 100644
    --- a/include/boost/smart_ptr/weak_ptr.hpp
    +++ b/include/boost/smart_ptr/weak_ptr.hpp
    @@ -86,13 +86,13 @@ public:
         weak_ptr( weak_ptr && r )
     
     #endif
    -    : px(r.lock().get()), pn(std::move(r.pn)) // never throws
    +    : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws
         {
             r.px = 0;
         }
     
         // for better efficiency in the T == Y case
    -    weak_ptr( weak_ptr && r ): px( r.px ), pn(std::move(r.pn)) // never throws
    +    weak_ptr( weak_ptr && r ): px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws
         {
             r.px = 0;
         }
    @@ -100,7 +100,7 @@ public:
         // for better efficiency in the T == Y case
         weak_ptr & operator=( weak_ptr && r ) // never throws
         {
    -        this_type( std::move( r ) ).swap( *this );
    +        this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
             return *this;
         }
     
    @@ -134,9 +134,9 @@ public:
     #if defined( BOOST_HAS_RVALUE_REFS )
     
         template
    -    weak_ptr & operator=(weak_ptr && r)
    +    weak_ptr & operator=( weak_ptr && r )
         {
    -        this_type( std::move( r ) ).swap( *this );
    +        this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
             return *this;
         }
     
    
    From 3824a6b156fb07e7461a0642d96928da73463737 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 2 Dec 2009 11:47:58 +0000
    Subject: [PATCH 036/210] Add memory_order_consume.
    
    [SVN r58094]
    ---
     include/boost/memory_order.hpp | 22 ++++++++++++++++++++--
     1 file changed, 20 insertions(+), 2 deletions(-)
    
    diff --git a/include/boost/memory_order.hpp b/include/boost/memory_order.hpp
    index 2524e8a..4945af6 100644
    --- a/include/boost/memory_order.hpp
    +++ b/include/boost/memory_order.hpp
    @@ -11,7 +11,7 @@
     //
     //  Defines enum boost::memory_order per the C++0x working draft
     //
    -//  Copyright (c) 2008 Peter Dimov
    +//  Copyright (c) 2008, 2009 Peter Dimov
     //
     //  Distributed under the Boost Software License, Version 1.0.
     //  See accompanying file LICENSE_1_0.txt or copy at
    @@ -21,13 +21,31 @@
     namespace boost
     {
     
    +//
    +// Enum values are chosen so that code that needs to insert
    +// a trailing fence for acquire semantics can use a single
    +// test such as:
    +//
    +// if( mo & memory_order_acquire ) { ...fence... }
    +//
    +// For leading fences one can use:
    +//
    +// if( mo & memory_order_release ) { ...fence... }
    +//
    +// Architectures such as Alpha that need a fence on consume
    +// can use:
    +//
    +// if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... }
    +//
    +
     enum memory_order
     {
         memory_order_relaxed = 0,
         memory_order_acquire = 1,
         memory_order_release = 2,
         memory_order_acq_rel = 3, // acquire | release
    -    memory_order_seq_cst = 7  // acq_rel | 4
    +    memory_order_seq_cst = 7, // acq_rel | 4
    +    memory_order_consume = 8
     };
     
     } // namespace boost
    
    From e78efdbb96418045a219baa35aad4999cd41db57 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 3 Dec 2009 18:10:37 +0000
    Subject: [PATCH 037/210] Fix smart_ptr tests to not require RTTI.
    
    [SVN r58123]
    ---
     test/pointer_cast_test.cpp     | 10 ++++++++++
     test/shared_from_this_test.cpp |  2 ++
     test/shared_ptr_basic_test.cpp | 12 ++++++++++++
     test/shared_ptr_test.cpp       |  8 ++++++++
     4 files changed, 32 insertions(+)
    
    diff --git a/test/pointer_cast_test.cpp b/test/pointer_cast_test.cpp
    index 6e4620c..bd25dd1 100644
    --- a/test/pointer_cast_test.cpp
    +++ b/test/pointer_cast_test.cpp
    @@ -9,6 +9,8 @@
     // http://www.boost.org/LICENSE_1_0.txt)
     //
     
    +#include 
    +
     #include 
     
     #include 
    @@ -58,6 +60,8 @@ class derived_derived
     
     // And now some simple check functions
     
    +#if !defined( BOOST_NO_RTTI )
    +
     template 
     bool check_dynamic_pointer_cast(const BasePtr &ptr)
     {
    @@ -74,6 +78,8 @@ bool check_dynamic_pointer_cast(const BasePtr &ptr)
           dynamic_cast(boost::get_pointer(ptr));
     }
     
    +#endif
    +
     template 
     bool check_static_pointer_cast(const BasePtr &ptr)
     {
    @@ -107,7 +113,9 @@ int main()
     
             boost::shared_ptr ptr(new derived);
     
    +#if !defined( BOOST_NO_RTTI )
             BOOST_TEST( check_dynamic_pointer_cast( ptr ) );
    +#endif
             BOOST_TEST( check_static_pointer_cast( ptr ) );
             BOOST_TEST( check_const_pointer_cast( ptr ) );
         }
    @@ -117,7 +125,9 @@ int main()
     
             boost::scoped_ptr ptr(new derived);
     
    +#if !defined( BOOST_NO_RTTI )
             BOOST_TEST( check_dynamic_pointer_cast( ptr.get() ) );
    +#endif
             BOOST_TEST( check_static_pointer_cast( ptr.get() ) );
             BOOST_TEST( check_const_pointer_cast( ptr.get() ) );
         }
    diff --git a/test/shared_from_this_test.cpp b/test/shared_from_this_test.cpp
    index 68d6098..b3d7838 100644
    --- a/test/shared_from_this_test.cpp
    +++ b/test/shared_from_this_test.cpp
    @@ -63,10 +63,12 @@ void test()
     
             px->f();
     
    +#if !defined( BOOST_NO_RTTI )
             boost::shared_ptr py2 = boost::dynamic_pointer_cast(px);
             BOOST_TEST(py.get() == py2.get());
             BOOST_TEST(!(py < py2 || py2 < py));
             BOOST_TEST(py.use_count() == 3);
    +#endif
         }
         catch( boost::bad_weak_ptr const& )
         {
    diff --git a/test/shared_ptr_basic_test.cpp b/test/shared_ptr_basic_test.cpp
    index f699848..4d4179e 100644
    --- a/test/shared_ptr_basic_test.cpp
    +++ b/test/shared_ptr_basic_test.cpp
    @@ -188,6 +188,7 @@ int main()
                 test_eq(p, q);
             }
     
    +#if !defined( BOOST_NO_RTTI )
             shared_ptr p3 = dynamic_pointer_cast(p);
             shared_ptr p4 = dynamic_pointer_cast(p2);
     
    @@ -201,6 +202,7 @@ int main()
             test_is_Y(p3);
             test_eq2(p, p3);
             test_ne2(p2, p4);
    +#endif
     
             shared_ptr p5(p);
     
    @@ -214,13 +216,17 @@ int main()
     
             p.reset();
             p2.reset();
    +#if !defined( BOOST_NO_RTTI )
             p3.reset();
             p4.reset();
    +#endif
     
             test_is_zero(p);
             test_is_zero(p2);
    +#if !defined( BOOST_NO_RTTI )
             test_is_zero(p3);
             test_is_zero(p4);
    +#endif
     
             BOOST_TEST(p5.use_count() == 1);
     
    @@ -250,6 +256,7 @@ int main()
                 test_is_nonzero(wp2.lock());
             }
     
    +#if !defined( BOOST_NO_RTTI )
             weak_ptr wp3 = dynamic_pointer_cast(wp2.lock());
     
             BOOST_TEST(wp3.use_count() == 1);
    @@ -259,12 +266,15 @@ int main()
     
             BOOST_TEST(wp4.use_count() == 1);
             test_shared(wp2, wp4);
    +#endif
     
             wp1 = p2;
             test_is_zero(wp1.lock());
     
    +#if !defined( BOOST_NO_RTTI )
             wp1 = p4;
             wp1 = wp3;
    +#endif
             wp1 = wp2;
     
             BOOST_TEST(wp1.use_count() == 1);
    @@ -279,7 +289,9 @@ int main()
     
             BOOST_TEST(wp1.use_count() == 0);
             BOOST_TEST(wp2.use_count() == 0);
    +#if !defined( BOOST_NO_RTTI )
             BOOST_TEST(wp3.use_count() == 0);
    +#endif
     
             // Test operator< stability for std::set< weak_ptr<> >
             // Thanks to Joe Gottman for pointing this out
    diff --git a/test/shared_ptr_test.cpp b/test/shared_ptr_test.cpp
    index f697192..60ed906 100644
    --- a/test/shared_ptr_test.cpp
    +++ b/test/shared_ptr_test.cpp
    @@ -2462,6 +2462,8 @@ void test()
     
     } // namespace n_const_cast
     
    +#if !defined( BOOST_NO_RTTI )
    +
     namespace n_dynamic_cast
     {
     
    @@ -2527,6 +2529,8 @@ void test()
     
     } // namespace n_dynamic_cast
     
    +#endif
    +
     namespace n_map
     {
     
    @@ -3200,10 +3204,12 @@ void test()
         BOOST_TEST(px.get() != 0);
         BOOST_TEST(py.use_count() == 2);
     
    +#if !defined( BOOST_NO_RTTI )
         boost::shared_ptr py2 = boost::dynamic_pointer_cast(px);
         BOOST_TEST(py.get() == py2.get());
         BOOST_TEST(!(py < py2 || py2 < py));
         BOOST_TEST(py.use_count() == 3);
    +#endif
     }
     
     } // namespace n_spt_shared_from_this
    @@ -3229,7 +3235,9 @@ int main()
         n_comparison::test();
         n_static_cast::test();
         n_const_cast::test();
    +#if !defined( BOOST_NO_RTTI )
         n_dynamic_cast::test();
    +#endif
     
         n_map::test();
     
    
    From 577528812a81e31954b210226b30c0ad3e82be94 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 3 Dec 2009 20:31:01 +0000
    Subject: [PATCH 038/210] Fix sp_typeinfo to match the interface of
     std::type_info.
    
    [SVN r58127]
    ---
     include/boost/detail/sp_typeinfo.hpp | 54 +++++++++++++++++++++++++---
     test/Jamfile.v2                      |  1 +
     test/sp_typeinfo_test.cpp            | 51 ++++++++++++++++++++++++++
     3 files changed, 102 insertions(+), 4 deletions(-)
     create mode 100644 test/sp_typeinfo_test.cpp
    
    diff --git a/include/boost/detail/sp_typeinfo.hpp b/include/boost/detail/sp_typeinfo.hpp
    index e78c943..636fe27 100644
    --- a/include/boost/detail/sp_typeinfo.hpp
    +++ b/include/boost/detail/sp_typeinfo.hpp
    @@ -19,20 +19,66 @@
     
     #if defined( BOOST_NO_TYPEID )
     
    +#include 
    +#include 
    +
     namespace boost
     {
     
     namespace detail
     {
     
    -typedef void* sp_typeinfo;
    +class sp_typeinfo
    +{
    +private:
    +
    +    sp_typeinfo( sp_typeinfo const& );
    +    sp_typeinfo& operator=( sp_typeinfo const& );
    +
    +    char const * name_;
    +
    +public:
    +
    +    explicit sp_typeinfo( char const * name ): name_( name )
    +    {
    +    }
    +
    +    bool operator==( sp_typeinfo const& rhs ) const
    +    {
    +        return this == &rhs;
    +    }
    +
    +    bool operator!=( sp_typeinfo const& rhs ) const
    +    {
    +        return this != &rhs;
    +    }
    +
    +    bool before( sp_typeinfo const& rhs ) const
    +    {
    +        return std::less< sp_typeinfo const* >()( this, &rhs );
    +    }
    +
    +    char const* name() const
    +    {
    +        return name_;
    +    }
    +};
     
     template struct sp_typeid_
     {
    -    static char v_;
    +    static sp_typeinfo ti_;
    +
    +    static char const * name()
    +    {
    +        return BOOST_CURRENT_FUNCTION;
    +    }
     };
     
    -template char sp_typeid_< T >::v_;
    +template sp_typeinfo sp_typeid_< T >::ti_( sp_typeid_< T >::name() );
    +
    +template struct sp_typeid_< T & >: sp_typeid_< T >
    +{
    +};
     
     template struct sp_typeid_< T const >: sp_typeid_< T >
     {
    @@ -50,7 +96,7 @@ template struct sp_typeid_< T const volatile >: sp_typeid_< T >
     
     } // namespace boost
     
    -#define BOOST_SP_TYPEID(T) (&boost::detail::sp_typeid_::v_)
    +#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_::ti_)
     
     #else
     
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
    index fee0107..8782d59 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -63,5 +63,6 @@ import testing ;
               [ run enable_shared_from_raw_test.cpp ]
               [ compile-fail auto_ptr_lv_fail.cpp ]
               [ run atomic_count_test2.cpp ]
    +          [ run sp_typeinfo_test.cpp ]
             ;
     }
    diff --git a/test/sp_typeinfo_test.cpp b/test/sp_typeinfo_test.cpp
    new file mode 100644
    index 0000000..c47d04e
    --- /dev/null
    +++ b/test/sp_typeinfo_test.cpp
    @@ -0,0 +1,51 @@
    +//
    +// sp_typeinfo_test.cpp
    +//
    +// Copyright (c) 2009 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 
    +
    +int main()
    +{
    +    BOOST_TEST( BOOST_SP_TYPEID( int ) == BOOST_SP_TYPEID( int ) );
    +    BOOST_TEST( BOOST_SP_TYPEID( int ) != BOOST_SP_TYPEID( long ) );
    +    BOOST_TEST( BOOST_SP_TYPEID( int ) != BOOST_SP_TYPEID( void ) );
    +
    +    boost::detail::sp_typeinfo const & ti = BOOST_SP_TYPEID( int );
    +
    +    boost::detail::sp_typeinfo const * pti = &BOOST_SP_TYPEID( int );
    +    BOOST_TEST( *pti == ti );
    +
    +    BOOST_TEST( ti == ti );
    +    BOOST_TEST( !( ti != ti ) );
    +    BOOST_TEST( !ti.before( ti ) );
    +
    +    char const * nti = ti.name();
    +	std::cout << nti << std::endl;
    +
    +    boost::detail::sp_typeinfo const & tv = BOOST_SP_TYPEID( void );
    +
    +    boost::detail::sp_typeinfo const * ptv = &BOOST_SP_TYPEID( void );
    +    BOOST_TEST( *ptv == tv );
    +
    +    BOOST_TEST( tv == tv );
    +    BOOST_TEST( !( tv != tv ) );
    +    BOOST_TEST( !tv.before( tv ) );
    +
    +    char const * ntv = tv.name();
    +	std::cout << ntv << std::endl;
    +
    +    BOOST_TEST( ti != tv );
    +    BOOST_TEST( !( ti == tv ) );
    +
    +    BOOST_TEST( ti.before( tv ) != tv.before( ti ) );
    +
    +    return boost::report_errors();
    +}
    
    From 1b91c1dbea01681e0bd23042c7121196efb8a78a Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 10 Dec 2009 20:34:46 +0000
    Subject: [PATCH 039/210] Avoid static destruction order issues with
     quick_allocator.
    
    [SVN r58275]
    ---
     include/boost/smart_ptr/detail/quick_allocator.hpp | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/quick_allocator.hpp b/include/boost/smart_ptr/detail/quick_allocator.hpp
    index 6d136f8..159bd5e 100644
    --- a/include/boost/smart_ptr/detail/quick_allocator.hpp
    +++ b/include/boost/smart_ptr/detail/quick_allocator.hpp
    @@ -74,8 +74,9 @@ template struct allocator_impl
     
         static lightweight_mutex & mutex()
         {
    -        static lightweight_mutex m;
    -        return m;
    +        static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm;
    +        static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
    +        return *pm;
         }
     
         static lightweight_mutex * mutex_init;
    
    From ae34be773f948d20667c47b1eb1c664591d8e456 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Fri, 11 Dec 2009 22:36:35 +0000
    Subject: [PATCH 040/210] Qualify detail:: references. Detabify
     sp_typeinfo_test.cpp.
    
    [SVN r58306]
    ---
     include/boost/smart_ptr/intrusive_ptr.hpp |  2 +-
     include/boost/smart_ptr/shared_ptr.hpp    | 10 +++++-----
     include/boost/smart_ptr/weak_ptr.hpp      |  6 +++---
     test/sp_typeinfo_test.cpp                 |  4 ++--
     4 files changed, 11 insertions(+), 11 deletions(-)
    
    diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp
    index 0e30ece..e72eb21 100644
    --- a/include/boost/smart_ptr/intrusive_ptr.hpp
    +++ b/include/boost/smart_ptr/intrusive_ptr.hpp
    @@ -77,7 +77,7 @@ public:
         template
     #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
     
    -    intrusive_ptr( intrusive_ptr const & rhs, typename detail::sp_enable_if_convertible::type = detail::sp_empty() )
    +    intrusive_ptr( intrusive_ptr const & rhs, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() )
     
     #else
     
    diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp
    index d826783..3f1c1d3 100644
    --- a/include/boost/smart_ptr/shared_ptr.hpp
    +++ b/include/boost/smart_ptr/shared_ptr.hpp
    @@ -222,7 +222,7 @@ public:
         template
     #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
     
    -    shared_ptr( shared_ptr const & r, typename detail::sp_enable_if_convertible::type = detail::sp_empty() )
    +    shared_ptr( shared_ptr const & r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() )
     
     #else
     
    @@ -347,7 +347,7 @@ public:
         template
     #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
     
    -    shared_ptr( shared_ptr && r, typename detail::sp_enable_if_convertible::type = detail::sp_empty() )
    +    shared_ptr( shared_ptr && r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() )
     
     #else
     
    @@ -442,7 +442,7 @@ public:
             return pn < rhs.pn;
         }
     
    -    void * _internal_get_deleter( detail::sp_typeinfo const & ti ) const
    +    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
         {
             return pn.get_deleter( ti );
         }
    @@ -639,10 +639,10 @@ public:
     
     template D * get_deleter(shared_ptr const & p)
     {
    -    D *del = detail::basic_get_deleter(p);
    +    D *del = boost::detail::basic_get_deleter(p);
         if(del == 0)
         {
    -        detail::esft2_deleter_wrapper *del_wrapper = detail::basic_get_deleter(p);
    +        boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter(p);
     // The following get_deleter method call is fully qualified because
     // older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter()
             if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter();
    diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp
    index ceb026b..db56103 100644
    --- a/include/boost/smart_ptr/weak_ptr.hpp
    +++ b/include/boost/smart_ptr/weak_ptr.hpp
    @@ -63,7 +63,7 @@ public:
         template
     #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
     
    -    weak_ptr( weak_ptr const & r, typename detail::sp_enable_if_convertible::type = detail::sp_empty() )
    +    weak_ptr( weak_ptr const & r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() )
     
     #else
     
    @@ -79,7 +79,7 @@ public:
         template
     #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
     
    -    weak_ptr( weak_ptr && r, typename detail::sp_enable_if_convertible::type = detail::sp_empty() )
    +    weak_ptr( weak_ptr && r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() )
     
     #else
     
    @@ -110,7 +110,7 @@ public:
         template
     #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
     
    -    weak_ptr( shared_ptr const & r, typename detail::sp_enable_if_convertible::type = detail::sp_empty() )
    +    weak_ptr( shared_ptr const & r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() )
     
     #else
     
    diff --git a/test/sp_typeinfo_test.cpp b/test/sp_typeinfo_test.cpp
    index c47d04e..e29e576 100644
    --- a/test/sp_typeinfo_test.cpp
    +++ b/test/sp_typeinfo_test.cpp
    @@ -28,7 +28,7 @@ int main()
         BOOST_TEST( !ti.before( ti ) );
     
         char const * nti = ti.name();
    -	std::cout << nti << std::endl;
    +    std::cout << nti << std::endl;
     
         boost::detail::sp_typeinfo const & tv = BOOST_SP_TYPEID( void );
     
    @@ -40,7 +40,7 @@ int main()
         BOOST_TEST( !tv.before( tv ) );
     
         char const * ntv = tv.name();
    -	std::cout << ntv << std::endl;
    +    std::cout << ntv << std::endl;
     
         BOOST_TEST( ti != tv );
         BOOST_TEST( !( ti == tv ) );
    
    From f7919f0b9f473ccaf49ae2eda25a19193d46d03c Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 5 Apr 2010 18:53:58 +0000
    Subject: [PATCH 041/210] Borland 6.21 still needs the workaround. Refs #4067.
    
    [SVN r61074]
    ---
     include/boost/smart_ptr/detail/sp_convertible.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp
    index b7f0ea8..fe44069 100644
    --- a/include/boost/smart_ptr/detail/sp_convertible.hpp
    +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp
    @@ -25,7 +25,7 @@
     # define BOOST_SP_NO_SP_CONVERTIBLE
     #endif
     
    -#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ <= 0x620 )
    +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
     # define BOOST_SP_NO_SP_CONVERTIBLE
     #endif
     
    
    From 458dffdab9fadb550fc9660505bbc31348a27170 Mon Sep 17 00:00:00 2001
    From: Steven Watanabe 
    Date: Sat, 17 Apr 2010 20:13:27 +0000
    Subject: [PATCH 042/210] Work around over-eager ADL with msvc-10.0.  Refs
     #4108
    
    [SVN r61344]
    ---
     include/boost/smart_ptr/detail/sp_convertible.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp
    index fe44069..eb39797 100644
    --- a/include/boost/smart_ptr/detail/sp_convertible.hpp
    +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp
    @@ -45,7 +45,7 @@ template< class Y, class T > struct sp_convertible
         static yes f( T* );
         static no  f( ... );
     
    -    enum _vt { value = sizeof( f( static_cast(0) ) ) == sizeof(yes) };
    +    enum _vt { value = sizeof( (f)( static_cast(0) ) ) == sizeof(yes) };
     };
     
     struct sp_empty
    
    From 7aac2f3263a307dd037c266f930c6b4360bcec8e Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 26 Apr 2010 12:16:55 +0000
    Subject: [PATCH 043/210] Fix detail::forward to work with rvalue references
     v2.
    
    [SVN r61574]
    ---
     include/boost/smart_ptr/make_shared.hpp | 98 +++++++++++++------------
     1 file changed, 50 insertions(+), 48 deletions(-)
    
    diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp
    index d477188..a01cec6 100644
    --- a/include/boost/smart_ptr/make_shared.hpp
    +++ b/include/boost/smart_ptr/make_shared.hpp
    @@ -87,10 +87,12 @@ public:
     };
     
     #if defined( BOOST_HAS_RVALUE_REFS )
    -template< class T > T&& forward( T &&t )
    +
    +template< class T > T&& sp_forward( T & t )
     {
    -    return t;
    +    return static_cast< T&& >( t );
     }
    +
     #endif
     
     } // namespace detail
    @@ -101,9 +103,9 @@ template< class T > T&& forward( T &&t )
     
     template< class T > boost::shared_ptr< T > make_shared()
     {
    -    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -118,9 +120,9 @@ template< class T > boost::shared_ptr< T > make_shared()
     
     template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
     {
    -    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -139,13 +141,13 @@ template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a
     
     template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
     {
    -    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    -    ::new( pv ) T( detail::forward( args )... );
    +    ::new( pv ) T( boost::detail::sp_forward( args )... );
         pd->set_initialized();
     
         T * pt2 = static_cast< T* >( pv );
    @@ -156,13 +158,13 @@ template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && .
     
     template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
     {
    -    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    -    ::new( pv ) T( detail::forward( args )... );
    +    ::new( pv ) T( boost::detail::sp_forward( args )... );
         pd->set_initialized();
     
         T * pt2 = static_cast< T* >( pv );
    @@ -178,9 +180,9 @@ template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shar
     template< class T, class A1 >
     boost::shared_ptr< T > make_shared( A1 const & a1 )
     {
    -    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -196,9 +198,9 @@ boost::shared_ptr< T > make_shared( A1 const & a1 )
     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 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -214,9 +216,9 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
     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 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -232,9 +234,9 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
     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 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -250,9 +252,9 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -268,9 +270,9 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3
     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 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -286,9 +288,9 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -304,9 +306,9 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -322,9 +324,9 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -340,9 +342,9 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -358,9 +360,9 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -376,9 +378,9 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -394,9 +396,9 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -412,9 +414,9 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -430,9 +432,9 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -448,9 +450,9 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -466,9 +468,9 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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 ), detail::sp_ms_deleter< T >() );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    @@ -484,9 +486,9 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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 ), detail::sp_ms_deleter< T >(), a );
    +    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
     
    -    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
    +    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
     
         void * pv = pd->address();
     
    
    From 7083e7666613996e2b7718f7ae0545c5a3003bd8 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 26 Apr 2010 12:20:44 +0000
    Subject: [PATCH 044/210] Remove duplicate using declarations.
    
    [SVN r61575]
    ---
     test/weak_ptr_test.cpp | 3 ---
     1 file changed, 3 deletions(-)
    
    diff --git a/test/weak_ptr_test.cpp b/test/weak_ptr_test.cpp
    index 7213794..a4ad766 100644
    --- a/test/weak_ptr_test.cpp
    +++ b/test/weak_ptr_test.cpp
    @@ -914,7 +914,6 @@ void test()
             BOOST_TEST(wp2.use_count() == 0);
             BOOST_TEST(!(wp < wp3 || wp3 < wp));
     
    -        using std::swap;
             swap(wp, wp2);
     
             BOOST_TEST(wp.use_count() == 0);
    @@ -950,7 +949,6 @@ void test()
             BOOST_TEST(wp2.use_count() == 0);
             BOOST_TEST(!(wp < wp3 || wp3 < wp));
     
    -        using std::swap;
             swap(wp, wp2);
     
             BOOST_TEST(wp.use_count() == 0);
    @@ -965,7 +963,6 @@ void test()
             BOOST_TEST(wp2.use_count() == 0);
             BOOST_TEST(!(wp < wp3 || wp3 < wp));
     
    -        using std::swap;
             swap(wp, wp2);
     
             BOOST_TEST(wp.use_count() == 0);
    
    From 37c9a235a5824108d40f88005fb363bf7ad7e8c4 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 26 Apr 2010 16:39:45 +0000
    Subject: [PATCH 045/210] Add BOOST_HAS_VARIADIC_TMPL as a test condition.
    
    [SVN r61579]
    ---
     test/make_shared_perfect_forwarding_test.cpp | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/test/make_shared_perfect_forwarding_test.cpp b/test/make_shared_perfect_forwarding_test.cpp
    index 45a111c..ed7ee3b 100644
    --- a/test/make_shared_perfect_forwarding_test.cpp
    +++ b/test/make_shared_perfect_forwarding_test.cpp
    @@ -12,14 +12,14 @@
     #include 
     #include 
     
    -#ifndef BOOST_HAS_RVALUE_REFS
    +#if !defined( BOOST_HAS_RVALUE_REFS ) || !defined( BOOST_HAS_VARIADIC_TMPL )
     
     int main()
     {
         return 0;
     }
     
    -#else // BOOST_HAS_RVALUE_REFS
    +#else // BOOST_HAS_RVALUE_REFS, BOOST_HAS_VARIADIC_TMPL
     
     class myarg
     {
    
    From 2e53b1eb383474c33dd4fcf680ec9b5ec345d7e9 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 26 May 2010 17:43:58 +0000
    Subject: [PATCH 046/210] Applied patch for Sun C++. Refs #4199.
    
    [SVN r62245]
    ---
     include/boost/detail/sp_typeinfo.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/include/boost/detail/sp_typeinfo.hpp b/include/boost/detail/sp_typeinfo.hpp
    index 636fe27..3ee934f 100644
    --- a/include/boost/detail/sp_typeinfo.hpp
    +++ b/include/boost/detail/sp_typeinfo.hpp
    @@ -74,7 +74,7 @@ template struct sp_typeid_
         }
     };
     
    -template sp_typeinfo sp_typeid_< T >::ti_( sp_typeid_< T >::name() );
    +template sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
     
     template struct sp_typeid_< T & >: sp_typeid_< T >
     {
    
    From a46d4057787ff1a9ea7a2817fd4beb9d3e6627ba Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 26 May 2010 17:49:37 +0000
    Subject: [PATCH 047/210] DWORD is unsigned long, not unsigned int. Refs #4217.
    
    [SVN r62246]
    ---
     include/boost/smart_ptr/detail/yield_k.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp
    index a956cc0..23eadd8 100644
    --- a/include/boost/smart_ptr/detail/yield_k.hpp
    +++ b/include/boost/smart_ptr/detail/yield_k.hpp
    @@ -55,7 +55,7 @@ namespace detail
     {
     
     #if !defined( BOOST_USE_WINDOWS_H )
    -  extern "C" void __stdcall Sleep( unsigned ms );
    +  extern "C" void __stdcall Sleep( unsigned long ms );
     #endif
     
     inline void yield( unsigned k )
    
    From 3c8438818618406f006bc40d5e8502919cf481e5 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 26 May 2010 18:18:10 +0000
    Subject: [PATCH 048/210] Resolve the ambiguity between the zero argument
     make_shared and the variadic one. Refs #3856.
    
    [SVN r62248]
    ---
     include/boost/smart_ptr/make_shared.hpp |  8 ++++----
     test/Jamfile.v2                         |  1 +
     test/make_shared_fp_test.cpp            | 19 +++++++++++++++++++
     3 files changed, 24 insertions(+), 4 deletions(-)
     create mode 100644 test/make_shared_fp_test.cpp
    
    diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp
    index a01cec6..c4ed28a 100644
    --- a/include/boost/smart_ptr/make_shared.hpp
    +++ b/include/boost/smart_ptr/make_shared.hpp
    @@ -139,7 +139,7 @@ template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a
     
     // Variadic templates, rvalue reference
     
    -template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
    +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::detail::sp_ms_deleter< T >() );
     
    @@ -147,7 +147,7 @@ template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && .
     
         void * pv = pd->address();
     
    -    ::new( pv ) T( boost::detail::sp_forward( args )... );
    +    ::new( pv ) T( boost::detail::sp_forward( arg1 ), boost::detail::sp_forward( args )... );
         pd->set_initialized();
     
         T * pt2 = static_cast< T* >( pv );
    @@ -156,7 +156,7 @@ template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && .
         return boost::shared_ptr< T >( pt, pt2 );
     }
     
    -template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
    +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::detail::sp_ms_deleter< T >(), a );
     
    @@ -164,7 +164,7 @@ template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shar
     
         void * pv = pd->address();
     
    -    ::new( pv ) T( boost::detail::sp_forward( args )... );
    +    ::new( pv ) T( boost::detail::sp_forward( arg1 ), boost::detail::sp_forward( args )... );
         pd->set_initialized();
     
         T * pt2 = static_cast< T* >( pv );
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
    index 8782d59..95e0654 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -64,5 +64,6 @@ import testing ;
               [ compile-fail auto_ptr_lv_fail.cpp ]
               [ run atomic_count_test2.cpp ]
               [ run sp_typeinfo_test.cpp ]
    +          [ compile make_shared_fp_test.cpp ]
             ;
     }
    diff --git a/test/make_shared_fp_test.cpp b/test/make_shared_fp_test.cpp
    new file mode 100644
    index 0000000..f443d34
    --- /dev/null
    +++ b/test/make_shared_fp_test.cpp
    @@ -0,0 +1,19 @@
    +//
    +//  make_shared_fp_test.cpp
    +//
    +//  Copyright 2010 Georg Fritzsche
    +//
    +//  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 
    +
    +int main()
    +{
    +    typedef boost::shared_ptr(*FP)(); 
    +    FP fp = boost::make_shared;
    +}
    
    From 37f10d500d2af4f0cf88caf834e095aeb2d581cb Mon Sep 17 00:00:00 2001
    From: Hartmut Kaiser 
    Date: Sun, 17 Oct 2010 02:24:40 +0000
    Subject: [PATCH 049/210] Fixing sp_typeinfo for clang and gcc 4.5.1
    
    [SVN r66031]
    ---
     include/boost/detail/sp_typeinfo.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/include/boost/detail/sp_typeinfo.hpp b/include/boost/detail/sp_typeinfo.hpp
    index 3ee934f..c7bd549 100644
    --- a/include/boost/detail/sp_typeinfo.hpp
    +++ b/include/boost/detail/sp_typeinfo.hpp
    @@ -74,7 +74,7 @@ template struct sp_typeid_
         }
     };
     
    -template sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
    +template sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name());
     
     template struct sp_typeid_< T & >: sp_typeid_< T >
     {
    
    From 825786d59a8e85ca065a01de1fce0f9e5ec0d29b Mon Sep 17 00:00:00 2001
    From: Hartmut Kaiser 
    Date: Tue, 19 Oct 2010 13:33:00 +0000
    Subject: [PATCH 050/210] Re-added sunpro specific initialization
    
    [SVN r66091]
    ---
     include/boost/detail/sp_typeinfo.hpp | 6 ++++++
     1 file changed, 6 insertions(+)
    
    diff --git a/include/boost/detail/sp_typeinfo.hpp b/include/boost/detail/sp_typeinfo.hpp
    index c7bd549..43fae78 100644
    --- a/include/boost/detail/sp_typeinfo.hpp
    +++ b/include/boost/detail/sp_typeinfo.hpp
    @@ -74,7 +74,13 @@ template struct sp_typeid_
         }
     };
     
    +#if defined(__SUNPRO_CC)
    +// see #4199, the Sun Studio compiler gets confused about static initialization 
    +// constructor arguments. But an assignment works just fine. 
    +template sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
    +#else
     template sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name());
    +#endif
     
     template struct sp_typeid_< T & >: sp_typeid_< T >
     {
    
    From c3b51e201be7ba3320a5588c7252c184134b4bc7 Mon Sep 17 00:00:00 2001
    From: Bryce Adelstein-Lelbach 
    Date: Fri, 14 Jan 2011 02:59:34 +0000
    Subject: [PATCH 051/210] Pathscale-4.0 configuration code/workarounds.
    
    [SVN r68142]
    ---
     include/boost/smart_ptr/detail/sp_has_sync.hpp | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    index 7fcd09e..7e7860b 100644
    --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp
    +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    @@ -44,6 +44,10 @@
     #undef BOOST_SP_HAS_SYNC
     #endif
     
    +#if defined (__PATHSCALE__)
    +#undef BOOST_SP_HAS_SYNC
    +#endif
    +
     #endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401
     
     #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
    
    From a2fc6e12da7f17396a85c00617d408339f5a29ed Mon Sep 17 00:00:00 2001
    From: Bryce Adelstein-Lelbach 
    Date: Sat, 19 Feb 2011 01:33:46 +0000
    Subject: [PATCH 052/210] Intel 11.0 doesn't provide __sync intrinsics - this
     is added in Intel 11.1.
    
    [SVN r69019]
    ---
     include/boost/smart_ptr/detail/sp_has_sync.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    index 7e7860b..e89ba3a 100644
    --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp
    +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    @@ -40,7 +40,7 @@
     #undef BOOST_SP_HAS_SYNC
     #endif
     
    -#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1100 )
    +#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
     #undef BOOST_SP_HAS_SYNC
     #endif
     
    
    From 4fabf9b352df123f0ba3f17a2df36edae017183f Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 24 Feb 2011 20:29:38 +0000
    Subject: [PATCH 053/210] Add include guards, make_shared.hpp to smart_ptr.hpp.
     Refs #4288. Refs #5189.
    
    [SVN r69242]
    ---
     include/boost/smart_ptr.hpp | 6 ++++++
     test/smart_ptr_test.cpp     | 5 +----
     2 files changed, 7 insertions(+), 4 deletions(-)
    
    diff --git a/include/boost/smart_ptr.hpp b/include/boost/smart_ptr.hpp
    index 98e0894..b5e569d 100644
    --- a/include/boost/smart_ptr.hpp
    +++ b/include/boost/smart_ptr.hpp
    @@ -1,3 +1,6 @@
    +#ifndef BOOST_SMART_PTR_HPP_INCLUDED
    +#define BOOST_SMART_PTR_HPP_INCLUDED
    +
     //
     //  smart_ptr.hpp
     //
    @@ -22,4 +25,7 @@
     # include 
     # include 
     # include 
    +# include 
     #endif
    +
    +#endif // #ifndef BOOST_SMART_PTR_HPP_INCLUDED
    diff --git a/test/smart_ptr_test.cpp b/test/smart_ptr_test.cpp
    index 8832deb..7b4de34 100644
    --- a/test/smart_ptr_test.cpp
    +++ b/test/smart_ptr_test.cpp
    @@ -33,10 +33,7 @@
     # pragma warn -8092 // template argument passed to 'find' is not an iterator
     #endif
     
    -#include 
    -#include 
    -#include 
    -#include 
    +#include 
     
     #include 
     
    
    From 1426b0bbdd49352e4458c1c5d41698baf4b580e9 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 24 Feb 2011 20:41:29 +0000
    Subject: [PATCH 054/210] Apply patch to allow perfect forwarding without
     variadics. Refs #4892.
    
    [SVN r69244]
    ---
     include/boost/smart_ptr/make_shared.hpp      | 454 +++++++++++++++++++
     test/make_shared_perfect_forwarding_test.cpp |   4 +-
     2 files changed, 456 insertions(+), 2 deletions(-)
    
    diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp
    index c4ed28a..3d12bbe 100644
    --- a/include/boost/smart_ptr/make_shared.hpp
    +++ b/include/boost/smart_ptr/make_shared.hpp
    @@ -173,6 +173,460 @@ template< class T, class A, class Arg1, class... Args > boost::shared_ptr< T > a
         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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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::detail::sp_ms_deleter< 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
    diff --git a/test/make_shared_perfect_forwarding_test.cpp b/test/make_shared_perfect_forwarding_test.cpp
    index ed7ee3b..bd5f5c5 100644
    --- a/test/make_shared_perfect_forwarding_test.cpp
    +++ b/test/make_shared_perfect_forwarding_test.cpp
    @@ -12,14 +12,14 @@
     #include 
     #include 
     
    -#if !defined( BOOST_HAS_RVALUE_REFS ) || !defined( BOOST_HAS_VARIADIC_TMPL )
    +#if !defined( BOOST_HAS_RVALUE_REFS )
     
     int main()
     {
         return 0;
     }
     
    -#else // BOOST_HAS_RVALUE_REFS, BOOST_HAS_VARIADIC_TMPL
    +#else // BOOST_HAS_RVALUE_REFS
     
     class myarg
     {
    
    From 53d5d086ea55d9706a5799edcc58b16f96b3564f Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 24 Feb 2011 20:48:17 +0000
    Subject: [PATCH 055/210] Warning 4284 is obsolete. Refs #4433.
    
    [SVN r69245]
    ---
     include/boost/smart_ptr/intrusive_ptr.hpp | 9 ---------
     include/boost/smart_ptr/shared_ptr.hpp    | 9 ---------
     2 files changed, 18 deletions(-)
    
    diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp
    index e72eb21..2fa4670 100644
    --- a/include/boost/smart_ptr/intrusive_ptr.hpp
    +++ b/include/boost/smart_ptr/intrusive_ptr.hpp
    @@ -15,11 +15,6 @@
     
     #include 
     
    -#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
    -# pragma warning(push)
    -# pragma warning(disable:4284) // odd return type for operator->
    -#endif
    -
     #include 
     #include 
     #include 
    @@ -292,8 +287,4 @@ template std::basic_ostream & operator<< (std::
     
     } // namespace boost
     
    -#ifdef BOOST_MSVC
    -# pragma warning(pop)
    -#endif    
    -
     #endif  // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
    diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp
    index 3f1c1d3..66ab48a 100644
    --- a/include/boost/smart_ptr/shared_ptr.hpp
    +++ b/include/boost/smart_ptr/shared_ptr.hpp
    @@ -50,11 +50,6 @@
     #endif
     #endif
     
    -#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
    -# pragma warning(push)
    -# pragma warning(disable:4284) // odd return type for operator->
    -#endif
    -
     namespace boost
     {
     
    @@ -731,10 +726,6 @@ template inline bool atomic_compare_exchange_explicit( shared_ptr *
     
     } // namespace boost
     
    -#ifdef BOOST_MSVC
    -# pragma warning(pop)
    -#endif
    -
     #endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
     
     #endif  // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
    
    From 9196247dead39a97f97996951b6d4b0738e2da49 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 24 Feb 2011 20:53:46 +0000
    Subject: [PATCH 056/210] Apply patch. Refs #4478.
    
    [SVN r69246]
    ---
     include/boost/smart_ptr/detail/spinlock_pool.hpp | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/include/boost/smart_ptr/detail/spinlock_pool.hpp b/include/boost/smart_ptr/detail/spinlock_pool.hpp
    index 0e2e08a..f09d5c6 100644
    --- a/include/boost/smart_ptr/detail/spinlock_pool.hpp
    +++ b/include/boost/smart_ptr/detail/spinlock_pool.hpp
    @@ -41,7 +41,11 @@ public:
     
         static spinlock & spinlock_for( void const * pv )
         {
    +#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64  
    +        std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41;
    +#else  
             std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
    +#endif  
             return pool_[ i ];
         }
     
    
    From 593093e46dc0c5bec17b0c9db9950dc75fc2d307 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 24 Feb 2011 21:51:21 +0000
    Subject: [PATCH 057/210] Fix make_shared to not copy the deleter. Refs #4256.
     Refs #3875.
    
    [SVN r69250]
    ---
     .../boost/smart_ptr/detail/shared_count.hpp   | 88 +++++++++++++++++++
     .../smart_ptr/detail/sp_counted_impl.hpp      | 12 ++-
     include/boost/smart_ptr/make_shared.hpp       | 88 ++++++++++---------
     3 files changed, 146 insertions(+), 42 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp
    index 4943e37..f96a220 100644
    --- a/include/boost/smart_ptr/detail/shared_count.hpp
    +++ b/include/boost/smart_ptr/detail/shared_count.hpp
    @@ -52,6 +52,10 @@ int const   weak_count_id = 0x298C38A4;
     
     struct sp_nothrow_tag {};
     
    +template< class D > struct sp_inplace_tag
    +{
    +};
    +
     class weak_count;
     
     class shared_count
    @@ -142,6 +146,40 @@ public:
     #endif
         }
     
    +#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
    +
    +    template< class P, class D > shared_count( P p, sp_inplace_tag ): pi_( 0 )
    +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
    +        , id_(shared_count_id)
    +#endif
    +    {
    +#ifndef BOOST_NO_EXCEPTIONS
    +
    +        try
    +        {
    +            pi_ = new sp_counted_impl_pd< P, D >( p );
    +        }
    +        catch( ... )
    +        {
    +            D()( p ); // delete p
    +            throw;
    +        }
    +
    +#else
    +
    +        pi_ = new sp_counted_impl_pd< P, D >( p );
    +
    +        if( pi_ == 0 )
    +        {
    +            D()( p ); // delete p
    +            boost::throw_exception( std::bad_alloc() );
    +        }
    +
    +#endif // #ifndef BOOST_NO_EXCEPTIONS
    +    }
    +
    +#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
    +
         template shared_count( P p, D d, A a ): pi_( 0 )
     #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
             , id_(shared_count_id)
    @@ -188,6 +226,56 @@ public:
     #endif
         }
     
    +#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
    +
    +    template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
    +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
    +        , id_(shared_count_id)
    +#endif
    +    {
    +        typedef sp_counted_impl_pda< P, D, A > impl_type;
    +        typedef typename A::template rebind< impl_type >::other A2;
    +
    +        A2 a2( a );
    +
    +#ifndef BOOST_NO_EXCEPTIONS
    +
    +        try
    +        {
    +            pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
    +            new( static_cast< void* >( pi_ ) ) impl_type( p, a );
    +        }
    +        catch(...)
    +        {
    +            D()( p );
    +
    +            if( pi_ != 0 )
    +            {
    +                a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
    +            }
    +
    +            throw;
    +        }
    +
    +#else
    +
    +        pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
    +
    +        if( pi_ != 0 )
    +        {
    +            new( static_cast< void* >( pi_ ) ) impl_type( p, a );
    +        }
    +        else
    +        {
    +            D()( p );
    +            boost::throw_exception( std::bad_alloc() );
    +        }
    +
    +#endif // #ifndef BOOST_NO_EXCEPTIONS
    +    }
    +
    +#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
    +
     #ifndef BOOST_NO_AUTO_PTR
     
         // auto_ptr is special cased to provide the strong guarantee
    diff --git a/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/include/boost/smart_ptr/detail/sp_counted_impl.hpp
    index 397421a..aab39bd 100644
    --- a/include/boost/smart_ptr/detail/sp_counted_impl.hpp
    +++ b/include/boost/smart_ptr/detail/sp_counted_impl.hpp
    @@ -135,7 +135,11 @@ public:
     
         // pre: d(p) must not throw
     
    -    sp_counted_impl_pd( P p, D d ): ptr(p), del(d)
    +    sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
    +    {
    +    }
    +
    +    sp_counted_impl_pd( P p ): ptr( p ), del()
         {
         }
     
    @@ -195,7 +199,11 @@ public:
     
         // pre: d( p ) must not throw
     
    -    sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a )
    +    sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
    +    {
    +    }
    +
    +    sp_counted_impl_pda( P p, A a ): p_( p ), d_(), a_( a )
         {
         }
     
    diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp
    index 3d12bbe..3d40aa2 100644
    --- a/include/boost/smart_ptr/make_shared.hpp
    +++ b/include/boost/smart_ptr/make_shared.hpp
    @@ -97,13 +97,19 @@ template< class T > T&& sp_forward( T & t )
     
     } // 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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -120,7 +126,7 @@ template< class T > boost::shared_ptr< T > make_shared()
     
     template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
     {
    -    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -141,7 +147,7 @@ template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a
     
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -158,7 +164,7 @@ template< class T, class Arg1, class... Args > boost::shared_ptr< T > make_share
     
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -180,7 +186,7 @@ template< class T, class A, class Arg1, class... Args > boost::shared_ptr< T > a
     template< class T, class A1 >
     boost::shared_ptr< T > make_shared( A1 && a1 )
     {
    -    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -201,7 +207,7 @@ boost::shared_ptr< T > make_shared( A1 && a1 )
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -222,7 +228,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1 )
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -244,7 +250,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2 )
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -266,7 +272,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2 )
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -289,7 +295,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3 )
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -312,7 +318,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -336,7 +342,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -360,7 +366,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -385,7 +391,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 &
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -410,7 +416,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -436,7 +442,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 &
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -462,7 +468,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -489,7 +495,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 &
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -516,7 +522,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -544,7 +550,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 &
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -572,7 +578,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -601,7 +607,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 &
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -634,7 +640,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     template< class T, class A1 >
     boost::shared_ptr< T > make_shared( A1 const & a1 )
     {
    -    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -652,7 +658,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1 )
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -670,7 +676,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -688,7 +694,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -706,7 +712,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -724,7 +730,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -742,7 +748,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -760,7 +766,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -778,7 +784,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -796,7 +802,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -814,7 +820,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -832,7 +838,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -850,7 +856,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -868,7 +874,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -886,7 +892,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -904,7 +910,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -922,7 +928,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     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::detail::sp_ms_deleter< T >() );
    +    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 );
     
    @@ -940,7 +946,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     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::detail::sp_ms_deleter< T >(), 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 );
     
    @@ -957,6 +963,8 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     
     #endif
     
    +#undef BOOST_SP_MSD
    +
     } // namespace boost
     
     #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
    
    From e3d2f2ee6ba5e03823ebb6054d96963e08959e29 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 24 Feb 2011 22:05:04 +0000
    Subject: [PATCH 058/210] Apply suggested fix. Refs #4127.
    
    [SVN r69251]
    ---
     include/boost/smart_ptr/make_shared.hpp | 11 +++++++++++
     1 file changed, 11 insertions(+)
    
    diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp
    index 3d40aa2..7b605e2 100644
    --- a/include/boost/smart_ptr/make_shared.hpp
    +++ b/include/boost/smart_ptr/make_shared.hpp
    @@ -49,7 +49,18 @@ private:
         {
             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;
             }
         }
    
    From 69aa01ec001ac2a737274fb7738d2c370fac3d19 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 24 Feb 2011 23:24:54 +0000
    Subject: [PATCH 059/210] Add hash_value for shared_ptr; prevents hash_value(
     bool ) from being used. Refs #5216.
    
    [SVN r69260]
    ---
     include/boost/smart_ptr/shared_ptr.hpp | 12 ++++++++-
     test/Jamfile.v2                        |  1 +
     test/sp_hash_test.cpp                  | 34 ++++++++++++++++++++++++++
     3 files changed, 46 insertions(+), 1 deletion(-)
     create mode 100644 test/sp_hash_test.cpp
    
    diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp
    index 66ab48a..16a1f92 100644
    --- a/include/boost/smart_ptr/shared_ptr.hpp
    +++ b/include/boost/smart_ptr/shared_ptr.hpp
    @@ -41,6 +41,7 @@
     #include             // for std::swap
     #include            // for std::less
     #include              // for std::bad_cast
    +#include               // for std::size_t
     
     #if !defined(BOOST_NO_IOSTREAM)
     #if !defined(BOOST_NO_IOSFWD)
    @@ -722,7 +723,16 @@ template inline bool atomic_compare_exchange_explicit( shared_ptr *
         return atomic_compare_exchange( p, v, w ); // std::move( w )
     }
     
    -#endif
    +#endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS)
    +
    +// hash_value
    +
    +template< class T > struct hash;
    +
    +template< class T > std::size_t hash_value( boost::shared_ptr const & p )
    +{
    +    return boost::hash< T* >()( p.get() );
    +}
     
     } // namespace boost
     
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
    index 95e0654..632ef08 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -65,5 +65,6 @@ import testing ;
               [ run atomic_count_test2.cpp ]
               [ run sp_typeinfo_test.cpp ]
               [ compile make_shared_fp_test.cpp ]
    +          [ run sp_hash_test.cpp ]
             ;
     }
    diff --git a/test/sp_hash_test.cpp b/test/sp_hash_test.cpp
    new file mode 100644
    index 0000000..b67f547
    --- /dev/null
    +++ b/test/sp_hash_test.cpp
    @@ -0,0 +1,34 @@
    +//
    +// sp_hash_test.cpp
    +//
    +// Copyright 2011 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 
    +
    +int main()
    +{
    +    boost::hash< boost::shared_ptr > hasher;
    +
    +    boost::shared_ptr< int > p1, p2( p1 ), p3( new int ), p4( p3 ), p5( new int );
    +
    +    BOOST_TEST_EQ( p1, p2 );
    +    BOOST_TEST_EQ( hasher( p1 ), hasher( p2 ) );
    +
    +    BOOST_TEST_NE( p1, p3 );
    +    BOOST_TEST_NE( hasher( p1 ), hasher( p3 ) );
    +
    +    BOOST_TEST_EQ( p3, p4 );
    +    BOOST_TEST_EQ( hasher( p3 ), hasher( p4 ) );
    +
    +    BOOST_TEST_NE( p3, p5 );
    +    BOOST_TEST_NE( hasher( p3 ), hasher( p5 ) );
    +
    +    return boost::report_errors();
    +}
    
    From b18b47770d5853f12853934b8fcc1044da5a15d0 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 24 Feb 2011 23:30:22 +0000
    Subject: [PATCH 060/210] Add support for BOOST_SP_NO_SYNC. Refs #5019.
    
    [SVN r69261]
    ---
     include/boost/smart_ptr/detail/sp_has_sync.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    index e89ba3a..2149210 100644
    --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp
    +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    @@ -20,7 +20,7 @@
     //  are available.
     //
     
    -#if defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
    +#if defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( BOOST_SP_NO_SYNC )
     
     #define BOOST_SP_HAS_SYNC
     
    
    From 634866c28afcf8b46ce231f5ca2f5619144fe990 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 24 Feb 2011 23:35:22 +0000
    Subject: [PATCH 061/210] Honor BOOST_SP_USE_PTHREADS. Refs #5018.
    
    [SVN r69262]
    ---
     include/boost/smart_ptr/detail/spinlock.hpp | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/include/boost/smart_ptr/detail/spinlock.hpp b/include/boost/smart_ptr/detail/spinlock.hpp
    index 1640a38..88d7ad6 100644
    --- a/include/boost/smart_ptr/detail/spinlock.hpp
    +++ b/include/boost/smart_ptr/detail/spinlock.hpp
    @@ -31,7 +31,10 @@
     #include 
     #include 
     
    -#if defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
    +#if defined( BOOST_SP_USE_PTHREADS )
    +#  include 
    +
    +#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
     #  include 
     
     #elif defined( BOOST_SP_HAS_SYNC )
    
    From f76a8d95d850f2796dde7c48f14fc5312036192f Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 23 Mar 2011 00:29:22 +0000
    Subject: [PATCH 062/210] Apply suggested patch. Refs #5327.
    
    [SVN r70452]
    ---
     .../boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp  | 9 +++++++++
     1 file changed, 9 insertions(+)
    
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
    index 0c69b0b..3f1f449 100644
    --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
    +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
    @@ -37,9 +37,12 @@ inline void atomic_increment( int * pw )
         __asm__ __volatile__
         (
             "0:\n\t"
    +        ".set push\n\t"
    +        ".set mips2\n\t"
             "ll %0, %1\n\t"
             "addiu %0, 1\n\t"
             "sc %0, %1\n\t"
    +        ".set pop\n\t"
             "beqz %0, 0b":
             "=&r"( tmp ), "=m"( *pw ):
             "m"( *pw )
    @@ -55,9 +58,12 @@ inline int atomic_decrement( int * pw )
         __asm__ __volatile__
         (
             "0:\n\t"
    +        ".set push\n\t"
    +        ".set mips2\n\t"
             "ll %1, %2\n\t"
             "addiu %0, %1, -1\n\t"
             "sc %0, %2\n\t"
    +        ".set pop\n\t"
             "beqz %0, 0b\n\t"
             "addiu %0, %1, -1":
             "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
    @@ -78,10 +84,13 @@ inline int atomic_conditional_increment( int * pw )
         __asm__ __volatile__
         (
             "0:\n\t"
    +        ".set push\n\t"
    +        ".set mips2\n\t"
             "ll %0, %2\n\t"
             "beqz %0, 1f\n\t"
             "addiu %1, %0, 1\n\t"
             "sc %1, %2\n\t"
    +        ".set pop\n\t"
             "beqz %1, 0b\n\t"
             "addiu %0, %0, 1\n\t"
             "1:":
    
    From b4b415553c6b9354fd1e2804403b929f22b4963a Mon Sep 17 00:00:00 2001
    From: Emil Dotchevski 
    Date: Mon, 6 Jun 2011 18:56:07 +0000
    Subject: [PATCH 063/210] Lock-free sp_counted_base for SNC/PS3, thanks Peter
     Dimov
    
    [SVN r72437]
    ---
     .../smart_ptr/detail/sp_counted_base.hpp      |   3 +
     .../detail/sp_counted_base_snc_ps3.hpp        | 161 ++++++++++++++++++
     2 files changed, 164 insertions(+)
     create mode 100644 include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
    
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    index cab45cc..dc8b4d3 100644
    --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp
    +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    @@ -32,6 +32,9 @@
     #elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
     # include 
     
    +#elif defined( __SNC__ )
    +# include 
    +
     #elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
     # include 
     
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
    new file mode 100644
    index 0000000..e51e676
    --- /dev/null
    +++ b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
    @@ -0,0 +1,161 @@
    +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
    +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
    +
    +// MS compatible compilers support #pragma once
    +#if defined(_MSC_VER) && (_MSC_VER >= 1020)
    +# pragma once
    +#endif
    +
    +//  detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
    +//
    +//  Copyright (c) 2006 Piotr Wyderski
    +//  Copyright (c) 2006 Tomas Puverle
    +//  Copyright (c) 2006 Peter Dimov
    +//  Copyright (c) 2011 Emil Dotchevski
    +//
    +//  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
    +//
    +//  Thanks to Michael van der Westhuizen
    +
    +#include 
    +#include  // uint32_t
    +
    +namespace boost
    +{
    +
    +namespace detail
    +{
    +
    +inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
    +{
    +	return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
    +}
    +
    +inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
    +{
    +    // long r = *pw;
    +    // *pw += dv;
    +    // return r;
    +
    +    for( ;; )
    +    {
    +        uint32_t r = *pw;
    +
    +        if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
    +        {
    +            return r;
    +        }
    +    }
    +}
    +
    +inline void atomic_increment( uint32_t * pw )
    +{
    +    (void) __builtin_cellAtomicIncr32( pw );
    +}
    +
    +inline uint32_t atomic_decrement( uint32_t * pw )
    +{
    +    return __builtin_cellAtomicDecr32( pw );
    +}
    +
    +inline uint32_t atomic_conditional_increment( uint32_t * pw )
    +{
    +    // long r = *pw;
    +    // if( r != 0 ) ++*pw;
    +    // return r;
    +
    +    for( ;; )
    +    {
    +        uint32_t r = *pw;
    +
    +        if( r == 0 )
    +        {
    +            return r;
    +        }
    +
    +        if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
    +        {
    +            return r;
    +        }
    +    }    
    +}
    +
    +class sp_counted_base
    +{
    +private:
    +
    +    sp_counted_base( sp_counted_base const & );
    +    sp_counted_base & operator= ( sp_counted_base const & );
    +
    +    uint32_t use_count_;        // #shared
    +    uint32_t weak_count_;       // #weak + (#shared != 0)
    +
    +public:
    +
    +    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
    +    {
    +    }
    +
    +    virtual ~sp_counted_base() // nothrow
    +    {
    +    }
    +
    +    // dispose() is called when use_count_ drops to zero, to release
    +    // the resources managed by *this.
    +
    +    virtual void dispose() = 0; // nothrow
    +
    +    // destroy() is called when weak_count_ drops to zero.
    +
    +    virtual void destroy() // nothrow
    +    {
    +        delete this;
    +    }
    +
    +    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
    +
    +    void add_ref_copy()
    +    {
    +        atomic_increment( &use_count_ );
    +    }
    +
    +    bool add_ref_lock() // true on success
    +    {
    +        return atomic_conditional_increment( &use_count_ ) != 0;
    +    }
    +
    +    void release() // nothrow
    +    {
    +        if( atomic_decrement( &use_count_ ) == 1 )
    +        {
    +            dispose();
    +            weak_release();
    +        }
    +    }
    +
    +    void weak_add_ref() // nothrow
    +    {
    +        atomic_increment( &weak_count_ );
    +    }
    +
    +    void weak_release() // nothrow
    +    {
    +        if( atomic_decrement( &weak_count_ ) == 1 )
    +        {
    +            destroy();
    +        }
    +    }
    +
    +    long use_count() const // nothrow
    +    {
    +        return const_cast< uint32_t const volatile & >( use_count_ );
    +    }
    +};
    +
    +} // namespace detail
    +
    +} // namespace boost
    +
    +#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
    
    From 7e9664396a8c86aa04e5cc550b5801b95ea6c930 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Sun, 17 Jul 2011 20:35:44 +0000
    Subject: [PATCH 064/210] Add copy constructor/assignment - in C++0x, move
     disables implicit copy.
    
    [SVN r73202]
    ---
     include/boost/smart_ptr/shared_array.hpp | 20 +++++++++++++++++++-
     include/boost/smart_ptr/shared_ptr.hpp   | 12 +++++++++++-
     include/boost/smart_ptr/weak_ptr.hpp     | 18 +++++++++++++++++-
     3 files changed, 47 insertions(+), 3 deletions(-)
    
    diff --git a/include/boost/smart_ptr/shared_array.hpp b/include/boost/smart_ptr/shared_array.hpp
    index 1f50403..0acdff7 100644
    --- a/include/boost/smart_ptr/shared_array.hpp
    +++ b/include/boost/smart_ptr/shared_array.hpp
    @@ -69,7 +69,25 @@ public:
         {
         }
     
    -//  generated copy constructor, assignment, destructor are fine
    +//  generated copy constructor, destructor are fine...
    +
    +#if defined( BOOST_HAS_RVALUE_REFS )
    +
    +// ... except in C++0x, move disables the implicit copy
    +
    +    shared_array( shared_array const & r ): px( r.px ), pn( r.pn ) // never throws
    +    {
    +    }
    +
    +#endif
    +
    +    // assignment
    +
    +    shared_array & operator=( shared_array const & r ) // never throws
    +    {
    +        this_type( r ).swap( *this );
    +        return *this;
    +    }
     
         void reset(T * p = 0)
         {
    diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp
    index 16a1f92..d3973da 100644
    --- a/include/boost/smart_ptr/shared_ptr.hpp
    +++ b/include/boost/smart_ptr/shared_ptr.hpp
    @@ -197,7 +197,17 @@ public:
             boost::detail::sp_enable_shared_from_this( this, p, p );
         }
     
    -//  generated copy constructor, destructor are fine
    +//  generated copy constructor, destructor are fine...
    +
    +#if defined( BOOST_HAS_RVALUE_REFS )
    +
    +// ... except in C++0x, move disables the implicit copy
    +
    +    shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
    +    {
    +    }
    +
    +#endif
     
         template
         explicit shared_ptr(weak_ptr const & r): pn(r.pn) // may throw
    diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp
    index db56103..e00d96e 100644
    --- a/include/boost/smart_ptr/weak_ptr.hpp
    +++ b/include/boost/smart_ptr/weak_ptr.hpp
    @@ -40,8 +40,24 @@ public:
         {
         }
     
    -//  generated copy constructor, assignment, destructor are fine
    +//  generated copy constructor, assignment, destructor are fine...
     
    +#if defined( BOOST_HAS_RVALUE_REFS )
    +
    +// ... except in C++0x, move disables the implicit copy
    +
    +    weak_ptr( weak_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
    +    {
    +    }
    +
    +    weak_ptr & operator=( weak_ptr const & r ) // never throws
    +    {
    +        px = r.px;
    +        pn = r.pn;
    +        return *this;
    +    }
    +
    +#endif
     
     //
     //  The "obvious" converting constructor implementation:
    
    From 9d9e6350f2787ea1b5d9c784a51deee838463851 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 7 Nov 2011 15:03:44 +0000
    Subject: [PATCH 065/210] Apply patch from #6099. Refs #6099.
    
    [SVN r75385]
    ---
     include/boost/smart_ptr/detail/sp_has_sync.hpp | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    index 2149210..67f4c38 100644
    --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp
    +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    @@ -36,6 +36,10 @@
     #undef BOOST_SP_HAS_SYNC
     #endif
     
    +#if defined( __sh__ )
    +#undef BOOST_SP_HAS_SYNC
    +#endif
    +
     #if defined( __sparc__ )
     #undef BOOST_SP_HAS_SYNC
     #endif
    
    From 288fb7efcf677d1cd27905d8a604ef63cbf9b1e8 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 7 Nov 2011 17:50:31 +0000
    Subject: [PATCH 066/210] Add ARM memory barriers. Refs #5372.
    
    [SVN r75389]
    ---
     .../smart_ptr/detail/spinlock_gcc_arm.hpp     | 23 ++++++++++++++++---
     1 file changed, 20 insertions(+), 3 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp b/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
    index ba6c511..f58ea44 100644
    --- a/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
    +++ b/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
    @@ -2,7 +2,7 @@
     #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
     
     //
    -//  Copyright (c) 2008 Peter Dimov
    +//  Copyright (c) 2008, 2011 Peter Dimov
     //
     //  Distributed under the Boost Software License, Version 1.0.
     //  See accompanying file LICENSE_1_0.txt or copy at
    @@ -11,6 +11,20 @@
     
     #include 
     
    +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
    +
    +# define BOOST_SP_ARM_BARRIER "dmb"
    +
    +#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
    +
    +# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
    +
    +#else
    +
    +# define BOOST_SP_ARM_BARRIER ""
    +
    +#endif
    +
     namespace boost
     {
     
    @@ -30,7 +44,8 @@ public:
             int r;
     
             __asm__ __volatile__(
    -            "swp %0, %1, [%2]":
    +            "swp %0, %1, [%2]\n\t"
    +			BOOST_SP_ARM_BARRIER :
                 "=&r"( r ): // outputs
                 "r"( 1 ), "r"( &v_ ): // inputs
                 "memory", "cc" );
    @@ -48,7 +63,7 @@ public:
     
         void unlock()
         {
    -        __asm__ __volatile__( "" ::: "memory" );
    +        __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
             *const_cast< int volatile* >( &v_ ) = 0;
         }
     
    @@ -82,4 +97,6 @@ public:
     
     #define BOOST_DETAIL_SPINLOCK_INIT {0}
     
    +#undef BOOST_SP_ARM_BARRIER
    +
     #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
    
    From fbe4ddf4a23d15b07d9ead225ff9265e68ad49b9 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 7 Nov 2011 18:19:24 +0000
    Subject: [PATCH 067/210] Add get_deleter for shared_array. Refs #4493.
    
    [SVN r75390]
    ---
     include/boost/smart_ptr/shared_array.hpp | 10 +++
     test/Jamfile.v2                          |  1 +
     test/get_deleter_array_test.cpp          | 95 ++++++++++++++++++++++++
     3 files changed, 106 insertions(+)
     create mode 100644 test/get_deleter_array_test.cpp
    
    diff --git a/include/boost/smart_ptr/shared_array.hpp b/include/boost/smart_ptr/shared_array.hpp
    index 0acdff7..36799e6 100644
    --- a/include/boost/smart_ptr/shared_array.hpp
    +++ b/include/boost/smart_ptr/shared_array.hpp
    @@ -131,6 +131,11 @@ public:
             pn.swap(other.pn);
         }
     
    +    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
    +    {
    +        return pn.get_deleter( ti );
    +    }
    +
     private:
     
         T * px;                     // contained pointer
    @@ -158,6 +163,11 @@ template void swap(shared_array & a, shared_array & b) // never t
         a.swap(b);
     }
     
    +template< class D, class T > D * get_deleter( shared_array const & p )
    +{
    +    return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
    +}
    +
     } // namespace boost
     
     #endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
    index 632ef08..16bda20 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -66,5 +66,6 @@ import testing ;
               [ run sp_typeinfo_test.cpp ]
               [ compile make_shared_fp_test.cpp ]
               [ run sp_hash_test.cpp ]
    +          [ run get_deleter_array_test.cpp ]
             ;
     }
    diff --git a/test/get_deleter_array_test.cpp b/test/get_deleter_array_test.cpp
    new file mode 100644
    index 0000000..f6d2500
    --- /dev/null
    +++ b/test/get_deleter_array_test.cpp
    @@ -0,0 +1,95 @@
    +//
    +//  get_deleter_array_test.cpp
    +//
    +//  Copyright (c) 2002, 2011 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 deleter
    +{
    +    int data;
    +
    +    deleter(): data(0)
    +    {
    +    }
    +
    +    void operator()(void *)
    +    {
    +        BOOST_TEST(data == 17041);
    +    }
    +};
    +
    +struct deleter2
    +{
    +};
    +
    +struct X
    +{
    +};
    +
    +int main()
    +{
    +    {
    +        boost::shared_array p;
    +
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +    }
    +
    +    {
    +        boost::shared_array p(new X[1]);
    +
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +    }
    +
    +    {
    +        X x[1];
    +        boost::shared_array p(x, deleter());
    +
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +        BOOST_TEST(boost::get_deleter(p) == 0);
    +
    +        deleter * q = boost::get_deleter(p);
    +
    +        BOOST_TEST(q != 0);
    +        BOOST_TEST(q->data == 0);
    +
    +        q->data = 17041;
    +
    +        deleter const * r = boost::get_deleter(p);
    +
    +        BOOST_TEST(r == q);
    +        BOOST_TEST(r->data == 17041);
    +    }
    +
    +    return boost::report_errors();
    +}
    
    From e4cb5e131f7baac58d3483dc4adaae6143314a5f Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 7 Nov 2011 18:46:46 +0000
    Subject: [PATCH 068/210] Add hash_value for intrusive_ptr. Refs #6087.
    
    [SVN r75392]
    ---
     include/boost/smart_ptr/intrusive_ptr.hpp |  9 +++
     test/Jamfile.v2                           |  1 +
     test/ip_hash_test.cpp                     | 75 +++++++++++++++++++++++
     3 files changed, 85 insertions(+)
     create mode 100644 test/ip_hash_test.cpp
    
    diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp
    index 2fa4670..a575223 100644
    --- a/include/boost/smart_ptr/intrusive_ptr.hpp
    +++ b/include/boost/smart_ptr/intrusive_ptr.hpp
    @@ -285,6 +285,15 @@ template std::basic_ostream & operator<< (std::
     
     #endif // !defined(BOOST_NO_IOSTREAM)
     
    +// hash_value
    +
    +template< class T > struct hash;
    +
    +template< class T > std::size_t hash_value( boost::intrusive_ptr const & p )
    +{
    +    return boost::hash< T* >()( p.get() );
    +}
    +
     } // namespace boost
     
     #endif  // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
    index 16bda20..ad7d8fd 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -67,5 +67,6 @@ import testing ;
               [ compile make_shared_fp_test.cpp ]
               [ run sp_hash_test.cpp ]
               [ run get_deleter_array_test.cpp ]
    +          [ run ip_hash_test.cpp ]
             ;
     }
    diff --git a/test/ip_hash_test.cpp b/test/ip_hash_test.cpp
    new file mode 100644
    index 0000000..be38b3d
    --- /dev/null
    +++ b/test/ip_hash_test.cpp
    @@ -0,0 +1,75 @@
    +//
    +// ip_hash_test.cpp
    +//
    +// Copyright 2011 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 base
    +{
    +private:
    +
    +    int use_count_;
    +
    +    base(base const &);
    +    base & operator=(base const &);
    +
    +protected:
    +
    +    base(): use_count_(0)
    +    {
    +    }
    +
    +    virtual ~base()
    +    {
    +    }
    +
    +public:
    +
    +    long use_count() const
    +    {
    +        return use_count_;
    +    }
    +
    +    inline friend void intrusive_ptr_add_ref(base * p)
    +    {
    +        ++p->use_count_;
    +    }
    +
    +    inline friend void intrusive_ptr_release(base * p)
    +    {
    +        if(--p->use_count_ == 0) delete p;
    +    }
    +};
    +
    +struct X: public base
    +{
    +};
    +
    +int main()
    +{
    +    boost::hash< boost::intrusive_ptr > hasher;
    +
    +    boost::intrusive_ptr p1, p2( p1 ), p3( new X ), p4( p3 ), p5( new X );
    +
    +    BOOST_TEST_EQ( p1, p2 );
    +    BOOST_TEST_EQ( hasher( p1 ), hasher( p2 ) );
    +
    +    BOOST_TEST_NE( p1, p3 );
    +    BOOST_TEST_NE( hasher( p1 ), hasher( p3 ) );
    +
    +    BOOST_TEST_EQ( p3, p4 );
    +    BOOST_TEST_EQ( hasher( p3 ), hasher( p4 ) );
    +
    +    BOOST_TEST_NE( p3, p5 );
    +    BOOST_TEST_NE( hasher( p3 ), hasher( p5 ) );
    +
    +    return boost::report_errors();
    +}
    
    From 017ab7e2eef96972f571f548b764860e73627092 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 21 Dec 2011 00:36:55 +0000
    Subject: [PATCH 069/210] Apply AIX patch from #6308. Refs #6308.
    
    [SVN r76086]
    ---
     .../smart_ptr/detail/sp_counted_base.hpp      |   3 +
     .../smart_ptr/detail/sp_counted_base_aix.hpp  | 113 ++++++++++++++++++
     2 files changed, 116 insertions(+)
     create mode 100644 include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
    
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    index dc8b4d3..169c651 100644
    --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp
    +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    @@ -62,6 +62,9 @@
     #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
     # include 
     
    +#elif defined( _AIX )
    +# include 
    +
     #elif !defined( BOOST_HAS_THREADS )
     # include 
     
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp b/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
    new file mode 100644
    index 0000000..9dc77c8
    --- /dev/null
    +++ b/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
    @@ -0,0 +1,113 @@
    +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
    +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
    +
    +//
    +//  detail/sp_counted_base_aix.hpp
    +//   based on: detail/sp_counted_base_w32.hpp
    +//
    +//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
    +//  Copyright 2004-2005 Peter Dimov
    +//  Copyright 2006 Michael van der Westhuizen
    +//
    +//  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)
    +//
    +//
    +//  Lock-free algorithm by Alexander Terekhov
    +//
    +//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
    +//  formulation
    +//
    +
    +#include 
    +#include 
    +
    +namespace boost
    +{
    +
    +namespace detail
    +{
    +
    +class sp_counted_base
    +{
    +private:
    +
    +    sp_counted_base( sp_counted_base const & );
    +    sp_counted_base & operator= ( sp_counted_base const & );
    +
    +    int32_t use_count_;        // #shared
    +    int32_t weak_count_;       // #weak + (#shared != 0)
    +
    +public:
    +
    +    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
    +    {
    +    }
    +
    +    virtual ~sp_counted_base() // nothrow
    +    {
    +    }
    +
    +    // dispose() is called when use_count_ drops to zero, to release
    +    // the resources managed by *this.
    +
    +    virtual void dispose() = 0; // nothrow
    +
    +    // destroy() is called when weak_count_ drops to zero.
    +
    +    virtual void destroy() // nothrow
    +    {
    +        delete this;
    +    }
    +
    +    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
    +
    +    void add_ref_copy()
    +    {
    +        fetch_and_add( &use_count_, 1 );
    +    }
    +
    +    bool add_ref_lock() // true on success
    +    {
    +        int32_t tmp = fetch_and_add( &use_count_, 0 );
    +        for( ;; )
    +        {
    +            if( tmp == 0 ) return false;
    +            if( compare_and_swap( &use_count_, &tmp, tmp + 1 ) ) return true;
    +        }
    +    }
    +
    +    void release() // nothrow
    +    {
    +        if( fetch_and_add( &use_count_, -1 ) == 1 )
    +        {
    +            dispose();
    +            weak_release();
    +        }
    +    }
    +
    +    void weak_add_ref() // nothrow
    +    {
    +        fetch_and_add( &weak_count_, 1 );
    +    }
    +
    +    void weak_release() // nothrow
    +    {
    +        if( fetch_and_add( &weak_count_, -1 ) == 1 )
    +        {
    +            destroy();
    +        }
    +    }
    +
    +    long use_count() const // nothrow
    +    {
    +        return fetch_and_add( const_cast(&use_count_), 0 );
    +    }
    +};
    +
    +} // namespace detail
    +
    +} // namespace boost
    +
    +#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
    
    From 57a5441ebfbf28b8952be9297b38a4a4084825f0 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Fri, 23 Dec 2011 03:00:05 +0000
    Subject: [PATCH 070/210] Creatively apply patch from #2603. Refs #2603.
    
    [SVN r76111]
    ---
     include/boost/smart_ptr/owner_less.hpp | 57 ++++++++++++++++++++++
     include/boost/smart_ptr/shared_ptr.hpp |  9 +++-
     include/boost/smart_ptr/weak_ptr.hpp   |  9 +++-
     test/Jamfile.v2                        |  1 +
     test/owner_less_test.cpp               | 67 ++++++++++++++++++++++++++
     5 files changed, 139 insertions(+), 4 deletions(-)
     create mode 100644 include/boost/smart_ptr/owner_less.hpp
     create mode 100644 test/owner_less_test.cpp
    
    diff --git a/include/boost/smart_ptr/owner_less.hpp b/include/boost/smart_ptr/owner_less.hpp
    new file mode 100644
    index 0000000..6899325
    --- /dev/null
    +++ b/include/boost/smart_ptr/owner_less.hpp
    @@ -0,0 +1,57 @@
    +#ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
    +#define BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
    +
    +//
    +//  owner_less.hpp
    +//
    +//  Copyright (c) 2008 Frank Mori Hess
    +//
    +//  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/smart_ptr.htm for documentation.
    +//
    +
    +#include 
    +
    +namespace boost
    +{
    +  template class shared_ptr;
    +  template class weak_ptr;
    +
    +  namespace detail
    +  {
    +    template
    +      struct generic_owner_less : public std::binary_function
    +    {
    +      bool operator()(const T &lhs, const T &rhs) const
    +      {
    +        return lhs.owner_before(rhs);
    +      }
    +      bool operator()(const T &lhs, const U &rhs) const
    +      {
    +        return lhs.owner_before(rhs);
    +      }
    +      bool operator()(const U &lhs, const T &rhs) const
    +      {
    +        return lhs.owner_before(rhs);
    +      }
    +    };
    +  } // namespace detail
    +
    +  template struct owner_less;
    +
    +  template
    +    struct owner_less >:
    +    public detail::generic_owner_less, weak_ptr >
    +  {};
    +
    +  template
    +    struct owner_less >:
    +    public detail::generic_owner_less, shared_ptr >
    +  {};
    +
    +} // namespace boost
    +
    +#endif  // #ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
    diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp
    index d3973da..0932cc3 100644
    --- a/include/boost/smart_ptr/shared_ptr.hpp
    +++ b/include/boost/smart_ptr/shared_ptr.hpp
    @@ -443,7 +443,12 @@ public:
             pn.swap(other.pn);
         }
     
    -    template bool _internal_less(shared_ptr const & rhs) const
    +    template bool owner_before( shared_ptr const & rhs ) const
    +    {
    +        return pn < rhs.pn;
    +    }
    +
    +    template bool owner_before( weak_ptr const & rhs ) const
         {
             return pn < rhs.pn;
         }
    @@ -499,7 +504,7 @@ template inline bool operator!=(shared_ptr const & a, shared_ptr
     
     template inline bool operator<(shared_ptr const & a, shared_ptr const & b)
     {
    -    return a._internal_less(b);
    +    return a.owner_before( b );
     }
     
     template inline void swap(shared_ptr & a, shared_ptr & b)
    diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp
    index e00d96e..7d94254 100644
    --- a/include/boost/smart_ptr/weak_ptr.hpp
    +++ b/include/boost/smart_ptr/weak_ptr.hpp
    @@ -206,7 +206,12 @@ public:
             pn = r.pn;
         }
     
    -    template bool _internal_less(weak_ptr const & rhs) const
    +    template bool owner_before( weak_ptr const & rhs ) const
    +    {
    +        return pn < rhs.pn;
    +    }
    +
    +    template bool owner_before( shared_ptr const & rhs ) const
         {
             return pn < rhs.pn;
         }
    @@ -230,7 +235,7 @@ private:
     
     template inline bool operator<(weak_ptr const & a, weak_ptr const & b)
     {
    -    return a._internal_less(b);
    +    return a.owner_before( b );
     }
     
     template void swap(weak_ptr & a, weak_ptr & b)
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
    index ad7d8fd..66d8007 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -68,5 +68,6 @@ import testing ;
               [ run sp_hash_test.cpp ]
               [ run get_deleter_array_test.cpp ]
               [ run ip_hash_test.cpp ]
    +          [ run owner_less_test.cpp ]
             ;
     }
    diff --git a/test/owner_less_test.cpp b/test/owner_less_test.cpp
    new file mode 100644
    index 0000000..572b72b
    --- /dev/null
    +++ b/test/owner_less_test.cpp
    @@ -0,0 +1,67 @@
    +//
    +//  owner_less_test.cpp
    +//
    +//  A regression test for owner_less
    +//
    +//  Copyright (c) 2008 Frank Mori Hess
    +//
    +//  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 
    +
    +int main()
    +{
    +  boost::owner_less > comp;
    +  {
    +    boost::shared_ptr x;
    +    boost::shared_ptr y;
    +    boost::weak_ptr w;
    +    BOOST_TEST(!(comp(x, w) || comp(w, x)));
    +  }
    +  {
    +    boost::shared_ptr z((int*)0);
    +    boost::weak_ptr w;
    +    BOOST_TEST(comp(z, w) || comp(w, z));
    +    {
    +      boost::shared_ptr zz(z);
    +      w = boost::weak_ptr(zz);
    +      BOOST_TEST(!(comp(z, zz) || comp(z, zz)));
    +      BOOST_TEST(!(comp(z, w) || comp(z, w)));
    +    }
    +    BOOST_TEST(!(comp(z, w) || comp(w, z)));
    +  }
    +  {
    +    boost::shared_ptr x;
    +    boost::shared_ptr z((int*)0);
    +    BOOST_TEST(comp(x, z) || comp(z, x));
    +  }
    +  {
    +    boost::shared_ptr a((int*)0);
    +    boost::shared_ptr b((int*)0);
    +    BOOST_TEST(comp(a, b) || comp(b, a));
    +    boost::weak_ptr w(a);
    +    BOOST_TEST(!(comp(a, w) || comp(w, a)));
    +    BOOST_TEST(comp(b, w) || comp(w, b));
    +  }
    +
    +  boost::owner_less > weak_comp;
    +  {
    +    boost::shared_ptr a((int*)0);
    +    boost::weak_ptr wa(a);
    +    boost::shared_ptr b((int*)0);
    +    boost::weak_ptr wb(b);
    +    BOOST_TEST(!(weak_comp(a, wa) || weak_comp(wa, a)));
    +    BOOST_TEST(!(weak_comp(b, wb) || weak_comp(wb, b)));
    +    BOOST_TEST(weak_comp(wa, wb) || weak_comp(wb, wa));
    +    BOOST_TEST(weak_comp(wa, b) || weak_comp(b, wa));
    +  }
    +
    +  return boost::report_errors();
    +}
    
    From faf212f4aaa9d4be25dc2345cae378ac185db91d Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Fri, 23 Dec 2011 15:03:39 +0000
    Subject: [PATCH 071/210] Add memory barriers to sp_counted_base_aix.hpp. Refs
     #6308.
    
    [SVN r76119]
    ---
     .../smart_ptr/detail/sp_counted_base_aix.hpp  | 48 +++++++++++++++----
     1 file changed, 38 insertions(+), 10 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp b/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
    index 9dc77c8..a17e6cc 100644
    --- a/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
    +++ b/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
    @@ -26,6 +26,39 @@
     namespace boost
     {
     
    +inline void atomic_increment( int32_t* pw )
    +{
    +    // ++*pw;
    +
    +    fetch_and_add( pw, 1 );
    +}
    +
    +inline int32_t atomic_decrement( int32_t * pw )
    +{
    +    // return --*pw;
    +
    +    int32_t originalValue;
    +
    +    __asm__ __volatile__( "sync" );
    +    originalValue = fetch_and_add( pw, -1 );
    +    __asm__ __volatile__( "isync" );
    +
    +    return (originalValue - 1);
    +}
    +
    +inline int32_t atomic_conditional_increment( int32_t * pw )
    +{
    +    // if( *pw != 0 ) ++*pw;
    +    // return *pw;
    +
    +    int32_t tmp = fetch_and_add( pw, 0 );
    +    for( ;; )
    +    {
    +        if( tmp == 0 ) return 0;
    +        if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
    +    }
    +}
    +
     namespace detail
     {
     
    @@ -65,22 +98,17 @@ public:
     
         void add_ref_copy()
         {
    -        fetch_and_add( &use_count_, 1 );
    +        atomic_increment( &use_count_ );
         }
     
         bool add_ref_lock() // true on success
         {
    -        int32_t tmp = fetch_and_add( &use_count_, 0 );
    -        for( ;; )
    -        {
    -            if( tmp == 0 ) return false;
    -            if( compare_and_swap( &use_count_, &tmp, tmp + 1 ) ) return true;
    -        }
    +        return atomic_conditional_increment( &use_count_ ) != 0;
         }
     
         void release() // nothrow
         {
    -        if( fetch_and_add( &use_count_, -1 ) == 1 )
    +        if( atomic_decrement( &use_count_ ) == 0 )
             {
                 dispose();
                 weak_release();
    @@ -89,12 +117,12 @@ public:
     
         void weak_add_ref() // nothrow
         {
    -        fetch_and_add( &weak_count_, 1 );
    +        atomic_increment( &weak_count_ );
         }
     
         void weak_release() // nothrow
         {
    -        if( fetch_and_add( &weak_count_, -1 ) == 1 )
    +        if( atomic_decrement( &weak_count_ ) == 0 )
             {
                 destroy();
             }
    
    From 33ba2c4722b7438e03c086dbc4526f1e78785f80 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Fri, 23 Dec 2011 23:10:37 +0000
    Subject: [PATCH 072/210] sp_counted_base_aix.hpp: switch to lwsync and
     builtins. Refs #6308.
    
    [SVN r76123]
    ---
     .../boost/smart_ptr/detail/sp_counted_base_aix.hpp    | 11 ++++++-----
     1 file changed, 6 insertions(+), 5 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp b/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
    index a17e6cc..0208678 100644
    --- a/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
    +++ b/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
    @@ -21,11 +21,15 @@
     //
     
     #include 
    +#include 
     #include 
     
     namespace boost
     {
     
    +namespace detail
    +{
    +
     inline void atomic_increment( int32_t* pw )
     {
         // ++*pw;
    @@ -39,9 +43,9 @@ inline int32_t atomic_decrement( int32_t * pw )
     
         int32_t originalValue;
     
    -    __asm__ __volatile__( "sync" );
    +    __lwsync();
         originalValue = fetch_and_add( pw, -1 );
    -    __asm__ __volatile__( "isync" );
    +    __isync();
     
         return (originalValue - 1);
     }
    @@ -59,9 +63,6 @@ inline int32_t atomic_conditional_increment( int32_t * pw )
         }
     }
     
    -namespace detail
    -{
    -
     class sp_counted_base
     {
     private:
    
    From df364f37f2576cfe49e6dd06a16940cdbe8ffb89 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Fri, 23 Dec 2011 23:54:41 +0000
    Subject: [PATCH 073/210] std::move is in .
    
    [SVN r76125]
    ---
     test/intrusive_ptr_move_test.cpp | 3 +--
     test/shared_ptr_move_test.cpp    | 1 +
     test/weak_ptr_move_test.cpp      | 1 +
     3 files changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/test/intrusive_ptr_move_test.cpp b/test/intrusive_ptr_move_test.cpp
    index b5f0e65..3faf16e 100644
    --- a/test/intrusive_ptr_move_test.cpp
    +++ b/test/intrusive_ptr_move_test.cpp
    @@ -30,8 +30,7 @@
     #include 
     #include 
     #include 
    -#include 
    -#include 
    +#include 
     
     #if defined( BOOST_HAS_RVALUE_REFS )
     
    diff --git a/test/shared_ptr_move_test.cpp b/test/shared_ptr_move_test.cpp
    index c02ffa9..82ba9d6 100644
    --- a/test/shared_ptr_move_test.cpp
    +++ b/test/shared_ptr_move_test.cpp
    @@ -10,6 +10,7 @@
     
     #include 
     #include 
    +#include 
     
     #if defined( BOOST_HAS_RVALUE_REFS )
     
    diff --git a/test/weak_ptr_move_test.cpp b/test/weak_ptr_move_test.cpp
    index 572b13d..4df3691 100644
    --- a/test/weak_ptr_move_test.cpp
    +++ b/test/weak_ptr_move_test.cpp
    @@ -10,6 +10,7 @@
     
     #include 
     #include 
    +#include 
     
     #if defined( BOOST_HAS_RVALUE_REFS )
     
    
    From 2c29f1e5a9d2360bdb89155eeda5641fbfb21e2e Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 29 Dec 2011 22:27:37 +0000
    Subject: [PATCH 074/210] Warning 4284 is obsolete. Refs #6332. See also #4433.
    
    [SVN r76219]
    ---
     include/boost/smart_ptr/weak_ptr.hpp | 9 ---------
     1 file changed, 9 deletions(-)
    
    diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp
    index 7d94254..5391910 100644
    --- a/include/boost/smart_ptr/weak_ptr.hpp
    +++ b/include/boost/smart_ptr/weak_ptr.hpp
    @@ -17,11 +17,6 @@
     #include 
     #include 
     
    -#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
    -# pragma warning(push)
    -# pragma warning(disable:4284) // odd return type for operator->
    -#endif
    -
     namespace boost
     {
     
    @@ -245,8 +240,4 @@ template void swap(weak_ptr & a, weak_ptr & b)
     
     } // namespace boost
     
    -#ifdef BOOST_MSVC
    -# pragma warning(pop)
    -#endif
    -
     #endif  // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
    
    From 27a312228c94b2de5cfdf756bf27536605161327 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 12 Mar 2012 17:31:21 +0000
    Subject: [PATCH 075/210] Apply patch from #5331. Refs #5331.
    
    [SVN r77315]
    ---
     .../smart_ptr/detail/spinlock_gcc_arm.hpp     | 29 +++++++++++++++++--
     1 file changed, 27 insertions(+), 2 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp b/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
    index f58ea44..f1bbaf6 100644
    --- a/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
    +++ b/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
    @@ -43,13 +43,38 @@ public:
         {
             int r;
     
    +#if defined(__ARM_ARCH_6__) \
    +    || defined(__ARM_ARCH_6J__) \
    +    || defined(__ARM_ARCH_6K__) \
    +    || defined(__ARM_ARCH_6Z__) \
    +    || defined(__ARM_ARCH_6ZK__) \
    +    || defined(__ARM_ARCH_6T2__) \
    +    || defined(__ARM_ARCH_7__) \
    +    || defined(__ARM_ARCH_7A__) \
    +    || defined(__ARM_ARCH_7R__) \
    +    || defined(__ARM_ARCH_7M__) \
    +    || defined(__ARM_ARCH_7EM__)
    +
             __asm__ __volatile__(
    -            "swp %0, %1, [%2]\n\t"
    -			BOOST_SP_ARM_BARRIER :
    +            "ldrex %0, [%2]; \n"
    +            "cmp %0, %1; \n"
    +            "strexne %0, %1, [%2]; \n"
    +            BOOST_SP_ARM_BARRIER :
                 "=&r"( r ): // outputs
                 "r"( 1 ), "r"( &v_ ): // inputs
                 "memory", "cc" );
     
    +#else
    +
    +        __asm__ __volatile__(
    +            "swp %0, %1, [%2];\n"
    +            BOOST_SP_ARM_BARRIER :
    +            "=&r"( r ): // outputs
    +            "r"( 1 ), "r"( &v_ ): // inputs
    +            "memory", "cc" );
    +
    +#endif
    +
             return r == 0;
         }
     
    
    From 1029ae0ea5497db1a6884d129cb2bc4d9d238bc8 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 12 Mar 2012 17:33:50 +0000
    Subject: [PATCH 076/210] Apply patches from #6667. Refs #6667.
    
    [SVN r77316]
    ---
     .../smart_ptr/detail/sp_counted_base.hpp      |   6 +-
     .../detail/sp_counted_base_vacpp_ppc.hpp      | 150 ++++++++++++++++++
     2 files changed, 153 insertions(+), 3 deletions(-)
     create mode 100644 include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
    
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    index 169c651..a393736 100644
    --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp
    +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    @@ -44,6 +44,9 @@
     #elif defined(__HP_aCC) && defined(__ia64)
     # include 
     
    +#elif defined( __IBMCPP__ ) && defined( __powerpc )
    +# include 
    +
     #elif defined( __MWERKS__ ) && defined( __POWERPC__ )
     # include 
     
    @@ -62,9 +65,6 @@
     #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
     # include 
     
    -#elif defined( _AIX )
    -# include 
    -
     #elif !defined( BOOST_HAS_THREADS )
     # include 
     
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
    new file mode 100644
    index 0000000..842f58f
    --- /dev/null
    +++ b/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
    @@ -0,0 +1,150 @@
    +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
    +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
    +
    +//
    +//  detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
    +//   based on: detail/sp_counted_base_w32.hpp
    +//
    +//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
    +//  Copyright 2004-2005 Peter Dimov
    +//  Copyright 2006 Michael van der Westhuizen
    +//  Copyright 2012 IBM Corp.
    +//
    +//  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)
    +//
    +//
    +//  Lock-free algorithm by Alexander Terekhov
    +//
    +//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
    +//  formulation
    +//
    +
    +#include 
    +
    +extern "builtin" void __lwsync(void);
    +extern "builtin" void __isync(void);
    +extern "builtin" int __fetch_and_add(volatile int* addr, int val);
    +extern "builtin" int __compare_and_swap(volatile int*, int*, int);
    +
    +namespace boost
    +{
    +
    +namespace detail
    +{
    +
    +inline void atomic_increment( int *pw )
    +{
    +   // ++*pw;
    +   __lwsync();
    +   __fetch_and_add(pw, 1);
    +   __isync();
    +} 
    +
    +inline int atomic_decrement( int *pw )
    +{
    +   // return --*pw;
    +   __lwsync();
    +   int originalValue = __fetch_and_add(pw, -1);
    +   __isync();
    +
    +   return (originalValue - 1);
    +}
    +
    +inline int atomic_conditional_increment( int *pw )
    +{
    +   // if( *pw != 0 ) ++*pw;
    +   // return *pw;
    +
    +   __lwsync();
    +   int v = *const_cast(pw);
    +   for (;;)
    +   // loop until state is known
    +   {
    +      if (v == 0) return 0;
    +      if (__compare_and_swap(pw, &v, v + 1))
    +      {
    +         __isync(); return (v + 1);
    +      }
    +   }
    +}
    +
    +class sp_counted_base
    +{
    +private:
    +
    +    sp_counted_base( sp_counted_base const & );
    +    sp_counted_base & operator= ( sp_counted_base const & );
    +
    +    int use_count_;        // #shared
    +    int weak_count_;       // #weak + (#shared != 0)
    +    char pad[64] __attribute__((__aligned__(64)));
    +            // pad to prevent false sharing
    +public:
    +
    +    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
    +    {
    +    }
    +
    +    virtual ~sp_counted_base() // nothrow
    +    {
    +    }
    +
    +    // dispose() is called when use_count_ drops to zero, to release
    +    // the resources managed by *this.
    +
    +    virtual void dispose() = 0; // nothrow
    +
    +    // destroy() is called when weak_count_ drops to zero.
    +
    +    virtual void destroy() // nothrow
    +    {
    +        delete this;
    +    }
    +
    +    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
    +
    +    void add_ref_copy()
    +    {
    +        atomic_increment( &use_count_ );
    +    }
    +
    +    bool add_ref_lock() // true on success
    +    {
    +        return atomic_conditional_increment( &use_count_ ) != 0;
    +    }
    +
    +    void release() // nothrow
    +    {
    +        if( atomic_decrement( &use_count_ ) == 0 )
    +        {
    +            dispose();
    +            weak_release();
    +        }
    +    }
    +
    +    void weak_add_ref() // nothrow
    +    {
    +        atomic_increment( &weak_count_ );
    +    }
    +
    +    void weak_release() // nothrow
    +    {
    +        if( atomic_decrement( &weak_count_ ) == 0 )
    +        {
    +            destroy();
    +        }
    +    }
    +
    +    long use_count() const // nothrow
    +    {
    +        return *const_cast(&use_count_); 
    +    }
    +};
    +
    +} // namespace detail
    +
    +} // namespace boost
    +
    +#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
    
    From 4c98df7c57c03e5664afccb01bf2ac2f53a00618 Mon Sep 17 00:00:00 2001
    From: Bryce Adelstein-Lelbach 
    Date: Sun, 14 Oct 2012 23:06:12 +0000
    Subject: [PATCH 077/210] Update smart_ptr for the latest version of the
     PathScale compiler.
    
    [SVN r80988]
    ---
     include/boost/smart_ptr/detail/sp_counted_base.hpp | 8 ++++----
     include/boost/smart_ptr/detail/sp_has_sync.hpp     | 2 +-
     2 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    index a393736..606e3d5 100644
    --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp
    +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    @@ -35,10 +35,10 @@
     #elif defined( __SNC__ )
     # include 
     
    -#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
    +#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
     # include 
     
    -#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
    +#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
     # include 
     
     #elif defined(__HP_aCC) && defined(__ia64)
    @@ -50,10 +50,10 @@
     #elif defined( __MWERKS__ ) && defined( __POWERPC__ )
     # include 
     
    -#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
    +#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__)
     # include 
     
    -#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) )
    +#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
     # include 
     
     #elif defined( BOOST_SP_HAS_SYNC )
    diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    index 67f4c38..c266e75 100644
    --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp
    +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    @@ -48,7 +48,7 @@
     #undef BOOST_SP_HAS_SYNC
     #endif
     
    -#if defined (__PATHSCALE__)
    +#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9)) 
     #undef BOOST_SP_HAS_SYNC
     #endif
     
    
    From b0f72d7b3d5cd3ca8a0962b700555be1cbf5cde2 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 31 Oct 2012 16:04:03 +0000
    Subject: [PATCH 078/210] Add check for __ARM_ARCH_7S__. Refs #7599.
    
    [SVN r81119]
    ---
     .../boost/smart_ptr/detail/spinlock_gcc_arm.hpp | 17 +++++------------
     1 file changed, 5 insertions(+), 12 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp b/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
    index f1bbaf6..016796a 100644
    --- a/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
    +++ b/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
    @@ -11,13 +11,15 @@
     
     #include 
     
    -#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
    +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
     
     # define BOOST_SP_ARM_BARRIER "dmb"
    +# define BOOST_SP_ARM_HAS_LDREX
     
     #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
     
     # define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
    +# define BOOST_SP_ARM_HAS_LDREX
     
     #else
     
    @@ -43,17 +45,7 @@ public:
         {
             int r;
     
    -#if defined(__ARM_ARCH_6__) \
    -    || defined(__ARM_ARCH_6J__) \
    -    || defined(__ARM_ARCH_6K__) \
    -    || defined(__ARM_ARCH_6Z__) \
    -    || defined(__ARM_ARCH_6ZK__) \
    -    || defined(__ARM_ARCH_6T2__) \
    -    || defined(__ARM_ARCH_7__) \
    -    || defined(__ARM_ARCH_7A__) \
    -    || defined(__ARM_ARCH_7R__) \
    -    || defined(__ARM_ARCH_7M__) \
    -    || defined(__ARM_ARCH_7EM__)
    +#ifdef BOOST_SP_ARM_HAS_LDREX
     
             __asm__ __volatile__(
                 "ldrex %0, [%2]; \n"
    @@ -123,5 +115,6 @@ public:
     #define BOOST_DETAIL_SPINLOCK_INIT {0}
     
     #undef BOOST_SP_ARM_BARRIER
    +#undef BOOST_SP_ARM_HAS_LDREX
     
     #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
    
    From 3e447c919cd040ebaa4be24cb2e1dbc2eebe2f0e Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 31 Oct 2012 20:04:14 +0000
    Subject: [PATCH 079/210] Add get_pointer overloads for std::unique_ptr,
     std::shared_ptr. Refs #4185.
    
    [SVN r81125]
    ---
     include/boost/get_pointer.hpp | 19 +++++++++++++++++--
     1 file changed, 17 insertions(+), 2 deletions(-)
    
    diff --git a/include/boost/get_pointer.hpp b/include/boost/get_pointer.hpp
    index a0cd5c0..b27b98a 100644
    --- a/include/boost/get_pointer.hpp
    +++ b/include/boost/get_pointer.hpp
    @@ -3,13 +3,15 @@
     // accompanying file LICENSE_1_0.txt or copy at
     // http://www.boost.org/LICENSE_1_0.txt)
     #ifndef GET_POINTER_DWA20021219_HPP
    -# define GET_POINTER_DWA20021219_HPP
    +#define GET_POINTER_DWA20021219_HPP
    +
    +#include 
     
     // In order to avoid circular dependencies with Boost.TR1
     // we make sure that our include of  doesn't try to
     // pull in the TR1 headers: that's why we use this header 
     // rather than including  directly:
    -# include   // std::auto_ptr
    +#include   // std::auto_ptr
     
     namespace boost { 
     
    @@ -27,6 +29,19 @@ template T * get_pointer(std::auto_ptr const& p)
         return p.get();
     }
     
    +#if !defined( BOOST_NO_CXX11_SMART_PTR )
    +
    +template T * get_pointer( std::unique_ptr const& p )
    +{
    +    return p.get();
    +}
    +
    +template T * get_pointer( std::shared_ptr const& p )
    +{
    +    return p.get();
    +}
    +
    +#endif
     
     } // namespace boost
     
    
    From 16084637a6b5eb188cbd07f71cddf4eca43a66c1 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 31 Oct 2012 20:16:56 +0000
    Subject: [PATCH 080/210] Do not use sp_counted_base_gcc_ppc on AIX. Refs
     #6996.
    
    [SVN r81126]
    ---
     include/boost/smart_ptr/detail/sp_counted_base.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    index 606e3d5..783d130 100644
    --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp
    +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    @@ -50,7 +50,7 @@
     #elif defined( __MWERKS__ ) && defined( __POWERPC__ )
     # include 
     
    -#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__)
    +#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
     # include 
     
     #elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
    
    From f2d4b67a484746375e3d6f8aed7270d0b0655aed Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 31 Oct 2012 20:30:27 +0000
    Subject: [PATCH 081/210] Enable __sync primitives on VACPP. Refs #6901.
    
    [SVN r81127]
    ---
     include/boost/smart_ptr/detail/sp_has_sync.hpp | 12 ++++++++++--
     1 file changed, 10 insertions(+), 2 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    index c266e75..3a1d346 100644
    --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp
    +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    @@ -20,7 +20,9 @@
     //  are available.
     //
     
    -#if defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( BOOST_SP_NO_SYNC )
    +#ifndef BOOST_SP_NO_SYNC
    +
    +#if defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
     
     #define BOOST_SP_HAS_SYNC
     
    @@ -52,6 +54,12 @@
     #undef BOOST_SP_HAS_SYNC
     #endif
     
    -#endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401
    +#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
    +
    +#define BOOST_SP_HAS_SYNC
    +
    +#endif
    +
    +#endif // #ifndef BOOST_SP_NO_SYNC
     
     #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
    
    From 10dcb8db7c71c4bbdf8e46820722a775e29cea48 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 31 Oct 2012 20:37:21 +0000
    Subject: [PATCH 082/210] Define BOOST_SP_HAS_SYNC when
     __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 is set. Refs #7141.
    
    [SVN r81128]
    ---
     include/boost/smart_ptr/detail/sp_has_sync.hpp | 14 +++++++++-----
     1 file changed, 9 insertions(+), 5 deletions(-)
    
    diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    index 3a1d346..16de21d 100644
    --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp
    +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp
    @@ -22,7 +22,15 @@
     
     #ifndef BOOST_SP_NO_SYNC
     
    -#if defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
    +#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
    +
    +# define BOOST_SP_HAS_SYNC
    +
    +#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
    +
    +# define BOOST_SP_HAS_SYNC
    +
    +#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
     
     #define BOOST_SP_HAS_SYNC
     
    @@ -54,10 +62,6 @@
     #undef BOOST_SP_HAS_SYNC
     #endif
     
    -#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
    -
    -#define BOOST_SP_HAS_SYNC
    -
     #endif
     
     #endif // #ifndef BOOST_SP_NO_SYNC
    
    From 0c22e55f3e762b7e704bf22e75200b61a1fd8841 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Wed, 31 Oct 2012 22:16:20 +0000
    Subject: [PATCH 083/210] Add shared_ptr constructor taking std::unique_ptr.
     Refs #6625.
    
    [SVN r81131]
    ---
     .../boost/smart_ptr/detail/shared_count.hpp   |  63 ++++++++
     include/boost/smart_ptr/shared_ptr.hpp        |  12 ++
     test/Jamfile.v2                               |   1 +
     test/sp_unique_ptr_test.cpp                   | 152 ++++++++++++++++++
     4 files changed, 228 insertions(+)
     create mode 100644 test/sp_unique_ptr_test.cpp
    
    diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp
    index f96a220..2c99f02 100644
    --- a/include/boost/smart_ptr/detail/shared_count.hpp
    +++ b/include/boost/smart_ptr/detail/shared_count.hpp
    @@ -37,6 +37,10 @@
     #include        // std::less
     #include               // std::bad_alloc
     
    +#if !defined( BOOST_NO_CXX11_SMART_PTR )
    +# include 
    +#endif
    +
     namespace boost
     {
     
    @@ -56,6 +60,38 @@ template< class D > struct sp_inplace_tag
     {
     };
     
    +#if !defined( BOOST_NO_CXX11_SMART_PTR )
    +
    +template< class T > class sp_reference_wrapper
    +{ 
    +public:
    +
    +    explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
    +    {
    +    }
    +
    +    template< class Y > void operator()( Y * p ) const
    +    {
    +        (*t_)( p );
    +    }
    +
    +private:
    +
    +    T * t_;
    +};
    +
    +template< class D > struct sp_convert_reference
    +{
    +    typedef D type;
    +};
    +
    +template< class D > struct sp_convert_reference< D& >
    +{
    +    typedef sp_reference_wrapper< D > type;
    +};
    +
    +#endif
    +
     class weak_count;
     
     class shared_count
    @@ -300,6 +336,33 @@ public:
     
     #endif 
     
    +#if !defined( BOOST_NO_CXX11_SMART_PTR )
    +
    +    template
    +    explicit shared_count( std::unique_ptr & r ): pi_( 0 )
    +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
    +        , id_(shared_count_id)
    +#endif
    +    {
    +        typedef typename sp_convert_reference::type D2;
    +
    +        D2 d2( r.get_deleter() );
    +        pi_ = new sp_counted_impl_pd< Y*, D2 >( r.get(), d2 );
    +
    +#ifdef BOOST_NO_EXCEPTIONS
    +
    +        if( pi_ == 0 )
    +        {
    +            boost::throw_exception( std::bad_alloc() );
    +        }
    +
    +#endif
    +
    +        r.release();
    +    }
    +
    +#endif
    +
         ~shared_count() // nothrow
         {
             if( pi_ != 0 ) pi_->release();
    diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp
    index 0932cc3..924f621 100644
    --- a/include/boost/smart_ptr/shared_ptr.hpp
    +++ b/include/boost/smart_ptr/shared_ptr.hpp
    @@ -298,6 +298,18 @@ public:
     
     #endif // BOOST_NO_AUTO_PTR
     
    +#if !defined( BOOST_NO_CXX11_SMART_PTR )
    +
    +    template< class Y, class D >
    +    shared_ptr( std::unique_ptr< Y, D > && r): px( r.get() ), pn()
    +    {
    +        Y * tmp = r.get();
    +        pn = boost::detail::shared_count( r );
    +        boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
    +    }
    +
    +#endif
    +
         // assignment
     
         shared_ptr & operator=( shared_ptr const & r ) // never throws
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
    index 66d8007..1df2a3e 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -69,5 +69,6 @@ import testing ;
               [ run get_deleter_array_test.cpp ]
               [ run ip_hash_test.cpp ]
               [ run owner_less_test.cpp ]
    +          [ run sp_unique_ptr_test.cpp ]
             ;
     }
    diff --git a/test/sp_unique_ptr_test.cpp b/test/sp_unique_ptr_test.cpp
    new file mode 100644
    index 0000000..70c5aff
    --- /dev/null
    +++ b/test/sp_unique_ptr_test.cpp
    @@ -0,0 +1,152 @@
    +//
    +//  sp_unique_ptr_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 
    +
    +#if !defined( BOOST_NO_CXX11_SMART_PTR )
    +
    +struct X: public boost::enable_shared_from_this< X >
    +{
    +    static int instances;
    +
    +    X()
    +    {
    +        ++instances;
    +    }
    +
    +    ~X()
    +    {
    +        --instances;
    +    }
    +
    +private:
    +
    +    X( X const & );
    +    X & operator=( X const & );
    +};
    +
    +int X::instances = 0;
    +
    +struct Y
    +{
    +    static int instances;
    +
    +    bool deleted_;
    +
    +    Y(): deleted_( false )
    +    {
    +        ++instances;
    +    }
    +
    +    ~Y()
    +    {
    +        BOOST_TEST( deleted_ );
    +        --instances;
    +    }
    +
    +private:
    +
    +    Y( Y const & );
    +    Y & operator=( Y const & );
    +};
    +
    +int Y::instances = 0;
    +
    +struct YD
    +{
    +    void operator()( Y* p ) const
    +    {
    +        p->deleted_ = true;
    +        delete p;
    +    }
    +};
    +
    +int main()
    +{
    +    {
    +        BOOST_TEST( X::instances == 0 );
    +
    +        std::unique_ptr p( new X );
    +        BOOST_TEST( X::instances == 1 );
    +
    +        boost::shared_ptr p2( std::move( p ) );
    +        BOOST_TEST( X::instances == 1 );
    +        BOOST_TEST( p.get() == 0 );
    +
    +        boost::shared_ptr p3 = p2->shared_from_this();
    +        BOOST_TEST( p2 == p3 );
    +        BOOST_TEST( !(p2 < p3) && !(p3 < p2) );
    +
    +        p2.reset();
    +        p3.reset();
    +        BOOST_TEST( X::instances == 0 );
    +    }
    +
    +    {
    +        BOOST_TEST( Y::instances == 0 );
    +
    +        std::unique_ptr p( new Y, YD() );
    +        BOOST_TEST( Y::instances == 1 );
    +
    +        boost::shared_ptr p2( std::move( p ) );
    +        BOOST_TEST( Y::instances == 1 );
    +        BOOST_TEST( p.get() == 0 );
    +
    +        p2.reset();
    +        BOOST_TEST( Y::instances == 0 );
    +    }
    +
    +    {
    +        BOOST_TEST( Y::instances == 0 );
    +
    +        YD yd;
    +
    +        std::unique_ptr p( new Y, yd );
    +        BOOST_TEST( Y::instances == 1 );
    +
    +        boost::shared_ptr p2( std::move( p ) );
    +        BOOST_TEST( Y::instances == 1 );
    +        BOOST_TEST( p.get() == 0 );
    +
    +        p2.reset();
    +        BOOST_TEST( Y::instances == 0 );
    +    }
    +
    +    {
    +        BOOST_TEST( Y::instances == 0 );
    +
    +        YD yd;
    +
    +        std::unique_ptr p( new Y, yd );
    +        BOOST_TEST( Y::instances == 1 );
    +
    +        boost::shared_ptr p2( std::move( p ) );
    +        BOOST_TEST( Y::instances == 1 );
    +        BOOST_TEST( p.get() == 0 );
    +
    +        p2.reset();
    +        BOOST_TEST( Y::instances == 0 );
    +    }
    +
    +    return boost::report_errors();
    +}
    +
    +#else // !defined( BOOST_NO_CXX11_SMART_PTR )
    +
    +int main()
    +{
    +    return 0;
    +}
    +
    +#endif
    
    From 03ae5cdbc69854d5c5c8f597153e4832b9c4cc76 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Thu, 1 Nov 2012 17:50:41 +0000
    Subject: [PATCH 084/210] Add back _AIX-specific #ifdef that was mistakenly
     removed. Refs #6308. Refs #6667.
    
    [SVN r81134]
    ---
     include/boost/smart_ptr/detail/sp_counted_base.hpp | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    index 783d130..e97c237 100644
    --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp
    +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp
    @@ -65,6 +65,9 @@
     #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
     # include 
     
    +#elif defined( _AIX )
    +# include 
    +
     #elif !defined( BOOST_HAS_THREADS )
     # include 
     
    
    From 8c15401ea7ff3ba1c92a3e289e6de63633a5668f Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Fri, 2 Nov 2012 17:41:33 +0000
    Subject: [PATCH 085/210] Implement shared_ptr, weak_ptr. Refs #1113.
    
    [SVN r81149]
    ---
     .../boost/smart_ptr/detail/operator_bool.hpp  |   4 +-
     .../boost/smart_ptr/detail/shared_count.hpp   |   2 +-
     include/boost/smart_ptr/shared_ptr.hpp        | 205 +++++++++---
     include/boost/smart_ptr/weak_ptr.hpp          |  19 +-
     test/Jamfile.v2                               |  57 ++++
     test/array_fail_ap_spa_a.cpp                  |  20 ++
     test/array_fail_ap_spa_c.cpp                  |  20 ++
     test/array_fail_ap_spa_ma.cpp                 |  19 ++
     test/array_fail_ap_spa_mc.cpp                 |  19 ++
     test/array_fail_array_access.cpp              |  19 ++
     test/array_fail_dereference.cpp               |  19 ++
     test/array_fail_member_access.cpp             |  20 ++
     test/array_fail_sp_spa_a.cpp                  |  19 ++
     test/array_fail_sp_spa_c.cpp                  |  19 ++
     test/array_fail_sp_spa_ma.cpp                 |  18 ++
     test/array_fail_sp_spa_mc.cpp                 |  18 ++
     test/array_fail_sp_wpa_a.cpp                  |  20 ++
     test/array_fail_sp_wpa_c.cpp                  |  20 ++
     test/array_fail_sp_wpa_ma.cpp                 |  19 ++
     test/array_fail_sp_wpa_mc.cpp                 |  19 ++
     test/array_fail_spa_sp_a.cpp                  |  19 ++
     test/array_fail_spa_sp_c.cpp                  |  19 ++
     test/array_fail_spa_sp_ma.cpp                 |  18 ++
     test/array_fail_spa_sp_mc.cpp                 |  18 ++
     test/array_fail_spa_spa_a.cpp                 |  23 ++
     test/array_fail_spa_spa_c.cpp                 |  23 ++
     test/array_fail_spa_spa_ma.cpp                |  22 ++
     test/array_fail_spa_spa_mc.cpp                |  22 ++
     test/array_fail_spa_wp_a.cpp                  |  20 ++
     test/array_fail_spa_wp_c.cpp                  |  20 ++
     test/array_fail_spa_wp_ma.cpp                 |  19 ++
     test/array_fail_spa_wp_mc.cpp                 |  19 ++
     test/array_fail_spa_wpa_a.cpp                 |  24 ++
     test/array_fail_spa_wpa_c.cpp                 |  24 ++
     test/array_fail_spa_wpa_ma.cpp                |  23 ++
     test/array_fail_spa_wpa_mc.cpp                |  23 ++
     test/array_fail_up_spa_a.cpp                  |  20 ++
     test/array_fail_up_spa_c.cpp                  |  20 ++
     test/array_fail_up_spa_ma.cpp                 |  19 ++
     test/array_fail_up_spa_mc.cpp                 |  19 ++
     test/array_fail_upa_sp_a.cpp                  |  20 ++
     test/array_fail_upa_sp_c.cpp                  |  20 ++
     test/array_fail_upa_sp_ma.cpp                 |  19 ++
     test/array_fail_upa_sp_mc.cpp                 |  19 ++
     test/array_fail_wp_wpa_a.cpp                  |  19 ++
     test/array_fail_wp_wpa_c.cpp                  |  19 ++
     test/array_fail_wp_wpa_ma.cpp                 |  18 ++
     test/array_fail_wp_wpa_mc.cpp                 |  18 ++
     test/array_fail_wpa_wp_a.cpp                  |  19 ++
     test/array_fail_wpa_wp_c.cpp                  |  19 ++
     test/array_fail_wpa_wp_ma.cpp                 |  18 ++
     test/array_fail_wpa_wp_mc.cpp                 |  18 ++
     test/array_fail_wpa_wpa_a.cpp                 |  23 ++
     test/array_fail_wpa_wpa_c.cpp                 |  23 ++
     test/array_fail_wpa_wpa_ma.cpp                |  22 ++
     test/array_fail_wpa_wpa_mc.cpp                |  22 ++
     test/sp_array_test.cpp                        | 291 ++++++++++++++++++
     57 files changed, 1545 insertions(+), 51 deletions(-)
     create mode 100644 test/array_fail_ap_spa_a.cpp
     create mode 100644 test/array_fail_ap_spa_c.cpp
     create mode 100644 test/array_fail_ap_spa_ma.cpp
     create mode 100644 test/array_fail_ap_spa_mc.cpp
     create mode 100644 test/array_fail_array_access.cpp
     create mode 100644 test/array_fail_dereference.cpp
     create mode 100644 test/array_fail_member_access.cpp
     create mode 100644 test/array_fail_sp_spa_a.cpp
     create mode 100644 test/array_fail_sp_spa_c.cpp
     create mode 100644 test/array_fail_sp_spa_ma.cpp
     create mode 100644 test/array_fail_sp_spa_mc.cpp
     create mode 100644 test/array_fail_sp_wpa_a.cpp
     create mode 100644 test/array_fail_sp_wpa_c.cpp
     create mode 100644 test/array_fail_sp_wpa_ma.cpp
     create mode 100644 test/array_fail_sp_wpa_mc.cpp
     create mode 100644 test/array_fail_spa_sp_a.cpp
     create mode 100644 test/array_fail_spa_sp_c.cpp
     create mode 100644 test/array_fail_spa_sp_ma.cpp
     create mode 100644 test/array_fail_spa_sp_mc.cpp
     create mode 100644 test/array_fail_spa_spa_a.cpp
     create mode 100644 test/array_fail_spa_spa_c.cpp
     create mode 100644 test/array_fail_spa_spa_ma.cpp
     create mode 100644 test/array_fail_spa_spa_mc.cpp
     create mode 100644 test/array_fail_spa_wp_a.cpp
     create mode 100644 test/array_fail_spa_wp_c.cpp
     create mode 100644 test/array_fail_spa_wp_ma.cpp
     create mode 100644 test/array_fail_spa_wp_mc.cpp
     create mode 100644 test/array_fail_spa_wpa_a.cpp
     create mode 100644 test/array_fail_spa_wpa_c.cpp
     create mode 100644 test/array_fail_spa_wpa_ma.cpp
     create mode 100644 test/array_fail_spa_wpa_mc.cpp
     create mode 100644 test/array_fail_up_spa_a.cpp
     create mode 100644 test/array_fail_up_spa_c.cpp
     create mode 100644 test/array_fail_up_spa_ma.cpp
     create mode 100644 test/array_fail_up_spa_mc.cpp
     create mode 100644 test/array_fail_upa_sp_a.cpp
     create mode 100644 test/array_fail_upa_sp_c.cpp
     create mode 100644 test/array_fail_upa_sp_ma.cpp
     create mode 100644 test/array_fail_upa_sp_mc.cpp
     create mode 100644 test/array_fail_wp_wpa_a.cpp
     create mode 100644 test/array_fail_wp_wpa_c.cpp
     create mode 100644 test/array_fail_wp_wpa_ma.cpp
     create mode 100644 test/array_fail_wp_wpa_mc.cpp
     create mode 100644 test/array_fail_wpa_wp_a.cpp
     create mode 100644 test/array_fail_wpa_wp_c.cpp
     create mode 100644 test/array_fail_wpa_wp_ma.cpp
     create mode 100644 test/array_fail_wpa_wp_mc.cpp
     create mode 100644 test/array_fail_wpa_wpa_a.cpp
     create mode 100644 test/array_fail_wpa_wpa_c.cpp
     create mode 100644 test/array_fail_wpa_wpa_ma.cpp
     create mode 100644 test/array_fail_wpa_wpa_mc.cpp
     create mode 100644 test/sp_array_test.cpp
    
    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/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp
    index 924f621..2bd721a 100644
    --- a/include/boost/smart_ptr/shared_ptr.hpp
    +++ b/include/boost/smart_ptr/shared_ptr.hpp
    @@ -67,34 +67,93 @@ 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;
    +};
    +
    +#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;
    +};
    +
    +#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;
    +};
    +
    +#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;
    +};
    +
    +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
     
     // enable_shared_from_this support
     
    @@ -144,6 +203,47 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R
     
     #endif
     
    +// sp_assert_convertible
    +
    +template< class T > inline void sp_assert_convertible( T * )
    +{
    +}
    +
    +// 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< T[] >( static_cast< Y (*) [] >( 0 ) );
    +
    +    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< T[] >( static_cast< Y (*) [] >( 0 ) );
    +}
    +
    +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
    +
     } // namespace detail
     
     
    @@ -164,19 +264,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 +282,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 +307,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< T >( static_cast< Y* >( 0 ) );
    +
             // it is now safe to copy r.px, as pn(r.pn) did not throw
             px = r.px;
         }
    @@ -237,11 +336,12 @@ public:
     #endif
         : px( r.px ), pn( r.pn ) // never throws
         {
    +        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
         }
     
         // 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 +378,12 @@ public:
         template
         explicit shared_ptr(std::auto_ptr & r): px(r.get()), pn()
         {
    +        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +
             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 +391,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< T >( static_cast< Y* >( 0 ) );
    +
    +        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 +408,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< T >( static_cast< Y* >( 0 ) );
    +
    +        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 +457,6 @@ public:
             return *this;
         }
     
    -
     #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
     
     #endif // BOOST_NO_AUTO_PTR
    @@ -374,6 +483,8 @@ public:
     #endif
         : px( r.px ), pn() // never throws
         {
    +        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +
             pn.swap( r.pn );
             r.px = 0;
         }
    @@ -398,10 +509,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 +525,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 );
    +
    +        return px[ i ];
    +    }
    +
    +    element_type * get() const // never throws
         {
             return px;
         }
    @@ -449,7 +568,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 +607,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..f33116b 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< T >( static_cast< Y* >( 0 ) );
         }
     
     #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< T >( static_cast< Y* >( 0 ) );
             r.px = 0;
         }
     
    @@ -130,15 +132,19 @@ public:
     #endif
         : px( r.px ), pn( r.pn ) // never throws
         {
    +        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
         }
     
     #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< T >( static_cast< Y* >( 0 ) );
    +
             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< T >( static_cast< Y* >( 0 ) );
    +
             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
    @@ -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/test/Jamfile.v2 b/test/Jamfile.v2
    index 1df2a3e..c638d92 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -70,5 +70,62 @@ import testing ;
               [ run ip_hash_test.cpp ]
               [ run owner_less_test.cpp ]
               [ run sp_unique_ptr_test.cpp ]
    +          [ run sp_array_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 ]
             ;
     }
    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/sp_array_test.cpp b/test/sp_array_test.cpp
    new file mode 100644
    index 0000000..eab918e
    --- /dev/null
    +++ b/test/sp_array_test.cpp
    @@ -0,0 +1,291 @@
    +//
    +//  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& )
    +        {
    +        }
    +
    +        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& )
    +        {
    +        }
    +
    +        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& )
    +        {
    +        }
    +
    +        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& )
    +        {
    +        }
    +
    +        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& )
    +        {
    +        }
    +
    +        px.reset();
    +
    +        BOOST_TEST( X::allocations == 0 );
    +        BOOST_TEST( X::instances == 0 );
    +        BOOST_TEST( array_deleter< X >::calls == 2 );
    +    }
    +
    +    return boost::report_errors();
    +}
    
    From 0b6cab9f2f1c7e73054434620feccd0fae7fe9e0 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Sat, 3 Nov 2012 14:49:45 +0000
    Subject: [PATCH 086/210] Fix shared_ptr EDG issues.
    
    [SVN r81159]
    ---
     .../boost/smart_ptr/detail/sp_convertible.hpp | 25 +++++++++++
     include/boost/smart_ptr/shared_ptr.hpp        | 20 +++++----
     include/boost/smart_ptr/weak_ptr.hpp          | 12 +++---
     test/Jamfile.v2                               |  1 +
     test/sp_array_cv_test.cpp                     | 42 +++++++++++++++++++
     5 files changed, 85 insertions(+), 15 deletions(-)
     create mode 100644 test/sp_array_cv_test.cpp
    
    diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp
    index eb39797..00e5cb1 100644
    --- a/include/boost/smart_ptr/detail/sp_convertible.hpp
    +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp
    @@ -48,6 +48,31 @@ 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 T > struct sp_convertible< T[], T[] >
    +{
    +    enum _vt { value = true };
    +};
    +
    +template< class T > struct sp_convertible< T[], T const [] >
    +{
    +    enum _vt { value = true };
    +};
    +
    +template< class T > struct sp_convertible< T[], T volatile [] >
    +{
    +    enum _vt { value = true };
    +};
    +
    +template< class T > struct sp_convertible< T[], T const volatile [] >
    +{
    +    enum _vt { value = true };
    +};
    +
     struct sp_empty
     {
     };
    diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp
    index 2bd721a..7ca3ba8 100644
    --- a/include/boost/smart_ptr/shared_ptr.hpp
    +++ b/include/boost/smart_ptr/shared_ptr.hpp
    @@ -205,8 +205,10 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R
     
     // sp_assert_convertible
     
    -template< class T > inline void sp_assert_convertible( T * )
    +template< class Y, class T > inline void sp_assert_convertible()
     {
    +    T* p = static_cast< Y* >( 0 );
    +    (void)p;
     }
     
     // pointer constructor helper
    @@ -221,7 +223,7 @@ template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr
     
     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< T[] >( static_cast< Y (*) [] >( 0 ) );
    +    sp_assert_convertible< Y[], T[] >();
     
         boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
     }
    @@ -239,7 +241,7 @@ template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr
     
     template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ )
     {
    -    sp_assert_convertible< T[] >( static_cast< Y (*) [] >( 0 ) );
    +    sp_assert_convertible< Y[], T[] >();
     }
     
     #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
    @@ -309,7 +311,7 @@ public:
         template
         explicit shared_ptr( weak_ptr const & r ): pn( r.pn ) // may throw
         {
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        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;
    @@ -336,7 +338,7 @@ public:
     #endif
         : px( r.px ), pn( r.pn ) // never throws
         {
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        boost::detail::sp_assert_convertible< Y, T >();
         }
     
         // aliasing
    @@ -378,7 +380,7 @@ public:
         template
         explicit shared_ptr(std::auto_ptr & r): px(r.get()), pn()
         {
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        boost::detail::sp_assert_convertible< Y, T >();
     
             Y * tmp = r.get();
             pn = boost::detail::shared_count(r);
    @@ -393,7 +395,7 @@ public:
         {
             typedef typename Ap::element_type Y;
     
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        boost::detail::sp_assert_convertible< Y, T >();
     
             Y * tmp = r.get();
             pn = boost::detail::shared_count( r );
    @@ -410,7 +412,7 @@ public:
         template< class Y, class D >
         shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
         {
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        boost::detail::sp_assert_convertible< Y, T >();
     
             typename std::unique_ptr< Y, D >::pointer tmp = r.get();
             pn = boost::detail::shared_count( r );
    @@ -483,7 +485,7 @@ public:
     #endif
         : px( r.px ), pn() // never throws
         {
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        boost::detail::sp_assert_convertible< Y, T >();
     
             pn.swap( r.pn );
             r.px = 0;
    diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp
    index f33116b..62b6afe 100644
    --- a/include/boost/smart_ptr/weak_ptr.hpp
    +++ b/include/boost/smart_ptr/weak_ptr.hpp
    @@ -83,7 +83,7 @@ public:
     #endif
         : px(r.lock().get()), pn(r.pn) // never throws
         {
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        boost::detail::sp_assert_convertible< Y, T >();
         }
     
     #if defined( BOOST_HAS_RVALUE_REFS )
    @@ -100,7 +100,7 @@ public:
     #endif
         : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws
         {
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        boost::detail::sp_assert_convertible< Y, T >();
             r.px = 0;
         }
     
    @@ -132,7 +132,7 @@ public:
     #endif
         : px( r.px ), pn( r.pn ) // never throws
         {
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        boost::detail::sp_assert_convertible< Y, T >();
         }
     
     #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
    @@ -140,7 +140,7 @@ public:
         template
         weak_ptr & operator=( weak_ptr const & r ) // never throws
         {
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        boost::detail::sp_assert_convertible< Y, T >();
     
             px = r.lock().get();
             pn = r.pn;
    @@ -162,7 +162,7 @@ public:
         template
         weak_ptr & operator=( shared_ptr const & r ) // never throws
         {
    -        boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) );
    +        boost::detail::sp_assert_convertible< Y, T >();
     
             px = r.px;
             pn = r.pn;
    @@ -204,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;
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
    index c638d92..1fe79ab 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -71,6 +71,7 @@ import testing ;
               [ run owner_less_test.cpp ]
               [ run sp_unique_ptr_test.cpp ]
               [ run sp_array_test.cpp ]
    +          [ compile sp_array_cv_test.cpp ]
     
               [ compile-fail array_fail_spa_sp_c.cpp ]
               [ compile-fail array_fail_sp_spa_c.cpp ]
    diff --git a/test/sp_array_cv_test.cpp b/test/sp_array_cv_test.cpp
    new file mode 100644
    index 0000000..2bdc9b6
    --- /dev/null
    +++ b/test/sp_array_cv_test.cpp
    @@ -0,0 +1,42 @@
    +//
    +//  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
    +{
    +};
    +
    +int main()
    +{
    +    boost::shared_ptr< X[] > px;
    +
    +    boost::shared_ptr< X const[] > pcx( px );
    +    boost::shared_ptr< X volatile[] > pvx( px );
    +
    +    boost::shared_ptr< X const volatile[] > pcvx( px );
    +    boost::shared_ptr< X const volatile[] > pcvx2( pcx );
    +    boost::shared_ptr< X const volatile[] > pcvx3( pvx );
    +
    +    boost::shared_ptr< void > pv( px );
    +
    +    boost::shared_ptr< void const > pcv( px );
    +    boost::shared_ptr< void const > pcv2( pcx );
    +
    +    boost::shared_ptr< void volatile > pvv( px );
    +    boost::shared_ptr< void volatile > pvv2( pvx );
    +
    +    boost::shared_ptr< void const volatile > pcvv( px );
    +    boost::shared_ptr< void const volatile > pcvv2( pcx );
    +    boost::shared_ptr< void const volatile > pcvv3( pvx );
    +    boost::shared_ptr< void const volatile > pcvv4( pcvx );
    +
    +    return 0;
    +}
    
    From a30e29102293f96c008707b0fdd14ce17c8f243a Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Sun, 4 Nov 2012 14:53:51 +0000
    Subject: [PATCH 087/210] Disable make_shared overloads when T is Q[].
    
    [SVN r81171]
    ---
     include/boost/smart_ptr/make_shared.hpp | 95 ++++++++++++++-----------
     1 file changed, 54 insertions(+), 41 deletions(-)
    
    diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp
    index 7b605e2..cd8f662 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
    @@ -106,6 +106,19 @@ template< class T > T&& sp_forward( 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[] >
    +{
    +};
    +
    +#endif
    +
     } // namespace detail
     
     #if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
    @@ -118,7 +131,7 @@ template< class T > T&& sp_forward( T & t )
     //
     // Used even when variadic templates are available because of the new T() vs new T issue
     
    -template< class T > boost::shared_ptr< T > make_shared()
    +template< 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 ) );
     
    @@ -135,7 +148,7 @@ template< class T > boost::shared_ptr< T > make_shared()
         return boost::shared_ptr< T >( pt, pt2 );
     }
     
    -template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
    +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 );
     
    @@ -156,7 +169,7 @@ template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a
     
     // Variadic templates, rvalue reference
     
    -template< class T, class Arg1, class... Args > boost::shared_ptr< T > make_shared( Arg1 && arg1, Args && ... args )
    +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 ) );
     
    @@ -173,7 +186,7 @@ template< class T, class Arg1, class... Args > boost::shared_ptr< T > make_share
         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 )
    +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 );
     
    @@ -195,7 +208,7 @@ template< class T, class A, class Arg1, class... Args > boost::shared_ptr< T > a
     // For example MSVC 10.0
     
     template< class T, class A1 >
    -boost::shared_ptr< T > make_shared( A1 && 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 ) );
     
    @@ -216,7 +229,7 @@ boost::shared_ptr< T > make_shared( A1 && a1 )
     }
     
     template< class T, class A, class A1 >
    -boost::shared_ptr< T > allocate_shared( A const & a, A1 && 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 );
     
    @@ -237,7 +250,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1 )
     }
     
     template< class T, class A1, class A2 >
    -boost::shared_ptr< T > make_shared( A1 && a1, A2 && 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 ) );
     
    @@ -259,7 +272,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2 )
     }
     
     template< class T, class A, class A1, class A2 >
    -boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && 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 );
     
    @@ -281,7 +294,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2 )
     }
     
     template< class T, class A1, class A2, class A3 >
    -boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && 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 ) );
     
    @@ -304,7 +317,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3 )
     }
     
     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 )
    +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 );
     
    @@ -327,7 +340,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     }
     
     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 )
    +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 ) );
     
    @@ -351,7 +364,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
     }
     
     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 )
    +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 );
     
    @@ -375,7 +388,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     }
     
     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 )
    +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 ) );
     
    @@ -400,7 +413,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 &
     }
     
     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 )
    +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 );
     
    @@ -425,7 +438,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     }
     
     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 )
    +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 ) );
     
    @@ -451,7 +464,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 &
     }
     
     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 )
    +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 );
     
    @@ -477,7 +490,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     }
     
     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 )
    +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 ) );
     
    @@ -504,7 +517,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 &
     }
     
     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 )
    +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 );
     
    @@ -531,7 +544,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     }
     
     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 )
    +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 ) );
     
    @@ -559,7 +572,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 &
     }
     
     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 )
    +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 );
     
    @@ -587,7 +600,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     }
     
     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 )
    +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 ) );
     
    @@ -616,7 +629,7 @@ boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 &
     }
     
     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 )
    +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 );
     
    @@ -649,7 +662,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a
     // C++03 version
     
     template< class T, class A1 >
    -boost::shared_ptr< T > make_shared( A1 const & 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 ) );
     
    @@ -667,7 +680,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1 )
     }
     
     template< class T, class A, class A1 >
    -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & 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 );
     
    @@ -685,7 +698,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
     }
     
     template< class T, class A1, class A2 >
    -boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & 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 ) );
     
    @@ -703,7 +716,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
     }
     
     template< class T, class A, class A1, class A2 >
    -boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & 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 );
     
    @@ -721,7 +734,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     }
     
     template< class T, class A1, class A2, class A3 >
    -boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & 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 ) );
     
    @@ -739,7 +752,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3
     }
     
     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 )
    +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 );
     
    @@ -757,7 +770,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     }
     
     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 )
    +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 ) );
     
    @@ -775,7 +788,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     }
     
     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 )
    +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 );
     
    @@ -793,7 +806,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     }
     
     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 )
    +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 ) );
     
    @@ -811,7 +824,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     }
     
     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 )
    +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 );
     
    @@ -829,7 +842,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     }
     
     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 )
    +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 ) );
     
    @@ -847,7 +860,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     }
     
     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 )
    +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 );
     
    @@ -865,7 +878,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     }
     
     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 )
    +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 ) );
     
    @@ -883,7 +896,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     }
     
     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 )
    +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 );
     
    @@ -901,7 +914,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     }
     
     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 )
    +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 ) );
     
    @@ -919,7 +932,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     }
     
     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 )
    +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 );
     
    @@ -937,7 +950,7 @@ boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a
     }
     
     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 )
    +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 ) );
     
    @@ -955,7 +968,7 @@ boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3,
     }
     
     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 )
    +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 );
     
    
    From 2ba7b6b99b707371e05a80eb44fff07633fb99fe Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Sun, 4 Nov 2012 18:30:03 +0000
    Subject: [PATCH 088/210] Add catch(...) clauses to sp_array_test.cpp.
    
    [SVN r81174]
    ---
     test/sp_array_test.cpp | 20 ++++++++++++++++++++
     1 file changed, 20 insertions(+)
    
    diff --git a/test/sp_array_test.cpp b/test/sp_array_test.cpp
    index eab918e..0c7f597 100644
    --- a/test/sp_array_test.cpp
    +++ b/test/sp_array_test.cpp
    @@ -95,6 +95,10 @@ int main()
             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 );
    @@ -210,6 +214,10 @@ int main()
             catch( boost::bad_weak_ptr const& )
             {
             }
    +        catch( ... )
    +        {
    +            BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" );
    +        }
     
             px2.reset();
     
    @@ -236,6 +244,10 @@ int main()
             catch( boost::bad_weak_ptr const& )
             {
             }
    +        catch( ... )
    +        {
    +            BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" );
    +        }
     
             px2.reset();
     
    @@ -258,6 +270,10 @@ int main()
             catch( boost::bad_weak_ptr const& )
             {
             }
    +        catch( ... )
    +        {
    +            BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" );
    +        }
     
             px.reset();
     
    @@ -279,6 +295,10 @@ int main()
             catch( boost::bad_weak_ptr const& )
             {
             }
    +        catch( ... )
    +        {
    +            BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" );
    +        }
     
             px.reset();
     
    
    From 6662ae724229417b9da09bdaf0905a2ab0d0ae21 Mon Sep 17 00:00:00 2001
    From: Glen Fernandes 
    Date: Tue, 6 Nov 2012 14:17:32 +0000
    Subject: [PATCH 089/210] Add allocate_shared and make_shared for shared_ptr
     arrays of runtime size. Fulfills need for allocate_shared_array and
     make_shared_array.
    
    [SVN r81219]
    ---
     .../boost/smart_ptr/allocate_shared_array.hpp |  49 ++++++++
     .../detail/allocate_array_helper.hpp          |  99 +++++++++++++++
     .../boost/smart_ptr/detail/array_deleter.hpp  |  62 +++++++++
     .../smart_ptr/detail/make_array_helper.hpp    |  92 ++++++++++++++
     .../boost/smart_ptr/detail/sp_if_array.hpp    |  28 +++++
     include/boost/smart_ptr/make_shared_array.hpp |  62 +++++++++
     make_shared_array.html                        | 100 +++++++++++++++
     test/allocate_shared_array_esft_test.cpp      |  42 +++++++
     test/allocate_shared_array_test.cpp           |  87 +++++++++++++
     test/allocate_shared_array_throws_test.cpp    |  40 ++++++
     test/make_shared_array_esft_test.cpp          |  52 ++++++++
     test/make_shared_array_test.cpp               | 118 ++++++++++++++++++
     test/make_shared_array_throws_test.cpp        |  47 +++++++
     13 files changed, 878 insertions(+)
     create mode 100644 include/boost/smart_ptr/allocate_shared_array.hpp
     create mode 100644 include/boost/smart_ptr/detail/allocate_array_helper.hpp
     create mode 100644 include/boost/smart_ptr/detail/array_deleter.hpp
     create mode 100644 include/boost/smart_ptr/detail/make_array_helper.hpp
     create mode 100644 include/boost/smart_ptr/detail/sp_if_array.hpp
     create mode 100644 include/boost/smart_ptr/make_shared_array.hpp
     create mode 100644 make_shared_array.html
     create mode 100644 test/allocate_shared_array_esft_test.cpp
     create mode 100644 test/allocate_shared_array_test.cpp
     create mode 100644 test/allocate_shared_array_throws_test.cpp
     create mode 100644 test/make_shared_array_esft_test.cpp
     create mode 100644 test/make_shared_array_test.cpp
     create mode 100644 test/make_shared_array_throws_test.cpp
    
    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..7b32dd5
    --- /dev/null
    +++ b/include/boost/smart_ptr/allocate_shared_array.hpp
    @@ -0,0 +1,49 @@
    +/*
    + * 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 
    +
    +namespace boost {
    +    template
    +    inline typename detail::sp_if_array::type 
    +    allocate_shared(const A& allocator, size_t size) {
    +        typedef typename remove_cv::element_type>::type T1;
    +        T1* p1 = 0;
    +        detail::allocate_array_helper a1(allocator, size, &p1);
    +        detail::array_deleter d1;
    +        shared_ptr s1(p1, d1, a1);
    +        detail::array_deleter* d2;
    +        d2 = get_deleter >(s1);
    +        d2->construct(p1, size);
    +        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, size_t size, Args&&... args) {
    +        typedef typename remove_cv::element_type>::type T1;
    +        T1* p1 = 0;
    +        detail::allocate_array_helper a1(allocator, size, &p1);
    +        detail::array_deleter d1;
    +        shared_ptr s1(p1, d1, a1);
    +        detail::array_deleter* d2;
    +        d2 = get_deleter >(s1);
    +        d2->construct(p1, size, std::forward(args)...);
    +        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..deddf04
    --- /dev/null
    +++ b/include/boost/smart_ptr/detail/allocate_array_helper.hpp
    @@ -0,0 +1,99 @@
    +/*
    + * 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 
    +#include 
    +
    +namespace boost {
    +    namespace detail {
    +        template
    +        class allocate_array_helper {
    +            template
    +            friend class allocate_array_helper;
    +            typedef typename A::rebind   ::other A2;
    +            typedef typename A::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..6f06401
    --- /dev/null
    +++ b/include/boost/smart_ptr/detail/array_deleter.hpp
    @@ -0,0 +1,62 @@
    +/*
    + * 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
    +            void construct_noinit(T* memory, std::size_t count) {
    +                for (object = memory; size < count; size++) {
    +                    void* p1 = object + size;
    +                    ::new(p1) T;
    +                }
    +            }
    +            void operator()(T*) {
    +                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/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp
    new file mode 100644
    index 0000000..db77aea
    --- /dev/null
    +++ b/include/boost/smart_ptr/detail/make_array_helper.hpp
    @@ -0,0 +1,92 @@
    +/*
    + * 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 
    +#include 
    +
    +namespace boost {
    +    namespace detail {
    +        template
    +        class make_array_helper {
    +            template
    +            friend class make_array_helper;
    +        public:
    +            typedef typename Y           value_type;
    +            typedef typename Y*          pointer;
    +            typedef typename const Y*    const_pointer;
    +            typedef typename Y&          reference;
    +            typedef typename const Y&    const_reference;
    +            typedef typename std::size_t size_type;
    +            typedef typename 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/sp_if_array.hpp b/include/boost/smart_ptr/detail/sp_if_array.hpp
    new file mode 100644
    index 0000000..b907294
    --- /dev/null
    +++ b/include/boost/smart_ptr/detail/sp_if_array.hpp
    @@ -0,0 +1,28 @@
    +/*
    + * 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 {
    +        };
    +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
    +        template
    +        struct sp_if_array {
    +            typedef boost::shared_ptr type;
    +        };
    +#endif
    +    }
    +}
    +
    +#endif
    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..1550178
    --- /dev/null
    +++ b/include/boost/smart_ptr/make_shared_array.hpp
    @@ -0,0 +1,62 @@
    +/*
    + * 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 
    +
    +namespace boost {
    +    template
    +    inline typename detail::sp_if_array::type
    +    make_shared(std::size_t size) {
    +        typedef typename remove_cv::element_type>::type T1;
    +        T1* p1 = 0;
    +        detail::make_array_helper a1(size, &p1);
    +        detail::array_deleter d1;
    +        shared_ptr s1(p1, d1, a1);
    +        detail::array_deleter* d2;
    +        d2 = get_deleter >(s1);
    +        d2->construct(p1, size);
    +        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 remove_cv::element_type>::type T1;
    +        T1* p1 = 0;
    +        detail::make_array_helper a1(size, &p1);
    +        detail::array_deleter d1;
    +        shared_ptr s1(p1, d1, a1);
    +        detail::array_deleter* d2;
    +        d2 = get_deleter >(s1);
    +        d2->construct(p1, size, std::forward(args)...);
    +        return shared_ptr(s1, p1);
    +    }
    +#endif
    +    template
    +    inline typename detail::sp_if_array::type
    +    make_shared_noinit(std::size_t size) {
    +        typedef typename remove_cv::element_type>::type T1;
    +        T1* p1 = 0;
    +        detail::make_array_helper a1(size, &p1);
    +        detail::array_deleter d1;
    +        shared_ptr s1(p1, d1, a1);
    +        detail::array_deleter* d2;
    +        d2 = get_deleter >(s1);
    +        d2->construct_noinit(p1, size);
    +        return shared_ptr(s1, p1);
    +    }
    +}
    +
    +#endif
    diff --git a/make_shared_array.html b/make_shared_array.html
    new file mode 100644
    index 0000000..e35350c
    --- /dev/null
    +++ b/make_shared_array.html
    @@ -0,0 +1,100 @@
    +
    +
    +  
    +    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 A, typename... Args>
    +    shared_ptr<T> allocate_shared(const A& allocator, size_t size, Args&&... args);
    +#endif
    +
    +    template<typename T>
    +    shared_ptr<T> make_shared_noinit(size_t size);
    +}
    +

    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(std::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(std::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/allocate_shared_array_esft_test.cpp b/test/allocate_shared_array_esft_test.cpp new file mode 100644 index 0000000..3864b81 --- /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 (const boost::bad_weak_ptr&) { + BOOST_TEST(type::instances == 3); + } + } + 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..db2cffc --- /dev/null +++ b/test/allocate_shared_array_test.cpp @@ -0,0 +1,87 @@ +/* + * 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); + } +#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(type::instances == 3); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + 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..e787000 --- /dev/null +++ b/test/allocate_shared_array_throws_test.cpp @@ -0,0 +1,40 @@ +/* + * 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); + } + 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..3431f23 --- /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 (const boost::bad_weak_ptr&) { + 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 (const boost::bad_weak_ptr&) { + BOOST_TEST(type::instances == 3); + } + } + 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..6fe2c24 --- /dev/null +++ b/test/make_shared_array_test.cpp @@ -0,0 +1,118 @@ +/* + * 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); + } +#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(type::instances == 3); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + a1.reset(); + BOOST_TEST(type::instances == 0); + } +#endif + { + boost::shared_ptr a1 = boost::make_shared_noinit(3); + int* a2 = a1.get(); + 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(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(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(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + } + 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..2bac909 --- /dev/null +++ b/test/make_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::make_shared(6); + BOOST_ERROR("make_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + try { + boost::shared_ptr a1 = boost::make_shared_noinit(6); + BOOST_ERROR("make_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} From e7d3987cfb86502a7516bd8777cfe75f82b66fcb Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 6 Nov 2012 14:35:40 +0000 Subject: [PATCH 090/210] Update Jamfile.v2 to run make_shared array tests and allocate_shared array tests. [SVN r81220] --- test/Jamfile.v2 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 1fe79ab..fc41fdd 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -128,5 +128,12 @@ import testing ; [ 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_array_throws_test.cpp ] + [ run make_shared_array_esft_test.cpp ] + [ run allocate_shared_array_test.cpp ] + [ run allocate_shared_array_throws_test.cpp ] + [ run allocate_shared_array_esft_test.cpp ] ; } From d8eb2fc10568768b9d5f2ee27cf459b17a18ba82 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 6 Nov 2012 15:10:32 +0000 Subject: [PATCH 091/210] Fix g++ issues. [SVN r81222] --- .../boost/smart_ptr/allocate_shared_array.hpp | 4 ++-- .../smart_ptr/detail/allocate_array_helper.hpp | 6 +++--- .../boost/smart_ptr/detail/make_array_helper.hpp | 16 ++++++++-------- include/boost/smart_ptr/make_shared_array.hpp | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 7b32dd5..5d3f8cb 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -19,7 +19,7 @@ namespace boost { template inline typename detail::sp_if_array::type allocate_shared(const A& allocator, size_t size) { - typedef typename remove_cv::element_type>::type T1; + typedef typename remove_cv::element_type>::type T1; T1* p1 = 0; detail::allocate_array_helper a1(allocator, size, &p1); detail::array_deleter d1; @@ -33,7 +33,7 @@ namespace boost { template inline typename detail::sp_if_array::type allocate_shared(const A& allocator, size_t size, Args&&... args) { - typedef typename remove_cv::element_type>::type T1; + typedef typename remove_cv::element_type>::type T1; T1* p1 = 0; detail::allocate_array_helper a1(allocator, size, &p1); detail::array_deleter d1; diff --git a/include/boost/smart_ptr/detail/allocate_array_helper.hpp b/include/boost/smart_ptr/detail/allocate_array_helper.hpp index deddf04..3314e6c 100644 --- a/include/boost/smart_ptr/detail/allocate_array_helper.hpp +++ b/include/boost/smart_ptr/detail/allocate_array_helper.hpp @@ -16,10 +16,10 @@ namespace boost { namespace detail { template class allocate_array_helper { - template + template friend class allocate_array_helper; - typedef typename A::rebind ::other A2; - typedef typename A::rebind::other A3; + 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; diff --git a/include/boost/smart_ptr/detail/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp index db77aea..34cc2e7 100644 --- a/include/boost/smart_ptr/detail/make_array_helper.hpp +++ b/include/boost/smart_ptr/detail/make_array_helper.hpp @@ -16,16 +16,16 @@ namespace boost { namespace detail { template class make_array_helper { - template + template friend class make_array_helper; public: - typedef typename Y value_type; - typedef typename Y* pointer; - typedef typename const Y* const_pointer; - typedef typename Y& reference; - typedef typename const Y& const_reference; - typedef typename std::size_t size_type; - typedef typename ptrdiff_t difference_type; + 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; diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 1550178..b757fb7 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -19,7 +19,7 @@ namespace boost { template inline typename detail::sp_if_array::type make_shared(std::size_t size) { - typedef typename remove_cv::element_type>::type T1; + typedef typename remove_cv::element_type>::type T1; T1* p1 = 0; detail::make_array_helper a1(size, &p1); detail::array_deleter d1; @@ -33,7 +33,7 @@ namespace boost { template inline typename detail::sp_if_array::type make_shared(std::size_t size, Args&&... args) { - typedef typename remove_cv::element_type>::type T1; + typedef typename remove_cv::element_type>::type T1; T1* p1 = 0; detail::make_array_helper a1(size, &p1); detail::array_deleter d1; @@ -47,7 +47,7 @@ namespace boost { template inline typename detail::sp_if_array::type make_shared_noinit(std::size_t size) { - typedef typename remove_cv::element_type>::type T1; + typedef typename remove_cv::element_type>::type T1; T1* p1 = 0; detail::make_array_helper a1(size, &p1); detail::array_deleter d1; From bb72e0a092ee608599a5f670a6ede9357787d66b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 6 Nov 2012 16:23:09 +0000 Subject: [PATCH 092/210] Add specialization of sp_if_not_array. [SVN r81223] --- include/boost/smart_ptr/make_shared.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp index cd8f662..601edd3 100644 --- a/include/boost/smart_ptr/make_shared.hpp +++ b/include/boost/smart_ptr/make_shared.hpp @@ -117,6 +117,10 @@ 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 From 322bcd7efa277e46fa37884ebd33892d79581559 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 6 Nov 2012 16:29:56 +0000 Subject: [PATCH 093/210] Rename make_shared.hpp to make_shared_object.hpp, include from make_shared.hpp. [SVN r81224] --- include/boost/smart_ptr/make_shared.hpp | 985 +---------------- .../boost/smart_ptr/make_shared_object.hpp | 998 ++++++++++++++++++ 2 files changed, 1001 insertions(+), 982 deletions(-) create mode 100644 include/boost/smart_ptr/make_shared_object.hpp diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp index 601edd3..6b2bd27 100644 --- a/include/boost/smart_ptr/make_shared.hpp +++ b/include/boost/smart_ptr/make_shared.hpp @@ -12,987 +12,8 @@ // 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 +#include +#include +#include #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED 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 From 6e873de0fad18f7b219fef5b9dfbb8d9b3942156 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 6 Nov 2012 17:31:15 +0000 Subject: [PATCH 094/210] Add make_shared_array_args_test.cpp. [SVN r81226] --- test/Jamfile.v2 | 1 + test/make_shared_array_args_test.cpp | 172 +++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 test/make_shared_array_args_test.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index fc41fdd..481a1ca 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -132,6 +132,7 @@ import testing ; [ run make_shared_array_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_array_throws_test.cpp ] [ run allocate_shared_array_esft_test.cpp ] 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(); +} From dc5406aa5a7534fda2666d4f123c145cb289110f Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 7 Nov 2012 14:42:10 +0000 Subject: [PATCH 095/210] Add support for make_shared of array of arrays. Correctly destroy elements and construct elements for the variadic template constructor variants. [SVN r81229] --- .../boost/smart_ptr/allocate_shared_array.hpp | 2 +- .../boost/smart_ptr/detail/array_deleter.hpp | 12 +-- .../boost/smart_ptr/detail/array_helper.hpp | 64 +++++++++++ include/boost/smart_ptr/make_shared_array.hpp | 2 +- test/allocate_shared_arrays_test.cpp | 75 +++++++++++++ test/make_shared_arrays_test.cpp | 101 ++++++++++++++++++ 6 files changed, 247 insertions(+), 9 deletions(-) create mode 100644 include/boost/smart_ptr/detail/array_helper.hpp create mode 100644 test/allocate_shared_arrays_test.cpp create mode 100644 test/make_shared_arrays_test.cpp diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 5d3f8cb..86d4065 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -9,7 +9,7 @@ #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP -#include +#include #include #include #include diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 6f06401..de8b304 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -10,6 +10,7 @@ #define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP #include +#include #include namespace boost { @@ -25,23 +26,20 @@ namespace boost { } void construct(T* memory, std::size_t count) { for (object = memory; size < count; size++) { - void* p1 = object + size; - ::new(p1) T(); + array_helper::create(object[size]); } } #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...); + array_helper::create(object[size], args...); } } #endif void construct_noinit(T* memory, std::size_t count) { for (object = memory; size < count; size++) { - void* p1 = object + size; - ::new(p1) T; + array_helper::create_noinit(object[size]); } } void operator()(T*) { @@ -50,7 +48,7 @@ namespace boost { private: void destroy() { while (size > 0) { - object[--size].~T(); + array_helper::destroy(object[--size]); } } std::size_t size; diff --git a/include/boost/smart_ptr/detail/array_helper.hpp b/include/boost/smart_ptr/detail/array_helper.hpp new file mode 100644 index 0000000..72b470c --- /dev/null +++ b/include/boost/smart_ptr/detail/array_helper.hpp @@ -0,0 +1,64 @@ +/* + * 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_HELPER_HPP +#define BOOST_SMART_PTR_DETAIL_ARRAY_HELPER_HPP + +namespace boost { + namespace detail { + template + struct array_helper { + static void destroy(T& value) { + value.~T(); + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + template + static void create(T& value, Args... args) { + void* p1 = &value; + ::new(p1) T(args...); + } +#endif + }; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + template + struct array_helper { + static void create(T value[N]) { + void* p1 = &value; + ::new(p1) T[N](); + } + static void create_noinit(T value[N]) { + void* p1 = &value; + ::new(p1) T[N]; + } + static void destroy(T value[N]) { + array_helper::destroy(value[N-1]); + array_helper::destroy(value); + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + template + static void create(T value[N], Args... args) { + array_helper::create(value, args); + array_helper::create(value[N-1], args); + } +#endif + }; + template + struct array_helper { + static void destroy(T[]) { + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + template + static void create(T[], Args...) { + } +#endif + }; +#endif + } +} + +#endif diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index b757fb7..b76cc73 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -9,7 +9,7 @@ #ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP -#include +#include #include #include #include diff --git a/test/allocate_shared_arrays_test.cpp b/test/allocate_shared_arrays_test.cpp new file mode 100644 index 0000000..5bb48e5 --- /dev/null +++ b/test/allocate_shared_arrays_test.cpp @@ -0,0 +1,75 @@ +/* + * 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); + } +#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); + } +#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..22fe447 --- /dev/null +++ b/test/make_shared_arrays_test.cpp @@ -0,0 +1,101 @@ +/* + * 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); + } +#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); + } +#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(2); + 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(2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + } + return boost::report_errors(); +} From 0467af1b83fcffc85f4c89b94db2e49ead6869c9 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 7 Nov 2012 15:00:24 +0000 Subject: [PATCH 096/210] Fix sp_convertible. [SVN r81230] --- .../boost/smart_ptr/detail/sp_convertible.hpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp index 00e5cb1..4f47709 100644 --- a/include/boost/smart_ptr/detail/sp_convertible.hpp +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp @@ -53,24 +53,9 @@ template< class Y, class T > struct sp_convertible< Y, T[] > enum _vt { value = false }; }; -template< class T > struct sp_convertible< T[], T[] > +template< class Y, class T > struct sp_convertible< Y[], T[] > { - enum _vt { value = true }; -}; - -template< class T > struct sp_convertible< T[], T const [] > -{ - enum _vt { value = true }; -}; - -template< class T > struct sp_convertible< T[], T volatile [] > -{ - enum _vt { value = true }; -}; - -template< class T > struct sp_convertible< T[], T const volatile [] > -{ - enum _vt { value = true }; + enum _vt { value = sp_convertible< Y[1], T[1] >::value }; }; struct sp_empty From 734b5d1354cec7a8076cc16ea45cadfcb1071c21 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 7 Nov 2012 15:04:04 +0000 Subject: [PATCH 097/210] Update smart_ptr/detail/array_helper to have create and create_noinit for non-array case. [SVN r81231] --- include/boost/smart_ptr/detail/array_helper.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/smart_ptr/detail/array_helper.hpp b/include/boost/smart_ptr/detail/array_helper.hpp index 72b470c..96ecf1b 100644 --- a/include/boost/smart_ptr/detail/array_helper.hpp +++ b/include/boost/smart_ptr/detail/array_helper.hpp @@ -13,6 +13,14 @@ namespace boost { namespace detail { template struct array_helper { + static void create(T& value) { + void* p1 = &value; + ::new(p1) T(); + } + static void create_noinit(T& value) { + void* p1 = &value; + ::new(p1) T; + } static void destroy(T& value) { value.~T(); } From c06ba497a37dbad202a31c7fb89477e3913a8a64 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 7 Nov 2012 15:07:08 +0000 Subject: [PATCH 098/210] Rename sp_convertible_test.cpp to shared_ptr_convertible_test.cpp. [SVN r81232] --- test/Jamfile.v2 | 2 +- ...{sp_convertible_test.cpp => shared_ptr_convertible_test.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test/{sp_convertible_test.cpp => shared_ptr_convertible_test.cpp} (100%) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 481a1ca..a864cc9 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 ] diff --git a/test/sp_convertible_test.cpp b/test/shared_ptr_convertible_test.cpp similarity index 100% rename from test/sp_convertible_test.cpp rename to test/shared_ptr_convertible_test.cpp From dbea328b8b8d91ca0afb1d29ff3bb44a6c045de9 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 7 Nov 2012 15:25:55 +0000 Subject: [PATCH 099/210] Don't treat array_helper create and create_noinit for array types as a special case. [SVN r81233] --- include/boost/smart_ptr/detail/array_helper.hpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_helper.hpp b/include/boost/smart_ptr/detail/array_helper.hpp index 96ecf1b..1815f05 100644 --- a/include/boost/smart_ptr/detail/array_helper.hpp +++ b/include/boost/smart_ptr/detail/array_helper.hpp @@ -36,12 +36,12 @@ namespace boost { template struct array_helper { static void create(T value[N]) { - void* p1 = &value; - ::new(p1) T[N](); + array_helper::create(value); + array_helper::create(value[N-1]); } static void create_noinit(T value[N]) { - void* p1 = &value; - ::new(p1) T[N]; + array_helper::create_noinit(value, args); + array_helper::create_noinit(value[N-1], args); } static void destroy(T value[N]) { array_helper::destroy(value[N-1]); @@ -57,6 +57,10 @@ namespace boost { }; template struct array_helper { + static void create(T[]) { + } + static void create_noinit(T[]) { + } static void destroy(T[]) { } #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) From e50c849ab3918e80d00dda3dd2f6ba6c888da44e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 7 Nov 2012 15:33:44 +0000 Subject: [PATCH 100/210] Add sp_convertible_test.cpp. [SVN r81234] --- test/Jamfile.v2 | 1 + test/sp_convertible_test.cpp | 93 ++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 test/sp_convertible_test.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index a864cc9..feb38bf 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -72,6 +72,7 @@ import testing ; [ run sp_unique_ptr_test.cpp ] [ run sp_array_test.cpp ] [ compile sp_array_cv_test.cpp ] + [ run sp_convertible_test.cpp ] [ compile-fail array_fail_spa_sp_c.cpp ] [ compile-fail array_fail_sp_spa_c.cpp ] diff --git a/test/sp_convertible_test.cpp b/test/sp_convertible_test.cpp new file mode 100644 index 0000000..7a4a1cb --- /dev/null +++ b/test/sp_convertible_test.cpp @@ -0,0 +1,93 @@ +#include + +// sp_convertible_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 + +// + +class X; + +class B +{ +}; + +class D: public B +{ +}; + +#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 )); + +#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() +{ +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + 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(); +} From 93b5cace12b2521d0029c6768396a66fdf9df06f Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 7 Nov 2012 15:36:15 +0000 Subject: [PATCH 101/210] Fix array_helper (create_noinit and use of args...). [SVN r81235] --- include/boost/smart_ptr/detail/array_helper.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_helper.hpp b/include/boost/smart_ptr/detail/array_helper.hpp index 1815f05..6d2fe62 100644 --- a/include/boost/smart_ptr/detail/array_helper.hpp +++ b/include/boost/smart_ptr/detail/array_helper.hpp @@ -40,8 +40,8 @@ namespace boost { array_helper::create(value[N-1]); } static void create_noinit(T value[N]) { - array_helper::create_noinit(value, args); - array_helper::create_noinit(value[N-1], args); + array_helper::create_noinit(value); + array_helper::create_noinit(value[N-1]); } static void destroy(T value[N]) { array_helper::destroy(value[N-1]); @@ -50,8 +50,8 @@ namespace boost { #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) template static void create(T value[N], Args... args) { - array_helper::create(value, args); - array_helper::create(value[N-1], args); + array_helper::create(value, args...); + array_helper::create(value[N-1], args...); } #endif }; From 5d9312239cd8a35881e96ef9fcf30349a5f77dc8 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 7 Nov 2012 18:37:17 +0000 Subject: [PATCH 102/210] Update allocate_shared and make_shared to treat multidimensional array as single dimension. Remove detail array_helper. Add detail array traits. Update tests. [SVN r81236] --- .../boost/smart_ptr/allocate_shared_array.hpp | 38 ++++++---- .../boost/smart_ptr/detail/array_deleter.hpp | 26 ++++--- .../boost/smart_ptr/detail/array_helper.hpp | 76 ------------------- .../boost/smart_ptr/detail/array_traits.hpp | 39 ++++++++++ include/boost/smart_ptr/make_shared_array.hpp | 50 +++++++----- test/Jamfile.v2 | 2 + 6 files changed, 109 insertions(+), 122 deletions(-) delete mode 100644 include/boost/smart_ptr/detail/array_helper.hpp create mode 100644 include/boost/smart_ptr/detail/array_traits.hpp diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 86d4065..04c8f2b 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -12,36 +12,44 @@ #include #include #include +#include #include -#include namespace boost { template inline typename detail::sp_if_array::type allocate_shared(const A& allocator, size_t size) { - typedef typename remove_cv::element_type>::type T1; + typedef typename shared_ptr::element_type T1; + typedef typename detail::array_type::type T2; T1* p1 = 0; - detail::allocate_array_helper a1(allocator, size, &p1); - detail::array_deleter d1; + T2* p2 = 0; + size_t n1 = size * detail::array_size::size; + detail::allocate_array_helper a1(allocator, n1, &p2); + detail::array_deleter d1; shared_ptr s1(p1, d1, a1); - detail::array_deleter* d2; - d2 = get_deleter >(s1); - d2->construct(p1, size); + 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, size_t size, Args&&... args) { - typedef typename remove_cv::element_type>::type T1; + typedef typename shared_ptr::element_type T1; + typedef typename detail::array_type::type T2; T1* p1 = 0; - detail::allocate_array_helper a1(allocator, size, &p1); - detail::array_deleter d1; - shared_ptr s1(p1, d1, a1); - detail::array_deleter* d2; - d2 = get_deleter >(s1); - d2->construct(p1, size, std::forward(args)...); - return shared_ptr(s1, p1); + T2* p2 = 0; + size_t n1 = size * detail::array_size::size; + detail::allocate_array_helper a1(allocator, n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p2, 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 } diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index de8b304..11f195b 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -10,7 +10,6 @@ #define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP #include -#include #include namespace boost { @@ -24,31 +23,34 @@ namespace boost { ~array_deleter() { destroy(); } - void construct(T* memory, std::size_t count) { - for (object = memory; size < count; size++) { - array_helper::create(object[size]); + void construct(void* memory, std::size_t count) { + for (object = static_cast(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++) { - array_helper::create(object[size], args...); + void construct(void* memory, std::size_t count, Args&&... args) { + for (object = static_cast(memory); size < count; size++) { + void* p1 = object + size; + ::new(p1) T(args...); } } #endif - void construct_noinit(T* memory, std::size_t count) { - for (object = memory; size < count; size++) { - array_helper::create_noinit(object[size]); + void construct_noinit(void* memory, std::size_t count) { + for (object = static_cast(memory); size < count; size++) { + void* p1 = object + size; + ::new(p1) T; } } - void operator()(T*) { + void operator()(const void*) { destroy(); } private: void destroy() { while (size > 0) { - array_helper::destroy(object[--size]); + object[--size].~T(); } } std::size_t size; diff --git a/include/boost/smart_ptr/detail/array_helper.hpp b/include/boost/smart_ptr/detail/array_helper.hpp deleted file mode 100644 index 6d2fe62..0000000 --- a/include/boost/smart_ptr/detail/array_helper.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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_HELPER_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_HELPER_HPP - -namespace boost { - namespace detail { - template - struct array_helper { - static void create(T& value) { - void* p1 = &value; - ::new(p1) T(); - } - static void create_noinit(T& value) { - void* p1 = &value; - ::new(p1) T; - } - static void destroy(T& value) { - value.~T(); - } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) - template - static void create(T& value, Args... args) { - void* p1 = &value; - ::new(p1) T(args...); - } -#endif - }; -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - template - struct array_helper { - static void create(T value[N]) { - array_helper::create(value); - array_helper::create(value[N-1]); - } - static void create_noinit(T value[N]) { - array_helper::create_noinit(value); - array_helper::create_noinit(value[N-1]); - } - static void destroy(T value[N]) { - array_helper::destroy(value[N-1]); - array_helper::destroy(value); - } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) - template - static void create(T value[N], Args... args) { - array_helper::create(value, args...); - array_helper::create(value[N-1], args...); - } -#endif - }; - template - struct array_helper { - static void create(T[]) { - } - static void create_noinit(T[]) { - } - static void destroy(T[]) { - } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) - template - static void create(T[], Args...) { - } -#endif - }; -#endif - } -} - -#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..46b9933 --- /dev/null +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -0,0 +1,39 @@ +/* + * 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_type { + typedef typename boost::remove_cv::type type; + }; + template + struct array_type { + typedef typename array_type::type type; + }; + template + struct array_size { + enum { + size = 1 + }; + }; + template + struct array_size { + enum { + size = N * array_size::size + }; + }; + } +} + +#endif diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index b76cc73..1a9c7f9 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -11,50 +11,62 @@ #include #include +#include #include #include -#include namespace boost { template inline typename detail::sp_if_array::type make_shared(std::size_t size) { - typedef typename remove_cv::element_type>::type T1; + typedef typename shared_ptr::element_type T1; + typedef typename detail::array_type::type T2; T1* p1 = 0; - detail::make_array_helper a1(size, &p1); - detail::array_deleter d1; + T2* p2 = 0; + size_t n1 = size * detail::array_size::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; shared_ptr s1(p1, d1, a1); - detail::array_deleter* d2; - d2 = get_deleter >(s1); - d2->construct(p1, size); + 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 remove_cv::element_type>::type T1; + typedef typename shared_ptr::element_type T1; + typedef typename detail::array_type::type T2; T1* p1 = 0; - detail::make_array_helper a1(size, &p1); - detail::array_deleter d1; + T2* p2 = 0; + size_t n1 = size * detail::array_size::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; shared_ptr s1(p1, d1, a1); - detail::array_deleter* d2; - d2 = get_deleter >(s1); - d2->construct(p1, size, std::forward(args)...); + 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 template inline typename detail::sp_if_array::type make_shared_noinit(std::size_t size) { - typedef typename remove_cv::element_type>::type T1; + typedef typename shared_ptr::element_type T1; + typedef typename detail::array_type::type T2; T1* p1 = 0; - detail::make_array_helper a1(size, &p1); - detail::array_deleter d1; + T2* p2 = 0; + size_t n1 = size * detail::array_size::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; shared_ptr s1(p1, d1, a1); - detail::array_deleter* d2; - d2 = get_deleter >(s1); - d2->construct_noinit(p1, size); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_noinit(p2, n1); return shared_ptr(s1, p1); } } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index feb38bf..8d22562 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -131,10 +131,12 @@ import testing ; [ compile-fail array_fail_array_access.cpp ] [ run make_shared_array_test.cpp ] + [ run make_shared_arrays_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_throws_test.cpp ] [ run allocate_shared_array_esft_test.cpp ] ; From 89190ca17edcfec9ed452814760e8bf92a06452a Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 7 Nov 2012 18:58:41 +0000 Subject: [PATCH 103/210] Simplify array_deleter interface [SVN r81237] --- include/boost/smart_ptr/detail/array_deleter.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 11f195b..05a9991 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -23,23 +23,23 @@ namespace boost { ~array_deleter() { destroy(); } - void construct(void* memory, std::size_t count) { - for (object = static_cast(memory); size < count; size++) { + 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(void* memory, std::size_t count, Args&&... args) { - for (object = static_cast(memory); size < count; size++) { + 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 - void construct_noinit(void* memory, std::size_t count) { - for (object = static_cast(memory); size < count; size++) { + void construct_noinit(T* memory, std::size_t count) { + for (object = memory; size < count; size++) { void* p1 = object + size; ::new(p1) T; } From df544871d79d72a765078c739940919ad7fd5cf4 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 7 Nov 2012 23:41:52 +0000 Subject: [PATCH 104/210] Add missing semicolon. [SVN r81238] --- include/boost/smart_ptr/allocate_shared_array.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 04c8f2b..086cd05 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -49,7 +49,7 @@ namespace boost { p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); d2->construct(p2, n1, std::forward(args)...); - return shared_ptr(s1, p1) + return shared_ptr(s1, p1); } #endif } From 945c013a12dd263aa03bb67a00680eea9c6a6a54 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 7 Nov 2012 23:45:31 +0000 Subject: [PATCH 105/210] Fix typo. [SVN r81239] --- include/boost/smart_ptr/allocate_shared_array.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 086cd05..25c366e 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -44,7 +44,7 @@ namespace boost { size_t n1 = size * detail::array_size::size; detail::allocate_array_helper a1(allocator, n1, &p2); detail::array_deleter d1; - shared_ptr s1(p2, d1, a1); + shared_ptr s1(p1, d1, a1); detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); From c57245d7105c5e3229cfd285fcf1036b7a0f86c6 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Thu, 8 Nov 2012 05:33:52 +0000 Subject: [PATCH 106/210] Add tests for variadic template constructors overload of array forms of make_shared and allocate_shared for multidimensional arrays and up to 9 constructor arguments. [SVN r81242] --- test/Jamfile.v2 | 6 +- test/allocate_shared_array_create_test.cpp | 78 ++++++++++++++++++++++ test/make_shared_array_create_test.cpp | 78 ++++++++++++++++++++++ 3 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 test/allocate_shared_array_create_test.cpp create mode 100644 test/make_shared_array_create_test.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 8d22562..ef64f89 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -129,14 +129,16 @@ import testing ; [ 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_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_arrays_test.cpp ] + [ run allocate_shared_array_create_test.cpp ] [ run allocate_shared_array_throws_test.cpp ] [ run allocate_shared_array_esft_test.cpp ] ; diff --git a/test/allocate_shared_array_create_test.cpp b/test/allocate_shared_array_create_test.cpp new file mode 100644 index 0000000..4b45518 --- /dev/null +++ b/test/allocate_shared_array_create_test.cpp @@ -0,0 +1,78 @@ +/* + * 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(), 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(), 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(), 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); + } +#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..6d1ef71 --- /dev/null +++ b/test/make_shared_array_create_test.cpp @@ -0,0 +1,78 @@ +/* + * 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(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(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(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); + } +#endif + return boost::report_errors(); +} From aa7562c3e5c50bcb2270df4f11656b91c24a06cb Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 8 Nov 2012 18:07:49 +0000 Subject: [PATCH 107/210] Add support for shared_ptr. [SVN r81253] --- .../boost/smart_ptr/detail/sp_convertible.hpp | 5 + include/boost/smart_ptr/shared_ptr.hpp | 53 +++- test/Jamfile.v2 | 1 + test/sp_array_cv_test.cpp | 54 ++-- test/sp_array_n_test.cpp | 248 ++++++++++++++++++ test/sp_convertible_test.cpp | 2 +- 6 files changed, 341 insertions(+), 22 deletions(-) create mode 100644 test/sp_array_n_test.cpp diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp index 4f47709..31b2627 100644 --- a/include/boost/smart_ptr/detail/sp_convertible.hpp +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp @@ -58,6 +58,11 @@ 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/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 7ca3ba8..af1b13d 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -81,6 +81,11 @@ template< class T > struct sp_element< T[] > 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* @@ -121,6 +126,11 @@ 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-> @@ -137,6 +147,11 @@ 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[] @@ -153,6 +168,27 @@ 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 @@ -207,8 +243,9 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R template< class Y, class T > inline void sp_assert_convertible() { - T* p = static_cast< Y* >( 0 ); - (void)p; + // static_assert( sp_convertible< Y, T >::value ); + typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ]; + (void)sizeof( tmp ); } // pointer constructor helper @@ -224,7 +261,12 @@ template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr 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 ); } @@ -244,6 +286,11 @@ template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr 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 @@ -547,7 +594,7 @@ public: typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const // never throws { BOOST_ASSERT( px != 0 ); - BOOST_ASSERT( i >= 0 ); + BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) ); return px[ i ]; } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index ef64f89..f445193 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -73,6 +73,7 @@ import testing ; [ 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 ] diff --git a/test/sp_array_cv_test.cpp b/test/sp_array_cv_test.cpp index 2bdc9b6..8618fb0 100644 --- a/test/sp_array_cv_test.cpp +++ b/test/sp_array_cv_test.cpp @@ -14,29 +14,47 @@ 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() { - boost::shared_ptr< X[] > px; + TEST_CV_TRUE( X, X ) + TEST_CV_TRUE( X, void ) + TEST_CV_TRUE( D, B ) - boost::shared_ptr< X const[] > pcx( px ); - boost::shared_ptr< X volatile[] > pvx( px ); + TEST_CV_TRUE( X[], X[] ) + TEST_CV_TRUE( X[3], X[3] ) - boost::shared_ptr< X const volatile[] > pcvx( px ); - boost::shared_ptr< X const volatile[] > pcvx2( pcx ); - boost::shared_ptr< X const volatile[] > pcvx3( pvx ); + TEST_CV_TRUE( X[3], X[] ) - boost::shared_ptr< void > pv( px ); - - boost::shared_ptr< void const > pcv( px ); - boost::shared_ptr< void const > pcv2( pcx ); - - boost::shared_ptr< void volatile > pvv( px ); - boost::shared_ptr< void volatile > pvv2( pvx ); - - boost::shared_ptr< void const volatile > pcvv( px ); - boost::shared_ptr< void const volatile > pcvv2( pcx ); - boost::shared_ptr< void const volatile > pcvv3( pvx ); - boost::shared_ptr< void const volatile > pcvv4( pcvx ); + 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_convertible_test.cpp b/test/sp_convertible_test.cpp index 7a4a1cb..05b15c1 100644 --- a/test/sp_convertible_test.cpp +++ b/test/sp_convertible_test.cpp @@ -78,7 +78,7 @@ int main() TEST_CV_FALSE( X[3], X[4] ) TEST_CV_FALSE( D[3], B[3] ) - //TEST_CV_TRUE( X[3], X[] ) + TEST_CV_TRUE( X[3], X[] ) TEST_CV_FALSE( X[], X[3] ) TEST_CV_TRUE( X[], void ) From 3d50db11b90de858efc2c8864ed3f113a3ec18b2 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 9 Nov 2012 06:17:05 +0000 Subject: [PATCH 108/210] Add C++11 initializer list support for make_shared and allocate_shared array forms. [SVN r81257] --- .../boost/smart_ptr/allocate_shared_array.hpp | 22 +++++++++++++++++++ .../boost/smart_ptr/detail/array_deleter.hpp | 8 +++++++ .../boost/smart_ptr/detail/array_traits.hpp | 18 +++++++++++++++ include/boost/smart_ptr/make_shared_array.hpp | 22 +++++++++++++++++++ test/allocate_shared_array_create_test.cpp | 16 ++++++++++++++ test/make_shared_array_create_test.cpp | 16 ++++++++++++++ 6 files changed, 102 insertions(+) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 25c366e..f83c6e3 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -52,6 +52,28 @@ namespace boost { 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, size_t size, typename detail::array_list::type list) { + typedef typename shared_ptr::element_type T1; + typedef typename detail::array_type::type T2; + typedef const T1* L1; + typedef const T2* L2; + T1* p1 = 0; + T2* p2 = 0; + L1 l1 = list.begin(); + size_t n1 = size * detail::array_size::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, L2(l1)); + return shared_ptr(s1, p1); + } +#endif } #endif diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 05a9991..70d7479 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -37,6 +37,14 @@ namespace boost { ::new(p1) T(args...); } } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void construct(T* memory, std::size_t count, const T* list) { + for (object = memory; size < count; size++) { + void* p1 = object + size; + ::new(p1) T(list[size]); + } + } #endif void construct_noinit(T* memory, std::size_t count) { for (object = memory; size < count; size++) { diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index 46b9933..ba22f61 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -10,6 +10,9 @@ #define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif namespace boost { namespace detail { @@ -17,22 +20,37 @@ namespace boost { struct array_type { typedef typename boost::remove_cv::type type; }; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct array_type { typedef typename array_type::type type; }; +#endif template struct array_size { enum { size = 1 }; }; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct array_size { enum { size = N * array_size::size }; }; +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + struct array_list { + }; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + template + struct array_list { + typedef std::initializer_list type; + }; +#endif +#endif } } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 1a9c7f9..b19edf4 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -51,6 +51,28 @@ namespace boost { 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::size_t size, typename detail::array_list::type list) { + typedef typename shared_ptr::element_type T1; + typedef typename detail::array_type::type T2; + typedef const T1* L1; + typedef const T2* L2; + T1* p1 = 0; + T2* p2 = 0; + L1 l1 = list.begin(); + size_t n1 = size * detail::array_size::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, L2(l1)); + return shared_ptr(s1, p1); + } #endif template inline typename detail::sp_if_array::type diff --git a/test/allocate_shared_array_create_test.cpp b/test/allocate_shared_array_create_test.cpp index 4b45518..5c3f831 100644 --- a/test/allocate_shared_array_create_test.cpp +++ b/test/allocate_shared_array_create_test.cpp @@ -73,6 +73,22 @@ int main() { BOOST_TEST(a1[0][1][0][0].f == 0); BOOST_TEST(a1[1][0][0][0].i == 0); } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 4, { 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(), 2, { {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); + } #endif return boost::report_errors(); } diff --git a/test/make_shared_array_create_test.cpp b/test/make_shared_array_create_test.cpp index 6d1ef71..7510585 100644 --- a/test/make_shared_array_create_test.cpp +++ b/test/make_shared_array_create_test.cpp @@ -73,6 +73,22 @@ int main() { BOOST_TEST(a1[0][1][0][0].f == 0); BOOST_TEST(a1[1][0][0][0].i == 0); } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + { + boost::shared_ptr a1 = boost::make_shared(4, { 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(2, { {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); + } #endif return boost::report_errors(); } From 730980f3ee4a142bad1788d9024d8e129a100d7a Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 9 Nov 2012 09:14:23 +0000 Subject: [PATCH 109/210] Clean up code in allocate_shared_array.hpp and make_shared_array.hpp [SVN r81258] --- include/boost/smart_ptr/allocate_shared_array.hpp | 8 ++++---- include/boost/smart_ptr/make_shared_array.hpp | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index f83c6e3..d860d05 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -58,19 +58,19 @@ namespace boost { allocate_shared(const A& allocator, size_t size, typename detail::array_list::type list) { typedef typename shared_ptr::element_type T1; typedef typename detail::array_type::type T2; - typedef const T1* L1; - typedef const T2* L2; + typedef const T2 T3; T1* p1 = 0; T2* p2 = 0; - L1 l1 = list.begin(); + T3* p3 = 0; size_t n1 = size * detail::array_size::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(p2, n1, L2(l1)); + d2->construct(p2, n1, p3); return shared_ptr(s1, p1); } #endif diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index b19edf4..343ecfd 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -58,19 +58,19 @@ namespace boost { make_shared(std::size_t size, typename detail::array_list::type list) { typedef typename shared_ptr::element_type T1; typedef typename detail::array_type::type T2; - typedef const T1* L1; - typedef const T2* L2; + typedef const T2 T3; T1* p1 = 0; T2* p2 = 0; - L1 l1 = list.begin(); + T3* p3 = 0; size_t n1 = size * detail::array_size::size; detail::make_array_helper a1(n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); - detail::array_deleter* d2; + detail::array_deleter* d2; + p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, L2(l1)); + d2->construct(p2, n1, p3); return shared_ptr(s1, p1); } #endif From d512eaaa0f631ef7d08dc7e10af6a640712c92d2 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 9 Nov 2012 10:14:55 +0000 Subject: [PATCH 110/210] Change make_shared and allocate_shared array form semantics with initializer lists overload that takes no size. [SVN r81259] --- include/boost/smart_ptr/allocate_shared_array.hpp | 4 ++-- include/boost/smart_ptr/make_shared_array.hpp | 4 ++-- test/allocate_shared_array_create_test.cpp | 4 ++-- test/make_shared_array_create_test.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index d860d05..8a70098 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -55,14 +55,14 @@ namespace boost { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template inline typename detail::sp_if_array::type - allocate_shared(const A& allocator, size_t size, typename detail::array_list::type list) { + allocate_shared(const A& allocator, typename detail::array_list::type list) { typedef typename shared_ptr::element_type T1; typedef typename detail::array_type::type T2; typedef const T2 T3; T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - size_t n1 = size * detail::array_size::size; + size_t n1 = list.size() * detail::array_size::size; detail::allocate_array_helper a1(allocator, n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 343ecfd..9c30e94 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -55,14 +55,14 @@ namespace boost { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template inline typename detail::sp_if_array::type - make_shared(std::size_t size, typename detail::array_list::type list) { + make_shared(typename detail::array_list::type list) { typedef typename shared_ptr::element_type T1; typedef typename detail::array_type::type T2; typedef const T2 T3; T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - size_t n1 = size * detail::array_size::size; + size_t n1 = list.size() * detail::array_size::size; detail::make_array_helper a1(n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); diff --git a/test/allocate_shared_array_create_test.cpp b/test/allocate_shared_array_create_test.cpp index 5c3f831..3df1e82 100644 --- a/test/allocate_shared_array_create_test.cpp +++ b/test/allocate_shared_array_create_test.cpp @@ -76,14 +76,14 @@ int main() { #endif #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) { - boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 4, { 0, 1, 2, 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(), 2, { {0, 1}, {2, 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); diff --git a/test/make_shared_array_create_test.cpp b/test/make_shared_array_create_test.cpp index 7510585..b89d95f 100644 --- a/test/make_shared_array_create_test.cpp +++ b/test/make_shared_array_create_test.cpp @@ -76,14 +76,14 @@ int main() { #endif #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) { - boost::shared_ptr a1 = boost::make_shared(4, { 0, 1, 2, 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(2, { {0, 1}, {2, 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); From 999c284109d759c1c97fbc624bd4a2f024278254 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 9 Nov 2012 12:37:03 +0000 Subject: [PATCH 111/210] Disable make_shared for arrays when the compiler doesn't support partial specialization or SFINAE. [SVN r81260] --- include/boost/smart_ptr/make_shared.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp index 6b2bd27..8d0e3ea 100644 --- a/include/boost/smart_ptr/make_shared.hpp +++ b/include/boost/smart_ptr/make_shared.hpp @@ -13,7 +13,10 @@ // for documentation. #include -#include -#include + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE ) +# include +# include +#endif #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED From ffa3327817fce77ce0cd73dde0be69431d6c597d Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 9 Nov 2012 16:06:48 +0000 Subject: [PATCH 112/210] For allocate_shared and make_shared: Separate test case that g++ does support yet. Remove macros testing for no partial specialization in traits. Add additional traits. [SVN r81261] --- .../boost/smart_ptr/allocate_shared_array.hpp | 12 ++++----- .../boost/smart_ptr/detail/array_traits.hpp | 26 ++++++++++--------- .../boost/smart_ptr/detail/sp_if_array.hpp | 6 +++-- include/boost/smart_ptr/make_shared_array.hpp | 16 ++++++------ test/Jamfile.v2 | 2 ++ test/allocate_shared_arrays_create_test.cpp | 23 ++++++++++++++++ test/make_shared_arrays_create_test.cpp | 23 ++++++++++++++++ 7 files changed, 80 insertions(+), 28 deletions(-) create mode 100644 test/allocate_shared_arrays_create_test.cpp create mode 100644 test/make_shared_arrays_create_test.cpp diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 8a70098..d0123a6 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -19,8 +19,8 @@ namespace boost { template inline typename detail::sp_if_array::type allocate_shared(const A& allocator, size_t size) { - typedef typename shared_ptr::element_type T1; - typedef typename detail::array_type::type T2; + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; size_t n1 = size * detail::array_size::size; @@ -37,8 +37,8 @@ namespace boost { template inline typename detail::sp_if_array::type allocate_shared(const A& allocator, size_t size, Args&&... args) { - typedef typename shared_ptr::element_type T1; - typedef typename detail::array_type::type T2; + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; size_t n1 = size * detail::array_size::size; @@ -56,8 +56,8 @@ namespace boost { template inline typename detail::sp_if_array::type allocate_shared(const A& allocator, typename detail::array_list::type list) { - typedef typename shared_ptr::element_type T1; - typedef typename detail::array_type::type T2; + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; typedef const T2 T3; T1* p1 = 0; T2* p2 = 0; diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index ba22f61..b95a598 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -13,43 +13,45 @@ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif +#include namespace boost { namespace detail { template - struct array_type { + struct array_base { typedef typename boost::remove_cv::type type; }; -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - template - struct array_type { - typedef typename array_type::type type; + template + struct array_base { + typedef typename array_base::type type; }; -#endif template struct array_size { enum { size = 1 }; }; -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - template + template struct array_size { enum { size = N * array_size::size }; }; -#endif -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template + struct array_inner { + }; + template + struct array_inner { + typedef T type; + }; +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template struct array_list { }; -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct array_list { typedef std::initializer_list type; }; -#endif #endif } } diff --git a/include/boost/smart_ptr/detail/sp_if_array.hpp b/include/boost/smart_ptr/detail/sp_if_array.hpp index b907294..4a838fc 100644 --- a/include/boost/smart_ptr/detail/sp_if_array.hpp +++ b/include/boost/smart_ptr/detail/sp_if_array.hpp @@ -16,12 +16,14 @@ namespace boost { template struct sp_if_array { }; -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct sp_if_array { typedef boost::shared_ptr type; }; -#endif + template + struct sp_if_array { + typedef boost::shared_ptr type; + }; } } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 9c30e94..50a78fd 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -19,8 +19,8 @@ namespace boost { template inline typename detail::sp_if_array::type make_shared(std::size_t size) { - typedef typename shared_ptr::element_type T1; - typedef typename detail::array_type::type T2; + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; size_t n1 = size * detail::array_size::size; @@ -37,8 +37,8 @@ namespace boost { template inline typename detail::sp_if_array::type make_shared(std::size_t size, Args&&... args) { - typedef typename shared_ptr::element_type T1; - typedef typename detail::array_type::type T2; + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; size_t n1 = size * detail::array_size::size; @@ -56,8 +56,8 @@ namespace boost { template inline typename detail::sp_if_array::type make_shared(typename detail::array_list::type list) { - typedef typename shared_ptr::element_type T1; - typedef typename detail::array_type::type T2; + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; typedef const T2 T3; T1* p1 = 0; T2* p2 = 0; @@ -77,8 +77,8 @@ namespace boost { template inline typename detail::sp_if_array::type make_shared_noinit(std::size_t size) { - typedef typename shared_ptr::element_type T1; - typedef typename detail::array_type::type T2; + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; size_t n1 = size * detail::array_size::size; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f445193..d8fbe2a 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -134,12 +134,14 @@ import testing ; [ run make_shared_array_test.cpp ] [ run make_shared_arrays_test.cpp ] [ run make_shared_array_create_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_arrays_create_test.cpp ] [ run allocate_shared_array_throws_test.cpp ] [ run allocate_shared_array_esft_test.cpp ] ; diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp new file mode 100644 index 0000000..08226e0 --- /dev/null +++ b/test/allocate_shared_arrays_create_test.cpp @@ -0,0 +1,23 @@ +/* + * 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); + } +#endif + 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..08c1e4a --- /dev/null +++ b/test/make_shared_arrays_create_test.cpp @@ -0,0 +1,23 @@ +/* + * 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::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); + } +#endif + return boost::report_errors(); +} From c1f41aa925d089426b2b172d63ac77adf1d9c62a Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 9 Nov 2012 16:35:18 +0000 Subject: [PATCH 113/210] Actually remove test cases from make_shared_array_create_test.cpp and allocate_shared_array_create_test.cpp that g++ does not handle. [SVN r81262] --- test/allocate_shared_array_create_test.cpp | 7 ------- test/make_shared_array_create_test.cpp | 7 ------- 2 files changed, 14 deletions(-) diff --git a/test/allocate_shared_array_create_test.cpp b/test/allocate_shared_array_create_test.cpp index 3df1e82..9758c78 100644 --- a/test/allocate_shared_array_create_test.cpp +++ b/test/allocate_shared_array_create_test.cpp @@ -82,13 +82,6 @@ int main() { 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] == 0); - BOOST_TEST(a1[0][1] == 1); - BOOST_TEST(a1[1][0] == 2); - BOOST_TEST(a1[1][1] == 3); - } #endif return boost::report_errors(); } diff --git a/test/make_shared_array_create_test.cpp b/test/make_shared_array_create_test.cpp index b89d95f..869d21c 100644 --- a/test/make_shared_array_create_test.cpp +++ b/test/make_shared_array_create_test.cpp @@ -82,13 +82,6 @@ int main() { 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] == 0); - BOOST_TEST(a1[0][1] == 1); - BOOST_TEST(a1[1][0] == 2); - BOOST_TEST(a1[1][1] == 3); - } #endif return boost::report_errors(); } From fe06c120b9b182dead9c3515fccd739d372f7d76 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 9 Nov 2012 17:12:56 +0000 Subject: [PATCH 114/210] Add overloads to support fixed size arrays, T[N], to allocate_shared (variadic) and make_shared (variadic) and make_shared_noinit. [SVN r81265] --- .../boost/smart_ptr/allocate_shared_array.hpp | 17 +++++++++ .../boost/smart_ptr/detail/array_traits.hpp | 4 +++ .../boost/smart_ptr/detail/sp_if_array.hpp | 5 ++- include/boost/smart_ptr/make_shared_array.hpp | 34 ++++++++++++++++++ make_shared_array.html | 23 ++++++++++-- test/allocate_shared_array_create_test.cpp | 36 +++++++++++++++++++ test/make_shared_array_create_test.cpp | 36 +++++++++++++++++++ test/make_shared_arrays_test.cpp | 26 ++++++++++++++ 8 files changed, 177 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index d0123a6..ae44827 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -51,6 +51,23 @@ namespace boost { 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; + size_t n1 = detail::array_size::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 diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index b95a598..d8f93ef 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -44,6 +44,10 @@ namespace boost { struct array_inner { typedef T type; }; + template + struct array_inner { + typedef T type; + }; #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template struct array_list { diff --git a/include/boost/smart_ptr/detail/sp_if_array.hpp b/include/boost/smart_ptr/detail/sp_if_array.hpp index 4a838fc..96819b5 100644 --- a/include/boost/smart_ptr/detail/sp_if_array.hpp +++ b/include/boost/smart_ptr/detail/sp_if_array.hpp @@ -20,8 +20,11 @@ namespace boost { struct sp_if_array { typedef boost::shared_ptr type; }; + template + struct sp_if_size_array { + }; template - struct sp_if_array { + struct sp_if_size_array { typedef boost::shared_ptr type; }; } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 50a78fd..10d42a5 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -51,6 +51,23 @@ namespace boost { 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; + size_t n1 = detail::array_size::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 @@ -91,6 +108,23 @@ namespace boost { 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; + size_t n1 = detail::array_size::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/make_shared_array.html b/make_shared_array.html index e35350c..01bf71b 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -28,21 +28,38 @@

    Synopsis

    namespace boost {
         template<typename T>
    -    shared_ptr<T> make_shared(size_t size);
    +    shared_ptr<T[]> make_shared(size_t size);
     
         template<typename T, typename A>
    -    shared_ptr<T> allocate_shared(const A& allocator, size_t size);
    +    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);
    +    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(std::initializer_list<T> list);
    +        
    +    template<typename T, typename A, typename... Args>
    +    shared_ptr<T[]> allocate_shared(const A& allocator, std::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>
    diff --git a/test/allocate_shared_array_create_test.cpp b/test/allocate_shared_array_create_test.cpp
    index 9758c78..9959838 100644
    --- a/test/allocate_shared_array_create_test.cpp
    +++ b/test/allocate_shared_array_create_test.cpp
    @@ -47,6 +47,15 @@ int main() {
             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);
    @@ -56,6 +65,15 @@ int main() {
             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);
    @@ -65,6 +83,15 @@ int main() {
             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);
    @@ -73,6 +100,15 @@ int main() {
             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
     #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
         {
    diff --git a/test/make_shared_array_create_test.cpp b/test/make_shared_array_create_test.cpp
    index 869d21c..cc47dd6 100644
    --- a/test/make_shared_array_create_test.cpp
    +++ b/test/make_shared_array_create_test.cpp
    @@ -47,6 +47,15 @@ int main() {
             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);
    @@ -56,6 +65,15 @@ int main() {
             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);
    @@ -65,6 +83,15 @@ int main() {
             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);
    @@ -73,6 +100,15 @@ int main() {
             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
     #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
         {
    diff --git a/test/make_shared_arrays_test.cpp b/test/make_shared_arrays_test.cpp
    index 22fe447..e4c3d48 100644
    --- a/test/make_shared_arrays_test.cpp
    +++ b/test/make_shared_arrays_test.cpp
    @@ -75,11 +75,21 @@ int main() {
             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);
         {
    @@ -91,11 +101,27 @@ int main() {
             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);
         }
    +    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);
    +    }
         return boost::report_errors();
     }
    
    From 2731957b5b18e65b5d3a6b904f11d98396cd1b0e Mon Sep 17 00:00:00 2001
    From: Glen Fernandes 
    Date: Fri, 9 Nov 2012 17:30:07 +0000
    Subject: [PATCH 115/210] Add additional overload for make_shared and
     allocate_shared for arrays for fixed size arrays and initializer lists.
    
    [SVN r81266]
    ---
     .../boost/smart_ptr/allocate_shared_array.hpp | 20 +++++++++++++++++++
     .../boost/smart_ptr/detail/array_traits.hpp   |  4 ++++
     include/boost/smart_ptr/make_shared_array.hpp | 20 +++++++++++++++++++
     make_shared_array.html                        |  6 ++++++
     test/allocate_shared_array_create_test.cpp    |  7 +++++++
     test/allocate_shared_arrays_create_test.cpp   |  7 +++++++
     test/make_shared_array_create_test.cpp        |  7 +++++++
     test/make_shared_arrays_create_test.cpp       |  7 +++++++
     8 files changed, 78 insertions(+)
    
    diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp
    index ae44827..f151c00 100644
    --- a/include/boost/smart_ptr/allocate_shared_array.hpp
    +++ b/include/boost/smart_ptr/allocate_shared_array.hpp
    @@ -90,6 +90,26 @@ namespace boost {
             d2->construct(p2, n1, p3);
             return shared_ptr(s1, p1);
         }
    +    template
    +    inline typename detail::sp_if_size_array::type
    +    allocate_shared(const A& allocator, typename detail::array_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;
    +        size_t n1 = detail::array_size::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(p2, n1, p3);
    +        return shared_ptr(s1, p1);
    +    }
     #endif
     }
     
    diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp
    index d8f93ef..d80798f 100644
    --- a/include/boost/smart_ptr/detail/array_traits.hpp
    +++ b/include/boost/smart_ptr/detail/array_traits.hpp
    @@ -56,6 +56,10 @@ namespace boost {
             struct array_list {
                 typedef std::initializer_list type;
             };
    +        template
    +        struct array_list {
    +            typedef std::initializer_list type;
    +        };
     #endif
         }
     }
    diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp
    index 10d42a5..a1a9f40 100644
    --- a/include/boost/smart_ptr/make_shared_array.hpp
    +++ b/include/boost/smart_ptr/make_shared_array.hpp
    @@ -90,6 +90,26 @@ namespace boost {
             d2->construct(p2, n1, p3);
             return shared_ptr(s1, p1);
         }
    +    template
    +    inline typename detail::sp_if_size_array::type
    +    make_shared(typename detail::array_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;
    +        size_t n1 = detail::array_size::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(p2, n1, p3);
    +        return shared_ptr(s1, p1);
    +    }
     #endif
         template
         inline typename detail::sp_if_array::type
    diff --git a/make_shared_array.html b/make_shared_array.html
    index 01bf71b..5553f41 100644
    --- a/make_shared_array.html
    +++ b/make_shared_array.html
    @@ -50,9 +50,15 @@
     #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
         template<typename T, typename... Args>
         shared_ptr<T[]> make_shared(std::initializer_list<T> list);
    +    
    +    template<typename T, typename... Args>
    +    shared_ptr<T[N]> make_shared(std::initializer_list<T> list);
             
         template<typename T, typename A, typename... Args>
         shared_ptr<T[]> allocate_shared(const A& allocator, std::initializer_list<T> list);
    +    
    +    template<typename T, typename A, typename... Args>
    +    shared_ptr<T[N]> allocate_shared(const A& allocator, std::initializer_list<T> list);
     #endif
     
         template<typename T>
    diff --git a/test/allocate_shared_array_create_test.cpp b/test/allocate_shared_array_create_test.cpp
    index 9959838..3c18844 100644
    --- a/test/allocate_shared_array_create_test.cpp
    +++ b/test/allocate_shared_array_create_test.cpp
    @@ -118,6 +118,13 @@ int main() {
             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);
    +    }
     #endif
         return boost::report_errors();
     }
    diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp
    index 08226e0..d88a428 100644
    --- a/test/allocate_shared_arrays_create_test.cpp
    +++ b/test/allocate_shared_arrays_create_test.cpp
    @@ -18,6 +18,13 @@ int main() {
             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);
    +    }
     #endif
         return boost::report_errors();
     }
    diff --git a/test/make_shared_array_create_test.cpp b/test/make_shared_array_create_test.cpp
    index cc47dd6..1c6ca08 100644
    --- a/test/make_shared_array_create_test.cpp
    +++ b/test/make_shared_array_create_test.cpp
    @@ -118,6 +118,13 @@ int main() {
             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);
    +    }
     #endif
         return boost::report_errors();
     }
    diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp
    index 08c1e4a..5e773a5 100644
    --- a/test/make_shared_arrays_create_test.cpp
    +++ b/test/make_shared_arrays_create_test.cpp
    @@ -18,6 +18,13 @@ int main() {
             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);
    +    }
     #endif
         return boost::report_errors();
     }
    
    From 8cc50a5ce996d669574fa50f2a6f9ee23907a606 Mon Sep 17 00:00:00 2001
    From: Glen Fernandes 
    Date: Fri, 9 Nov 2012 18:01:39 +0000
    Subject: [PATCH 116/210] Add assertion to overload of make_shared and
     allocate_shared for T[N] with initializer lists. Rename detail type to be
     more intuitive.
    
    [SVN r81267]
    ---
     include/boost/smart_ptr/allocate_shared_array.hpp | 11 ++++++-----
     include/boost/smart_ptr/detail/array_traits.hpp   | 14 +++++++++++---
     include/boost/smart_ptr/detail/sp_if_array.hpp    |  2 +-
     include/boost/smart_ptr/make_shared_array.hpp     | 15 ++++++++-------
     4 files changed, 26 insertions(+), 16 deletions(-)
    
    diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp
    index f151c00..c3ca93e 100644
    --- a/include/boost/smart_ptr/allocate_shared_array.hpp
    +++ b/include/boost/smart_ptr/allocate_shared_array.hpp
    @@ -23,7 +23,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = size * detail::array_size::size;
    +        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);
    @@ -41,7 +41,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = size * detail::array_size::size;
    +        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);
    @@ -58,7 +58,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = detail::array_size::size;
    +        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);
    @@ -79,7 +79,7 @@ namespace boost {
             T1* p1 = 0;
             T2* p2 = 0;
             T3* p3 = 0;
    -        size_t n1 = list.size() * detail::array_size::size;
    +        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);
    @@ -93,13 +93,14 @@ namespace boost {
         template
         inline typename detail::sp_if_size_array::type
         allocate_shared(const A& allocator, typename detail::array_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;
    -        size_t n1 = detail::array_size::size;
    +        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);
    diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp
    index d80798f..6343f71 100644
    --- a/include/boost/smart_ptr/detail/array_traits.hpp
    +++ b/include/boost/smart_ptr/detail/array_traits.hpp
    @@ -13,7 +13,6 @@
     #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
     #include 
     #endif
    -#include 
     
     namespace boost {
         namespace detail {
    @@ -27,14 +26,23 @@ namespace boost {
             };
             template
             struct array_size {
    +        };
    +        template
    +        struct array_size {
    +            enum {
    +                size = N
    +            };
    +        };
    +        template
    +        struct array_total {
                 enum {
                     size = 1
                 };
             };
             template
    -        struct array_size {
    +        struct array_total {
                 enum {
    -                size = N * array_size::size
    +                size = N * array_total::size
                 };
             };
             template 
    diff --git a/include/boost/smart_ptr/detail/sp_if_array.hpp b/include/boost/smart_ptr/detail/sp_if_array.hpp
    index 96819b5..3ba3a0e 100644
    --- a/include/boost/smart_ptr/detail/sp_if_array.hpp
    +++ b/include/boost/smart_ptr/detail/sp_if_array.hpp
    @@ -23,7 +23,7 @@ namespace boost {
             template
             struct sp_if_size_array {
             };
    -        template
    +        template
             struct sp_if_size_array {
                 typedef boost::shared_ptr type;
             };
    diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp
    index a1a9f40..9e96412 100644
    --- a/include/boost/smart_ptr/make_shared_array.hpp
    +++ b/include/boost/smart_ptr/make_shared_array.hpp
    @@ -23,7 +23,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = size * detail::array_size::size;
    +        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);
    @@ -41,7 +41,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = size * detail::array_size::size;
    +        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);
    @@ -58,7 +58,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = detail::array_size::size;
    +        size_t n1 = detail::array_total::size;
             detail::make_array_helper a1(n1, &p2);
             detail::array_deleter d1;
             shared_ptr s1(p1, d1, a1);
    @@ -79,7 +79,7 @@ namespace boost {
             T1* p1 = 0;
             T2* p2 = 0;
             T3* p3 = 0;
    -        size_t n1 = list.size() * detail::array_size::size;
    +        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);
    @@ -93,13 +93,14 @@ namespace boost {
         template
         inline typename detail::sp_if_size_array::type
         make_shared(typename detail::array_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;
    -        size_t n1 = detail::array_size::size;
    +        size_t n1 = detail::array_total::size;
             detail::make_array_helper a1(n1, &p2);
             detail::array_deleter d1;
             shared_ptr s1(p1, d1, a1);
    @@ -118,7 +119,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = size * detail::array_size::size;
    +        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);
    @@ -135,7 +136,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = detail::array_size::size;
    +        size_t n1 = detail::array_total::size;
             detail::make_array_helper a1(n1, &p2);
             detail::array_deleter d1;
             shared_ptr s1(p1, d1, a1);
    
    From 58a46f4e55047d856434ae158af66b50c28b5adf Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Fri, 9 Nov 2012 18:26:40 +0000
    Subject: [PATCH 117/210] Add allocate_shared_array_args_test.cpp.
    
    [SVN r81268]
    ---
     test/Jamfile.v2                          |   1 +
     test/allocate_shared_array_args_test.cpp | 173 +++++++++++++++++++++++
     2 files changed, 174 insertions(+)
     create mode 100644 test/allocate_shared_array_args_test.cpp
    
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
    index d8fbe2a..bde61b2 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -144,5 +144,6 @@ import testing ;
               [ 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();
    +}
    
    From 2aaa913b1149d6e2dd70ffe1cdb64917aacaad99 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Fri, 9 Nov 2012 23:27:02 +0000
    Subject: [PATCH 118/210] Keep old definition of sp_assert_convertible when
     BOOST_SP_NO_SP_CONVERTIBLE is set.
    
    [SVN r81271]
    ---
     include/boost/smart_ptr/shared_ptr.hpp | 9 +++++++++
     1 file changed, 9 insertions(+)
    
    diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp
    index af1b13d..d9cc6f2 100644
    --- a/include/boost/smart_ptr/shared_ptr.hpp
    +++ b/include/boost/smart_ptr/shared_ptr.hpp
    @@ -243,9 +243,18 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R
     
     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
    
    From 5bdde37414d0d959fa95505d14353741e35762f7 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Sat, 10 Nov 2012 00:04:49 +0000
    Subject: [PATCH 119/210] Updated shared_array to match shared_ptr. Refs #1113.
    
    [SVN r81272]
    ---
     include/boost/smart_ptr/shared_array.hpp | 106 +++++++++++++++++++++--
     test/smart_ptr_test.cpp                  |   4 +-
     2 files changed, 100 insertions(+), 10 deletions(-)
    
    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/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
     
    
    From 980070e63f68d6d05bace4dc42cec660cd288dcf Mon Sep 17 00:00:00 2001
    From: Glen Fernandes 
    Date: Sat, 10 Nov 2012 01:33:29 +0000
    Subject: [PATCH 120/210] Add final overload of make_shared and allocate_shared
     (array forms) for T[][N] with C++11 initializer lists.
    
    [SVN r81275]
    ---
     .../boost/smart_ptr/allocate_shared_array.hpp | 39 ++++++++++++++-----
     .../detail/allocate_array_helper.hpp          |  1 -
     .../boost/smart_ptr/detail/array_deleter.hpp  |  8 +++-
     .../boost/smart_ptr/detail/array_traits.hpp   |  7 ++++
     .../smart_ptr/detail/make_array_helper.hpp    |  1 -
     include/boost/smart_ptr/make_shared_array.hpp | 39 ++++++++++++++-----
     make_shared_array.html                        | 18 ++++++---
     test/allocate_shared_arrays_create_test.cpp   | 14 +++++++
     test/make_shared_arrays_create_test.cpp       | 15 +++++++
     9 files changed, 115 insertions(+), 27 deletions(-)
    
    diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp
    index c3ca93e..cb29bf6 100644
    --- a/include/boost/smart_ptr/allocate_shared_array.hpp
    +++ b/include/boost/smart_ptr/allocate_shared_array.hpp
    @@ -18,12 +18,12 @@
     namespace boost {
         template
         inline typename detail::sp_if_array::type 
    -    allocate_shared(const A& allocator, size_t size) {
    +    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;
    -        size_t n1 = size * detail::array_total::size;
    +        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);
    @@ -36,12 +36,12 @@ namespace boost {
     #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
         template
         inline typename detail::sp_if_array::type
    -    allocate_shared(const A& allocator, size_t size, Args&&... args) {
    +    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;
    -        size_t n1 = size * detail::array_total::size;
    +        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);
    @@ -58,7 +58,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = detail::array_total::size;
    +        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);
    @@ -79,7 +79,7 @@ namespace boost {
             T1* p1 = 0;
             T2* p2 = 0;
             T3* p3 = 0;
    -        size_t n1 = list.size() * detail::array_total::size;
    +        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);
    @@ -87,7 +87,7 @@ namespace boost {
             p3 = reinterpret_cast(list.begin());
             p1 = reinterpret_cast(p2);
             d2 = get_deleter >(s1);
    -        d2->construct(p2, n1, p3);
    +        d2->construct_list(p2, n1, p3);
             return shared_ptr(s1, p1);
         }
         template
    @@ -100,7 +100,7 @@ namespace boost {
             T1* p1 = 0;
             T2* p2 = 0;
             T3* p3 = 0;
    -        size_t n1 = detail::array_total::size;
    +        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);
    @@ -108,7 +108,28 @@ namespace boost {
             p3 = reinterpret_cast(list.begin());
             p1 = reinterpret_cast(p2);
             d2 = get_deleter >(s1);
    -        d2->construct(p2, n1, p3);
    +        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, typename detail::inner_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
    diff --git a/include/boost/smart_ptr/detail/allocate_array_helper.hpp b/include/boost/smart_ptr/detail/allocate_array_helper.hpp
    index 3314e6c..bfb4dec 100644
    --- a/include/boost/smart_ptr/detail/allocate_array_helper.hpp
    +++ b/include/boost/smart_ptr/detail/allocate_array_helper.hpp
    @@ -10,7 +10,6 @@
     #define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
     
     #include 
    -#include 
     
     namespace boost {
         namespace detail {
    diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp
    index 70d7479..273dcac 100644
    --- a/include/boost/smart_ptr/detail/array_deleter.hpp
    +++ b/include/boost/smart_ptr/detail/array_deleter.hpp
    @@ -39,12 +39,18 @@ namespace boost {
                 }
     #endif
     #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    -            void construct(T* memory, std::size_t count, const T* 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++) {
    diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp
    index 6343f71..14bdf01 100644
    --- a/include/boost/smart_ptr/detail/array_traits.hpp
    +++ b/include/boost/smart_ptr/detail/array_traits.hpp
    @@ -68,6 +68,13 @@ namespace boost {
             struct array_list {
                 typedef std::initializer_list type;
             };
    +        template
    +        struct inner_list {
    +        };
    +        template
    +        struct inner_list {
    +            typedef std::initializer_list type;
    +        };
     #endif
         }
     }
    diff --git a/include/boost/smart_ptr/detail/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp
    index 34cc2e7..96fa3f9 100644
    --- a/include/boost/smart_ptr/detail/make_array_helper.hpp
    +++ b/include/boost/smart_ptr/detail/make_array_helper.hpp
    @@ -10,7 +10,6 @@
     #define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
     
     #include 
    -#include 
     
     namespace boost {
         namespace detail {
    diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp
    index 9e96412..7cb9e7a 100644
    --- a/include/boost/smart_ptr/make_shared_array.hpp
    +++ b/include/boost/smart_ptr/make_shared_array.hpp
    @@ -23,7 +23,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = size * detail::array_total::size;
    +        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);
    @@ -41,7 +41,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = size * detail::array_total::size;
    +        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);
    @@ -58,7 +58,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = detail::array_total::size;
    +        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);
    @@ -79,7 +79,7 @@ namespace boost {
             T1* p1 = 0;
             T2* p2 = 0;
             T3* p3 = 0;
    -        size_t n1 = list.size() * detail::array_total::size;
    +        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);
    @@ -87,7 +87,7 @@ namespace boost {
             p3 = reinterpret_cast(list.begin());
             p1 = reinterpret_cast(p2);
             d2 = get_deleter >(s1);
    -        d2->construct(p2, n1, p3);
    +        d2->construct_list(p2, n1, p3);
             return shared_ptr(s1, p1);
         }
         template
    @@ -100,7 +100,7 @@ namespace boost {
             T1* p1 = 0;
             T2* p2 = 0;
             T3* p3 = 0;
    -        size_t n1 = detail::array_total::size;
    +        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);
    @@ -108,7 +108,28 @@ namespace boost {
             p3 = reinterpret_cast(list.begin());
             p1 = reinterpret_cast(p2);
             d2 = get_deleter >(s1);
    -        d2->construct(p2, n1, p3);
    +        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, typename detail::inner_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
    @@ -119,7 +140,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = size * detail::array_total::size;
    +        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);
    @@ -136,7 +157,7 @@ namespace boost {
             typedef typename detail::array_base::type T2;
             T1* p1 = 0;
             T2* p2 = 0;
    -        size_t n1 = detail::array_total::size;
    +        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);
    diff --git a/make_shared_array.html b/make_shared_array.html
    index 5553f41..4739b3a 100644
    --- a/make_shared_array.html
    +++ b/make_shared_array.html
    @@ -49,16 +49,22 @@
     
     #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
         template<typename T, typename... Args>
    -    shared_ptr<T[]> make_shared(std::initializer_list<T> list);
    +    shared_ptr<T[]> make_shared(initializer_list<T> list);
         
         template<typename T, typename... Args>
    -    shared_ptr<T[N]> make_shared(std::initializer_list<T> list);
    +    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, std::initializer_list<T> list);
    +    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, std::initializer_list<T> list);
    +    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>
    @@ -74,7 +80,7 @@ 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(std::forward<Args>(args)...), where + 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 @@ -85,7 +91,7 @@ template<typename T, typename A, typename... Args> T and size size and constructs an array of objects in it via the placement new expression new(pointer) T() or - new(pointer) T(std::forward<Args>(args)...). + new(pointer) T(forward<Args>(args)...). allocate_shared uses a copy of allocator to allocate memory. If an exception is thrown, has no effect.

    diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index d88a428..fd44aa0 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -25,6 +25,20 @@ int main() { 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/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp index 5e773a5..b5b96d5 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -8,6 +8,7 @@ */ #include #include +#include int main() { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -25,6 +26,20 @@ int main() { 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(); } From 0e90213746e7190fe5e4b553be52c43a5a5fab2e Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 10 Nov 2012 02:17:02 +0000 Subject: [PATCH 121/210] Change traits for initializer list for g++ [SVN r81276] --- .../boost/smart_ptr/allocate_shared_array.hpp | 9 ++++--- .../boost/smart_ptr/detail/array_traits.hpp | 26 ++++--------------- include/boost/smart_ptr/make_shared_array.hpp | 9 ++++--- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index cb29bf6..89923c7 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -14,6 +14,9 @@ #include #include #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif namespace boost { template @@ -72,7 +75,7 @@ namespace boost { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template inline typename detail::sp_if_array::type - allocate_shared(const A& allocator, typename detail::array_list::type list) { + 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; @@ -92,7 +95,7 @@ namespace boost { } template inline typename detail::sp_if_size_array::type - allocate_shared(const A& allocator, typename detail::array_list::type list) { + 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; @@ -113,7 +116,7 @@ namespace boost { } template inline typename detail::sp_if_array::type - allocate_shared(const A& allocator, std::size_t size, typename detail::inner_list::type list) { + 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; diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index 14bdf01..068629a 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -10,9 +10,6 @@ #define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP #include -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif namespace boost { namespace detail { @@ -56,26 +53,13 @@ namespace boost { struct array_inner { typedef T type; }; -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - template - struct array_list { + template + struct arrays_inner { }; - template - struct array_list { - typedef std::initializer_list type; + template + struct arrays_inner { + typedef T type; }; - template - struct array_list { - typedef std::initializer_list type; - }; - template - struct inner_list { - }; - template - struct inner_list { - typedef std::initializer_list type; - }; -#endif } } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 7cb9e7a..5329322 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -14,6 +14,9 @@ #include #include #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif namespace boost { template @@ -72,7 +75,7 @@ namespace boost { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template inline typename detail::sp_if_array::type - make_shared(typename detail::array_list::type list) { + 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; @@ -92,7 +95,7 @@ namespace boost { } template inline typename detail::sp_if_size_array::type - make_shared(typename detail::array_list::type list) { + 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; @@ -113,7 +116,7 @@ namespace boost { } template inline typename detail::sp_if_array::type - make_shared(std::size_t size, typename detail::inner_list::type list) { + 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; From fa513340d74c987ca21e3c8fe74fa2d4284852a2 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 10 Nov 2012 02:33:48 +0000 Subject: [PATCH 122/210] Tidy long line formatting in allocate_shared_array.hpp and make_shared_array.hpp [SVN r81277] --- include/boost/smart_ptr/allocate_shared_array.hpp | 9 ++++++--- include/boost/smart_ptr/make_shared_array.hpp | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 89923c7..b2aa826 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -75,7 +75,8 @@ namespace boost { #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) { + 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; @@ -95,7 +96,8 @@ namespace boost { } template inline typename detail::sp_if_size_array::type - allocate_shared(const A& allocator, std::initializer_list::type> list) { + 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; @@ -116,7 +118,8 @@ namespace boost { } template inline typename detail::sp_if_array::type - allocate_shared(const A& allocator, std::size_t size, std::initializer_list::type> list) { + 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; diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 5329322..f9a39ff 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -116,7 +116,8 @@ namespace boost { } template inline typename detail::sp_if_array::type - make_shared(std::size_t size, std::initializer_list::type> list) { + 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; From 25e11b20d3c0d7d82ff6aa7e013a6099b633155b Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 11 Nov 2012 19:14:50 +0000 Subject: [PATCH 123/210] Update tests for make_shared and allocate_shared array forms, for normal case, initializer lists, variadic template arguments, for arrays and fixed size arrays. [SVN r81299] --- test/allocate_shared_array_create_test.cpp | 16 ---- test/allocate_shared_array_esft_test.cpp | 2 +- test/allocate_shared_array_init_test.cpp | 82 +++++++++++++++++++ test/allocate_shared_array_test.cpp | 38 +++++++++ test/allocate_shared_array_throws_test.cpp | 7 ++ test/allocate_shared_arrays_test.cpp | 29 +++++++ test/make_shared_array_create_test.cpp | 16 ---- test/make_shared_array_esft_test.cpp | 4 +- test/make_shared_array_init_test.cpp | 82 +++++++++++++++++++ test/make_shared_array_test.cpp | 91 ++++++++++++++++++++-- test/make_shared_array_throws_test.cpp | 16 +++- test/make_shared_arrays_test.cpp | 33 ++++++++ 12 files changed, 375 insertions(+), 41 deletions(-) create mode 100644 test/allocate_shared_array_init_test.cpp create mode 100644 test/make_shared_array_init_test.cpp diff --git a/test/allocate_shared_array_create_test.cpp b/test/allocate_shared_array_create_test.cpp index 3c18844..2e03be6 100644 --- a/test/allocate_shared_array_create_test.cpp +++ b/test/allocate_shared_array_create_test.cpp @@ -109,22 +109,6 @@ int main() { BOOST_TEST(a1[0][1][0][0].f == 0); BOOST_TEST(a1[1][0][0][0].i == 0); } -#endif -#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); - } #endif return boost::report_errors(); } diff --git a/test/allocate_shared_array_esft_test.cpp b/test/allocate_shared_array_esft_test.cpp index 3864b81..2315421 100644 --- a/test/allocate_shared_array_esft_test.cpp +++ b/test/allocate_shared_array_esft_test.cpp @@ -34,7 +34,7 @@ int main() { try { a1[0].shared_from_this(); BOOST_ERROR("shared_from_this did not throw"); - } catch (const boost::bad_weak_ptr&) { + } catch (...) { BOOST_TEST(type::instances == 3); } } 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 index db2cffc..91f3fb5 100644 --- a/test/allocate_shared_array_test.cpp +++ b/test/allocate_shared_array_test.cpp @@ -70,15 +70,53 @@ int main() { 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); } diff --git a/test/allocate_shared_array_throws_test.cpp b/test/allocate_shared_array_throws_test.cpp index e787000..d52104c 100644 --- a/test/allocate_shared_array_throws_test.cpp +++ b/test/allocate_shared_array_throws_test.cpp @@ -36,5 +36,12 @@ int main() { } 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_test.cpp b/test/allocate_shared_arrays_test.cpp index 5bb48e5..ab22c23 100644 --- a/test/allocate_shared_arrays_test.cpp +++ b/test/allocate_shared_arrays_test.cpp @@ -59,6 +59,8 @@ int main() { 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); @@ -70,6 +72,33 @@ int main() { 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/make_shared_array_create_test.cpp b/test/make_shared_array_create_test.cpp index 1c6ca08..46db862 100644 --- a/test/make_shared_array_create_test.cpp +++ b/test/make_shared_array_create_test.cpp @@ -109,22 +109,6 @@ int main() { BOOST_TEST(a1[0][1][0][0].f == 0); BOOST_TEST(a1[1][0][0][0].i == 0); } -#endif -#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); - } #endif return boost::report_errors(); } diff --git a/test/make_shared_array_esft_test.cpp b/test/make_shared_array_esft_test.cpp index 3431f23..9d0adb1 100644 --- a/test/make_shared_array_esft_test.cpp +++ b/test/make_shared_array_esft_test.cpp @@ -34,7 +34,7 @@ int main() { try { a1[0].shared_from_this(); BOOST_ERROR("shared_from_this did not throw"); - } catch (const boost::bad_weak_ptr&) { + } catch (...) { BOOST_TEST(type::instances == 3); } } @@ -44,7 +44,7 @@ int main() { try { a1[0].shared_from_this(); BOOST_ERROR("shared_from_this did not throw"); - } catch (const boost::bad_weak_ptr&) { + } catch (...) { BOOST_TEST(type::instances == 3); } } 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 index 6fe2c24..d9b9134 100644 --- a/test/make_shared_array_test.cpp +++ b/test/make_shared_array_test.cpp @@ -70,15 +70,53 @@ int main() { 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(type::instances == 3); + BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a2 != 0); - BOOST_TEST(size_t(a2) % boost::alignment_of::value == 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); } @@ -86,12 +124,28 @@ int main() { { 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_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); } @@ -99,6 +153,7 @@ int main() { { 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); @@ -108,11 +163,37 @@ int main() { } BOOST_TEST(type::instances == 0); { - boost::shared_ptr a1 = boost::make_shared_noinit(3); - const type* a2 = a1.get(); + 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 index 2bac909..7e06d41 100644 --- a/test/make_shared_array_throws_test.cpp +++ b/test/make_shared_array_throws_test.cpp @@ -38,7 +38,21 @@ int main() { } BOOST_TEST(type::instances == 0); try { - boost::shared_ptr a1 = boost::make_shared_noinit(6); + 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); diff --git a/test/make_shared_arrays_test.cpp b/test/make_shared_arrays_test.cpp index e4c3d48..eb79d4f 100644 --- a/test/make_shared_arrays_test.cpp +++ b/test/make_shared_arrays_test.cpp @@ -59,6 +59,8 @@ int main() { 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); @@ -70,6 +72,33 @@ int main() { 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); @@ -115,6 +144,8 @@ int main() { 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); { @@ -122,6 +153,8 @@ int main() { 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(); } From 3b0b10d06d2bd364b1191878abf32ad57cf8229f Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 11 Nov 2012 19:21:18 +0000 Subject: [PATCH 124/210] Update Jamfile.v2 with two new smart_ptr tests for allocate_shared and make_shared [SVN r81300] --- test/Jamfile.v2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index bde61b2..e3b41c0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -134,6 +134,7 @@ import testing ; [ 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 ] @@ -141,6 +142,7 @@ import testing ; [ 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 ] From 6b2556edfbc6645d598f3d2eeba3b311dbceaae9 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 14 Nov 2012 15:18:50 +0000 Subject: [PATCH 125/210] Add additional overload for allocate_shared and make_shared array forms that take initializer list of T for the array types T[M][N] [SVN r81341] --- .../boost/smart_ptr/allocate_shared_array.hpp | 25 ++++++++++++++++++- .../boost/smart_ptr/detail/array_traits.hpp | 10 +++++--- include/boost/smart_ptr/make_shared_array.hpp | 24 +++++++++++++++++- make_shared_array.html | 18 +++++++++++-- test/allocate_shared_arrays_create_test.cpp | 14 +++++++++++ test/make_shared_arrays_create_test.cpp | 14 +++++++++++ 6 files changed, 98 insertions(+), 7 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index b2aa826..3f428c3 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -98,10 +98,10 @@ namespace boost { 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; + BOOST_ASSERT(list.size() == detail::array_size::size); T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; @@ -138,6 +138,29 @@ namespace boost { d2->construct_list(p2, n1, p3, n0); return shared_ptr(s1, p1); } + template + inline typename detail::sp_if_size_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; + BOOST_ASSERT(list.size() == detail::array_size::size); + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n0 = detail::array_total::size; + 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, n0); + return shared_ptr(s1, p1); + } #endif } diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index 068629a..3b80f46 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -24,7 +24,7 @@ namespace boost { template struct array_size { }; - template + template struct array_size { enum { size = N @@ -49,17 +49,21 @@ namespace boost { struct array_inner { typedef T type; }; - template + template struct array_inner { typedef T type; }; template struct arrays_inner { }; - template + template struct arrays_inner { typedef T type; }; + template + struct arrays_inner { + typedef T type; + }; } } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index f9a39ff..2c0fd8d 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -96,10 +96,10 @@ namespace boost { 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; + BOOST_ASSERT(list.size() == detail::array_size::size); T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; @@ -136,6 +136,28 @@ namespace boost { d2->construct_list(p2, n1, p3, n0); return shared_ptr(s1, p1); } + template + inline typename detail::sp_if_size_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; + BOOST_ASSERT(list.size() == detail::array_size::size); + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n0 = detail::array_total::size; + 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, n0); + return shared_ptr(s1, p1); + } #endif template inline typename detail::sp_if_array::type diff --git a/make_shared_array.html b/make_shared_array.html index 4739b3a..9c46926 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -56,7 +56,10 @@ template<typename T, typename... Args> shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T> list); - + + template<typename T, typename... Args> + shared_ptr<T[M][N]> make_shared(initializer_list<T> list); + template<typename T, typename A, typename... Args> shared_ptr<T[]> allocate_shared(const A& allocator, initializer_list<T> list); @@ -65,6 +68,9 @@ template<typename T, typename A, typename... Args> shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list); + + template<typename T, typename A, typename... Args> + shared_ptr<T[M][N]> allocate_shared(const A& allocator, initializer_list<T> list); #endif template<typename T> @@ -117,7 +123,15 @@ template<typename T, typename A, typename... Args> constructor of T for each array element.

    Example

    -
    boost::shared_ptr<int[]> array = boost::make_shared<int[]>(size);
    +
    boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size);
    +boost::shared_ptr<point[5]> a2 = boost::make_shared<point[5]>(x, y);
    +boost::shared_ptr<int[5]> a3 = boost::make_shared<int[5]>();
    +boost::shared_ptr<int[]> a4 = boost::make_shared<int[]>({1, 2, 3});
    +boost::shared_ptr<int[3]> a5 = boost::make_shared<int[3]>({1, 2, 3});
    +boost::shared_ptr<int[][3]> a6 = boost::make_shared<int[][3]>(size, {1, 2, 3});
    +boost::shared_ptr<int[5][3]> a7 = boost::make_shared<int[5][3]>({1, 2, 3});
    +boost::shared_ptr<int[]> a8 = boost::make_shared_noinit<int[]>(size);
    +boost::shared_ptr<int[5]> a9 = boost::make_shared_noinit<int[5]>();

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

    Copyright 2012 Glen Fernandes. Distributed under the Boost diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index fd44aa0..03a2d7e 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -25,6 +25,13 @@ int main() { BOOST_TEST(a1[1][0] == 2); BOOST_TEST(a1[1][1] == 3); } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), {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}); BOOST_TEST(a1[0][0] == 0); @@ -39,6 +46,13 @@ int main() { BOOST_TEST(a1[1][1][0] == 2); BOOST_TEST(a1[1][1][1] == 3); } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { {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_create_test.cpp b/test/make_shared_arrays_create_test.cpp index b5b96d5..e468378 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -26,6 +26,13 @@ int main() { BOOST_TEST(a1[1][0] == 2); BOOST_TEST(a1[1][1] == 3); } + { + boost::shared_ptr a1 = boost::make_shared({ 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}); BOOST_TEST(a1[0][0] == 0); @@ -40,6 +47,13 @@ int main() { BOOST_TEST(a1[1][1][0] == 2); BOOST_TEST(a1[1][1][1] == 3); } + { + boost::shared_ptr a1 = boost::make_shared({ {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(); } From da9524d6373f35d669d45b31472432ac15f69536 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 14 Nov 2012 15:33:30 +0000 Subject: [PATCH 126/210] Minor style change: Fix indentation in allocate_shared_array.hpp and make_shared_array.hpp [SVN r81342] --- include/boost/smart_ptr/allocate_shared_array.hpp | 4 ++-- include/boost/smart_ptr/make_shared_array.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 3f428c3..904902c 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -101,7 +101,7 @@ namespace boost { typedef typename detail::array_inner::type T1; typedef typename detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == detail::array_size::size); + BOOST_ASSERT(list.size() == detail::array_size::size); T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; @@ -145,7 +145,7 @@ namespace boost { typedef typename detail::array_inner::type T1; typedef typename detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == detail::array_size::size); + BOOST_ASSERT(list.size() == detail::array_size::size); T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 2c0fd8d..70083b1 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -99,7 +99,7 @@ namespace boost { typedef typename detail::array_inner::type T1; typedef typename detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == detail::array_size::size); + BOOST_ASSERT(list.size() == detail::array_size::size); T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; @@ -142,7 +142,7 @@ namespace boost { typedef typename detail::array_inner::type T1; typedef typename detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == detail::array_size::size); + BOOST_ASSERT(list.size() == detail::array_size::size); T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; From 7adb1cc1ec47fd5bf4a96c43805cdb00ae418f54 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 14 Nov 2012 18:24:05 +0000 Subject: [PATCH 127/210] Reorder HP aCC and g++ #ifdefs. Refs #7693. [SVN r81348] --- include/boost/smart_ptr/detail/sp_counted_base.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp index e97c237..9ced2b9 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp @@ -38,12 +38,12 @@ #elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__) # include -#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__) -# include - #elif defined(__HP_aCC) && defined(__ia64) # include +#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__) +# include + #elif defined( __IBMCPP__ ) && defined( __powerpc ) # include From cf769b94a75a3f13ba067371e84aa269144987b5 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 16 Nov 2012 15:05:25 +0000 Subject: [PATCH 128/210] Apply BOOST_NOEXCEPT patch. Refs #7523. [SVN r81368] --- .../boost/smart_ptr/detail/operator_bool.hpp | 10 +-- .../smart_ptr/enable_shared_from_this.hpp | 8 +- include/boost/smart_ptr/intrusive_ptr.hpp | 12 +-- .../boost/smart_ptr/make_shared_object.hpp | 10 +-- include/boost/smart_ptr/scoped_array.hpp | 12 +-- include/boost/smart_ptr/scoped_ptr.hpp | 10 +-- include/boost/smart_ptr/shared_array.hpp | 38 +++++----- include/boost/smart_ptr/shared_ptr.hpp | 76 ++++++++++--------- include/boost/smart_ptr/weak_ptr.hpp | 41 +++++----- 9 files changed, 112 insertions(+), 105 deletions(-) diff --git a/include/boost/smart_ptr/detail/operator_bool.hpp b/include/boost/smart_ptr/detail/operator_bool.hpp index 1d5be11..e38593f 100644 --- a/include/boost/smart_ptr/detail/operator_bool.hpp +++ b/include/boost/smart_ptr/detail/operator_bool.hpp @@ -8,7 +8,7 @@ #if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__) - operator bool () const + operator bool () const BOOST_NOEXCEPT { return px != 0; } @@ -21,7 +21,7 @@ typedef void (*unspecified_bool_type)( this_type*** ); - operator unspecified_bool_type() const // never throws + operator unspecified_bool_type() const BOOST_NOEXCEPT { return px == 0? 0: unspecified_bool; } @@ -33,7 +33,7 @@ typedef element_type * (this_type::*unspecified_bool_type)() const; - operator unspecified_bool_type() const // never throws + operator unspecified_bool_type() const BOOST_NOEXCEPT { return px == 0? 0: &this_type::get; } @@ -42,7 +42,7 @@ typedef element_type * this_type::*unspecified_bool_type; - operator unspecified_bool_type() const // never throws + operator unspecified_bool_type() const BOOST_NOEXCEPT { return px == 0? 0: &this_type::px; } @@ -50,7 +50,7 @@ #endif // operator! is redundant, but some compilers need it - bool operator! () const // never throws + bool operator! () const BOOST_NOEXCEPT { return px == 0; } diff --git a/include/boost/smart_ptr/enable_shared_from_this.hpp b/include/boost/smart_ptr/enable_shared_from_this.hpp index f7b1445..3230f02 100644 --- a/include/boost/smart_ptr/enable_shared_from_this.hpp +++ b/include/boost/smart_ptr/enable_shared_from_this.hpp @@ -25,20 +25,20 @@ template class enable_shared_from_this { protected: - enable_shared_from_this() + enable_shared_from_this() BOOST_NOEXCEPT { } - enable_shared_from_this(enable_shared_from_this const &) + enable_shared_from_this(enable_shared_from_this const &) BOOST_NOEXCEPT { } - enable_shared_from_this & operator=(enable_shared_from_this const &) + enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_NOEXCEPT { return *this; } - ~enable_shared_from_this() + ~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr newer throws, so this call also must not throw { } diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index a575223..01e2429 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -58,7 +58,7 @@ public: typedef T element_type; - intrusive_ptr(): px( 0 ) + intrusive_ptr() BOOST_NOEXCEPT : px( 0 ) { } @@ -110,12 +110,12 @@ public: #if defined( BOOST_HAS_RVALUE_REFS ) - intrusive_ptr(intrusive_ptr && rhs): px( rhs.px ) + intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px ) { rhs.px = 0; } - intrusive_ptr & operator=(intrusive_ptr && rhs) + intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT { this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this); return *this; @@ -135,7 +135,7 @@ public: return *this; } - void reset() + void reset() BOOST_NOEXCEPT { this_type().swap( *this ); } @@ -145,7 +145,7 @@ public: this_type( rhs ).swap( *this ); } - T * get() const + T * get() const BOOST_NOEXCEPT { return px; } @@ -165,7 +165,7 @@ public: // implicit conversion to "bool" #include - void swap(intrusive_ptr & rhs) + void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT { T * tmp = px; px = rhs.px; diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp index 3872909..3f4cac7 100644 --- a/include/boost/smart_ptr/make_shared_object.hpp +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -67,12 +67,12 @@ private: public: - sp_ms_deleter(): initialized_( false ) + sp_ms_deleter() BOOST_NOEXCEPT : initialized_( false ) { } // optimization: do not copy storage_ - sp_ms_deleter( sp_ms_deleter const & ): initialized_( false ) + sp_ms_deleter( sp_ms_deleter const & ) BOOST_NOEXCEPT : initialized_( false ) { } @@ -86,12 +86,12 @@ public: destroy(); } - void * address() + void * address() BOOST_NOEXCEPT { return storage_.data_; } - void set_initialized() + void set_initialized() BOOST_NOEXCEPT { initialized_ = true; } @@ -99,7 +99,7 @@ public: #if defined( BOOST_HAS_RVALUE_REFS ) -template< class T > T&& sp_forward( T & t ) +template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT { return static_cast< T&& >( t ); } diff --git a/include/boost/smart_ptr/scoped_array.hpp b/include/boost/smart_ptr/scoped_array.hpp index 483460f..83352e2 100644 --- a/include/boost/smart_ptr/scoped_array.hpp +++ b/include/boost/smart_ptr/scoped_array.hpp @@ -53,7 +53,7 @@ public: typedef T element_type; - explicit scoped_array( T * p = 0 ) : px( p ) // never throws + explicit scoped_array( T * p = 0 ) BOOST_NOEXCEPT : px( p ) { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_array_constructor_hook( px ); @@ -68,20 +68,20 @@ public: boost::checked_array_delete( px ); } - void reset(T * p = 0) // never throws + void reset(T * p = 0) // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) { BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors this_type(p).swap(*this); } - T & operator[](std::ptrdiff_t i) const // never throws + T & operator[](std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) { BOOST_ASSERT( px != 0 ); BOOST_ASSERT( i >= 0 ); return px[i]; } - T * get() const // never throws + T * get() const BOOST_NOEXCEPT { return px; } @@ -89,7 +89,7 @@ public: // implicit conversion to "bool" #include - void swap(scoped_array & b) // never throws + void swap(scoped_array & b) BOOST_NOEXCEPT { T * tmp = b.px; b.px = px; @@ -97,7 +97,7 @@ public: } }; -template inline void swap(scoped_array & a, scoped_array & b) // never throws +template inline void swap(scoped_array & a, scoped_array & b) BOOST_NOEXCEPT { a.swap(b); } diff --git a/include/boost/smart_ptr/scoped_ptr.hpp b/include/boost/smart_ptr/scoped_ptr.hpp index df479e5..3ccf697 100644 --- a/include/boost/smart_ptr/scoped_ptr.hpp +++ b/include/boost/smart_ptr/scoped_ptr.hpp @@ -63,7 +63,7 @@ public: #ifndef BOOST_NO_AUTO_PTR - explicit scoped_ptr( std::auto_ptr p ): px( p.release() ) // never throws + explicit scoped_ptr( std::auto_ptr p ) BOOST_NOEXCEPT : px( p.release() ) { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_scalar_constructor_hook( px ); @@ -98,7 +98,7 @@ public: return px; } - T * get() const // never throws + T * get() const BOOST_NOEXCEPT { return px; } @@ -106,7 +106,7 @@ public: // implicit conversion to "bool" #include - void swap(scoped_ptr & b) // never throws + void swap(scoped_ptr & b) BOOST_NOEXCEPT { T * tmp = b.px; b.px = px; @@ -114,14 +114,14 @@ public: } }; -template inline void swap(scoped_ptr & a, scoped_ptr & b) // never throws +template inline void swap(scoped_ptr & a, scoped_ptr & b) BOOST_NOEXCEPT { a.swap(b); } // get_pointer(p) is a generic way to say p.get() -template inline T * get_pointer(scoped_ptr const & p) +template inline T * get_pointer(scoped_ptr const & p) BOOST_NOEXCEPT { return p.get(); } diff --git a/include/boost/smart_ptr/shared_array.hpp b/include/boost/smart_ptr/shared_array.hpp index 3e79582..ac64099 100644 --- a/include/boost/smart_ptr/shared_array.hpp +++ b/include/boost/smart_ptr/shared_array.hpp @@ -56,7 +56,7 @@ public: typedef T element_type; - shared_array(): px( 0 ), pn() // never throws + shared_array() BOOST_NOEXCEPT : px( 0 ), pn() { } @@ -90,11 +90,11 @@ public: // ... except in C++0x, move disables the implicit copy - shared_array( shared_array const & r ): px( r.px ), pn( r.pn ) // never throws + shared_array( shared_array const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) { } - shared_array( shared_array && r ): px( r.px ), pn() // never throws + shared_array( shared_array && r ) BOOST_NOEXCEPT : px( r.px ), pn() { pn.swap( r.pn ); r.px = 0; @@ -114,7 +114,7 @@ public: shared_array( shared_array const & r ) #endif - : px( r.px ), pn( r.pn ) // never throws + BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) // never throws { boost::detail::sp_assert_convertible< Y[], T[] >(); } @@ -122,13 +122,13 @@ public: // aliasing template< class Y > - shared_array( shared_array const & r, element_type * p ): px( p ), pn( r.pn ) // never throws + shared_array( shared_array const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn ) { } // assignment - shared_array & operator=( shared_array const & r ) // never throws + shared_array & operator=( shared_array const & r ) BOOST_NOEXCEPT { this_type( r ).swap( *this ); return *this; @@ -137,7 +137,7 @@ public: #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400) template - shared_array & operator=( shared_array const & r ) // never throws + shared_array & operator=( shared_array const & r ) BOOST_NOEXCEPT { this_type( r ).swap( *this ); return *this; @@ -147,14 +147,14 @@ public: #if defined( BOOST_HAS_RVALUE_REFS ) - shared_array & operator=( shared_array && r ) // never throws + shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT { this_type( static_cast< shared_array && >( r ) ).swap( *this ); return *this; } template - shared_array & operator=( shared_array && r ) // never throws + shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT { this_type( static_cast< shared_array && >( r ) ).swap( *this ); return *this; @@ -162,7 +162,7 @@ public: #endif - void reset() // never throws + void reset() BOOST_NOEXCEPT { this_type().swap( *this ); } @@ -188,14 +188,14 @@ public: this_type( r, p ).swap( *this ); } - T & operator[] (std::ptrdiff_t i) const // never throws + T & operator[] (std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) { BOOST_ASSERT(px != 0); BOOST_ASSERT(i >= 0); return px[i]; } - T * get() const // never throws + T * get() const BOOST_NOEXCEPT { return px; } @@ -203,17 +203,17 @@ public: // implicit conversion to "bool" #include - bool unique() const // never throws + bool unique() const BOOST_NOEXCEPT { return pn.unique(); } - long use_count() const // never throws + long use_count() const BOOST_NOEXCEPT { return pn.use_count(); } - void swap(shared_array & other) // never throws + void swap(shared_array & other) BOOST_NOEXCEPT { std::swap(px, other.px); pn.swap(other.pn); @@ -233,22 +233,22 @@ private: }; // shared_array -template inline bool operator==(shared_array const & a, shared_array const & b) // never throws +template inline bool operator==(shared_array const & a, shared_array const & b) BOOST_NOEXCEPT { return a.get() == b.get(); } -template inline bool operator!=(shared_array const & a, shared_array const & b) // never throws +template inline bool operator!=(shared_array const & a, shared_array const & b) BOOST_NOEXCEPT { return a.get() != b.get(); } -template inline bool operator<(shared_array const & a, shared_array const & b) // never throws +template inline bool operator<(shared_array const & a, shared_array const & b) BOOST_NOEXCEPT { return std::less()(a.get(), b.get()); } -template void swap(shared_array & a, shared_array & b) // never throws +template void swap(shared_array & a, shared_array & b) BOOST_NOEXCEPT { a.swap(b); } diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index d9cc6f2..a696093 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -324,7 +324,7 @@ public: typedef typename boost::detail::sp_element< T >::type element_type; - shared_ptr(): px( 0 ), pn() // never throws in 1.30+ + shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+ { } @@ -358,7 +358,7 @@ public: // ... except in C++0x, move disables the implicit copy - shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws + shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) { } @@ -374,7 +374,8 @@ public: } template - shared_ptr( weak_ptr const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws + shared_ptr( weak_ptr const & r, boost::detail::sp_nothrow_tag ) + BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) { if( !pn.empty() ) { @@ -392,24 +393,26 @@ public: shared_ptr( shared_ptr const & r ) #endif - : px( r.px ), pn( r.pn ) // never throws + BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) { boost::detail::sp_assert_convertible< Y, T >(); } // aliasing template< class Y > - shared_ptr( shared_ptr const & r, element_type * p ): px( p ), pn( r.pn ) // never throws + shared_ptr( shared_ptr const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn ) { } template - shared_ptr(shared_ptr const & r, boost::detail::static_cast_tag): px(static_cast(r.px)), pn(r.pn) + shared_ptr(shared_ptr const & r, boost::detail::static_cast_tag) + BOOST_NOEXCEPT : px(static_cast(r.px)), pn(r.pn) { } template - shared_ptr(shared_ptr const & r, boost::detail::const_cast_tag): px(const_cast(r.px)), pn(r.pn) + shared_ptr(shared_ptr const & r, boost::detail::const_cast_tag) + BOOST_NOEXCEPT : px(const_cast(r.px)), pn(r.pn) { } @@ -480,7 +483,7 @@ public: // assignment - shared_ptr & operator=( shared_ptr const & r ) // never throws + shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT { this_type(r).swap(*this); return *this; @@ -489,7 +492,7 @@ public: #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400) template - shared_ptr & operator=(shared_ptr const & r) // never throws + shared_ptr & operator=(shared_ptr const & r) BOOST_NOEXCEPT { this_type(r).swap(*this); return *this; @@ -523,7 +526,7 @@ public: #if defined( BOOST_HAS_RVALUE_REFS ) - shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws + shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn() { pn.swap( r.pn ); r.px = 0; @@ -539,7 +542,7 @@ public: shared_ptr( shared_ptr && r ) #endif - : px( r.px ), pn() // never throws + BOOST_NOEXCEPT : px( r.px ), pn() { boost::detail::sp_assert_convertible< Y, T >(); @@ -547,14 +550,14 @@ public: r.px = 0; } - shared_ptr & operator=( shared_ptr && r ) // never throws + shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT { this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); return *this; } template - shared_ptr & operator=( shared_ptr && r ) // never throws + shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT { this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); return *this; @@ -562,7 +565,7 @@ public: #endif - void reset() // never throws in 1.30+ + void reset() BOOST_NOEXCEPT // never throws in 1.30+ { this_type().swap(*this); } @@ -587,20 +590,23 @@ public: { this_type( r, p ).swap( *this ); } - - typename boost::detail::sp_dereference< T >::type operator* () const // never throws + + // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) + typename boost::detail::sp_dereference< T >::type operator* () const { BOOST_ASSERT( px != 0 ); return *px; } - - typename boost::detail::sp_member_access< T >::type operator-> () const // never throws + + // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) + typename boost::detail::sp_member_access< T >::type operator-> () const { BOOST_ASSERT( px != 0 ); return px; } - - typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const // never throws + + // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) + typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const { BOOST_ASSERT( px != 0 ); BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) ); @@ -608,7 +614,7 @@ public: return px[ i ]; } - element_type * get() const // never throws + element_type * get() const BOOST_NOEXCEPT { return px; } @@ -616,28 +622,28 @@ public: // implicit conversion to "bool" #include - bool unique() const // never throws + bool unique() const BOOST_NOEXCEPT { return pn.unique(); } - long use_count() const // never throws + long use_count() const BOOST_NOEXCEPT { return pn.use_count(); } - void swap( shared_ptr & other ) // never throws + void swap( shared_ptr & other ) BOOST_NOEXCEPT { std::swap(px, other.px); pn.swap(other.pn); } - template bool owner_before( shared_ptr const & rhs ) const + template bool owner_before( shared_ptr const & rhs ) const BOOST_NOEXCEPT { return pn < rhs.pn; } - template bool owner_before( weak_ptr const & rhs ) const + template bool owner_before( weak_ptr const & rhs ) const BOOST_NOEXCEPT { return pn < rhs.pn; } @@ -647,7 +653,7 @@ public: return pn.get_deleter( ti ); } - bool _internal_equiv( shared_ptr const & r ) const + bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT { return px == r.px && pn == r.pn; } @@ -670,12 +676,12 @@ private: }; // shared_ptr -template inline bool operator==(shared_ptr const & a, shared_ptr const & b) +template inline bool operator==(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT { return a.get() == b.get(); } -template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) +template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT { return a.get() != b.get(); } @@ -684,19 +690,19 @@ template inline bool operator!=(shared_ptr const & a, share // Resolve the ambiguity between our op!= and the one in rel_ops -template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) +template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT { return a.get() != b.get(); } #endif -template inline bool operator<(shared_ptr const & a, shared_ptr const & b) +template inline bool operator<(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT { return a.owner_before( b ); } -template inline void swap(shared_ptr & a, shared_ptr & b) +template inline void swap(shared_ptr & a, shared_ptr & b) BOOST_NOEXCEPT { a.swap(b); } @@ -741,7 +747,7 @@ template shared_ptr shared_polymorphic_downcast(shared_ptr< // get_pointer() enables boost::mem_fn to recognize shared_ptr -template inline T * get_pointer(shared_ptr const & p) +template inline T * get_pointer(shared_ptr const & p) BOOST_NOEXCEPT { return p.get(); } @@ -854,7 +860,7 @@ template D * get_deleter(shared_ptr const & p) #if !defined(BOOST_SP_NO_ATOMIC_ACCESS) -template inline bool atomic_is_lock_free( shared_ptr const * /*p*/ ) +template inline bool atomic_is_lock_free( shared_ptr const * /*p*/ ) BOOST_NOEXCEPT { return false; } @@ -933,7 +939,7 @@ template inline bool atomic_compare_exchange_explicit( shared_ptr * template< class T > struct hash; -template< class T > std::size_t hash_value( boost::shared_ptr const & p ) +template< class T > std::size_t hash_value( boost::shared_ptr const & p ) BOOST_NOEXCEPT { return boost::hash< T* >()( p.get() ); } diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index 62b6afe..59cdd45 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -31,7 +31,7 @@ public: typedef typename boost::detail::sp_element< T >::type element_type; - weak_ptr(): px(0), pn() // never throws in 1.30+ + weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+ { } @@ -41,11 +41,11 @@ public: // ... except in C++0x, move disables the implicit copy - weak_ptr( weak_ptr const & r ): px( r.px ), pn( r.pn ) // never throws + weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) { } - weak_ptr & operator=( weak_ptr const & r ) // never throws + weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT { px = r.px; pn = r.pn; @@ -81,7 +81,7 @@ public: weak_ptr( weak_ptr const & r ) #endif - : px(r.lock().get()), pn(r.pn) // never throws + BOOST_NOEXCEPT : px(r.lock().get()), pn(r.pn) { boost::detail::sp_assert_convertible< Y, T >(); } @@ -98,20 +98,21 @@ public: weak_ptr( weak_ptr && r ) #endif - : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws + BOOST_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) { boost::detail::sp_assert_convertible< Y, T >(); r.px = 0; } // for better efficiency in the T == Y case - weak_ptr( weak_ptr && r ): px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws + weak_ptr( weak_ptr && r ) + BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) { r.px = 0; } // for better efficiency in the T == Y case - weak_ptr & operator=( weak_ptr && r ) // never throws + weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT { this_type( static_cast< weak_ptr && >( r ) ).swap( *this ); return *this; @@ -130,7 +131,7 @@ public: weak_ptr( shared_ptr const & r ) #endif - : px( r.px ), pn( r.pn ) // never throws + BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) { boost::detail::sp_assert_convertible< Y, T >(); } @@ -138,7 +139,7 @@ public: #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) template - weak_ptr & operator=( weak_ptr const & r ) // never throws + weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT { boost::detail::sp_assert_convertible< Y, T >(); @@ -151,7 +152,7 @@ public: #if defined( BOOST_HAS_RVALUE_REFS ) template - weak_ptr & operator=( weak_ptr && r ) + weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT { this_type( static_cast< weak_ptr && >( r ) ).swap( *this ); return *this; @@ -160,7 +161,7 @@ public: #endif template - weak_ptr & operator=( shared_ptr const & r ) // never throws + weak_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT { boost::detail::sp_assert_convertible< Y, T >(); @@ -172,17 +173,17 @@ public: #endif - shared_ptr lock() const // never throws + shared_ptr lock() const BOOST_NOEXCEPT { return shared_ptr( *this, boost::detail::sp_nothrow_tag() ); } - long use_count() const // never throws + long use_count() const BOOST_NOEXCEPT { return pn.use_count(); } - bool expired() const // never throws + bool expired() const BOOST_NOEXCEPT { return pn.use_count() == 0; } @@ -192,12 +193,12 @@ public: return pn.empty(); } - void reset() // never throws in 1.30+ + void reset() BOOST_NOEXCEPT // never throws in 1.30+ { this_type().swap(*this); } - void swap(this_type & other) // never throws + void swap(this_type & other) BOOST_NOEXCEPT { std::swap(px, other.px); pn.swap(other.pn); @@ -210,12 +211,12 @@ public: pn = r.pn; } - template bool owner_before( weak_ptr const & rhs ) const + template bool owner_before( weak_ptr const & rhs ) const BOOST_NOEXCEPT { return pn < rhs.pn; } - template bool owner_before( shared_ptr const & rhs ) const + template bool owner_before( shared_ptr const & rhs ) const BOOST_NOEXCEPT { return pn < rhs.pn; } @@ -237,12 +238,12 @@ private: }; // weak_ptr -template inline bool operator<(weak_ptr const & a, weak_ptr const & b) +template inline bool operator<(weak_ptr const & a, weak_ptr const & b) BOOST_NOEXCEPT { return a.owner_before( b ); } -template void swap(weak_ptr & a, weak_ptr & b) +template void swap(weak_ptr & a, weak_ptr & b) BOOST_NOEXCEPT { a.swap(b); } From 94b6487ca16ffcd8eeda7c066b510db0e80fae84 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 17 Nov 2012 16:21:41 +0000 Subject: [PATCH 129/210] Replace std::forward with detail::sp_forward. [SVN r81399] --- .../boost/smart_ptr/allocate_shared_array.hpp | 5 ++- include/boost/smart_ptr/detail/sp_forward.hpp | 39 +++++++++++++++++++ include/boost/smart_ptr/make_shared_array.hpp | 5 ++- .../boost/smart_ptr/make_shared_object.hpp | 10 +---- 4 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 include/boost/smart_ptr/detail/sp_forward.hpp diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 904902c..3c45b1c 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif @@ -51,7 +52,7 @@ namespace boost { detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, std::forward(args)...); + d2->construct(p2, n1, boost::detail::sp_forward(args)...); return shared_ptr(s1, p1); } template @@ -68,7 +69,7 @@ namespace boost { detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, std::forward(args)...); + d2->construct(p2, n1, boost::detail::sp_forward(args)...); return shared_ptr(s1, p1); } #endif diff --git a/include/boost/smart_ptr/detail/sp_forward.hpp b/include/boost/smart_ptr/detail/sp_forward.hpp new file mode 100644 index 0000000..25c4d48 --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_forward.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_forward.hpp +// +// Copyright 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 + +#include + +namespace boost +{ + +namespace detail +{ + +#if defined( BOOST_HAS_RVALUE_REFS ) + +template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT +{ + return static_cast< T&& >( t ); +} + +#endif + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 70083b1..110ee34 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif @@ -51,7 +52,7 @@ namespace boost { detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, std::forward(args)...); + d2->construct(p2, n1, boost::detail::sp_forward(args)...); return shared_ptr(s1, p1); } template @@ -68,7 +69,7 @@ namespace boost { detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, std::forward(args)...); + d2->construct(p2, n1, boost::detail::sp_forward(args)...); 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 index 3f4cac7..1a9d769 100644 --- a/include/boost/smart_ptr/make_shared_object.hpp +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -97,15 +98,6 @@ public: } }; -#if defined( BOOST_HAS_RVALUE_REFS ) - -template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT -{ - return static_cast< T&& >( t ); -} - -#endif - template< class T > struct sp_if_not_array { typedef boost::shared_ptr< T > type; From 79b229adcd9fb708f9415682abe57db38de58fa6 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 17 Nov 2012 22:20:32 +0000 Subject: [PATCH 130/210] Cosmetic changes in make_shared_array.hpp and allocate_shared_array.hpp [SVN r81407] --- include/boost/smart_ptr/allocate_shared_array.hpp | 4 ++-- include/boost/smart_ptr/make_shared_array.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 3c45b1c..cc894e7 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -52,7 +52,7 @@ namespace boost { detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, boost::detail::sp_forward(args)...); + d2->construct(p2, n1, detail::sp_forward(args)...); return shared_ptr(s1, p1); } template @@ -69,7 +69,7 @@ namespace boost { detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, boost::detail::sp_forward(args)...); + d2->construct(p2, n1, detail::sp_forward(args)...); return shared_ptr(s1, p1); } #endif diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 110ee34..8422150 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -52,7 +52,7 @@ namespace boost { detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, boost::detail::sp_forward(args)...); + d2->construct(p2, n1, detail::sp_forward(args)...); return shared_ptr(s1, p1); } template @@ -69,7 +69,7 @@ namespace boost { detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, boost::detail::sp_forward(args)...); + d2->construct(p2, n1, detail::sp_forward(args)...); return shared_ptr(s1, p1); } #endif From 3f458c68f45f53487486134d13500d0a122dfc6e Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 18 Nov 2012 01:51:46 +0000 Subject: [PATCH 131/210] Documentation of make_shared_array: Minor corrections [SVN r81408] --- make_shared_array.html | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/make_shared_array.html b/make_shared_array.html index 9c46926..f1e08bc 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -41,7 +41,7 @@ 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); + 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); @@ -74,7 +74,7 @@ #endif template<typename T> - shared_ptr<T> make_shared_noinit(size_t size); + shared_ptr<T[]> make_shared_noinit(size_t size); template<typename T> shared_ptr<T[N]> make_shared_noinit(); @@ -123,15 +123,18 @@ template<typename T, typename A, typename... Args> constructor of T for each array element.

    Example

    -
    boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size);
    -boost::shared_ptr<point[5]> a2 = boost::make_shared<point[5]>(x, y);
    -boost::shared_ptr<int[5]> a3 = boost::make_shared<int[5]>();
    +    

    An example of each overload of make_shared for arrays:

    +
    +
    boost::shared_ptr<point[]> a1 = boost::make_shared<point[]>(size);
    +boost::shared_ptr<point[]> a2 = boost::make_shared<point[]>(size, x, y);
    +boost::shared_ptr<point[5]> a3 = boost::make_shared<point[5]>(x, y);
     boost::shared_ptr<int[]> a4 = boost::make_shared<int[]>({1, 2, 3});
     boost::shared_ptr<int[3]> a5 = boost::make_shared<int[3]>({1, 2, 3});
     boost::shared_ptr<int[][3]> a6 = boost::make_shared<int[][3]>(size, {1, 2, 3});
     boost::shared_ptr<int[5][3]> a7 = boost::make_shared<int[5][3]>({1, 2, 3});
     boost::shared_ptr<int[]> a8 = boost::make_shared_noinit<int[]>(size);
     boost::shared_ptr<int[5]> a9 = boost::make_shared_noinit<int[5]>();
    +

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

    Copyright 2012 Glen Fernandes. Distributed under the Boost From ddfcc5f4170f8d0c89bfbba29ebac5994c9061a9 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 18 Nov 2012 02:51:06 +0000 Subject: [PATCH 132/210] Make make_shared_array.hpp and allocate_shared_array.hpp consistent with namespace qualification in rest of smart_ptr. [SVN r81409] --- .../boost/smart_ptr/allocate_shared_array.hpp | 160 +++++++------- .../detail/allocate_array_helper.hpp | 4 +- .../smart_ptr/detail/make_array_helper.hpp | 2 +- include/boost/smart_ptr/make_shared_array.hpp | 200 +++++++++--------- 4 files changed, 183 insertions(+), 183 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index cc894e7..e6fa081 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -13,154 +13,154 @@ #include #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 + inline typename boost::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; + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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; + std::size_t n1 = size * boost::detail::array_total::size; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct(p2, n1); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) template - inline typename detail::sp_if_array::type + inline typename boost::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; + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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; + std::size_t n1 = size * boost::detail::array_total::size; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct(p2, n1, detail::sp_forward(args)...); - return shared_ptr(s1, p1); + d2 = get_deleter >(s1); + d2->construct(p2, n1, boost::detail::sp_forward(args)...); + return boost::shared_ptr(s1, p1); } template - inline typename detail::sp_if_size_array::type + inline typename boost::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; + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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; + std::size_t n1 = boost::detail::array_total::size; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct(p2, n1, detail::sp_forward(args)...); - return shared_ptr(s1, p1); + d2 = get_deleter >(s1); + d2->construct(p2, n1, boost::detail::sp_forward(args)...); + return boost::shared_ptr(s1, p1); } #endif #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template - inline typename detail::sp_if_array::type + inline typename boost::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; + std::initializer_list::type> list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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; + std::size_t n1 = list.size() * boost::detail::array_total::size; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } template - inline typename detail::sp_if_size_array::type + inline typename boost::detail::sp_if_size_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; + std::initializer_list::type> list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == detail::array_size::size); + BOOST_ASSERT(list.size() == boost::detail::array_size::size); 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; + std::size_t n1 = boost::detail::array_total::size; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } template - inline typename detail::sp_if_array::type + inline typename boost::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; + std::initializer_list::type> list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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 n0 = boost::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; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3, n0); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } template - inline typename detail::sp_if_size_array::type + inline typename boost::detail::sp_if_size_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; + std::initializer_list::type> list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == detail::array_size::size); + BOOST_ASSERT(list.size() == boost::detail::array_size::size); T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - std::size_t n0 = detail::array_total::size; - 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; + std::size_t n0 = boost::detail::array_total::size; + std::size_t n1 = boost::detail::array_total::size; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3, n0); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } #endif } diff --git a/include/boost/smart_ptr/detail/allocate_array_helper.hpp b/include/boost/smart_ptr/detail/allocate_array_helper.hpp index bfb4dec..dee34ad 100644 --- a/include/boost/smart_ptr/detail/allocate_array_helper.hpp +++ b/include/boost/smart_ptr/detail/allocate_array_helper.hpp @@ -57,7 +57,7 @@ namespace boost { return allocator.max_size(); } pointer allocate(size_type count, const void* value = 0) { - std::size_t a1 = alignment_of::value; + std::size_t a1 = boost::alignment_of::value; std::size_t n1 = count * sizeof(Y) + a1 - 1; char* p1 = A3(allocator).allocate(n1 + size, value); char* p2 = p1 + n1; @@ -68,7 +68,7 @@ namespace boost { return reinterpret_cast(p1); } void deallocate(pointer memory, size_type count) { - std::size_t a1 = alignment_of::value; + std::size_t a1 = boost::alignment_of::value; std::size_t n1 = count * sizeof(Y) + a1 - 1; char* p1 = reinterpret_cast(memory); A3(allocator).deallocate(p1, n1 + size); diff --git a/include/boost/smart_ptr/detail/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp index 96fa3f9..4d92be3 100644 --- a/include/boost/smart_ptr/detail/make_array_helper.hpp +++ b/include/boost/smart_ptr/detail/make_array_helper.hpp @@ -52,7 +52,7 @@ namespace boost { return static_cast(-1) / sizeof(Y); } pointer allocate(size_type count, const void* = 0) { - std::size_t a1 = alignment_of::value; + std::size_t a1 = boost::alignment_of::value; std::size_t n1 = count * sizeof(Y) + a1 - 1; void* p1 = ::operator new(n1 + size); char* p2 = static_cast(p1) + n1; diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 8422150..36e0ddd 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -13,186 +13,186 @@ #include #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 + inline typename boost::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; + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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; + std::size_t n1 = size * boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct(p2, n1); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) template - inline typename detail::sp_if_array::type + inline typename boost::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; + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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; + std::size_t n1 = size * boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct(p2, n1, detail::sp_forward(args)...); - return shared_ptr(s1, p1); + d2 = get_deleter >(s1); + d2->construct(p2, n1, boost::detail::sp_forward(args)...); + return boost::shared_ptr(s1, p1); } template - inline typename detail::sp_if_size_array::type + inline typename boost::detail::sp_if_size_array::type make_shared(Args&&... args) { - typedef typename detail::array_inner::type T1; - typedef typename detail::array_base::type T2; + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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; + std::size_t n1 = boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct(p2, n1, detail::sp_forward(args)...); - return shared_ptr(s1, p1); + d2 = get_deleter >(s1); + d2->construct(p2, n1, boost::detail::sp_forward(args)...); + return boost::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; + inline typename boost::detail::sp_if_array::type + make_shared(std::initializer_list::type> list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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; + std::size_t n1 = list.size() * boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } template - inline typename detail::sp_if_size_array::type - make_shared(std::initializer_list::type> list) { - typedef typename detail::array_inner::type T1; - typedef typename detail::array_base::type T2; + inline typename boost::detail::sp_if_size_array::type + make_shared(std::initializer_list::type> list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == detail::array_size::size); + BOOST_ASSERT(list.size() == boost::detail::array_size::size); 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; + std::size_t n1 = boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } template - inline typename detail::sp_if_array::type + inline typename boost::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; + std::initializer_list::type> list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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 n0 = boost::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; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3, n0); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } template - inline typename detail::sp_if_size_array::type - make_shared(std::initializer_list::type> list) { - typedef typename detail::array_inner::type T1; - typedef typename detail::array_base::type T2; + inline typename boost::detail::sp_if_size_array::type + make_shared(std::initializer_list::type> list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == detail::array_size::size); + BOOST_ASSERT(list.size() == boost::detail::array_size::size); T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - std::size_t n0 = detail::array_total::size; - 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; + std::size_t n0 = boost::detail::array_total::size; + std::size_t n1 = boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3, n0); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } #endif template - inline typename detail::sp_if_array::type + inline typename boost::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; + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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; + std::size_t n1 = size * boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_noinit(p2, n1); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } template - inline typename detail::sp_if_size_array::type + inline typename boost::detail::sp_if_size_array::type make_shared_noinit() { - typedef typename detail::array_inner::type T1; - typedef typename detail::array_base::type T2; + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::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; + std::size_t n1 = boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_noinit(p2, n1); - return shared_ptr(s1, p1); + return boost::shared_ptr(s1, p1); } } From b4594eab3b5096075e98f5b1138cb8b6c4fe2aad Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 19 Nov 2012 08:08:27 +0000 Subject: [PATCH 133/210] Update smart_ptr.htm with link to make_shared_array.htm which lists the many overloads of make_shared and allocate_shared for arrays. [SVN r81419] --- smart_ptr.htm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/smart_ptr.htm b/smart_ptr.htm index 92ad2be..10fe5d6 100644 --- a/smart_ptr.htm +++ b/smart_ptr.htm @@ -70,6 +70,11 @@ <boost/make_shared.hpp> Efficient creation of shared_ptr objects. + + make_shared and allocate_shared for arrays + <boost/make_shared.hpp> + Efficient creation of shared_ptr arrays. +

    A test program, smart_ptr_test.cpp, is @@ -126,6 +131,12 @@

    Functions which destroy objects of the pointed to type are prohibited from throwing exceptions by the common requirements.

    History and Acknowledgements

    +

    November 2012. Glen Fernandes provided implementations of make_shared + and allocate_shared for arrays. They achieve a single allocation for an + array that can be initialized with constructor arguments or initializer lists + as well as overloads for default initialization and no value initialization. + See the make_shared and allocate_shared for + arrays page for more information.

    January 2002. Peter Dimov reworked all four classes, adding features, fixing bugs, and splitting them into four separate headers, and added weak_ptr. See the compatibility page for a summary of the From 392885a56a61c421671ca27c891272cda950b23b Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 20 Nov 2012 03:00:02 +0000 Subject: [PATCH 134/210] Update documentation for make_shared and allocate_shared array forms. [SVN r81430] --- make_shared_array.html | 79 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/make_shared_array.html b/make_shared_array.html index f1e08bc..f2dbe40 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -12,12 +12,14 @@ Synopsis
    Free Functions
    Example
    + History

    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.

    +

    Originally the Boost function templates make_shared and + allocate_shared were for efficient allocation of single + objects only. There was a need to have efficient, single, allocation of + arrays. One criticism of shared_array was + always the lack of a make_shared utility + which ensures only a single allocation for an array.

    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, @@ -55,10 +57,10 @@ 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); + shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T[N]> list); template<typename T, typename... Args> - shared_ptr<T[M][N]> make_shared(initializer_list<T> list); + shared_ptr<T[M][N]> make_shared(initializer_list<T[N]> list); template<typename T, typename A, typename... Args> shared_ptr<T[]> allocate_shared(const A& allocator, initializer_list<T> list); @@ -67,10 +69,10 @@ 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); + shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T[N]> list); template<typename T, typename A, typename... Args> - shared_ptr<T[M][N]> allocate_shared(const A& allocator, initializer_list<T> list); + shared_ptr<T[M][N]> allocate_shared(const A& allocator, initializer_list<T[N]> list); #endif template<typename T> @@ -81,9 +83,9 @@ }

    Free Functions

    template<typename T, typename... Args>
    -    shared_ptr<T> make_shared(size_t size, Args&&... 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);
    + shared_ptr<T[]> allocate_shared(const A& allocator, size_t size, Args&&... args);

    Requires: The expression new(pointer) T(forward<Args>(args)...), where @@ -122,6 +124,58 @@ template<typename T, typename A, typename... Args> take any constructor arguments. These overloads invoke the default constructor of T for each array element.

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

    Description: These overloads of the utilities above are for a + fixed size array.

    +
    +
    template<typename T, typename... Args>
    +    shared_ptr<T[]> make_shared(initializer_list<T> list);
    +template<typename T, typename A, typename... Args>
    +    shared_ptr<T[]> allocate_shared(const A& allocator, initializer_list<T> list);
    +
    +

    Description: These overloads initialize the array elements + from the initializer list.

    +
    +
    template<typename T, typename... Args>
    +    shared_ptr<T[N]> make_shared(initializer_list<T> list);
    +template<typename T, typename A, typename... Args>
    +    shared_ptr<T[N]> allocate_shared(const A& allocator, initializer_list<T> list);
    +
    +

    Description: These overloads of the utilities above are for a + fixed size array.

    +
    +
    template<typename T, typename... Args>
    +    shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T[N]> list);
    +template<typename T, typename A, typename... Args>
    +    shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T[N]> list);
    +
    +

    Description: These overloads initialize inner array elements + from the initializer list.

    +
    +
    template<typename T, typename... Args>
    +    shared_ptr<T[M][N]> make_shared(initializer_list<T[N]> list);
    +template<typename T, typename A, typename... Args>
    +    shared_ptr<T[M][N]> allocate_shared(const A& allocator, initializer_list<T[N]> list);
    +
    +

    Description: These overloads of the utilities above are for a + fixed size array.

    +
    +
    template<typename T>
    +    shared_ptr<T[]> make_shared_noinit(size_t size);
    +
    +

    Description: This overload does not perform value + initialization of elements.

    +
    +
    template<typename T>
    +    shared_ptr<T[N]> make_shared_noinit();
    +
    +

    Description: This overload of the utility above is used for a + fixed size array.

    +

    Example

    An example of each overload of make_shared for arrays:

    @@ -135,6 +189,9 @@ boost::shared_ptr<int[5][3]> a7 = boost::make_shared<int[5][3]>({1, boost::shared_ptr<int[]> a8 = boost::make_shared_noinit<int[]>(size); boost::shared_ptr<int[5]> a9 = boost::make_shared_noinit<int[5]>();
    +

    History

    +

    November 2012. Glen Fernandes contributed implementations of + make_shared and allocate_shared for arrays.


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

    Copyright 2012 Glen Fernandes. Distributed under the Boost From 98b92fa83a9328e6077c688cec198939a2a98131 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 20 Nov 2012 04:07:58 +0000 Subject: [PATCH 135/210] Minor corrections in make_shared_array.html documentation. [SVN r81431] --- make_shared_array.html | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/make_shared_array.html b/make_shared_array.html index f2dbe40..2c0d5fc 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -34,17 +34,17 @@ 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 @@ -52,32 +52,32 @@ #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[N]> list); - + shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T> list); + template<typename T, typename... Args> - shared_ptr<T[M][N]> make_shared(initializer_list<T[N]> list); + shared_ptr<T[M][N]> make_shared(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[N]> list); - + shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list); + template<typename T, typename A, typename... Args> - shared_ptr<T[M][N]> allocate_shared(const A& allocator, initializer_list<T[N]> list); + shared_ptr<T[M][N]> allocate_shared(const A& allocator, 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(); } @@ -149,17 +149,17 @@ template<typename T, typename A, typename... Args> fixed size array.

    template<typename T, typename... Args>
    -    shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T[N]> list);
    +    shared_ptr<T[][N]> make_shared(size_t size, 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[N]> list);
    + shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list);

    Description: These overloads initialize inner array elements from the initializer list.

    template<typename T, typename... Args>
    -    shared_ptr<T[M][N]> make_shared(initializer_list<T[N]> list);
    +    shared_ptr<T[M][N]> make_shared(initializer_list<T> list);
     template<typename T, typename A, typename... Args>
    -    shared_ptr<T[M][N]> allocate_shared(const A& allocator, initializer_list<T[N]> list);
    + shared_ptr<T[M][N]> allocate_shared(const A& allocator, initializer_list<T> list);

    Description: These overloads of the utilities above are for a fixed size array.

    From 7835914d83b6b5b09e1d9dbf77e2aa4980aaca62 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 20 Nov 2012 15:22:19 +0000 Subject: [PATCH 136/210] Borland fixes. [SVN r81437] --- include/boost/smart_ptr/make_shared_object.hpp | 4 ++++ include/boost/smart_ptr/shared_ptr.hpp | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp index 1a9d769..c6e28aa 100644 --- a/include/boost/smart_ptr/make_shared_object.hpp +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -109,12 +109,16 @@ template< class T > struct sp_if_not_array< T[] > { }; +#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 ) + template< class T, std::size_t N > struct sp_if_not_array< T[N] > { }; #endif +#endif + } // namespace detail #if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index a696093..3fbe00e 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -81,11 +81,15 @@ template< class T > struct sp_element< T[] > typedef T type; }; +#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 ) + template< class T, std::size_t N > struct sp_element< T[N] > { typedef T type; }; +#endif + #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_dereference, return type of operator* @@ -126,11 +130,15 @@ template< class T > struct sp_dereference< T[] > typedef void type; }; +#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 ) + template< class T, std::size_t N > struct sp_dereference< T[N] > { typedef void type; }; +#endif + #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_member_access, return type of operator-> @@ -147,11 +155,15 @@ template< class T > struct sp_member_access< T[] > typedef void type; }; +#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 ) + template< class T, std::size_t N > struct sp_member_access< T[N] > { typedef void type; }; +#endif + #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_array_access, return type of operator[] @@ -168,11 +180,15 @@ template< class T > struct sp_array_access< T[] > typedef T & type; }; +#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 ) + template< class T, std::size_t N > struct sp_array_access< T[N] > { typedef T & type; }; +#endif + #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_extent, for operator[] index check From 97d32745aa66fdb072303533f10a64f9bcdd9f35 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 21 Nov 2012 17:43:48 +0000 Subject: [PATCH 137/210] Update shared_ptr casts. [SVN r81463] --- include/boost/smart_ptr/shared_ptr.hpp | 85 ++++------- test/Jamfile.v2 | 1 + test/sp_array_cast_test.cpp | 202 +++++++++++++++++++++++++ 3 files changed, 229 insertions(+), 59 deletions(-) create mode 100644 test/sp_array_cast_test.cpp diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 3fbe00e..5e13c01 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -62,11 +62,6 @@ class enable_shared_from_raw; namespace detail { -struct static_cast_tag {}; -struct const_cast_tag {}; -struct dynamic_cast_tag {}; -struct polymorphic_cast_tag {}; - // sp_element, element_type template< class T > struct sp_element @@ -420,36 +415,6 @@ public: { } - template - shared_ptr(shared_ptr const & r, boost::detail::static_cast_tag) - BOOST_NOEXCEPT : px(static_cast(r.px)), pn(r.pn) - { - } - - template - shared_ptr(shared_ptr const & r, boost::detail::const_cast_tag) - BOOST_NOEXCEPT : px(const_cast(r.px)), pn(r.pn) - { - } - - template - shared_ptr(shared_ptr const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) - { - if(px == 0) // need to allocate new counter -- the cast failed - { - pn = boost::detail::shared_count(); - } - } - - template - shared_ptr(shared_ptr const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) - { - if(px == 0) - { - boost::throw_exception(std::bad_cast()); - } - } - #ifndef BOOST_NO_AUTO_PTR template @@ -723,42 +688,44 @@ template inline void swap(shared_ptr & a, shared_ptr & b) BOOST_N a.swap(b); } -template shared_ptr static_pointer_cast(shared_ptr const & r) +template shared_ptr static_pointer_cast( shared_ptr const & r ) BOOST_NOEXCEPT { - return shared_ptr(r, boost::detail::static_cast_tag()); + (void) static_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = static_cast< E* >( r.get() ); + return shared_ptr( r, p ); } -template shared_ptr const_pointer_cast(shared_ptr const & r) +template shared_ptr const_pointer_cast( shared_ptr const & r ) BOOST_NOEXCEPT { - return shared_ptr(r, boost::detail::const_cast_tag()); + (void) const_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = const_cast< E* >( r.get() ); + return shared_ptr( r, p ); } -template shared_ptr dynamic_pointer_cast(shared_ptr const & r) +template shared_ptr dynamic_pointer_cast( shared_ptr const & r ) BOOST_NOEXCEPT { - return shared_ptr(r, boost::detail::dynamic_cast_tag()); + (void) dynamic_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = dynamic_cast< E* >( r.get() ); + return p? shared_ptr( r, p ): shared_ptr(); } -// shared_*_cast names are deprecated. Use *_pointer_cast instead. - -template shared_ptr shared_static_cast(shared_ptr const & r) +template shared_ptr reinterpret_pointer_cast( shared_ptr const & r ) BOOST_NOEXCEPT { - return shared_ptr(r, boost::detail::static_cast_tag()); -} + (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); -template shared_ptr shared_dynamic_cast(shared_ptr const & r) -{ - return shared_ptr(r, boost::detail::dynamic_cast_tag()); -} + typedef typename shared_ptr::element_type E; -template shared_ptr shared_polymorphic_cast(shared_ptr const & r) -{ - return shared_ptr(r, boost::detail::polymorphic_cast_tag()); -} - -template shared_ptr shared_polymorphic_downcast(shared_ptr const & r) -{ - BOOST_ASSERT(dynamic_cast(r.get()) == r.get()); - return shared_static_cast(r); + E * p = reinterpret_cast< E* >( r.get() ); + return shared_ptr( r, p ); } // get_pointer() enables boost::mem_fn to recognize shared_ptr diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e3b41c0..2c95dd9 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -74,6 +74,7 @@ import testing ; [ compile sp_array_cv_test.cpp ] [ run sp_convertible_test.cpp ] [ run sp_array_n_test.cpp ] + [ run sp_array_cast_test.cpp ] [ compile-fail array_fail_spa_sp_c.cpp ] [ compile-fail array_fail_sp_spa_c.cpp ] diff --git a/test/sp_array_cast_test.cpp b/test/sp_array_cast_test.cpp new file mode 100644 index 0000000..5af7eb5 --- /dev/null +++ b/test/sp_array_cast_test.cpp @@ -0,0 +1,202 @@ +// +// sp_array_cast_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 + +struct X +{ +}; + +void static_cast_test() +{ + { + boost::shared_ptr pv; + + boost::shared_ptr pi = boost::static_pointer_cast( pv ); + BOOST_TEST( pi.get() == 0 ); + + boost::shared_ptr pi2 = boost::static_pointer_cast( pv ); + BOOST_TEST( pi2.get() == 0 ); + + boost::shared_ptr px = boost::static_pointer_cast( pv ); + BOOST_TEST( px.get() == 0 ); + + boost::shared_ptr px2 = boost::static_pointer_cast( pv ); + BOOST_TEST( px2.get() == 0 ); + } + + { + boost::shared_ptr pi( new int[2] ); + boost::shared_ptr pv( pi ); + + boost::shared_ptr pi2 = boost::static_pointer_cast( pv ); + BOOST_TEST(pi.get() == pi2.get()); + BOOST_TEST(!(pi < pi2 || pi2 < pi)); + + boost::shared_ptr pi3 = boost::static_pointer_cast( pv ); + BOOST_TEST(pi.get() == pi3.get()); + BOOST_TEST(!(pi < pi3 || pi3 < pi)); + + boost::shared_ptr pv2( pi3 ); + + boost::shared_ptr pi4 = boost::static_pointer_cast( pv2 ); + BOOST_TEST(pi.get() == pi4.get()); + BOOST_TEST(!(pi < pi4 || pi4 < pi)); + } + + { + boost::shared_ptr px( new X[4] ); + boost::shared_ptr pv( px ); + + boost::shared_ptr px2 = boost::static_pointer_cast( pv ); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + + boost::shared_ptr px3 = boost::static_pointer_cast( pv ); + BOOST_TEST(px.get() == px3.get()); + BOOST_TEST(!(px < px3 || px3 < px)); + + boost::shared_ptr pv2( px3 ); + + boost::shared_ptr px4 = boost::static_pointer_cast( pv2 ); + BOOST_TEST(px.get() == px4.get()); + BOOST_TEST(!(px < px4 || px4 < px)); + } +} + +void const_cast_test() +{ + { + boost::shared_ptr px; + + boost::shared_ptr px2 = boost::const_pointer_cast(px); + BOOST_TEST( px2.get() == 0 ); + } + + { + boost::shared_ptr px; + + boost::shared_ptr px2 = boost::const_pointer_cast(px); + BOOST_TEST( px2.get() == 0 ); + } + + { + boost::shared_ptr px; + + boost::shared_ptr px2 = boost::const_pointer_cast(px); + BOOST_TEST( px2.get() == 0 ); + } + + { + boost::shared_ptr px; + + boost::shared_ptr px2 = boost::const_pointer_cast(px); + BOOST_TEST( px2.get() == 0 ); + } + + { + boost::shared_ptr px( new int[3] ); + + boost::shared_ptr px2 = boost::const_pointer_cast(px); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + } + + { + boost::shared_ptr px( new int[3] ); + + boost::shared_ptr px2 = boost::const_pointer_cast(px); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + } + + { + boost::shared_ptr px( new X[4] ); + + boost::shared_ptr px2 = boost::const_pointer_cast(px); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + } + + { + boost::shared_ptr px( new X[4] ); + + boost::shared_ptr px2 = boost::const_pointer_cast(px); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + } +} + +void reinterpret_cast_test() +{ + { + boost::shared_ptr pi; + BOOST_TEST( pi.get() == 0 ); + + boost::shared_ptr pi2 = boost::reinterpret_pointer_cast( pi ); + BOOST_TEST( pi2.get() == 0 ); + + boost::shared_ptr pi3 = boost::reinterpret_pointer_cast( pi2 ); + BOOST_TEST( pi3.get() == 0 ); + } + + { + boost::shared_ptr px; + BOOST_TEST( px.get() == 0 ); + + boost::shared_ptr px2 = boost::reinterpret_pointer_cast( px ); + BOOST_TEST( px2.get() == 0 ); + + boost::shared_ptr px3 = boost::reinterpret_pointer_cast( px2 ); + BOOST_TEST( px3.get() == 0 ); + } + + { + boost::shared_ptr pi( new int[2] ); + + boost::shared_ptr pi2 = boost::reinterpret_pointer_cast( pi ); + BOOST_TEST(pi.get() == pi2.get()); + BOOST_TEST(!(pi < pi2 || pi2 < pi)); + + boost::shared_ptr pi3 = boost::reinterpret_pointer_cast( pi2 ); + BOOST_TEST(pi.get() == pi3.get()); + BOOST_TEST(!(pi < pi3 || pi3 < pi)); + + boost::shared_ptr pi4 = boost::reinterpret_pointer_cast( pi3 ); + BOOST_TEST(pi.get() == pi4.get()); + BOOST_TEST(!(pi < pi4 || pi4 < pi)); + } + + { + boost::shared_ptr px( new X[4] ); + + boost::shared_ptr px2 = boost::reinterpret_pointer_cast( px ); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + + boost::shared_ptr px3 = boost::reinterpret_pointer_cast( px2 ); + BOOST_TEST(px.get() == px3.get()); + BOOST_TEST(!(px < px3 || px3 < px)); + + boost::shared_ptr px4 = boost::reinterpret_pointer_cast( px3 ); + BOOST_TEST(px.get() == px4.get()); + BOOST_TEST(!(px < px4 || px4 < px)); + } +} + +int main() +{ + static_cast_test(); + const_cast_test(); + reinterpret_cast_test(); + + return boost::report_errors(); +} From d74c09dd5a4fc3dcdf4a03bc8727f654b447ac45 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 22 Nov 2012 17:39:27 +0000 Subject: [PATCH 138/210] Apply patch from #7722. Refs #7722. [SVN r81488] --- include/boost/smart_ptr/detail/shared_count.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index be4f65b..5d22f86 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -35,7 +35,10 @@ // rather than including directly: #include // std::auto_ptr #include // std::less -#include // std::bad_alloc + +#ifdef BOOST_NO_EXCEPTIONS +# include // std::bad_alloc +#endif #if !defined( BOOST_NO_CXX11_SMART_PTR ) # include From b17205ded768411ef74329978c879373ea0f9bd3 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 28 Nov 2012 06:07:45 +0000 Subject: [PATCH 139/210] Optimization: Add specializations of make_array_helper, allocate_array_helper, and array_deleter for fixed size arrays to avoid storing size. [SVN r81608] --- .../boost/smart_ptr/allocate_shared_array.hpp | 48 +++++------ .../detail/allocate_array_helper.hpp | 79 +++++++++++++++++-- .../boost/smart_ptr/detail/array_deleter.hpp | 63 +++++++++++++++ .../smart_ptr/detail/make_array_helper.hpp | 72 ++++++++++++++++- include/boost/smart_ptr/make_shared_array.hpp | 64 ++++++++------- 5 files changed, 266 insertions(+), 60 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index e6fa081..2e904ca 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -62,14 +62,16 @@ namespace boost { typedef typename boost::detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - std::size_t n1 = boost::detail::array_total::size; - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + enum { + N = boost::detail::array_total::size + }; + boost::detail::allocate_array_helper a1(allocator, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct(p2, n1, boost::detail::sp_forward(args)...); + d2 = get_deleter >(s1); + d2->construct(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } #endif @@ -106,15 +108,17 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - std::size_t n1 = boost::detail::array_total::size; - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + enum { + N = boost::detail::array_total::size + }; + boost::detail::allocate_array_helper a1(allocator, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3); + d2 = get_deleter >(s1); + d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } template @@ -127,8 +131,8 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - std::size_t n0 = boost::detail::array_total::size; - std::size_t n1 = n0 * list.size(); + enum { M = boost::detail::array_total::size }; + std::size_t n1 = M * list.size(); boost::detail::allocate_array_helper a1(allocator, n1, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); @@ -136,7 +140,7 @@ namespace boost { p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3, n0); + d2->construct_list(p2, n1, p3, M); return boost::shared_ptr(s1, p1); } template @@ -150,16 +154,16 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - std::size_t n0 = boost::detail::array_total::size; - std::size_t n1 = boost::detail::array_total::size; - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + enum { M = boost::detail::array_total::size }; + enum { N = boost::detail::array_total::size }; + boost::detail::allocate_array_helper a1(allocator, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3, n0); + d2 = get_deleter >(s1); + d2->construct_list(p2, p3, M); return boost::shared_ptr(s1, p1); } #endif diff --git a/include/boost/smart_ptr/detail/allocate_array_helper.hpp b/include/boost/smart_ptr/detail/allocate_array_helper.hpp index dee34ad..ca151bc 100644 --- a/include/boost/smart_ptr/detail/allocate_array_helper.hpp +++ b/include/boost/smart_ptr/detail/allocate_array_helper.hpp @@ -36,11 +36,6 @@ namespace boost { 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), @@ -92,6 +87,80 @@ namespace boost { std::size_t size; T** data; }; + 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, T** data) + : allocator(allocator), + data(data) { + } + template + allocate_array_helper(const allocate_array_helper& other) + : allocator(other.allocator), + 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 = boost::alignment_of::value; + std::size_t n1 = count * sizeof(Y) + a1 - 1; + char* p1 = A3(allocator).allocate(n1 + N1, 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 = boost::alignment_of::value; + std::size_t n1 = count * sizeof(Y) + a1 - 1; + char* p1 = reinterpret_cast(memory); + A3(allocator).deallocate(p1, n1 + N1); + } + 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: + enum { + N1 = N * sizeof(T) + }; + A2 allocator; + T** data; + }; } } diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 273dcac..b8c62ba 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -70,6 +70,69 @@ namespace boost { std::size_t size; T* object; }; + template + class array_deleter { + public: + array_deleter() + : object(0) { + } + ~array_deleter() { + destroy(); + } + void construct(T* memory) { + object = memory; + for (std::size_t i = 0; i < N; i++) { + void* p1 = object + i; + ::new(p1) T(); + } + } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + template + void construct(T* memory, Args&&... args) { + object = memory; + for (std::size_t i = 0; i < N; i++) { + void* p1 = object + i; + ::new(p1) T(args...); + } + } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void construct_list(T* memory, const T* list) { + object = memory; + for (std::size_t i = 0; i < N; i++) { + void* p1 = object + i; + ::new(p1) T(list[i]); + } + } + void construct_list(T* memory, const T* list, std::size_t n) { + object = memory; + for (std::size_t i = 0; i < N; i++) { + void* p1 = object + i; + ::new(p1) T(list[i % n]); + } + } +#endif + void construct_noinit(T* memory) { + object = memory; + for (std::size_t i = 0; i < N; i++) { + void* p1 = object + i; + ::new(p1) T; + } + } + void operator()(const void*) { + destroy(); + } + private: + void destroy() { + if (object) { + for (std::size_t i = N; i > 0; ) { + object[--i].~T(); + } + object = 0; + } + } + T* object; + }; } } diff --git a/include/boost/smart_ptr/detail/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp index 4d92be3..e6c0123 100644 --- a/include/boost/smart_ptr/detail/make_array_helper.hpp +++ b/include/boost/smart_ptr/detail/make_array_helper.hpp @@ -33,10 +33,6 @@ namespace boost { : 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), @@ -85,6 +81,74 @@ namespace boost { std::size_t size; T** data; }; + 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(T** data) + : data(data) { + } + template + make_array_helper(const make_array_helper& other) + : 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 = boost::alignment_of::value; + std::size_t n1 = count * sizeof(Y) + a1 - 1; + void* p1 = ::operator new(n1 + N1); + 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: + enum { + N1 = N * sizeof(T) + }; + T** data; + }; } } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 36e0ddd..a4c8137 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -62,14 +62,16 @@ namespace boost { typedef typename boost::detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - std::size_t n1 = boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + enum { + N = boost::detail::array_total::size + }; + boost::detail::make_array_helper a1(&p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct(p2, n1, boost::detail::sp_forward(args)...); + d2 = get_deleter >(s1); + d2->construct(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } #endif @@ -104,15 +106,17 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - std::size_t n1 = boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + enum { + N = boost::detail::array_total::size + }; + boost::detail::make_array_helper a1(&p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3); + d2 = get_deleter >(s1); + d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } template @@ -125,8 +129,8 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - std::size_t n0 = boost::detail::array_total::size; - std::size_t n1 = n0 * size; + enum { M = boost::detail::array_total::size }; + std::size_t n1 = M * size; boost::detail::make_array_helper a1(n1, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); @@ -134,7 +138,7 @@ namespace boost { p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3, n0); + d2->construct_list(p2, n1, p3, M); return boost::shared_ptr(s1, p1); } template @@ -147,16 +151,16 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - std::size_t n0 = boost::detail::array_total::size; - std::size_t n1 = boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + enum { M = boost::detail::array_total::size }; + enum { N = boost::detail::array_total::size }; + boost::detail::make_array_helper a1(&p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3, n0); + d2 = get_deleter >(s1); + d2->construct_list(p2, p3, M); return boost::shared_ptr(s1, p1); } #endif @@ -184,14 +188,16 @@ namespace boost { typedef typename boost::detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - std::size_t n1 = boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + enum { + N = boost::detail::array_total::size + }; + boost::detail::make_array_helper a1(&p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct_noinit(p2, n1); + boost::detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_noinit(p2); return boost::shared_ptr(s1, p1); } } From fceea2e584534e9178d734516fc1b5efa3b3059a Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 28 Nov 2012 06:26:50 +0000 Subject: [PATCH 140/210] Consistent formatting across overloads of make_shared and allocate_shared (array forms). [SVN r81609] --- include/boost/smart_ptr/allocate_shared_array.hpp | 8 ++------ include/boost/smart_ptr/make_shared_array.hpp | 12 +++--------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 2e904ca..22ad71b 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -62,9 +62,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - enum { - N = boost::detail::array_total::size - }; + enum { N = boost::detail::array_total::size }; boost::detail::allocate_array_helper a1(allocator, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); @@ -108,9 +106,7 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - enum { - N = boost::detail::array_total::size - }; + enum { N = boost::detail::array_total::size }; boost::detail::allocate_array_helper a1(allocator, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index a4c8137..c6b0e18 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -62,9 +62,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - enum { - N = boost::detail::array_total::size - }; + enum { N = boost::detail::array_total::size }; boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); @@ -106,9 +104,7 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - enum { - N = boost::detail::array_total::size - }; + enum { N = boost::detail::array_total::size }; boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); @@ -188,9 +184,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - enum { - N = boost::detail::array_total::size - }; + enum { N = boost::detail::array_total::size }; boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); From 39ff002d2ea0beca51cc3caaa5e8430cabbd4b32 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 28 Nov 2012 07:32:30 +0000 Subject: [PATCH 141/210] More consistency in type parameters in helper details of allocate_shared and make_shared. [SVN r81610] --- .../boost/smart_ptr/allocate_shared_array.hpp | 32 +++++++-------- .../detail/allocate_array_helper.hpp | 14 ++++--- .../boost/smart_ptr/detail/array_deleter.hpp | 4 +- .../smart_ptr/detail/make_array_helper.hpp | 14 ++++--- include/boost/smart_ptr/make_shared_array.hpp | 40 +++++++++---------- 5 files changed, 55 insertions(+), 49 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 22ad71b..4a7de24 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -28,12 +28,12 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct(p2, n1); return boost::shared_ptr(s1, p1); } @@ -46,12 +46,12 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct(p2, n1, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } @@ -85,13 +85,13 @@ namespace boost { T2* p2 = 0; T3* p3 = 0; std::size_t n1 = list.size() * boost::detail::array_total::size; - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3); return boost::shared_ptr(s1, p1); } @@ -129,13 +129,13 @@ namespace boost { T3* p3 = 0; enum { M = boost::detail::array_total::size }; std::size_t n1 = M * list.size(); - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3, M); return boost::shared_ptr(s1, p1); } diff --git a/include/boost/smart_ptr/detail/allocate_array_helper.hpp b/include/boost/smart_ptr/detail/allocate_array_helper.hpp index ca151bc..f7c64fe 100644 --- a/include/boost/smart_ptr/detail/allocate_array_helper.hpp +++ b/include/boost/smart_ptr/detail/allocate_array_helper.hpp @@ -13,8 +13,10 @@ namespace boost { namespace detail { - template - class allocate_array_helper { + template + class allocate_array_helper; + template + class allocate_array_helper { template friend class allocate_array_helper; typedef typename A::template rebind ::other A2; @@ -29,7 +31,7 @@ namespace boost { typedef typename A2::difference_type difference_type; template struct rebind { - typedef allocate_array_helper other; + typedef allocate_array_helper other; }; allocate_array_helper(const A& allocator, std::size_t size, T** data) : allocator(allocator), @@ -37,7 +39,7 @@ namespace boost { data(data) { } template - allocate_array_helper(const allocate_array_helper& other) + allocate_array_helper(const allocate_array_helper& other) : allocator(other.allocator), size(other.size), data(other.data) { @@ -75,11 +77,11 @@ namespace boost { allocator.destroy(memory); } template - bool operator==(const allocate_array_helper& other) const { + bool operator==(const allocate_array_helper& other) const { return allocator == other.allocator; } template - bool operator!=(const allocate_array_helper& other) const { + bool operator!=(const allocate_array_helper& other) const { return !(*this == other); } private: diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index b8c62ba..b43f5fa 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -15,7 +15,9 @@ namespace boost { namespace detail { template - class array_deleter { + class array_deleter; + template + class array_deleter { public: array_deleter() : size(0) { diff --git a/include/boost/smart_ptr/detail/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp index e6c0123..38c9dc9 100644 --- a/include/boost/smart_ptr/detail/make_array_helper.hpp +++ b/include/boost/smart_ptr/detail/make_array_helper.hpp @@ -13,8 +13,10 @@ namespace boost { namespace detail { - template - class make_array_helper { + template + class make_array_helper; + template + class make_array_helper { template friend class make_array_helper; public: @@ -27,14 +29,14 @@ namespace boost { typedef ptrdiff_t difference_type; template struct rebind { - typedef make_array_helper other; + typedef make_array_helper other; }; make_array_helper(std::size_t size, T** data) : size(sizeof(T) * size), data(data) { } template - make_array_helper(const make_array_helper& other) + make_array_helper(const make_array_helper& other) : size(other.size), data(other.data) { } @@ -70,11 +72,11 @@ namespace boost { memory->~Y(); } template - bool operator==(const make_array_helper& other) const { + bool operator==(const make_array_helper& other) const { return true; } template - bool operator!=(const make_array_helper& other) const { + bool operator!=(const make_array_helper& other) const { return !(*this == other); } private: diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index c6b0e18..d1eeac7 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -28,12 +28,12 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct(p2, n1); return boost::shared_ptr(s1, p1); } @@ -46,12 +46,12 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct(p2, n1, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } @@ -84,13 +84,13 @@ namespace boost { T2* p2 = 0; T3* p3 = 0; std::size_t n1 = list.size() * boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3); return boost::shared_ptr(s1, p1); } @@ -127,13 +127,13 @@ namespace boost { T3* p3 = 0; enum { M = boost::detail::array_total::size }; std::size_t n1 = M * size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3, M); return boost::shared_ptr(s1, p1); } @@ -168,12 +168,12 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + d2 = get_deleter >(s1); d2->construct_noinit(p2, n1); return boost::shared_ptr(s1, p1); } From 4da0e2b7fc942b11c256f00c1908e8feb5d81027 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 1 Dec 2012 04:36:41 +0000 Subject: [PATCH 142/210] Use const T (&)[N] for fixed size arrays instead of std::initializer in overloads of make_shared and allocate_shared for arrays. [SVN r81641] --- .../boost/smart_ptr/allocate_shared_array.hpp | 31 ++++++++++------- .../boost/smart_ptr/detail/array_traits.hpp | 13 ++----- include/boost/smart_ptr/make_shared_array.hpp | 34 ++++++++++++------- make_shared_array.html | 16 ++++----- test/allocate_shared_arrays_create_test.cpp | 14 ++++++++ test/make_shared_arrays_create_test.cpp | 14 ++++++++ 6 files changed, 78 insertions(+), 44 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 4a7de24..e6f47d3 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -60,9 +60,11 @@ namespace boost { allocate_shared(const A& allocator, Args&&... args) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; + enum { + N = boost::detail::array_total::size + }; T1* p1 = 0; T2* p2 = 0; - enum { N = boost::detail::array_total::size }; boost::detail::allocate_array_helper a1(allocator, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); @@ -97,21 +99,21 @@ namespace boost { } template inline typename boost::detail::sp_if_size_array::type - allocate_shared(const A& allocator, - std::initializer_list::type> list) { + allocate_shared(const A& allocator, const T& list) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == boost::detail::array_size::size); + enum { + N = boost::detail::array_total::size + }; T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - enum { N = boost::detail::array_total::size }; boost::detail::allocate_array_helper a1(allocator, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; - p3 = reinterpret_cast(list.begin()); + p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); d2->construct_list(p2, p3); @@ -124,10 +126,12 @@ namespace boost { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; + enum { + M = boost::detail::array_total::size + }; T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - enum { M = boost::detail::array_total::size }; std::size_t n1 = M * list.size(); boost::detail::allocate_array_helper a1(allocator, n1, &p2); boost::detail::array_deleter d1; @@ -142,21 +146,22 @@ namespace boost { template inline typename boost::detail::sp_if_size_array::type allocate_shared(const A& allocator, - std::initializer_list::type> list) { + const typename boost::detail::array_inner::type& list) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == boost::detail::array_size::size); + enum { + M = boost::detail::array_total::size, + N = boost::detail::array_total::size + }; T1* p1 = 0; T2* p2 = 0; - T3* p3 = 0; - enum { M = boost::detail::array_total::size }; - enum { N = boost::detail::array_total::size }; + T3* p3 = 0; boost::detail::allocate_array_helper a1(allocator, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; - p3 = reinterpret_cast(list.begin()); + p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); d2->construct_list(p2, p3, M); diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index 3b80f46..83726b0 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -22,8 +22,7 @@ namespace boost { typedef typename array_base::type type; }; template - struct array_size { - }; + struct array_size; template struct array_size { enum { @@ -43,8 +42,7 @@ namespace boost { }; }; template - struct array_inner { - }; + struct array_inner; template struct array_inner { typedef T type; @@ -54,16 +52,11 @@ namespace boost { typedef T type; }; template - struct arrays_inner { - }; + struct arrays_inner; template struct arrays_inner { typedef T type; }; - template - struct arrays_inner { - typedef T type; - }; } } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index d1eeac7..52adf38 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -60,9 +60,11 @@ namespace boost { make_shared(Args&&... args) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; + enum { + N = boost::detail::array_total::size + }; T1* p1 = 0; T2* p2 = 0; - enum { N = boost::detail::array_total::size }; boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); @@ -93,23 +95,24 @@ namespace boost { d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3); return boost::shared_ptr(s1, p1); - } + } template inline typename boost::detail::sp_if_size_array::type - make_shared(std::initializer_list::type> list) { + make_shared(const T& list) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == boost::detail::array_size::size); + enum { + N = boost::detail::array_total::size + }; T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - enum { N = boost::detail::array_total::size }; boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; - p3 = reinterpret_cast(list.begin()); + p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); d2->construct_list(p2, p3); @@ -122,10 +125,12 @@ namespace boost { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; + enum { + M = boost::detail::array_total::size + }; T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - enum { M = boost::detail::array_total::size }; std::size_t n1 = M * size; boost::detail::make_array_helper a1(n1, &p2); boost::detail::array_deleter d1; @@ -139,21 +144,22 @@ namespace boost { } template inline typename boost::detail::sp_if_size_array::type - make_shared(std::initializer_list::type> list) { + make_shared(const typename boost::detail::array_inner::type& list) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - BOOST_ASSERT(list.size() == boost::detail::array_size::size); + enum { + M = boost::detail::array_total::size, + N = boost::detail::array_total::size + }; T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - enum { M = boost::detail::array_total::size }; - enum { N = boost::detail::array_total::size }; boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; - p3 = reinterpret_cast(list.begin()); + p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); d2->construct_list(p2, p3, M); @@ -182,9 +188,11 @@ namespace boost { make_shared_noinit() { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; + enum { + N = boost::detail::array_total::size + }; T1* p1 = 0; T2* p2 = 0; - enum { N = boost::detail::array_total::size }; boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); diff --git a/make_shared_array.html b/make_shared_array.html index 2c0d5fc..3da2caa 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -54,25 +54,25 @@ shared_ptr<T[]> make_shared(initializer_list<T> list); template<typename T, typename... Args> - shared_ptr<T[N]> make_shared(initializer_list<T> list); + shared_ptr<T[N]> make_shared(const T (&list)[N]); template<typename T, typename... Args> shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T> list); template<typename T, typename... Args> - shared_ptr<T[M][N]> make_shared(initializer_list<T> list); + shared_ptr<T[M][N]> make_shared(const T (&list)[N]); 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); + shared_ptr<T[N]> allocate_shared(const A& allocator, const T (&list)[N]); template<typename T, typename A, typename... Args> shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list); template<typename T, typename A, typename... Args> - shared_ptr<T[M][N]> allocate_shared(const A& allocator, initializer_list<T> list); + shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]); #endif template<typename T> @@ -141,9 +141,9 @@ template<typename T, typename A, typename... Args> from the initializer list.

    template<typename T, typename... Args>
    -    shared_ptr<T[N]> make_shared(initializer_list<T> list);
    +    shared_ptr<T[N]> make_shared(const T (&list)[N]);
     template<typename T, typename A, typename... Args>
    -    shared_ptr<T[N]> allocate_shared(const A& allocator, initializer_list<T> list);
    + shared_ptr<T[N]> allocate_shared(const A& allocator, const T (&list)[N]);

    Description: These overloads of the utilities above are for a fixed size array.

    @@ -157,9 +157,9 @@ template<typename T, typename A, typename... Args> from the initializer list.

    template<typename T, typename... Args>
    -    shared_ptr<T[M][N]> make_shared(initializer_list<T> list);
    +    shared_ptr<T[M][N]> make_shared(const T (&list)[N]);
     template<typename T, typename A, typename... Args>
    -    shared_ptr<T[M][N]> allocate_shared(const A& allocator, initializer_list<T> list);
    + shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]);

    Description: These overloads of the utilities above are for a fixed size array.

    diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index 03a2d7e..7764edf 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -11,6 +11,20 @@ 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] == 0); diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp index e468378..e999182 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -12,6 +12,20 @@ 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] == 0); From 8597433028e504afed74c4af735cdc0a62d91213 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 1 Dec 2012 05:23:37 +0000 Subject: [PATCH 143/210] Use BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX instead for certain overloads of make_shared and allocate_shared [SVN r81642] --- .../boost/smart_ptr/allocate_shared_array.hpp | 46 ++++++++++--------- include/boost/smart_ptr/make_shared_array.hpp | 46 ++++++++++--------- make_shared_array.html | 22 +++++---- test/allocate_shared_array_init_test.cpp | 34 +++++++------- test/allocate_shared_arrays_create_test.cpp | 44 +++++++++--------- test/make_shared_array_init_test.cpp | 34 +++++++------- test/make_shared_arrays_create_test.cpp | 44 +++++++++--------- 7 files changed, 142 insertions(+), 128 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index e6f47d3..997a5c1 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -98,28 +98,6 @@ namespace boost { return boost::shared_ptr(s1, p1); } template - inline typename boost::detail::sp_if_size_array::type - allocate_shared(const A& allocator, const T& list) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef const T2 T3; - enum { - N = boost::detail::array_total::size - }; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = 0; - boost::detail::allocate_array_helper a1(allocator, &p2); - boost::detail::array_deleter d1; - boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p3 = reinterpret_cast(list); - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct_list(p2, p3); - return boost::shared_ptr(s1, p1); - } - template inline typename boost::detail::sp_if_array::type allocate_shared(const A& allocator, std::size_t size, std::initializer_list::type> list) { @@ -143,6 +121,30 @@ namespace boost { d2->construct_list(p2, n1, p3, M); return boost::shared_ptr(s1, p1); } +#endif +#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX + template + inline typename boost::detail::sp_if_size_array::type + allocate_shared(const A& allocator, const T& list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + typedef const T2 T3; + enum { + N = boost::detail::array_total::size + }; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + boost::detail::allocate_array_helper a1(allocator, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p3 = reinterpret_cast(list); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, p3); + return boost::shared_ptr(s1, p1); + } template inline typename boost::detail::sp_if_size_array::type allocate_shared(const A& allocator, diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 52adf38..bf9e95f 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -97,28 +97,6 @@ namespace boost { return boost::shared_ptr(s1, p1); } template - inline typename boost::detail::sp_if_size_array::type - make_shared(const T& list) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef const T2 T3; - enum { - N = boost::detail::array_total::size - }; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = 0; - boost::detail::make_array_helper a1(&p2); - boost::detail::array_deleter d1; - boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p3 = reinterpret_cast(list); - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct_list(p2, p3); - return boost::shared_ptr(s1, p1); - } - template inline typename boost::detail::sp_if_array::type make_shared(std::size_t size, std::initializer_list::type> list) { @@ -142,6 +120,30 @@ namespace boost { d2->construct_list(p2, n1, p3, M); return boost::shared_ptr(s1, p1); } +#endif +#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX + template + inline typename boost::detail::sp_if_size_array::type + make_shared(const T& list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + typedef const T2 T3; + enum { + N = boost::detail::array_total::size + }; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + boost::detail::make_array_helper a1(&p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p3 = reinterpret_cast(list); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, p3); + return boost::shared_ptr(s1, p1); + } template inline typename boost::detail::sp_if_size_array::type make_shared(const typename boost::detail::array_inner::type& list) { diff --git a/make_shared_array.html b/make_shared_array.html index 3da2caa..f638555 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -34,7 +34,7 @@ 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); @@ -48,28 +48,30 @@ 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(const T (&list)[N]); - template<typename T, typename... Args> shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T> list); - template<typename T, typename... Args> - shared_ptr<T[M][N]> make_shared(const T (&list)[N]); - 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, const T (&list)[N]); + shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list); +#endif + +#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX + template<typename T, typename... Args> + shared_ptr<T[N]> make_shared(const T (&list)[N]); + + template<typename T, typename... Args> + shared_ptr<T[M][N]> make_shared(const T (&list)[N]); template<typename T, typename A, typename... Args> - shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list); + shared_ptr<T[N]> allocate_shared(const A& allocator, const T (&list)[N]); template<typename T, typename A, typename... Args> shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]); diff --git a/test/allocate_shared_array_init_test.cpp b/test/allocate_shared_array_init_test.cpp index 6411aa8..8ca0d78 100644 --- a/test/allocate_shared_array_init_test.cpp +++ b/test/allocate_shared_array_init_test.cpp @@ -28,13 +28,6 @@ int main() { 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); @@ -42,13 +35,6 @@ int main() { 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); @@ -57,14 +43,30 @@ int main() { BOOST_TEST(a1[3].value == 3); } { - boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 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 +#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX { - boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 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); diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index 7764edf..8f7e052 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -18,13 +18,6 @@ int main() { 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] == 0); @@ -32,6 +25,29 @@ int main() { 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 +#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX + { + 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] == 0); @@ -46,20 +62,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 1); } - { - 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); - } { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { {0, 1}, {2, 3} }); BOOST_TEST(a1[0][0][0] == 0); diff --git a/test/make_shared_array_init_test.cpp b/test/make_shared_array_init_test.cpp index 6a4c5d5..528c26f 100644 --- a/test/make_shared_array_init_test.cpp +++ b/test/make_shared_array_init_test.cpp @@ -28,13 +28,6 @@ int main() { 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); @@ -42,13 +35,6 @@ int main() { 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); @@ -57,14 +43,30 @@ int main() { BOOST_TEST(a1[3].value == 3); } { - boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 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 +#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX { - boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 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); diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp index e999182..c1ef6b9 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -19,13 +19,6 @@ int main() { 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] == 0); @@ -33,6 +26,29 @@ int main() { 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 +#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX + { + 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] == 0); @@ -47,20 +63,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 1); } - { - 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); - } { boost::shared_ptr a1 = boost::make_shared({ {0, 1}, {2, 3} }); BOOST_TEST(a1[0][0][0] == 0); From f5adfb09637c83d784b29336e7caee1b926f561e Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 1 Dec 2012 05:40:06 +0000 Subject: [PATCH 144/210] Code consistency: Use the same style of #if conditional compilation checks in allocate_shared_array.hpp and make_shared_array.hpp. [SVN r81643] --- include/boost/smart_ptr/allocate_shared_array.hpp | 2 +- include/boost/smart_ptr/detail/array_deleter.hpp | 4 ---- include/boost/smart_ptr/make_shared_array.hpp | 2 +- make_shared_array.html | 2 +- test/allocate_shared_array_init_test.cpp | 2 +- test/allocate_shared_arrays_create_test.cpp | 2 +- test/make_shared_array_init_test.cpp | 2 +- test/make_shared_arrays_create_test.cpp | 2 +- 8 files changed, 7 insertions(+), 11 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 997a5c1..0c0d353 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -122,7 +122,7 @@ namespace boost { return boost::shared_ptr(s1, p1); } #endif -#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) template inline typename boost::detail::sp_if_size_array::type allocate_shared(const A& allocator, const T& list) { diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index b43f5fa..4a62f97 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -40,7 +40,6 @@ namespace boost { } } #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; @@ -53,7 +52,6 @@ namespace boost { ::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; @@ -98,7 +96,6 @@ namespace boost { } } #endif -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) void construct_list(T* memory, const T* list) { object = memory; for (std::size_t i = 0; i < N; i++) { @@ -113,7 +110,6 @@ namespace boost { ::new(p1) T(list[i % n]); } } -#endif void construct_noinit(T* memory) { object = memory; for (std::size_t i = 0; i < N; i++) { diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index bf9e95f..af59689 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -121,7 +121,7 @@ namespace boost { return boost::shared_ptr(s1, p1); } #endif -#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) template inline typename boost::detail::sp_if_size_array::type make_shared(const T& list) { diff --git a/make_shared_array.html b/make_shared_array.html index f638555..c5a9797 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -63,7 +63,7 @@ shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list); #endif -#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) template<typename T, typename... Args> shared_ptr<T[N]> make_shared(const T (&list)[N]); diff --git a/test/allocate_shared_array_init_test.cpp b/test/allocate_shared_array_init_test.cpp index 8ca0d78..1ff437f 100644 --- a/test/allocate_shared_array_init_test.cpp +++ b/test/allocate_shared_array_init_test.cpp @@ -50,7 +50,7 @@ int main() { BOOST_TEST(a1[3].value == 3); } #endif -#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 3 }); BOOST_TEST(a1[0] == 0); diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index 8f7e052..f764569 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -40,7 +40,7 @@ int main() { BOOST_TEST(a1[1][1][1] == 3); } #endif -#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), {0, 1, 2, 3}); BOOST_TEST(a1[0] == 0); diff --git a/test/make_shared_array_init_test.cpp b/test/make_shared_array_init_test.cpp index 528c26f..fd61caf 100644 --- a/test/make_shared_array_init_test.cpp +++ b/test/make_shared_array_init_test.cpp @@ -50,7 +50,7 @@ int main() { BOOST_TEST(a1[3].value == 3); } #endif -#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) { boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 3 }); BOOST_TEST(a1[0] == 0); diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp index c1ef6b9..cc637d1 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -41,7 +41,7 @@ int main() { BOOST_TEST(a1[1][1][1] == 3); } #endif -#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) { boost::shared_ptr a1 = boost::make_shared({0, 1, 2, 3}); BOOST_TEST(a1[0] == 0); From cfd4152291a6c32e3385fbcbe8100e0f3874d723 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 1 Dec 2012 22:43:57 +0000 Subject: [PATCH 145/210] Change make_shared and allocate_shared array form overload for size and inner array initialization list to use const T(&)[N] instead of std::initializer_list. [SVN r81658] --- .../boost/smart_ptr/allocate_shared_array.hpp | 48 +++++++++---------- .../boost/smart_ptr/detail/array_traits.hpp | 6 --- include/boost/smart_ptr/make_shared_array.hpp | 48 +++++++++---------- make_shared_array.html | 18 +++---- 4 files changed, 57 insertions(+), 63 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 0c0d353..94c417e 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -97,30 +97,6 @@ namespace boost { d2->construct_list(p2, n1, p3); return boost::shared_ptr(s1, p1); } - template - inline typename boost::detail::sp_if_array::type - allocate_shared(const A& allocator, std::size_t size, - std::initializer_list::type> list) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef const T2 T3; - enum { - M = boost::detail::array_total::size - }; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = 0; - std::size_t n1 = M * list.size(); - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; - boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p3 = reinterpret_cast(list.begin()); - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3, M); - return boost::shared_ptr(s1, p1); - } #endif #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) template @@ -146,6 +122,30 @@ namespace boost { return boost::shared_ptr(s1, p1); } template + inline typename boost::detail::sp_if_array::type + allocate_shared(const A& allocator, std::size_t size, + const typename boost::detail::array_inner::type& list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + typedef const T2 T3; + enum { + M = boost::detail::array_total::size + }; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n1 = M * size; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p3 = reinterpret_cast(list); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, n1, p3, M); + return boost::shared_ptr(s1, p1); + } + template inline typename boost::detail::sp_if_size_array::type allocate_shared(const A& allocator, const typename boost::detail::array_inner::type& list) { diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index 83726b0..3ef482a 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -51,12 +51,6 @@ namespace boost { struct array_inner { typedef T type; }; - template - struct arrays_inner; - template - struct arrays_inner { - typedef T type; - }; } } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index af59689..d268b71 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -96,30 +96,6 @@ namespace boost { d2->construct_list(p2, n1, p3); return boost::shared_ptr(s1, p1); } - template - inline typename boost::detail::sp_if_array::type - make_shared(std::size_t size, - std::initializer_list::type> list) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef const T2 T3; - enum { - M = boost::detail::array_total::size - }; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = 0; - std::size_t n1 = M * size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; - boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p3 = reinterpret_cast(list.begin()); - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3, M); - return boost::shared_ptr(s1, p1); - } #endif #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) template @@ -145,6 +121,30 @@ namespace boost { return boost::shared_ptr(s1, p1); } template + inline typename boost::detail::sp_if_array::type + make_shared(std::size_t size, + const typename boost::detail::array_inner::type& list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + typedef const T2 T3; + enum { + M = boost::detail::array_total::size + }; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n1 = M * size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p3 = reinterpret_cast(list); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, n1, p3, M); + return boost::shared_ptr(s1, p1); + } + template inline typename boost::detail::sp_if_size_array::type make_shared(const typename boost::detail::array_inner::type& list) { typedef typename boost::detail::array_inner::type T1; diff --git a/make_shared_array.html b/make_shared_array.html index c5a9797..b42d28a 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -12,7 +12,7 @@ Synopsis
    Free Functions
    Example
    - History
    + History

    Introduction

    Originally the Boost function templates make_shared and allocate_shared were for efficient allocation of single @@ -53,26 +53,26 @@ 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(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, size_t size, initializer_list<T> list); #endif #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) template<typename T, typename... Args> shared_ptr<T[N]> make_shared(const T (&list)[N]); + template<typename T, typename... Args> + shared_ptr<T[][N]> make_shared(size_t size, const T (&list)[N]); + template<typename T, typename... Args> shared_ptr<T[M][N]> make_shared(const T (&list)[N]); template<typename T, typename A, typename... Args> shared_ptr<T[N]> allocate_shared(const A& allocator, const T (&list)[N]); + template<typename T, typename A, typename... Args> + shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, const T (&list)[N]); + template<typename T, typename A, typename... Args> shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]); #endif @@ -151,9 +151,9 @@ template<typename T, typename A, typename... Args> fixed size array.

    template<typename T, typename... Args>
    -    shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T> list);
    +    shared_ptr<T[][N]> make_shared(size_t size, const T (&list)[N]);
     template<typename T, typename A, typename... Args>
    -    shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list);
    + shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);

    Description: These overloads initialize inner array elements from the initializer list.

    From 19283a354875ada57fcd1dd28ea37ce58d0812ab Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 2 Dec 2012 10:17:05 +0000 Subject: [PATCH 146/210] Move two tests for allocate_shared and make_shared within check for BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX [SVN r81669] --- test/allocate_shared_arrays_create_test.cpp | 28 ++++++++--------- test/make_shared_arrays_create_test.cpp | 33 ++++++++++----------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index f764569..8645179 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -25,20 +25,6 @@ int main() { 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 #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) { @@ -55,6 +41,20 @@ int main() { 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); + } { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), {0, 1}); BOOST_TEST(a1[0][0] == 0); diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp index cc637d1..eb08759 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -8,7 +8,6 @@ */ #include #include -#include int main() { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -26,6 +25,22 @@ int main() { BOOST_TEST(a1[1][0] == 2); BOOST_TEST(a1[1][1] == 3); } +#endif +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) + { + 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] == 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); @@ -40,22 +55,6 @@ int main() { BOOST_TEST(a1[1][1][0] == 2); BOOST_TEST(a1[1][1][1] == 3); } -#endif -#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) - { - 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] == 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 }); BOOST_TEST(a1[0][0] == 0); From 500913db6def096ab6c5b101f3925a54396c8974 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 2 Dec 2012 22:05:31 +0000 Subject: [PATCH 147/210] Make specializations of detail array_deleter consistent. [SVN r81681] --- .../boost/smart_ptr/allocate_shared_array.hpp | 16 +++--- .../boost/smart_ptr/detail/array_deleter.hpp | 51 +++++++++++-------- include/boost/smart_ptr/make_shared_array.hpp | 20 ++++---- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 94c417e..0c17edd 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -29,12 +29,12 @@ namespace boost { T2* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1); + d2->construct(p2); return boost::shared_ptr(s1, p1); } #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) @@ -47,12 +47,12 @@ namespace boost { T2* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, boost::detail::sp_forward(args)...); + d2->construct(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } template @@ -88,13 +88,13 @@ namespace boost { T3* p3 = 0; std::size_t n1 = list.size() * boost::detail::array_total::size; boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3); + d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } #endif @@ -136,13 +136,13 @@ namespace boost { T3* p3 = 0; std::size_t n1 = M * size; boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1; + boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3, M); + d2->construct_list(p2, p3, M); return boost::shared_ptr(s1, p1); } template diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 4a62f97..5d89dd8 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -19,42 +19,48 @@ namespace boost { template class array_deleter { public: - array_deleter() - : size(0) { + array_deleter(std::size_t size) + : size(size), + object(0) { } ~array_deleter() { destroy(); } - void construct(T* memory, std::size_t count) { - for (object = memory; size < count; size++) { - void* p1 = object + size; + void construct(T* memory) { + object = memory; + for (std::size_t i = 0; i < size; i++) { + void* p1 = object + i; ::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; + void construct(T* memory, Args&&... args) { + object = memory; + for (std::size_t i = 0; i < size; i++) { + void* p1 = object + i; ::new(p1) T(args...); } } #endif - 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, const T* list) { + object = memory; + for (std::size_t i = 0; i < size; i++) { + void* p1 = object + i; + ::new(p1) T(list[i]); } } - 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]); + void construct_list(T* memory, const T* list, std::size_t n) { + object = memory; + for (std::size_t i = 0; i < size; i++) { + void* p1 = object + i; + ::new(p1) T(list[i % n]); } } - void construct_noinit(T* memory, std::size_t count) { - for (object = memory; size < count; size++) { - void* p1 = object + size; + void construct_noinit(T* memory) { + object = memory; + for (std::size_t i = 0; i < size; i++) { + void* p1 = object + i; ::new(p1) T; } } @@ -63,8 +69,11 @@ namespace boost { } private: void destroy() { - while (size > 0) { - object[--size].~T(); + if (object) { + for (std::size_t i = size; i > 0; ) { + object[--i].~T(); + } + object = 0; } } std::size_t size; diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index d268b71..89ff8f1 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -29,12 +29,12 @@ namespace boost { T2* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1); + d2->construct(p2); return boost::shared_ptr(s1, p1); } #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) @@ -47,12 +47,12 @@ namespace boost { T2* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, boost::detail::sp_forward(args)...); + d2->construct(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } template @@ -87,13 +87,13 @@ namespace boost { T3* p3 = 0; std::size_t n1 = list.size() * boost::detail::array_total::size; boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3); + d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } #endif @@ -135,13 +135,13 @@ namespace boost { T3* p3 = 0; std::size_t n1 = M * size; boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_list(p2, n1, p3, M); + d2->construct_list(p2, p3, M); return boost::shared_ptr(s1, p1); } template @@ -177,12 +177,12 @@ namespace boost { T2* p2 = 0; std::size_t n1 = size * boost::detail::array_total::size; boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1; + boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); boost::detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_noinit(p2, n1); + d2->construct_noinit(p2); return boost::shared_ptr(s1, p1); } template From 5e5ff387fae41173d2f2d206a8e1c545285c8407 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 3 Dec 2012 05:41:34 +0000 Subject: [PATCH 148/210] For fixed size arrays upon constructor exception thrown destroy correctly. [SVN r81684] --- .../boost/smart_ptr/detail/array_deleter.hpp | 106 +++++++++++++----- test/allocate_shared_array_throws_test.cpp | 16 +++ test/make_shared_array_throws_test.cpp | 16 +++ 3 files changed, 110 insertions(+), 28 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 5d89dd8..b1b19d2 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -24,13 +24,18 @@ namespace boost { object(0) { } ~array_deleter() { - destroy(); + destroy(size); } void construct(T* memory) { object = memory; for (std::size_t i = 0; i < size; i++) { - void* p1 = object + i; - ::new(p1) T(); + try { + void* p1 = memory + i; + ::new(p1) T(); + } catch (...) { + destroy(i); + throw; + } } } #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) @@ -38,39 +43,59 @@ namespace boost { void construct(T* memory, Args&&... args) { object = memory; for (std::size_t i = 0; i < size; i++) { - void* p1 = object + i; - ::new(p1) T(args...); + try { + void* p1 = memory + i; + ::new(p1) T(args...); + } catch (...) { + destroy(i); + throw; + } } } #endif void construct_list(T* memory, const T* list) { object = memory; for (std::size_t i = 0; i < size; i++) { - void* p1 = object + i; - ::new(p1) T(list[i]); + try { + void* p1 = memory + i; + ::new(p1) T(list[i]); + } catch (...) { + destroy(i); + throw; + } } } void construct_list(T* memory, const T* list, std::size_t n) { object = memory; for (std::size_t i = 0; i < size; i++) { - void* p1 = object + i; - ::new(p1) T(list[i % n]); + try { + void* p1 = memory + i; + ::new(p1) T(list[i % n]); + } catch (...) { + destroy(i); + throw; + } } } void construct_noinit(T* memory) { object = memory; for (std::size_t i = 0; i < size; i++) { - void* p1 = object + i; - ::new(p1) T; + try { + void* p1 = memory + i; + ::new(p1) T; + } catch (...) { + destroy(i); + throw; + } } } void operator()(const void*) { - destroy(); + destroy(size); } private: - void destroy() { + void destroy(std::size_t n) { if (object) { - for (std::size_t i = size; i > 0; ) { + for (std::size_t i = n; i > 0; ) { object[--i].~T(); } object = 0; @@ -86,13 +111,18 @@ namespace boost { : object(0) { } ~array_deleter() { - destroy(); + destroy(N); } void construct(T* memory) { object = memory; for (std::size_t i = 0; i < N; i++) { - void* p1 = object + i; - ::new(p1) T(); + try { + void* p1 = memory + i; + ::new(p1) T(); + } catch (...) { + destroy(i); + throw; + } } } #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) @@ -100,39 +130,59 @@ namespace boost { void construct(T* memory, Args&&... args) { object = memory; for (std::size_t i = 0; i < N; i++) { - void* p1 = object + i; - ::new(p1) T(args...); + try { + void* p1 = memory + i; + ::new(p1) T(args...); + } catch (...) { + destroy(i); + throw; + } } } #endif void construct_list(T* memory, const T* list) { object = memory; for (std::size_t i = 0; i < N; i++) { - void* p1 = object + i; - ::new(p1) T(list[i]); + try { + void* p1 = memory + i; + ::new(p1) T(list[i]); + } catch (...) { + destroy(i); + throw; + } } } void construct_list(T* memory, const T* list, std::size_t n) { object = memory; for (std::size_t i = 0; i < N; i++) { - void* p1 = object + i; - ::new(p1) T(list[i % n]); + try { + void* p1 = memory + i; + ::new(p1) T(list[i % n]); + } catch (...) { + destroy(i); + throw; + } } } void construct_noinit(T* memory) { object = memory; for (std::size_t i = 0; i < N; i++) { - void* p1 = object + i; - ::new(p1) T; + try { + void* p1 = memory + i; + ::new(p1) T; + } catch (...) { + destroy(i); + throw; + } } } void operator()(const void*) { - destroy(); + destroy(N); } private: - void destroy() { + void destroy(std::size_t n) { if (object) { - for (std::size_t i = N; i > 0; ) { + for (std::size_t i = n; i > 0; ) { object[--i].~T(); } object = 0; diff --git a/test/allocate_shared_array_throws_test.cpp b/test/allocate_shared_array_throws_test.cpp index d52104c..65a7985 100644 --- a/test/allocate_shared_array_throws_test.cpp +++ b/test/allocate_shared_array_throws_test.cpp @@ -43,5 +43,21 @@ int main() { } catch (...) { BOOST_TEST(type::instances == 0); } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + BOOST_TEST(type::instances == 0); + try { + boost::allocate_shared(std::allocator()); + BOOST_ERROR("allocate_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + try { + boost::allocate_shared(std::allocator()); + BOOST_ERROR("allocate_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } +#endif return boost::report_errors(); } diff --git a/test/make_shared_array_throws_test.cpp b/test/make_shared_array_throws_test.cpp index 7e06d41..4faf193 100644 --- a/test/make_shared_array_throws_test.cpp +++ b/test/make_shared_array_throws_test.cpp @@ -43,6 +43,22 @@ int main() { } catch (...) { BOOST_TEST(type::instances == 0); } +#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) + BOOST_TEST(type::instances == 0); + try { + boost::make_shared(); + BOOST_ERROR("make_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + try { + boost::make_shared(); + BOOST_ERROR("make_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } +#endif BOOST_TEST(type::instances == 0); try { boost::make_shared_noinit(6); From 1adf546ddbb0e53deb3a3486b473b0d1a53b2f9e Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 3 Dec 2012 05:56:17 +0000 Subject: [PATCH 149/210] Minor cosmetic change in detail array_deleter [SVN r81685] --- .../boost/smart_ptr/detail/array_deleter.hpp | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index b1b19d2..b07b00a 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -1,9 +1,9 @@ /* - * Copyright (c) 2012 Glen Joseph Fernandes + * 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 + * 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 @@ -19,7 +19,7 @@ namespace boost { template class array_deleter { public: - array_deleter(std::size_t size) + array_deleter(std::size_t size) : size(size), object(0) { } @@ -27,66 +27,66 @@ namespace boost { destroy(size); } void construct(T* memory) { - object = memory; - for (std::size_t i = 0; i < size; i++) { - try { + std::size_t i = 0; + try { + for (object = memory; i < size; i++) { void* p1 = memory + i; ::new(p1) T(); - } catch (...) { - destroy(i); - throw; } + } catch (...) { + destroy(i); + throw; } } #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) template void construct(T* memory, Args&&... args) { - object = memory; - for (std::size_t i = 0; i < size; i++) { - try { + std::size_t i = 0; + try { + for (object = memory; i < size; i++) { void* p1 = memory + i; ::new(p1) T(args...); - } catch (...) { - destroy(i); - throw; } + } catch (...) { + destroy(i); + throw; } } #endif void construct_list(T* memory, const T* list) { - object = memory; - for (std::size_t i = 0; i < size; i++) { - try { + std::size_t i = 0; + try { + for (object = memory; i < size; i++) { void* p1 = memory + i; ::new(p1) T(list[i]); - } catch (...) { - destroy(i); - throw; } + } catch (...) { + destroy(i); + throw; } } void construct_list(T* memory, const T* list, std::size_t n) { - object = memory; - for (std::size_t i = 0; i < size; i++) { - try { + std::size_t i = 0; + try { + for (object = memory; i < size; i++) { void* p1 = memory + i; ::new(p1) T(list[i % n]); - } catch (...) { - destroy(i); - throw; } + } catch (...) { + destroy(i); + throw; } } void construct_noinit(T* memory) { - object = memory; - for (std::size_t i = 0; i < size; i++) { - try { + std::size_t i = 0; + try { + for (object = memory; i < size; i++) { void* p1 = memory + i; ::new(p1) T; - } catch (...) { - destroy(i); - throw; } + } catch (...) { + destroy(i); + throw; } } void operator()(const void*) { @@ -107,73 +107,73 @@ namespace boost { template class array_deleter { public: - array_deleter() + array_deleter() : object(0) { } ~array_deleter() { destroy(N); } void construct(T* memory) { - object = memory; - for (std::size_t i = 0; i < N; i++) { - try { + std::size_t i = 0; + try { + for (object = memory; i < N; i++) { void* p1 = memory + i; ::new(p1) T(); - } catch (...) { - destroy(i); - throw; } + } catch (...) { + destroy(i); + throw; } } #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) template void construct(T* memory, Args&&... args) { - object = memory; - for (std::size_t i = 0; i < N; i++) { - try { + std::size_t i = 0; + try { + for (object = memory; i < N; i++) { void* p1 = memory + i; ::new(p1) T(args...); - } catch (...) { - destroy(i); - throw; } + } catch (...) { + destroy(i); + throw; } } #endif void construct_list(T* memory, const T* list) { - object = memory; - for (std::size_t i = 0; i < N; i++) { - try { + std::size_t i = 0; + try { + for (object = memory; i < N; i++) { void* p1 = memory + i; ::new(p1) T(list[i]); - } catch (...) { - destroy(i); - throw; } + } catch (...) { + destroy(i); + throw; } } void construct_list(T* memory, const T* list, std::size_t n) { - object = memory; - for (std::size_t i = 0; i < N; i++) { - try { - void* p1 = memory + i; + std::size_t i = 0; + try { + for (object = memory; i < N; i++) { + void* p1 = memory + i; ::new(p1) T(list[i % n]); - } catch (...) { - destroy(i); - throw; } + } catch (...) { + destroy(i); + throw; } } void construct_noinit(T* memory) { - object = memory; - for (std::size_t i = 0; i < N; i++) { - try { + std::size_t i = 0; + try { + for (object = memory; i < N; i++) { void* p1 = memory + i; ::new(p1) T; - } catch (...) { - destroy(i); - throw; } + } catch (...) { + destroy(i); + throw; } } void operator()(const void*) { From 188602581da2f51034e0d144760bceaf5cfcdc3e Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 4 Dec 2012 06:06:23 +0000 Subject: [PATCH 150/210] Add overloads of make_shared and allocate_shared for arrays for E&& where E is typename boost::detail::array_base::type [SVN r81700] --- .../boost/smart_ptr/allocate_shared_array.hpp | 40 +++++++++++++++++++ .../boost/smart_ptr/detail/array_deleter.hpp | 32 ++++++++++++++- .../boost/smart_ptr/detail/array_traits.hpp | 4 ++ .../boost/smart_ptr/detail/sp_if_array.hpp | 6 +-- include/boost/smart_ptr/make_shared_array.hpp | 39 ++++++++++++++++++ make_shared_array.html | 36 ++++++++++++++++- test/allocate_shared_arrays_create_test.cpp | 27 +++++++++++++ test/make_shared_arrays_create_test.cpp | 27 +++++++++++++ 8 files changed, 203 insertions(+), 8 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 0c17edd..a98d97e 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -169,6 +169,46 @@ namespace boost { d2->construct_list(p2, p3, M); return boost::shared_ptr(s1, p1); } +#if defined(BOOST_HAS_RVALUE_REFS) + template + inline typename boost::detail::sp_if_array::type + allocate_shared(const A& allocator, std::size_t size, + typename boost::detail::array_base::type&& value) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = size * boost::detail::array_total::size; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1(n1); + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, boost::detail::sp_forward(value)); + return boost::shared_ptr(s1, p1); + } + template + inline typename boost::detail::sp_if_size_array::type + allocate_shared(const A& allocator, + typename boost::detail::array_base::type&& value) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + enum { + N = boost::detail::array_total::size + }; + T1* p1 = 0; + T2* p2 = 0; + boost::detail::allocate_array_helper a1(allocator, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, boost::detail::sp_forward(value)); + return boost::shared_ptr(s1, p1); + } +#endif #endif } diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index b07b00a..40e9d57 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -38,7 +38,20 @@ namespace boost { throw; } } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if defined(BOOST_HAS_RVALUE_REFS) + void construct(T* memory, T&& value) { + std::size_t i = 0; + try { + for (object = memory; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(value); + } + } catch (...) { + destroy(i); + throw; + } + } +#if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { std::size_t i = 0; @@ -52,6 +65,7 @@ namespace boost { throw; } } +#endif #endif void construct_list(T* memory, const T* list) { std::size_t i = 0; @@ -125,7 +139,20 @@ namespace boost { throw; } } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if defined(BOOST_HAS_RVALUE_REFS) + void construct(T* memory, T&& value) { + std::size_t i = 0; + try { + for (object = memory; i < N; i++) { + void* p1 = memory + i; + ::new(p1) T(value); + } + } catch (...) { + destroy(i); + throw; + } + } +#if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { std::size_t i = 0; @@ -139,6 +166,7 @@ namespace boost { throw; } } +#endif #endif void construct_list(T* memory, const T* list) { std::size_t i = 0; diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index 3ef482a..f3dc0be 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -17,6 +17,10 @@ namespace boost { struct array_base { typedef typename boost::remove_cv::type type; }; + template + struct array_base { + typedef typename array_base::type type; + }; template struct array_base { typedef typename array_base::type type; diff --git a/include/boost/smart_ptr/detail/sp_if_array.hpp b/include/boost/smart_ptr/detail/sp_if_array.hpp index 3ba3a0e..661e178 100644 --- a/include/boost/smart_ptr/detail/sp_if_array.hpp +++ b/include/boost/smart_ptr/detail/sp_if_array.hpp @@ -14,15 +14,13 @@ namespace boost { namespace detail { template - struct sp_if_array { - }; + struct sp_if_array; template struct sp_if_array { typedef boost::shared_ptr type; }; template - struct sp_if_size_array { - }; + struct sp_if_size_array; template struct sp_if_size_array { typedef boost::shared_ptr type; diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 89ff8f1..b4fd9f6 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -167,6 +167,45 @@ namespace boost { d2->construct_list(p2, p3, M); return boost::shared_ptr(s1, p1); } +#if defined(BOOST_HAS_RVALUE_REFS) + template + inline typename boost::detail::sp_if_array::type + make_shared(std::size_t size, + typename boost::detail::array_base::type&& value) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = size * boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1(n1); + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, boost::detail::sp_forward(value)); + return boost::shared_ptr(s1, p1); + } + template + inline typename boost::detail::sp_if_size_array::type + make_shared(typename boost::detail::array_base::type&& value) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + enum { + N = boost::detail::array_total::size + }; + T1* p1 = 0; + T2* p2 = 0; + boost::detail::make_array_helper a1(&p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, boost::detail::sp_forward(value)); + return boost::shared_ptr(s1, p1); + } +#endif #endif template inline typename boost::detail::sp_if_array::type diff --git a/make_shared_array.html b/make_shared_array.html index b42d28a..1e5ffbc 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -75,6 +75,20 @@ template<typename T, typename A, typename... Args> shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]); + +#if defined(BOOST_HAS_RVALUE_REFS) + template<typename T> + shared_ptr<T[]> make_shared(size_t size, T&& value); + + template<typename T> + shared_ptr<T[N]> make_shared(T&& value); + + template<typename T, typename A> + shared_ptr<T[]> allocate_shared(const A& allocator, size_t size, T&& value); + + template<typename T, typename A> + shared_ptr<T[N]> allocate_shared(const A& allocator, T&& value); +#endif #endif template<typename T> @@ -162,6 +176,22 @@ template<typename T, typename A, typename... Args> shared_ptr<T[M][N]> make_shared(const T (&list)[N]); template<typename T, typename A, typename... Args> shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]); +
    +

    Description: These overloads of the utilities above are for a + fixed size array.

    +
    +
    template<typename T>
    +    shared_ptr<T[]> make_shared(size_t size, T&& value);
    +template<typename T, typename A>
    +    shared_ptr<T[]> allocate_shared(const A& allocator, size_t size, T&& value);
    +
    +

    Description: These overloads initialize array elements with + the given value.

    +
    +
    template<typename T>
    +    shared_ptr<T[N]> make_shared(T&& value);
    +template<typename T, typename A>
    +    shared_ptr<T[N]> allocate_shared(const A& allocator, T&& value);

    Description: These overloads of the utilities above are for a fixed size array.

    @@ -188,8 +218,10 @@ boost::shared_ptr<int[]> a4 = boost::make_shared<int[]>({1, 2, 3}); boost::shared_ptr<int[3]> a5 = boost::make_shared<int[3]>({1, 2, 3}); boost::shared_ptr<int[][3]> a6 = boost::make_shared<int[][3]>(size, {1, 2, 3}); boost::shared_ptr<int[5][3]> a7 = boost::make_shared<int[5][3]>({1, 2, 3}); -boost::shared_ptr<int[]> a8 = boost::make_shared_noinit<int[]>(size); -boost::shared_ptr<int[5]> a9 = boost::make_shared_noinit<int[5]>(); +boost::shared_ptr<point[]> a8 = boost::make_shared<point[]>(4, {x, y}); +boost::shared_ptr<point[4]> a9 = boost::make_shared<point[4]>({x, y}); +boost::shared_ptr<int[]> a10 = boost::make_shared_noinit<int[]>(size); +boost::shared_ptr<int[5]> a11 = boost::make_shared_noinit<int[5]>();

    History

    November 2012. Glen Fernandes contributed implementations of diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index 8645179..4c53e91 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -9,6 +9,17 @@ #include #include +class type { +public: + type(int x, int y) + : x(x), y(y) { + } + const int x; + const int y; +private: + type& operator=(const type&); +}; + int main() { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) { @@ -69,6 +80,22 @@ int main() { BOOST_TEST(a1[1][1][0] == 2); BOOST_TEST(a1[1][1][1] == 3); } +#if defined(BOOST_HAS_RVALUE_REFS) + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 4, {1, 2}); + BOOST_TEST(a1[0].x == 1); + BOOST_TEST(a1[1].y == 2); + BOOST_TEST(a1[2].x == 1); + BOOST_TEST(a1[3].y == 2); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), {1, 2}); + BOOST_TEST(a1[0].x == 1); + BOOST_TEST(a1[1].y == 2); + BOOST_TEST(a1[2].x == 1); + BOOST_TEST(a1[3].y == 2); + } +#endif #endif return boost::report_errors(); } diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp index eb08759..7fc36bd 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -9,6 +9,17 @@ #include #include +class type { +public: + type(int x, int y) + : x(x), y(y) { + } + const int x; + const int y; +private: + type& operator=(const type&); +}; + int main() { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) { @@ -69,6 +80,22 @@ int main() { BOOST_TEST(a1[1][1][0] == 2); BOOST_TEST(a1[1][1][1] == 3); } +#if defined(BOOST_HAS_RVALUE_REFS) + { + boost::shared_ptr a1 = boost::make_shared(4, {1, 2}); + BOOST_TEST(a1[0].x == 1); + BOOST_TEST(a1[1].y == 2); + BOOST_TEST(a1[2].x == 1); + BOOST_TEST(a1[3].y == 2); + } + { + boost::shared_ptr a1 = boost::make_shared({1, 2}); + BOOST_TEST(a1[0].x == 1); + BOOST_TEST(a1[1].y == 2); + BOOST_TEST(a1[2].x == 1); + BOOST_TEST(a1[3].y == 2); + } +#endif #endif return boost::report_errors(); } From 2d3cc0db7dda12e71b3ecb0e86ffcad56eb61042 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 4 Dec 2012 11:21:24 +0000 Subject: [PATCH 151/210] Update documentation and remove unused code. [SVN r81703] --- include/boost/smart_ptr/detail/array_traits.hpp | 8 -------- make_shared_array.html | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index f3dc0be..8ef7874 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -26,14 +26,6 @@ namespace boost { typedef typename array_base::type type; }; template - struct array_size; - template - struct array_size { - enum { - size = N - }; - }; - template struct array_total { enum { size = 1 diff --git a/make_shared_array.html b/make_shared_array.html index 1e5ffbc..c1db41f 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -218,8 +218,8 @@ boost::shared_ptr<int[]> a4 = boost::make_shared<int[]>({1, 2, 3}); boost::shared_ptr<int[3]> a5 = boost::make_shared<int[3]>({1, 2, 3}); boost::shared_ptr<int[][3]> a6 = boost::make_shared<int[][3]>(size, {1, 2, 3}); boost::shared_ptr<int[5][3]> a7 = boost::make_shared<int[5][3]>({1, 2, 3}); -boost::shared_ptr<point[]> a8 = boost::make_shared<point[]>(4, {x, y}); -boost::shared_ptr<point[4]> a9 = boost::make_shared<point[4]>({x, y}); +boost::shared_ptr<point[]> a8 = boost::make_shared<point[]>(size, {x, y}); +boost::shared_ptr<point[5]> a9 = boost::make_shared<point[5]>({x, y}); boost::shared_ptr<int[]> a10 = boost::make_shared_noinit<int[]>(size); boost::shared_ptr<int[5]> a11 = boost::make_shared_noinit<int[5]>();

    From 7a733263da223f505b8908355b7ead6810044052 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 6 Dec 2012 03:18:54 +0000 Subject: [PATCH 152/210] Fix get_pointer for the array case, add operator= for unique_ptr, update auto_ptr signatures to use rvalue reference when available. [SVN r81730] --- include/boost/smart_ptr/shared_ptr.hpp | 45 ++++++++++++++++++++++---- test/sp_unique_ptr_test.cpp | 24 ++++++++++++++ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 5e13c01..6a09c28 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -418,17 +418,30 @@ public: #ifndef BOOST_NO_AUTO_PTR template - explicit shared_ptr(std::auto_ptr & r): px(r.get()), pn() + 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); + pn = boost::detail::shared_count( r ); boost::detail::sp_deleter_construct( this, tmp ); } -#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) +#if defined( BOOST_HAS_RVALUE_REFS ) + + template + 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_deleter_construct( this, tmp ); + } + +#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) template explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr::type = 0 ): px( r.get() ), pn() @@ -486,11 +499,20 @@ public: template shared_ptr & operator=( std::auto_ptr & r ) { - this_type(r).swap(*this); + this_type( r ).swap( *this ); return *this; } -#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) +#if defined( BOOST_HAS_RVALUE_REFS ) + + template + shared_ptr & operator=( std::auto_ptr && r ) + { + this_type( static_cast< std::auto_ptr && >( r ) ).swap( *this ); + return *this; + } + +#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) template typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r ) @@ -503,6 +525,17 @@ public: #endif // BOOST_NO_AUTO_PTR +#if !defined( BOOST_NO_CXX11_SMART_PTR ) + + template + shared_ptr & operator=( std::unique_ptr && r ) + { + this_type( static_cast< std::unique_ptr && >( r ) ).swap(*this); + return *this; + } + +#endif + // Move support #if defined( BOOST_HAS_RVALUE_REFS ) @@ -730,7 +763,7 @@ template shared_ptr reinterpret_pointer_cast( shared_ptr // get_pointer() enables boost::mem_fn to recognize shared_ptr -template inline T * get_pointer(shared_ptr const & p) BOOST_NOEXCEPT +template inline typename shared_ptr::element_type * get_pointer(shared_ptr const & p) BOOST_NOEXCEPT { return p.get(); } diff --git a/test/sp_unique_ptr_test.cpp b/test/sp_unique_ptr_test.cpp index 70c5aff..7656e75 100644 --- a/test/sp_unique_ptr_test.cpp +++ b/test/sp_unique_ptr_test.cpp @@ -91,6 +91,12 @@ int main() p2.reset(); p3.reset(); BOOST_TEST( X::instances == 0 ); + + p2 = std::unique_ptr( new X ); + BOOST_TEST( X::instances == 1 ); + + p2.reset(); + BOOST_TEST( X::instances == 0 ); } { @@ -105,6 +111,12 @@ int main() p2.reset(); BOOST_TEST( Y::instances == 0 ); + + p2 = std::unique_ptr( new Y, YD() ); + BOOST_TEST( Y::instances == 1 ); + + p2.reset(); + BOOST_TEST( Y::instances == 0 ); } { @@ -121,6 +133,12 @@ int main() p2.reset(); BOOST_TEST( Y::instances == 0 ); + + p2 = std::unique_ptr( new Y, yd ); + BOOST_TEST( Y::instances == 1 ); + + p2.reset(); + BOOST_TEST( Y::instances == 0 ); } { @@ -137,6 +155,12 @@ int main() p2.reset(); BOOST_TEST( Y::instances == 0 ); + + p2 = std::unique_ptr( new Y, yd ); + BOOST_TEST( Y::instances == 1 ); + + p2.reset(); + BOOST_TEST( Y::instances == 0 ); } return boost::report_errors(); From 6c2ed927e47122a0bd040bcb2dbc8800b7e864ad Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 6 Dec 2012 03:20:46 +0000 Subject: [PATCH 153/210] Update shared_ptr.htm. [SVN r81731] --- shared_ptr.htm | 968 ++++++++++++++++++++++++++----------------------- 1 file changed, 518 insertions(+), 450 deletions(-) diff --git a/shared_ptr.htm b/shared_ptr.htm index 77e1fa8..87e61b4 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -2,410 +2,496 @@ shared_ptr - + - -

    boost.png (6897 bytes)shared_ptr class template

    -

    Introduction
    - Best Practices
    - Synopsis
    - Members
    - Free Functions
    - Example
    - Handle/Body Idiom
    - Thread Safety
    - Frequently Asked Questions
    - Smart Pointer Timings
    - Programming Techniques

    -

    Introduction

    -

    The shared_ptr class template stores a pointer to a dynamically allocated - object, typically with a C++ new-expression. The object pointed to is - guaranteed to be deleted when the last shared_ptr pointing to it is - destroyed or reset. See the example.

    -

    Every shared_ptr meets the CopyConstructible and Assignable - requirements of the C++ Standard Library, and so can be used in standard - library containers. Comparison operators are supplied so that shared_ptr + +

    boost::shared_ptr class template

    +

    Introduction
    + Best Practices
    + Synopsis
    + Members
    + Free Functions
    + Example
    + Handle/Body Idiom
    + Thread Safety
    + Frequently Asked Questions
    + Smart Pointer Timings
    + Programming Techniques

    +

    Introduction

    +

    The shared_ptr class template stores a pointer to a dynamically allocated + object, typically with a C++ new-expression. The object pointed to is + guaranteed to be deleted when the last shared_ptr pointing to it is + destroyed or reset.

    +
    Example:
    shared_ptr<X> p1( new X );
    +shared_ptr<void> p2( new int(5) );
    +
    + +

    shared_ptr deletes the exact pointer that has been passed at construction time, + complete with its original type, regardless of the template parameter. In the second example above, + when p2 is destroyed or reset, it will call delete on the original int* + that has been passed to the constructor, even though p2 itself is of type + shared_ptr<void> and stores a pointer of type void*.

    + +

    Every shared_ptr meets the CopyConstructible, MoveConstructible, + CopyAssignable and MoveAssignable + requirements of the C++ Standard Library, and can be used in standard + library containers. Comparison operators are supplied so that shared_ptr works with the standard library's associative containers.

    -

    Normally, a shared_ptr cannot correctly hold a pointer to a dynamically - allocated array. See shared_array for - that usage.

    -

    Because the implementation uses reference counting, cycles of shared_ptr instances - will not be reclaimed. For example, if main() holds a shared_ptr to - A, which directly or indirectly holds a shared_ptr back to A, - A's use count will be 2. Destruction of the original shared_ptr will - leave A dangling with a use count of 1. Use weak_ptr +

    Because the implementation uses reference counting, cycles of shared_ptr instances + will not be reclaimed. For example, if main() holds a shared_ptr to + A, which directly or indirectly holds a shared_ptr back to A, + A's use count will be 2. Destruction of the original shared_ptr will + leave A dangling with a use count of 1. Use weak_ptr to "break cycles."

    -

    The class template is parameterized on T, the type of the object pointed - to. shared_ptr and most of its member functions place no - requirements on T; it is allowed to be an incomplete type, or - void. Member functions that do place additional requirements (constructors, - reset) are explicitly documented below.

    -

    shared_ptr<T> can be implicitly converted to shared_ptr<U> - whenever T* can be implicitly converted to U*. - In particular, shared_ptr<T> is implicitly convertible - to shared_ptr<T const>, to shared_ptr<U> - where U is an accessible base of T, and to - shared_ptr<void>.

    -

    shared_ptr is now part of TR1, the first C++ - Library Technical Report. The latest draft of TR1 is available - at the following location:

    -

    http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf - (1.36Mb PDF)

    -

    This implementation conforms to the TR1 specification, with the only exception - that it resides in namespace boost instead of std::tr1.

    -

    Best Practices

    -

    A simple guideline that nearly eliminates the possibility of memory leaks is: - always use a named smart pointer variable to hold the result of new. - Every occurence of the new keyword in the code should have the - form:

    -
    shared_ptr<T> p(new Y);
    -

    It is, of course, acceptable to use another smart pointer in place of shared_ptr - above; having T and Y be the same type, or - passing arguments to Y's constructor is also OK.

    -

    If you observe this guideline, it naturally follows that you will have no - explicit deletes; try/catch constructs will - be rare.

    -

    Avoid using unnamed shared_ptr temporaries to save typing; to - see why this is dangerous, consider this example:

    -
    void f(shared_ptr<int>, int);
    +		

    The class template is parameterized on T, the type of the object pointed + to. shared_ptr and most of its member functions place no + requirements on T; it is allowed to be an incomplete type, or + void. Member functions that do place additional requirements (constructors, + reset) are explicitly documented below.

    +

    shared_ptr<T> can be implicitly converted to shared_ptr<U> + whenever T* can be implicitly converted to U*. + In particular, shared_ptr<T> is implicitly convertible + to shared_ptr<T const>, to shared_ptr<U> + where U is an accessible base of T, and to + shared_ptr<void>.

    +

    shared_ptr is now part of the C++11 Standard, as std::shared_ptr.

    +

    Starting with Boost release 1.53, shared_ptr can be used to hold a pointer to a dynamically + allocated array. This is accomplished by using an array type (T[] or T[N]) as + the template parameter. There is almost no difference between using an unsized array, T[], + and a sized array, T[N]; the latter just enables operator[] to perform a range check + on the index.

    +
    Example:
    shared_ptr<double[1024]> p1( new double(1024) );
    +shared_ptr<double[]> p2( new double(n) );
    +
    + +

    Best Practices

    +

    A simple guideline that nearly eliminates the possibility of memory leaks is: + always use a named smart pointer variable to hold the result of new. + Every occurence of the new keyword in the code should have the + form:

    +
    shared_ptr<T> p(new Y);
    +

    It is, of course, acceptable to use another smart pointer in place of shared_ptr + above; having T and Y be the same type, or + passing arguments to Y's constructor is also OK.

    +

    If you observe this guideline, it naturally follows that you will have no + explicit delete statements; try/catch constructs will + be rare.

    +

    Avoid using unnamed shared_ptr temporaries to save typing; to + see why this is dangerous, consider this example:

    +
    void f(shared_ptr<int>, int);
     int g();
     
     void ok()
     {
    -    shared_ptr<int> p(new int(2));
    -    f(p, g());
    +    shared_ptr<int> p( new int(2) );
    +    f( p, g() );
     }
     
     void bad()
     {
    -    f(shared_ptr<int>(new int(2)), g());
    +    f( shared_ptr<int>( new int(2) ), g() );
     }
    -
    -

    The function ok follows the guideline to the letter, whereas - bad constructs the temporary shared_ptr in place, +

    +

    The function ok follows the guideline to the letter, whereas + bad constructs the temporary shared_ptr in place, admitting the possibility of a memory leak. Since function arguments are - evaluated in unspecified order, it is possible for new int(2) to - be evaluated first, g() second, and we may never get to the - shared_ptr constructor if g throws an exception. - See Herb Sutter's treatment (also - here) of the issue for more information.

    -

    The exception safety problem described above may also be eliminated by using + evaluated in unspecified order, it is possible for new int(2) to + be evaluated first, g() second, and we may never get to the + shared_ptrconstructor if g throws an exception. + See Herb Sutter's treatment (also + here) of the issue for more information.

    +

    The exception safety problem described above may also be eliminated by using the make_shared or allocate_shared - factory functions defined in boost/make_shared.hpp. These factory functions also provide - an efficiency benefit by consolidating allocations.

    -

    Synopsis

    + factory functions defined in boost/make_shared.hpp. + These factory functions also provide an efficiency benefit by consolidating allocations.

    +

    Synopsis

    namespace boost {
     
       class bad_weak_ptr: public std::exception;
     
    -  template<class T> class weak_ptr;
    +  template<class T> class weak_ptr;
     
       template<class T> class shared_ptr {
     
         public:
     
    -      typedef T element_type;
    +      typedef see below element_type;
     
    -      shared_ptr(); // never throws
    -      template<class Y> explicit shared_ptr(Y * p);
    -      template<class Y, class D> shared_ptr(Y * p, D d);
    -      template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);
    -      ~shared_ptr(); // never throws
    +      shared_ptr(); // never throws
     
    -      shared_ptr(shared_ptr const & r); // never throws
    -      template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
    -      template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p); // never throws
    -      template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);
    -      template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r);
    +      template<class Y> explicit shared_ptr(Y * p);
    +      template<class Y, class D> shared_ptr(Y * p, D d);
    +      template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);
     
    -      shared_ptr & operator=(shared_ptr const & r); // never throws
    -      template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws
    -      template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);
    +      ~shared_ptr(); // never throws
     
    -      void reset(); // never throws
    -      template<class Y> void reset(Y * p);
    -      template<class Y, class D> void reset(Y * p, D d);
    -      template<class Y, class D, class A> void reset(Y * p, D d, A a);
    -      template<class Y> void reset(shared_ptr<Y> const & r, T * p); // never throws
    +      shared_ptr(shared_ptr const & r); // never throws
    +      template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
     
    -      T & operator*() const; // never throws
    -      T * operator->() const; // never throws
    -      T * get() const; // never throws
    +      shared_ptr(shared_ptr && r); // never throws
    +      template<class Y> shared_ptr(shared_ptr<Y> && r); // never throws
     
    -      bool unique() const; // never throws
    -      long use_count() const; // never throws
    +      template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p); // never throws
     
    -      operator unspecified-bool-type() const; // never throws
    +      template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);
     
    -      void swap(shared_ptr & b); // never throws
    +      template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r);
    +      template<class Y> shared_ptr(std::auto_ptr<Y> && r);
    +
    +      template<class Y, class D> shared_ptr(std::unique_ptr<Y, D> && r);
    +
    +      shared_ptr & operator=(shared_ptr const & r); // never throws
    +      template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws
    +
    +      shared_ptr & operator=(shared_ptr const && r); // never throws
    +      template<class Y> shared_ptr & operator=(shared_ptr<Y> const && r); // never throws
    +
    +      template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);
    +      template<class Y> shared_ptr & operator=(std::auto_ptr<Y> && r);
    +
    +      template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r);
    +
    +      void reset(); // never throws
    +
    +      template<class Y> void reset(Y * p);
    +      template<class Y, class D> void reset(Y * p, D d);
    +      template<class Y, class D, class A> void reset(Y * p, D d, A a);
    +
    +      template<class Y> void reset(shared_ptr<Y> const & r, element_type * p); // never throws
    +
    +      T & operator*() const; // never throws; only valid when T is not an array type
    +      T * operator->() const; // never throws; only valid when T is not an array type
    +
    +      element_type & operator[]( std::ptrdiff_t i ) const; // never throws; only valid when T is an array type
    +
    +      element_type * get() const; // never throws
    +
    +      bool unique() const; // never throws
    +      long use_count() const; // never throws
    +
    +      operator unspecified-bool-type() const; // never throws
    +
    +      void swap(shared_ptr & b); // never throws
    +      
    +      template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const; // never throws
    +      template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const; // never throws
       };
     
       template<class T, class U>
    -    bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
    +    bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
     
       template<class T, class U>
    -    bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
    +    bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
     
       template<class T, class U>
    -    bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
    +    bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
     
    -  template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws
    +  template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws
     
    -  template<class T> T * get_pointer(shared_ptr<T> const & p); // never throws
    +  template<class T> typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p); // never throws
     
       template<class T, class U>
    -    shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws
    +    shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws
     
       template<class T, class U>
    -    shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws
    +    shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws
     
       template<class T, class U>
    -    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r); // never throws
    +    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r); // never throws
    +
    +  template<class T, class U>
    +    shared_ptr<T> reinterpet_pointer_cast(shared_ptr<U> const & r); // never throws
     
       template<class E, class T, class Y>
    -    std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);
    +    std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);
     
       template<class D, class T>
    -    D * get_deleter(shared_ptr<T> const & p);
    +    D * get_deleter(shared_ptr<T> const & p);
     }
    -

    Members

    -

    element_type

    -
    typedef T element_type;
    +

    Members

    +

    element_type

    +
    typedef ... element_type;
    -

    Provides the type of the template parameter T.

    +

    element_type is T when T is not an array type, + and U when T is U[] or U[N].

    -

    constructors

    +

    default constructor

    shared_ptr(); // never throws
    -

    Effects: Constructs an empty shared_ptr.

    +

    Effects: Constructs an empty shared_ptr.

    Postconditions: use_count() == 0 && get() == 0.

    Throws: nothing.

    -

    [The nothrow guarantee is important, since reset() is specified +

    [The nothrow guarantee is important, since reset() is specified in terms of the default constructor; this implies that the constructor must not - allocate memory.]

    + allocate memory.]

    +

    pointer constructor

    template<class Y> explicit shared_ptr(Y * p);
    -

    Requirements: p must be convertible to T *. Y - must be a complete type. The expression delete p must be - well-formed, must not invoke undefined behavior, and must not throw exceptions. +

    Requirements: + Y must be a complete type. + The expression delete[] p, when T is an array type, or delete p, + when T is not an array type, + must be well-formed, must not invoke undefined behavior, and must not throw exceptions. + When T is U[N], Y (*) [N] must be convertible to T*; + when T is U[], Y (*) [] must be convertible to T*; + otherwise, Y* must be convertible to T*.

    -

    Effects: Constructs a shared_ptr that owns the pointer p.

    +

    Effects: + When T is not an array type, constructs a shared_ptr that owns + the pointer p. + Otherwise, constructs a shared_ptr that owns + p and a deleter of an unspecified type that calls delete[] p.

    Postconditions: use_count() == 1 && get() == p.

    -

    Throws: std::bad_alloc, or an implementation-defined +

    Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

    -

    Exception safety: If an exception is thrown, delete p is - called.

    -

    Notes: p must be a pointer to an object that was - allocated via a C++ new expression or be 0. The postcondition that - use count is 1 holds even if p is 0; invoking delete - on a pointer that has a value of 0 is harmless.

    +

    Exception safety: If an exception is thrown, the constructor calls + delete[] p, when T is an array type, + or delete p, when T is not an array type.

    +

    Notes: p must be a pointer to an object that was + allocated via a C++ new expression or be 0. The postcondition that + use count is 1 holds even if p is 0; invoking delete + on a pointer that has a value of 0 is harmless.

    -

    [This constructor has been changed to a template in order to remember the actual - pointer type passed. The destructor will call delete with the - same pointer, complete with its original type, even when T does - not have a virtual destructor, or is void.

    -

    The optional intrusive counting support has been dropped as it exposes too much - implementation details and doesn't interact well with weak_ptr. - The current implementation uses a different mechanism, - enable_shared_from_this, to solve the "shared_ptr from - this" problem.]

    - +

    [This constructor is a template in order to remember the actual + pointer type passed. The destructor will call delete with the + same pointer, complete with its original type, even when T does + not have a virtual destructor, or is void.]

    +

    constructors taking a deleter

    template<class Y, class D> shared_ptr(Y * p, D d);
     template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);
    -

    Requirements: p must be convertible to T *. D - must be CopyConstructible. The copy constructor and destructor - of D must not throw. The expression d(p) must be - well-formed, must not invoke undefined behavior, and must not throw exceptions. - A must be an Allocator, as described in section 20.1.5 (Allocator - requirements) of the C++ Standard. +

    Requirements: + D must be CopyConstructible. The copy constructor and destructor + of D must not throw. The expression d(p) must be + well-formed, must not invoke undefined behavior, and must not throw exceptions. + A must be an Allocator, as described in section 20.1.5 + (Allocator requirements) of the C++ Standard. + When T is U[N], Y (*) [N] must be convertible to T*; + when T is U[], Y (*) [] must be convertible to T*; + otherwise, Y* must be convertible to T*.

    -

    Effects: Constructs a shared_ptr that owns the pointer - p and the deleter d. The second constructor allocates - memory using a copy of a.

    +

    Effects: Constructs a shared_ptr that owns the pointer + p and the deleter d. The second constructor allocates + memory using a copy of a.

    Postconditions: use_count() == 1 && get() == p.

    -

    Throws: std::bad_alloc, or an implementation-defined +

    Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

    Exception safety: If an exception is thrown, d(p) is called.

    -

    Notes: When the the time comes to delete the object pointed to by p, - the stored copy of d is invoked with the stored copy of p +

    Notes: When the the time comes to delete the object pointed to by p, + the stored copy of d is invoked with the stored copy of p as an argument.

    -

    [Custom deallocators allow a factory function returning a shared_ptr +

    [Custom deallocators allow a factory function returning a shared_ptr to insulate the user from its memory allocation strategy. Since the deallocator is not part of the type, changing the allocation strategy does not break source or binary compatibility, and does not require a client recompilation. For - example, a "no-op" deallocator is useful when returning a shared_ptr - to a statically allocated object, and other variations allow a shared_ptr - to be used as a wrapper for another smart pointer, easing interoperability.

    -

    The support for custom deallocators does not impose significant overhead. Other - shared_ptr features still require a deallocator to be kept.

    -

    The requirement that the copy constructor of D does not throw comes from - the pass by value. If the copy constructor throws, the pointer is leaked. - Removing the requirement requires a pass by (const) reference.

    -

    The main problem with pass by reference lies in its interaction with rvalues. A - const reference may still cause a copy, and will require a const operator(). A - non-const reference won't bind to an rvalue at all. A good solution to this - problem is the rvalue reference proposed in - N1377/N1385.]

    + example, a "no-op" deallocator is useful when returning a shared_ptr + to a statically allocated object, and other variations allow a shared_ptr + to be used as a wrapper for another smart pointer, easing interoperability.

    +

    The support for custom deallocators does not impose significant overhead. Other + shared_ptr features still require a deallocator to be kept.

    +

    The requirement that the copy constructor of D does not throw comes from + the pass by value. If the copy constructor throws, the pointer would leak.]

    +

    copy and converting constructors

    shared_ptr(shared_ptr const & r); // never throws
     template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
    -

    Effects: If r is empty, constructs an empty shared_ptr; - otherwise, constructs a shared_ptr that shares ownership with r.

    +

    Requires: Y* should be convertible to T*.

    +

    Effects: If r is empty, constructs an empty shared_ptr; + otherwise, constructs a shared_ptr that shares ownership with r.

    Postconditions: get() == r.get() && use_count() == r.use_count().

    Throws: nothing.

    -
    template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p); // never throws
    +

    move constructors

    +
    shared_ptr(shared_ptr && r); // never throws
    +template<class Y> shared_ptr(shared_ptr<Y> && r); // never throws
    -

    Effects: constructs a shared_ptr that shares ownership with - r and stores p.

    +

    Requires: Y* should be convertible to T*.

    +

    Effects: Move-constructs a shared_ptr from r.

    +

    Postconditions: *this contains the old value of r. r is empty and r.get() == 0.

    +

    Throws: nothing.

    +
    +

    aliasing constructor

    +
    template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p); // never throws
    +
    +

    Effects: constructs a shared_ptr that shares ownership with + r and stores p.

    Postconditions: get() == p && use_count() == r.use_count().

    Throws: nothing.

    -
    template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);
    +

    weak_ptr constructor

    +
    template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);
    -

    Effects: Constructs a shared_ptr that shares ownership with - r and stores a copy of the pointer stored in r.

    +

    Requires: Y* should be convertible to T*.

    +

    Effects: Constructs a shared_ptr that shares ownership with + r and stores a copy of the pointer stored in r.

    Postconditions: use_count() == r.use_count().

    -

    Throws: bad_weak_ptr when r.use_count() == 0.

    +

    Throws: bad_weak_ptr when r.use_count() == 0.

    Exception safety: If an exception is thrown, the constructor has no effect.

    -
    template<class Y> shared_ptr(std::auto_ptr<Y> & r);
    -
    -

    Effects: Constructs a shared_ptr, as if by storing a copy of r.release().

    +

    auto_ptr constructors

    +
    template<class Y> shared_ptr(std::auto_ptr<Y> & r);
    +template<class Y> shared_ptr(std::auto_ptr<Y> && r);
    +
    +

    Requires: Y* should be convertible to T*.

    +

    Effects: Constructs a shared_ptr, as if by storing a copy of r.release().

    Postconditions: use_count() == 1.

    -

    Throws: std::bad_alloc, or an implementation-defined +

    Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

    -

    Exception safety: If an exception is thrown, the constructor has no - effect.

    -
    -

    [This constructor takes a the source auto_ptr by reference and - not by value, and cannot accept auto_ptr temporaries. This is - by design, as the constructor offers the strong guarantee; an rvalue reference - would solve this problem, too.]

    -

    destructor

    +

    Exception safety: If an exception is thrown, the constructor has no + effect.

    +
    +

    unique_ptr constructor

    +
    template<class Y, class D> shared_ptr(std::unique_ptr<Y, D> && r);
    +
    +

    Requires: Y* should be convertible to T*.

    +

    Effects: + Equivalent to shared_ptr( r.release(), r.get_deleter() ) when D is not a reference type. + Otherwise, equivalent to shared_ptr( r.release(), del ), where del is a deleter + that stores the reference rd returned from r.get_deleter() and del(p) calls rd(p).

    +

    Postconditions: use_count() == 1.

    +

    Throws: std::bad_alloc, or an implementation-defined + exception when a resource other than memory could not be obtained.

    +

    Exception safety: If an exception is thrown, the constructor has no + effect.

    +
    +

    destructor

    ~shared_ptr(); // never throws
    -
    -

    Effects:

    -
      -
    • - If *this is empty, or shares ownership with - another shared_ptr instance (use_count() > 1), - there are no side effects. -
    • - Otherwise, if *this owns a pointer p - and a deleter d, d(p) - is called. -
    • - Otherwise, *this owns a pointer p, - and delete p is called.
    -

    Throws: nothing.

    -
    -

    assignment

    +
    +

    Effects:

    +
      +
    • + If *this is empty, or shares ownership with + another shared_ptr instance (use_count() > 1), + there are no side effects.
    • +
    • + Otherwise, if *this owns a pointer p + and a deleter d, d(p) + is called.
    • +
    • + Otherwise, *this owns a pointer p, + and delete p is called.
    • +
    +

    Throws: nothing.

    +
    +

    assignment

    shared_ptr & operator=(shared_ptr const & r); // never throws
     template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws
     template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);
    -
    -

    Effects: Equivalent to shared_ptr(r).swap(*this).

    -

    Returns: *this.

    -

    Notes: The use count updates caused by the temporary object construction +

    +

    Effects: Equivalent to shared_ptr(r).swap(*this).

    +

    Returns: *this.

    +

    Notes: The use count updates caused by the temporary object construction and destruction are not considered observable side effects, and the implementation is free to meet the effects (and the implied guarantees) via - different means, without creating a temporary. In particular, in the example:

    + different means, without creating a temporary. In particular, in the example:

    shared_ptr<int> p(new int);
     shared_ptr<void> q(p);
     p = p;
     q = p;
     

    both assignments may be no-ops.

    -
    -

    reset

    +
    +
    shared_ptr & operator=(shared_ptr && r); // never throws
    +template<class Y> shared_ptr & operator=(shared_ptr<Y> && r); // never throws
    +template<class Y> shared_ptr & operator=(std::auto_ptr<Y> && r);
    +template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r);
    +
    +

    Effects: Equivalent to shared_ptr( std::move(r) ).swap(*this).

    +

    Returns: *this.

    +
    +

    reset

    void reset(); // never throws
    -
    -

    Effects: Equivalent to shared_ptr().swap(*this).

    -
    +
    +

    Effects: Equivalent to shared_ptr().swap(*this).

    +
    template<class Y> void reset(Y * p);
    -
    -

    Effects: Equivalent to shared_ptr(p).swap(*this).

    -
    +
    +

    Effects: Equivalent to shared_ptr(p).swap(*this).

    +
    template<class Y, class D> void reset(Y * p, D d);
    -
    -

    Effects: Equivalent to shared_ptr(p, d).swap(*this).

    -
    +
    +

    Effects: Equivalent to shared_ptr(p, d).swap(*this).

    +
    template<class Y, class D, class A> void reset(Y * p, D d, A a);
    -
    -

    Effects: Equivalent to shared_ptr(p, d, a).swap(*this).

    -
    -
    template<class Y> void reset(shared_ptr<Y> const & r, T * p); // never throws
    -
    -

    Effects: Equivalent to shared_ptr(r, p).swap(*this).

    -
    -

    indirection

    +
    +

    Effects: Equivalent to shared_ptr(p, d, a).swap(*this).

    +
    +
    template<class Y> void reset(shared_ptr<Y> const & r, element_type * p); // never throws
    +
    +

    Effects: Equivalent to shared_ptr(r, p).swap(*this).

    +
    +

    indirection

    T & operator*() const; // never throws
    -

    Requirements: The stored pointer must not be 0.

    +

    Requirements: T should not be an array type. The stored pointer must not be 0.

    Returns: a reference to the object pointed to by the stored pointer.

    Throws: nothing.

    T * operator->() const; // never throws
    -

    Requirements: The stored pointer must not be 0.

    +

    Requirements: T should not be an array type. The stored pointer must not be 0.

    Returns: the stored pointer.

    Throws: nothing.

    -

    get

    -
    T * get() const; // never throws
    +
    element_type & operator[]( std::ptrdiff_t i ) const; // never throws
    +
    +

    Requirements: T should be an array type. The stored pointer must not be 0. + i >= 0. If T is U[N], i < N.

    +

    Returns: get()[ i ].

    +

    Throws: nothing.

    +
    +

    get

    +
    element_type * get() const; // never throws

    Returns: the stored pointer.

    Throws: nothing.

    -

    unique

    +

    unique

    bool unique() const; // never throws

    Returns: use_count() == 1.

    Throws: nothing.

    -

    Notes: unique() may be faster than use_count(). +

    Notes: unique() may be faster than use_count(). If you are using unique() to implement copy on write, do not rely - on a specific value when the stored pointer is zero.

    + on a specific value when the stored pointer is zero.

    -

    use_count

    +

    use_count

    long use_count() const; // never throws
    -

    Returns: the number of shared_ptr objects, *this included, - that share ownership with *this, or 0 when *this - is empty.

    +

    Returns: the number of shared_ptr objects, *this included, + that share ownership with *this, or 0 when *this + is empty.

    Throws: nothing.

    -

    Notes: use_count() is not necessarily efficient. Use only - for debugging and testing purposes, not for production code.

    +

    Notes: use_count() is not necessarily efficient. Use only + for debugging and testing purposes, not for production code.

    -

    conversions

    +

    conversions

    operator unspecified-bool-type () const; // never throws

    Returns: an unspecified value that, when used in boolean contexts, is equivalent to get() != 0.

    Throws: nothing.

    -

    Notes: This conversion operator allows shared_ptr objects to be +

    Notes: This conversion operator allows shared_ptr objects to be used in boolean contexts, like if (p && p->valid()) {}. The actual target type is typically a pointer to a member function, avoiding - many of the implicit conversion pitfalls.

    + many of the implicit conversion pitfalls.

    -

    [The conversion to bool is not merely syntactic sugar. It allows shared_ptrs - to be declared in conditions when using dynamic_pointer_cast - or weak_ptr::lock.]

    -

    swap

    +

    [The conversion to bool is not merely syntactic sugar. It allows shared_ptrs + to be declared in conditions when using dynamic_pointer_cast + or weak_ptr::lock.]

    +

    swap

    void swap(shared_ptr & b); // never throws

    Effects: Exchanges the contents of the two smart pointers.

    Throws: nothing.

    -

    Free Functions

    -

    comparison

    +

    Free Functions

    +

    comparison

    template<class T, class U>
       bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
    template<typename T>
    -    shared_ptr<T[]> make_shared_noinit(size_t size);
    + shared_ptr<T[]> make_shared_noinit(size_t size); +template<typename T, typename A> + shared_ptr<T[]> make_shared_noinit(const A& allocator, size_t size);

    Description: This overload does not perform value initialization of elements.

    template<typename T>
    -    shared_ptr<T[N]> make_shared_noinit();
    + shared_ptr<T[N]> make_shared_noinit(); +template<typename T, typename A> + shared_ptr<T[N]> make_shared_noinit(const A& allocator);

    Description: This overload of the utility above is used for a fixed size array.

    diff --git a/test/allocate_shared_array_esft_test.cpp b/test/allocate_shared_array_esft_test.cpp index 2315421..cea73c6 100644 --- a/test/allocate_shared_array_esft_test.cpp +++ b/test/allocate_shared_array_esft_test.cpp @@ -38,5 +38,15 @@ int main() { BOOST_TEST(type::instances == 3); } } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(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_test.cpp b/test/allocate_shared_array_test.cpp index 91f3fb5..84ef3a8 100644 --- a/test/allocate_shared_array_test.cpp +++ b/test/allocate_shared_array_test.cpp @@ -121,5 +121,79 @@ int main() { BOOST_TEST(type::instances == 0); } #endif + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(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::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + 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::allocate_shared_noinit(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::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + 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::allocate_shared_noinit(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_noinit(std::allocator()); + 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_noinit(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); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + 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/allocate_shared_array_throws_test.cpp b/test/allocate_shared_array_throws_test.cpp index 65a7985..d300f2c 100644 --- a/test/allocate_shared_array_throws_test.cpp +++ b/test/allocate_shared_array_throws_test.cpp @@ -59,5 +59,19 @@ int main() { BOOST_TEST(type::instances == 0); } #endif + BOOST_TEST(type::instances == 0); + try { + boost::allocate_shared_noinit(std::allocator(), 6); + BOOST_ERROR("allocate_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + try { + boost::allocate_shared_noinit(std::allocator(), 3); + BOOST_ERROR("allocate_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } return boost::report_errors(); } diff --git a/test/allocate_shared_arrays_test.cpp b/test/allocate_shared_arrays_test.cpp index ab22c23..7c719ce 100644 --- a/test/allocate_shared_arrays_test.cpp +++ b/test/allocate_shared_arrays_test.cpp @@ -100,5 +100,61 @@ int main() { BOOST_TEST(type::instances == 0); } #endif + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(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_noinit(std::allocator()); + 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_noinit(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_noinit(std::allocator()); + 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(); } From 6e269872df83e8be2939c90bd8c4afd3ca61ea22 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 11 Dec 2012 18:04:09 +0000 Subject: [PATCH 164/210] Explicitly name detail array construct overloads for different parameter types. [SVN r81859] --- include/boost/smart_ptr/detail/array_deleter.hpp | 8 ++++---- include/boost/smart_ptr/detail/array_utility.hpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 8ef0d11..7909265 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -34,13 +34,13 @@ namespace boost { } #if defined(BOOST_HAS_RVALUE_REFS) void construct(T* memory, T&& value) { - array_construct(memory, size, sp_forward(value)); + array_construct_value(memory, size, sp_forward(value)); object = memory; } #if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { - array_construct(memory, size, sp_forward(args)...); + array_construct_args(memory, size, sp_forward(args)...); object = memory; } #endif @@ -85,13 +85,13 @@ namespace boost { } #if defined(BOOST_HAS_RVALUE_REFS) void construct(T* memory, T&& value) { - array_construct(memory, N, sp_forward(value)); + array_construct_value(memory, N, sp_forward(value)); object = memory; } #if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { - array_construct(memory, N, sp_forward(args)...); + array_construct_args(memory, N, sp_forward(args)...); object = memory; } #endif diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp index b584599..3b685ad 100644 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -55,7 +55,7 @@ namespace boost { } #if defined(BOOST_HAS_RVALUE_REFS) template - inline void array_construct(T* memory, std::size_t size, T&& value) { + inline void array_construct_value(T* memory, std::size_t size, T&& value) { std::size_t i = 0; try { for (; i < size; i++) { @@ -69,7 +69,7 @@ namespace boost { } #if defined(BOOST_HAS_VARIADIC_TMPL) template - inline void array_construct(T* memory, std::size_t size, Args&&... args) { + inline void array_construct_args(T* memory, std::size_t size, Args&&... args) { std::size_t i = 0; try { for (; i < size; i++) { From fd52dbc411674054238fe40e779e1b3ddf3f933c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 11 Dec 2012 18:21:29 +0000 Subject: [PATCH 165/210] Change make_shared to use the new _internal_get_untyped_deleter. Refs #6830. [SVN r81860] --- .../boost/smart_ptr/detail/shared_count.hpp | 5 + .../detail/sp_counted_base_acc_ia64.hpp | 1 + .../smart_ptr/detail/sp_counted_base_aix.hpp | 1 + .../detail/sp_counted_base_cw_ppc.hpp | 1 + .../detail/sp_counted_base_cw_x86.hpp | 1 + .../detail/sp_counted_base_gcc_ia64.hpp | 1 + .../detail/sp_counted_base_gcc_mips.hpp | 1 + .../detail/sp_counted_base_gcc_ppc.hpp | 1 + .../detail/sp_counted_base_gcc_sparc.hpp | 1 + .../detail/sp_counted_base_gcc_x86.hpp | 1 + .../smart_ptr/detail/sp_counted_base_nt.hpp | 1 + .../smart_ptr/detail/sp_counted_base_pt.hpp | 1 + .../detail/sp_counted_base_snc_ps3.hpp | 1 + .../detail/sp_counted_base_solaris.hpp | 1 + .../smart_ptr/detail/sp_counted_base_spin.hpp | 1 + .../smart_ptr/detail/sp_counted_base_sync.hpp | 1 + .../detail/sp_counted_base_vacpp_ppc.hpp | 1 + .../smart_ptr/detail/sp_counted_base_w32.hpp | 1 + .../smart_ptr/detail/sp_counted_impl.hpp | 15 +++ .../boost/smart_ptr/make_shared_object.hpp | 97 +++++++++++-------- include/boost/smart_ptr/shared_ptr.hpp | 27 ++++-- 21 files changed, 112 insertions(+), 49 deletions(-) diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index 5d22f86..e91179d 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -447,6 +447,11 @@ public: { return pi_? pi_->get_deleter( ti ): 0; } + + void * get_untyped_deleter() const + { + return pi_? pi_->get_untyped_deleter(): 0; + } }; diff --git a/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp index dffd995..cebc243 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp @@ -104,6 +104,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp b/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp index 0208678..fe6c727 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp @@ -96,6 +96,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp index 51ac56a..6c268e8 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp @@ -124,6 +124,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp index 1234e78..81eba6f 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp @@ -112,6 +112,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp index d122a49..f6e3904 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp @@ -111,6 +111,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp index 3f1f449..545c8ae 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -135,6 +135,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp index 7f5c414..2e5bc0e 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp @@ -135,6 +135,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp index 21fa59d..c6d20ce 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @@ -120,6 +120,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp index 4d7fa8d..173dce5 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp @@ -127,6 +127,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp index dfd70e7..5c901f9 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp @@ -59,6 +59,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp index 3c56fec..a742c3d 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp @@ -70,6 +70,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp index e51e676..a043e02 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp @@ -115,6 +115,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp b/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp index d1b6bec..0e05fef 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp @@ -62,6 +62,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp index bbd11e6..77734e7 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp @@ -84,6 +84,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp index 41f654e..fafed0e 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp @@ -109,6 +109,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp index 842f58f..162f309 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp @@ -104,6 +104,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp index 06aa456..ff394dc 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp @@ -67,6 +67,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; void add_ref_copy() { diff --git a/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/include/boost/smart_ptr/detail/sp_counted_impl.hpp index aab39bd..d15cd3c 100644 --- a/include/boost/smart_ptr/detail/sp_counted_impl.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -83,6 +83,11 @@ public: return 0; } + virtual void * get_untyped_deleter() + { + return 0; + } + #if defined(BOOST_SP_USE_STD_ALLOCATOR) void * operator new( std::size_t ) @@ -153,6 +158,11 @@ public: return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast( del ): 0; } + virtual void * get_untyped_deleter() + { + return &reinterpret_cast( del ); + } + #if defined(BOOST_SP_USE_STD_ALLOCATOR) void * operator new( std::size_t ) @@ -226,6 +236,11 @@ public: { return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast( d_ ): 0; } + + virtual void * get_untyped_deleter() + { + return &reinterpret_cast( d_ ); + } }; #ifdef __CODEGUARD__ diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp index c6e28aa..468cc59 100644 --- a/include/boost/smart_ptr/make_shared_object.hpp +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -135,7 +135,7 @@ template< class T > typename boost::detail::sp_if_not_array< T >::type make_shar { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -148,11 +148,28 @@ template< class T > typename boost::detail::sp_if_not_array< T >::type make_shar return boost::shared_ptr< T >( pt, pt2 ); } +template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared_noinit() +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); + + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); + + 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -173,7 +190,7 @@ template< class T, class Arg1, class... Args > typename boost::detail::sp_if_not { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -190,7 +207,7 @@ template< class T, class A, class Arg1, class... Args > typename boost::detail:: { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -212,7 +229,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -233,7 +250,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -254,7 +271,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -276,7 +293,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -298,7 +315,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -321,7 +338,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -344,7 +361,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -368,7 +385,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -392,7 +409,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -417,7 +434,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -442,7 +459,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -468,7 +485,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -494,7 +511,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -521,7 +538,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -548,7 +565,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -576,7 +593,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -604,7 +621,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -633,7 +650,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -666,7 +683,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -684,7 +701,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -702,7 +719,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -720,7 +737,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -738,7 +755,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -756,7 +773,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -774,7 +791,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -792,7 +809,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -810,7 +827,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -828,7 +845,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -846,7 +863,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -864,7 +881,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -882,7 +899,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -900,7 +917,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -918,7 +935,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -936,7 +953,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -954,7 +971,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A { 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); @@ -972,7 +989,7 @@ 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 ); + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); void * pv = pd->address(); diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index ad7a92a..fa29116 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -696,11 +696,16 @@ public: return pn < rhs.pn; } - void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const + void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT { return pn.get_deleter( ti ); } + void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT + { + return pn.get_untyped_deleter(); + } + bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT { return px == r.px && pn == r.pn; @@ -881,9 +886,9 @@ template D * basic_get_deleter(shared_ptr const & p) #else -template D * basic_get_deleter(shared_ptr const & p) +template D * basic_get_deleter( shared_ptr const & p ) BOOST_NOEXCEPT { - return static_cast(p._internal_get_deleter(BOOST_SP_TYPEID(D))); + return static_cast( p._internal_get_deleter(BOOST_SP_TYPEID(D)) ); } #endif @@ -904,11 +909,13 @@ public: { deleter_ = deleter; } - template D* get_deleter() const + + template D* get_deleter() const BOOST_NOEXCEPT { - return boost::detail::basic_get_deleter(deleter_); + return boost::detail::basic_get_deleter( deleter_ ); } - template< class T> void operator()( T* ) + + template< class T> void operator()( T* ) { BOOST_ASSERT( deleter_.use_count() <= 1 ); deleter_.reset(); @@ -917,17 +924,19 @@ public: } // namespace detail -template D * get_deleter(shared_ptr const & p) +template D * get_deleter( shared_ptr const & p ) BOOST_NOEXCEPT { D *del = boost::detail::basic_get_deleter(p); - if(del == 0) + + if(del == 0) { boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter(p); // The following get_deleter method call is fully qualified because // older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter() if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter(); } - return del; + + return del; } // atomic access From 67f5e9825e2bc25d0a8899d35d1c93c7dc35201a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 11 Dec 2012 18:32:24 +0000 Subject: [PATCH 166/210] Add allocate_shared_noinit. [SVN r81861] --- include/boost/smart_ptr/make_shared_object.hpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp index 468cc59..aff19b9 100644 --- a/include/boost/smart_ptr/make_shared_object.hpp +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -182,6 +182,23 @@ template< class T, class A > typename boost::detail::sp_if_not_array< T >::type return boost::shared_ptr< T >( pt, pt2 ); } +template< class T, class A > typename boost::detail::sp_if_not_array< T >::type allocate_shared_noinit( A const & a ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); + + boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() ); + + 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 From db542de9085666c3b7642c8184913cb9e0cdaacf Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 11 Dec 2012 20:51:05 +0000 Subject: [PATCH 167/210] Use _internal_get_untyped_deleter in allocate_shared_array and make_shared_array [SVN r81865] --- .../boost/smart_ptr/allocate_shared_array.hpp | 92 +++++++++---------- include/boost/smart_ptr/make_shared_array.hpp | 90 +++++++++--------- 2 files changed, 91 insertions(+), 91 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 9aaacc7..7f78d0e 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -1,9 +1,9 @@ /* - * Copyright (c) 2012 Glen Joseph Fernandes + * 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 + * 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 @@ -20,7 +20,7 @@ namespace boost { template - inline typename boost::detail::sp_if_array::type + inline typename boost::detail::sp_if_array::type allocate_shared(const A& allocator, std::size_t size) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; @@ -30,9 +30,9 @@ namespace boost { boost::detail::allocate_array_helper a1(allocator, n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct(p2); return boost::shared_ptr(s1, p1); } @@ -48,9 +48,9 @@ namespace boost { boost::detail::allocate_array_helper a1(allocator, n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } @@ -59,17 +59,17 @@ namespace boost { allocate_shared(const A& allocator, Args&&... args) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - enum { - N = boost::detail::array_total::size + enum { + N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; boost::detail::allocate_array_helper a1(allocator, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } @@ -77,7 +77,7 @@ namespace boost { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template inline typename boost::detail::sp_if_array::type - allocate_shared(const A& allocator, + allocate_shared(const A& allocator, std::initializer_list::type> list) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; @@ -89,10 +89,10 @@ namespace boost { boost::detail::allocate_array_helper a1(allocator, n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } @@ -104,8 +104,8 @@ namespace boost { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - enum { - N = boost::detail::array_total::size + enum { + N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; @@ -113,21 +113,21 @@ namespace boost { boost::detail::allocate_array_helper a1(allocator, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } template inline typename boost::detail::sp_if_array::type - allocate_shared(const A& allocator, std::size_t size, + allocate_shared(const A& allocator, std::size_t size, const typename boost::detail::array_inner::type& list) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - enum { + enum { M = boost::detail::array_total::size }; T1* p1 = 0; @@ -137,41 +137,41 @@ namespace boost { boost::detail::allocate_array_helper a1(allocator, n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } template inline typename boost::detail::sp_if_size_array::type - allocate_shared(const A& allocator, + allocate_shared(const A& allocator, const typename boost::detail::array_inner::type& list) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - enum { - M = boost::detail::array_total::size, - N = boost::detail::array_total::size + enum { + M = boost::detail::array_total::size, + N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; - T3* p3 = 0; + T3* p3 = 0; boost::detail::allocate_array_helper a1(allocator, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } #if defined(BOOST_HAS_RVALUE_REFS) template inline typename boost::detail::sp_if_array::type - allocate_shared(const A& allocator, std::size_t size, + allocate_shared(const A& allocator, std::size_t size, typename boost::detail::array_base::type&& value) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; @@ -181,29 +181,29 @@ namespace boost { boost::detail::allocate_array_helper a1(allocator, n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } template inline typename boost::detail::sp_if_size_array::type - allocate_shared(const A& allocator, + allocate_shared(const A& allocator, typename boost::detail::array_base::type&& value) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - enum { - N = boost::detail::array_total::size + enum { + N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; boost::detail::allocate_array_helper a1(allocator, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } @@ -220,9 +220,9 @@ namespace boost { boost::detail::allocate_array_helper a1(allocator, n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + typedef boost::detail::array_deleter* D2; + p1 = reinterpret_cast(p2); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_noinit(p2); return boost::shared_ptr(s1, p1); } @@ -231,17 +231,17 @@ namespace boost { allocate_shared_noinit(const A& allocator) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - enum { - N = boost::detail::array_total::size + enum { + N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; boost::detail::allocate_array_helper a1(allocator, &p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + typedef boost::detail::array_deleter* D2; + p1 = reinterpret_cast(p2); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_noinit(p2); return boost::shared_ptr(s1, p1); } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index cf63ecb..b9c197c 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -1,9 +1,9 @@ /* - * Copyright (c) 2012 Glen Joseph Fernandes + * 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 + * 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 @@ -30,9 +30,9 @@ namespace boost { boost::detail::make_array_helper a1(n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + typedef boost::detail::array_deleter* D2; + p1 = reinterpret_cast(p2); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct(p2); return boost::shared_ptr(s1, p1); } @@ -48,9 +48,9 @@ namespace boost { boost::detail::make_array_helper a1(n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + typedef boost::detail::array_deleter* D2; + p1 = reinterpret_cast(p2); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } @@ -59,17 +59,17 @@ namespace boost { make_shared(Args&&... args) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - enum { - N = boost::detail::array_total::size + enum { + N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + typedef boost::detail::array_deleter* D2; + p1 = reinterpret_cast(p2); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } @@ -88,13 +88,13 @@ namespace boost { boost::detail::make_array_helper a1(n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); - } + } #endif #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) template @@ -103,8 +103,8 @@ namespace boost { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - enum { - N = boost::detail::array_total::size + enum { + N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; @@ -112,22 +112,22 @@ namespace boost { boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } template inline typename boost::detail::sp_if_array::type - make_shared(std::size_t size, + make_shared(std::size_t size, const typename boost::detail::array_inner::type& list) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - enum { - M = boost::detail::array_total::size + enum { + M = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; @@ -136,10 +136,10 @@ namespace boost { boost::detail::make_array_helper a1(n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } @@ -149,9 +149,9 @@ namespace boost { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; - enum { + enum { M = boost::detail::array_total::size, - N = boost::detail::array_total::size + N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; @@ -159,17 +159,17 @@ namespace boost { boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } #if defined(BOOST_HAS_RVALUE_REFS) template inline typename boost::detail::sp_if_array::type - make_shared(std::size_t size, + make_shared(std::size_t size, typename boost::detail::array_base::type&& value) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; @@ -179,9 +179,9 @@ namespace boost { boost::detail::make_array_helper a1(n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } @@ -190,17 +190,17 @@ namespace boost { make_shared(typename boost::detail::array_base::type&& value) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - enum { - N = boost::detail::array_total::size + enum { + N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; + typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } @@ -217,9 +217,9 @@ namespace boost { boost::detail::make_array_helper a1(n1, &p2); boost::detail::array_deleter d1(n1); boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + typedef boost::detail::array_deleter* D2; + p1 = reinterpret_cast(p2); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_noinit(p2); return boost::shared_ptr(s1, p1); } @@ -228,17 +228,17 @@ namespace boost { make_shared_noinit() { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - enum { - N = boost::detail::array_total::size + enum { + N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; boost::detail::make_array_helper a1(&p2); boost::detail::array_deleter d1; boost::shared_ptr s1(p1, d1, a1); - boost::detail::array_deleter* d2; - p1 = reinterpret_cast(p2); - d2 = get_deleter >(s1); + typedef boost::detail::array_deleter* D2; + p1 = reinterpret_cast(p2); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); d2->construct_noinit(p2); return boost::shared_ptr(s1, p1); } From 5f0155cca6299c75e8fe035a1d7d8d065df2fc6c Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 11 Dec 2012 22:44:57 +0000 Subject: [PATCH 168/210] Documentation corrections: make_shared_array.html [SVN r81867] --- make_shared_array.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/make_shared_array.html b/make_shared_array.html index 6f34519..1f0f4d3 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -205,17 +205,17 @@ template<typename T, typename A>
    template<typename T>
         shared_ptr<T[]> make_shared_noinit(size_t size);
     template<typename T, typename A>
    -    shared_ptr<T[]> make_shared_noinit(const A& allocator, size_t size);
    + shared_ptr<T[]> allocate_shared_noinit(const A& allocator, size_t size);
    -

    Description: This overload does not perform value +

    Description: These overloads do not perform any value initialization of elements.

    template<typename T>
         shared_ptr<T[N]> make_shared_noinit();
     template<typename T, typename A>
    -    shared_ptr<T[N]> make_shared_noinit(const A& allocator);
    + shared_ptr<T[N]> allocate_shared_noinit(const A& allocator);
    -

    Description: This overload of the utility above is used for a +

    Description: These overloads of the utilities above are for a fixed size array.

    Example

    From 4ba8d879f144fcff3de605feb74af77fb51b3848 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Thu, 13 Dec 2012 04:04:23 +0000 Subject: [PATCH 169/210] Use BOOST_NO_CXX11_RVALUE_REFERENCES and BOOST_NO_CXX11_VARIADIC_TEMPLATES instead of the legacy macros. Rename identifiers of detail utility functions. [SVN r81886] --- .../boost/smart_ptr/allocate_shared_array.hpp | 70 +++++++++---------- .../boost/smart_ptr/detail/array_deleter.hpp | 56 +++++++-------- .../boost/smart_ptr/detail/array_utility.hpp | 28 ++++---- include/boost/smart_ptr/make_shared_array.hpp | 68 +++++++++--------- make_shared_array.html | 22 +++--- test/Jamfile.v2 | 8 +-- test/allocate_shared_array_create_test.cpp | 2 +- test/allocate_shared_array_init_test.cpp | 58 +++++++-------- test/allocate_shared_array_test.cpp | 2 +- test/allocate_shared_array_throws_test.cpp | 2 +- test/allocate_shared_arrays_create_test.cpp | 34 ++++----- test/allocate_shared_arrays_test.cpp | 2 +- test/make_shared_array_create_test.cpp | 2 +- test/make_shared_array_init_test.cpp | 58 +++++++-------- test/make_shared_array_test.cpp | 2 +- test/make_shared_array_throws_test.cpp | 2 +- test/make_shared_arrays_create_test.cpp | 34 ++++----- test/make_shared_arrays_test.cpp | 2 +- 18 files changed, 226 insertions(+), 226 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 7f78d0e..8afe54d 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -33,10 +33,10 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct(p2); + d2->init(p2); return boost::shared_ptr(s1, p1); } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template inline typename boost::detail::sp_if_array::type allocate_shared(const A& allocator, std::size_t size, Args&&... args) { @@ -51,7 +51,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct(p2, boost::detail::sp_forward(args)...); + d2->init_args(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } template @@ -70,30 +70,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct(p2, boost::detail::sp_forward(args)...); - return boost::shared_ptr(s1, p1); - } -#endif -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - template - inline typename boost::detail::sp_if_array::type - allocate_shared(const A& allocator, - std::initializer_list::type> list) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef const T2 T3; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = 0; - std::size_t n1 = list.size() * boost::detail::array_total::size; - boost::detail::allocate_array_helper a1(allocator, n1, &p2); - boost::detail::array_deleter d1(n1); - boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; - p3 = reinterpret_cast(list.begin()); - p1 = reinterpret_cast(p2); - D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_list(p2, p3); + d2->init_args(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } #endif @@ -117,7 +94,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_list(p2, p3); + d2->init_list(p2, p3); return boost::shared_ptr(s1, p1); } template @@ -141,7 +118,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_list(p2, p3); + d2->init_list(p2, p3); return boost::shared_ptr(s1, p1); } template @@ -165,10 +142,33 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_list(p2, p3); + d2->init_list(p2, p3); return boost::shared_ptr(s1, p1); } -#if defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + inline typename boost::detail::sp_if_array::type + allocate_shared(const A& allocator, + std::initializer_list::type> list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + typedef const T2 T3; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n1 = list.size() * boost::detail::array_total::size; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1(n1); + boost::shared_ptr s1(p1, d1, a1); + typedef boost::detail::array_deleter* D2; + p3 = reinterpret_cast(list.begin()); + p1 = reinterpret_cast(p2); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); + d2->init_list(p2, p3); + return boost::shared_ptr(s1, p1); + } +#endif +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template inline typename boost::detail::sp_if_array::type allocate_shared(const A& allocator, std::size_t size, @@ -184,7 +184,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct(p2, boost::detail::sp_forward(value)); + d2->init_value(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } template @@ -204,7 +204,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct(p2, boost::detail::sp_forward(value)); + d2->init_value(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } #endif @@ -223,7 +223,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_noinit(p2); + d2->noinit(p2); return boost::shared_ptr(s1, p1); } template @@ -242,7 +242,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_noinit(p2); + d2->noinit(p2); return boost::shared_ptr(s1, p1); } } diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 7909265..2bc8a8a 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -28,34 +28,34 @@ namespace boost { array_destroy(object, size); } } - void construct(T* memory) { - array_construct(memory, size); + void init(T* memory) { + array_init(memory, size); object = memory; } -#if defined(BOOST_HAS_RVALUE_REFS) - void construct(T* memory, T&& value) { - array_construct_value(memory, size, sp_forward(value)); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + void init_value(T* memory, T&& value) { + array_init_value(memory, size, sp_forward(value)); object = memory; } -#if defined(BOOST_HAS_VARIADIC_TMPL) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template - void construct(T* memory, Args&&... args) { - array_construct_args(memory, size, sp_forward(args)...); + void init_args(T* memory, Args&&... args) { + array_init_args(memory, size, sp_forward(args)...); object = memory; } #endif #endif - void construct_list(T* memory, const T* list) { - array_construct_list(memory, size, list); + void init_list(T* memory, const T* list) { + array_init_list(memory, size, list); object = memory; } template - void construct_list(T* memory, const T* list) { - array_construct_list(memory, size, list); + void init_list(T* memory, const T* list) { + array_init_list(memory, size, list); object = memory; } - void construct_noinit(T* memory) { - array_construct_noinit(memory, size); + void noinit(T* memory) { + array_noinit(memory, size); object = memory; } void operator()(const void*) { @@ -79,34 +79,34 @@ namespace boost { array_destroy(object, N); } } - void construct(T* memory) { - array_construct(memory, N); + void init(T* memory) { + array_init(memory, N); object = memory; } -#if defined(BOOST_HAS_RVALUE_REFS) - void construct(T* memory, T&& value) { - array_construct_value(memory, N, sp_forward(value)); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + void init_value(T* memory, T&& value) { + array_init_value(memory, N, sp_forward(value)); object = memory; } -#if defined(BOOST_HAS_VARIADIC_TMPL) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template - void construct(T* memory, Args&&... args) { - array_construct_args(memory, N, sp_forward(args)...); + void init_args(T* memory, Args&&... args) { + array_init_args(memory, N, sp_forward(args)...); object = memory; } #endif #endif - void construct_list(T* memory, const T* list) { - array_construct_list(memory, N, list); + void init_list(T* memory, const T* list) { + array_init_list(memory, N, list); object = memory; } template - void construct_list(T* memory, const T* list) { - array_construct_list(memory, N, list); + void init_list(T* memory, const T* list) { + array_init_list(memory, N, list); object = memory; } - void construct_noinit(T* memory) { - array_construct_noinit(memory, N); + void noinit(T* memory) { + array_noinit(memory, N); object = memory; } void operator()(const void*) { diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp index 3b685ad..35694f0 100644 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -30,13 +30,13 @@ namespace boost { array_destroy(memory, size, type); } template - inline void array_construct(T* memory, std::size_t size, boost::true_type) { + inline void array_init(T* memory, std::size_t size, boost::true_type) { for (std::size_t i = 0; i < size; i++) { memory[i] = T(); } } template - inline void array_construct(T* memory, std::size_t size, boost::false_type) { + inline void array_init(T* memory, std::size_t size, boost::false_type) { std::size_t i = 0; try { for (; i < size; i++) { @@ -49,13 +49,13 @@ namespace boost { } } template - inline void array_construct(T* memory, std::size_t size) { + inline void array_init(T* memory, std::size_t size) { boost::has_trivial_default_constructor type; - array_construct(memory, size, type); + array_init(memory, size, type); } -#if defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template - inline void array_construct_value(T* memory, std::size_t size, T&& value) { + inline void array_init_value(T* memory, std::size_t size, T&& value) { std::size_t i = 0; try { for (; i < size; i++) { @@ -67,9 +67,9 @@ namespace boost { throw; } } -#if defined(BOOST_HAS_VARIADIC_TMPL) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template - inline void array_construct_args(T* memory, std::size_t size, Args&&... args) { + inline void array_init_args(T* memory, std::size_t size, Args&&... args) { std::size_t i = 0; try { for (; i < size; i++) { @@ -84,7 +84,7 @@ namespace boost { #endif #endif template - inline void array_construct_list(T* memory, std::size_t size, const T* list) { + inline void array_init_list(T* memory, std::size_t size, const T* list) { std::size_t i = 0; try { for (; i < size; i++) { @@ -97,7 +97,7 @@ namespace boost { } } template - inline void array_construct_list(T* memory, std::size_t size, const T* list) { + inline void array_init_list(T* memory, std::size_t size, const T* list) { std::size_t i = 0; try { for (; i < size; i++) { @@ -110,10 +110,10 @@ namespace boost { } } template - inline void array_construct_noinit(T*, std::size_t, boost::true_type) { + inline void array_noinit(T*, std::size_t, boost::true_type) { } template - inline void array_construct_noinit(T* memory, std::size_t size, boost::false_type) { + inline void array_noinit(T* memory, std::size_t size, boost::false_type) { std::size_t i = 0; try { for (; i < size; i++) { @@ -126,9 +126,9 @@ namespace boost { } } template - inline void array_construct_noinit(T* memory, std::size_t size) { + inline void array_noinit(T* memory, std::size_t size) { boost::has_trivial_default_constructor type; - array_construct_noinit(memory, size, type); + array_noinit(memory, size, type); } } } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index b9c197c..bb8e040 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -33,10 +33,10 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct(p2); + d2->init(p2); return boost::shared_ptr(s1, p1); } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template inline typename boost::detail::sp_if_array::type make_shared(std::size_t size, Args&&... args) { @@ -51,7 +51,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct(p2, boost::detail::sp_forward(args)...); + d2->init_args(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } template @@ -70,29 +70,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct(p2, boost::detail::sp_forward(args)...); - return boost::shared_ptr(s1, p1); - } -#endif -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - template - inline typename boost::detail::sp_if_array::type - make_shared(std::initializer_list::type> list) { - typedef typename boost::detail::array_inner::type T1; - typedef typename boost::detail::array_base::type T2; - typedef const T2 T3; - T1* p1 = 0; - T2* p2 = 0; - T3* p3 = 0; - std::size_t n1 = list.size() * boost::detail::array_total::size; - boost::detail::make_array_helper a1(n1, &p2); - boost::detail::array_deleter d1(n1); - boost::shared_ptr s1(p1, d1, a1); - typedef boost::detail::array_deleter* D2; - p3 = reinterpret_cast(list.begin()); - p1 = reinterpret_cast(p2); - D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_list(p2, p3); + d2->init_args(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } #endif @@ -116,7 +94,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_list(p2, p3); + d2->init_list(p2, p3); return boost::shared_ptr(s1, p1); } template @@ -140,7 +118,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_list(p2, p3); + d2->init_list(p2, p3); return boost::shared_ptr(s1, p1); } template @@ -163,10 +141,32 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_list(p2, p3); + d2->init_list(p2, p3); return boost::shared_ptr(s1, p1); } -#if defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + inline typename boost::detail::sp_if_array::type + make_shared(std::initializer_list::type> list) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + typedef const T2 T3; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n1 = list.size() * boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1(n1); + boost::shared_ptr s1(p1, d1, a1); + typedef boost::detail::array_deleter* D2; + p3 = reinterpret_cast(list.begin()); + p1 = reinterpret_cast(p2); + D2 d2 = static_cast(s1._internal_get_untyped_deleter()); + d2->init_list(p2, p3); + return boost::shared_ptr(s1, p1); + } +#endif +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template inline typename boost::detail::sp_if_array::type make_shared(std::size_t size, @@ -182,7 +182,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct(p2, boost::detail::sp_forward(value)); + d2->init_value(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } template @@ -201,7 +201,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct(p2, boost::detail::sp_forward(value)); + d2->init_value(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } #endif @@ -220,7 +220,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_noinit(p2); + d2->noinit(p2); return boost::shared_ptr(s1, p1); } template @@ -239,7 +239,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->construct_noinit(p2); + d2->noinit(p2); return boost::shared_ptr(s1, p1); } } diff --git a/make_shared_array.html b/make_shared_array.html index 1f0f4d3..fb75790 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -35,7 +35,7 @@ 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) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template<typename T, typename... Args> shared_ptr<T[]> make_shared(size_t size, Args&&... args); @@ -48,15 +48,7 @@ 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 A, typename... Args> - shared_ptr<T[]> allocate_shared(const A& allocator, initializer_list<T> list); -#endif - + #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) template<typename T, typename... Args> shared_ptr<T[N]> make_shared(const T (&list)[N]); @@ -76,7 +68,15 @@ template<typename T, typename A, typename... Args> shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]); -#if defined(BOOST_HAS_RVALUE_REFS) +#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 A, typename... Args> + shared_ptr<T[]> allocate_shared(const A& allocator, initializer_list<T> list); +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template<typename T> shared_ptr<T[]> make_shared(size_t size, T&& value); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 9f08375..3394d96 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -137,16 +137,16 @@ import testing ; [ 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_init_test.cpp : : : gcc:-fno-deduce-init-list ] + [ run make_shared_arrays_create_test.cpp : : : gcc:-fno-deduce-init-list ] [ 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_init_test.cpp : : : gcc:-fno-deduce-init-list ] + [ run allocate_shared_arrays_create_test.cpp : : : gcc:-fno-deduce-init-list ] [ 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_create_test.cpp b/test/allocate_shared_array_create_test.cpp index 2e03be6..90b6b96 100644 --- a/test/allocate_shared_array_create_test.cpp +++ b/test/allocate_shared_array_create_test.cpp @@ -36,7 +36,7 @@ private: int type::instances = 0; int main() { -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, 1, 2, 3, 4, 5, 6, 7, 8, 9); diff --git a/test/allocate_shared_array_init_test.cpp b/test/allocate_shared_array_init_test.cpp index 1ff437f..c75b41f 100644 --- a/test/allocate_shared_array_init_test.cpp +++ b/test/allocate_shared_array_init_test.cpp @@ -20,6 +20,35 @@ private: }; int main() { +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) + { + 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); + } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1, 2, 3 }); @@ -50,35 +79,6 @@ int main() { BOOST_TEST(a1[3].value == 3); } #endif -#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) - { - 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); - } #endif return boost::report_errors(); } diff --git a/test/allocate_shared_array_test.cpp b/test/allocate_shared_array_test.cpp index 84ef3a8..f27e5e8 100644 --- a/test/allocate_shared_array_test.cpp +++ b/test/allocate_shared_array_test.cpp @@ -73,7 +73,7 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3, 1, 5); diff --git a/test/allocate_shared_array_throws_test.cpp b/test/allocate_shared_array_throws_test.cpp index d300f2c..bb5ac52 100644 --- a/test/allocate_shared_array_throws_test.cpp +++ b/test/allocate_shared_array_throws_test.cpp @@ -43,7 +43,7 @@ int main() { } catch (...) { BOOST_TEST(type::instances == 0); } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_TEST(type::instances == 0); try { boost::allocate_shared(std::allocator()); diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index 4c53e91..8a2a7d8 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -21,22 +21,6 @@ private: }; 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] == 0); - BOOST_TEST(a1[0][1] == 1); - BOOST_TEST(a1[1][0] == 2); - BOOST_TEST(a1[1][1] == 3); - } -#endif #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), {0, 1, 2, 3}); @@ -80,7 +64,23 @@ int main() { BOOST_TEST(a1[1][1][0] == 2); BOOST_TEST(a1[1][1][1] == 3); } -#if defined(BOOST_HAS_RVALUE_REFS) +#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] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 2); + BOOST_TEST(a1[1][1] == 3); + } +#endif +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 4, {1, 2}); BOOST_TEST(a1[0].x == 1); diff --git a/test/allocate_shared_arrays_test.cpp b/test/allocate_shared_arrays_test.cpp index 7c719ce..c0746d3 100644 --- a/test/allocate_shared_arrays_test.cpp +++ b/test/allocate_shared_arrays_test.cpp @@ -62,7 +62,7 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, 1, 5); diff --git a/test/make_shared_array_create_test.cpp b/test/make_shared_array_create_test.cpp index 46db862..0bdd635 100644 --- a/test/make_shared_array_create_test.cpp +++ b/test/make_shared_array_create_test.cpp @@ -36,7 +36,7 @@ private: int type::instances = 0; int main() { -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(2, 1, 2, 3, 4, 5, 6, 7, 8, 9); diff --git a/test/make_shared_array_init_test.cpp b/test/make_shared_array_init_test.cpp index fd61caf..11dcb1c 100644 --- a/test/make_shared_array_init_test.cpp +++ b/test/make_shared_array_init_test.cpp @@ -20,6 +20,35 @@ private: }; int main() { +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) + { + 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); + } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) { boost::shared_ptr a1 = boost::make_shared({ 0, 1, 2, 3 }); @@ -50,35 +79,6 @@ int main() { BOOST_TEST(a1[3].value == 3); } #endif -#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) - { - 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); - } #endif return boost::report_errors(); } diff --git a/test/make_shared_array_test.cpp b/test/make_shared_array_test.cpp index d9b9134..8193553 100644 --- a/test/make_shared_array_test.cpp +++ b/test/make_shared_array_test.cpp @@ -73,7 +73,7 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(3, 1, 5); diff --git a/test/make_shared_array_throws_test.cpp b/test/make_shared_array_throws_test.cpp index 4faf193..69e9b88 100644 --- a/test/make_shared_array_throws_test.cpp +++ b/test/make_shared_array_throws_test.cpp @@ -43,7 +43,7 @@ int main() { } catch (...) { BOOST_TEST(type::instances == 0); } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_TEST(type::instances == 0); try { boost::make_shared(); diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp index 7fc36bd..ba22e4a 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -21,22 +21,6 @@ private: }; 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] == 0); - BOOST_TEST(a1[0][1] == 1); - BOOST_TEST(a1[1][0] == 2); - BOOST_TEST(a1[1][1] == 3); - } -#endif #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) { boost::shared_ptr a1 = boost::make_shared({0, 1, 2, 3}); @@ -80,7 +64,23 @@ int main() { BOOST_TEST(a1[1][1][0] == 2); BOOST_TEST(a1[1][1][1] == 3); } -#if defined(BOOST_HAS_RVALUE_REFS) +#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] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 2); + BOOST_TEST(a1[1][1] == 3); + } +#endif +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) { boost::shared_ptr a1 = boost::make_shared(4, {1, 2}); BOOST_TEST(a1[0].x == 1); diff --git a/test/make_shared_arrays_test.cpp b/test/make_shared_arrays_test.cpp index eb79d4f..e03a13c 100644 --- a/test/make_shared_arrays_test.cpp +++ b/test/make_shared_arrays_test.cpp @@ -62,7 +62,7 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(2, 1, 5); From 619b168614fb7790f0355f247dbe55ebfd562ae9 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Thu, 13 Dec 2012 04:20:23 +0000 Subject: [PATCH 170/210] Two detail utility functions identifier renaming reverted [SVN r81887] --- include/boost/smart_ptr/allocate_shared_array.hpp | 8 ++++---- include/boost/smart_ptr/detail/array_deleter.hpp | 8 ++++---- include/boost/smart_ptr/make_shared_array.hpp | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 8afe54d..2eb5ba5 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -51,7 +51,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_args(p2, boost::detail::sp_forward(args)...); + d2->init(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } template @@ -70,7 +70,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_args(p2, boost::detail::sp_forward(args)...); + d2->init(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } #endif @@ -184,7 +184,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_value(p2, boost::detail::sp_forward(value)); + d2->init(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } template @@ -204,7 +204,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_value(p2, boost::detail::sp_forward(value)); + d2->init(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } #endif diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 2bc8a8a..11f23fa 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -33,13 +33,13 @@ namespace boost { object = memory; } #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - void init_value(T* memory, T&& value) { + void init(T* memory, T&& value) { array_init_value(memory, size, sp_forward(value)); object = memory; } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template - void init_args(T* memory, Args&&... args) { + void init(T* memory, Args&&... args) { array_init_args(memory, size, sp_forward(args)...); object = memory; } @@ -84,13 +84,13 @@ namespace boost { object = memory; } #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - void init_value(T* memory, T&& value) { + void init(T* memory, T&& value) { array_init_value(memory, N, sp_forward(value)); object = memory; } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template - void init_args(T* memory, Args&&... args) { + void init(T* memory, Args&&... args) { array_init_args(memory, N, sp_forward(args)...); object = memory; } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index bb8e040..609a098 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -51,7 +51,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_args(p2, boost::detail::sp_forward(args)...); + d2->init(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } template @@ -70,7 +70,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_args(p2, boost::detail::sp_forward(args)...); + d2->init(p2, boost::detail::sp_forward(args)...); return boost::shared_ptr(s1, p1); } #endif @@ -182,7 +182,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_value(p2, boost::detail::sp_forward(value)); + d2->init(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } template @@ -201,7 +201,7 @@ namespace boost { typedef boost::detail::array_deleter* D2; p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_value(p2, boost::detail::sp_forward(value)); + d2->init(p2, boost::detail::sp_forward(value)); return boost::shared_ptr(s1, p1); } #endif From bbf0245248b024bb011bec3c54ef4df48b79b0b7 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Thu, 13 Dec 2012 12:21:44 +0000 Subject: [PATCH 171/210] Remove -fno-deduce-init-list for certain tests in Jamfile.v2 [SVN r81894] --- test/Jamfile.v2 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 3394d96..9f08375 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -137,16 +137,16 @@ import testing ; [ 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 : : : gcc:-fno-deduce-init-list ] - [ run make_shared_arrays_create_test.cpp : : : gcc:-fno-deduce-init-list ] + [ 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 : : : gcc:-fno-deduce-init-list ] - [ run allocate_shared_arrays_create_test.cpp : : : gcc:-fno-deduce-init-list ] + [ 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 ] From 647f67aabfb7186217131743270d9190cb8d164d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 13 Dec 2012 16:48:57 +0000 Subject: [PATCH 172/210] Replace use of BOOST_HAS_RVALUE_REFS with !BOOST_NO_CXX11_RVALUE_REFERENCES. [SVN r81900] --- include/boost/smart_ptr/detail/shared_count.hpp | 4 ++-- include/boost/smart_ptr/detail/sp_forward.hpp | 2 +- include/boost/smart_ptr/intrusive_ptr.hpp | 2 +- include/boost/smart_ptr/make_shared_object.hpp | 4 ++-- include/boost/smart_ptr/shared_array.hpp | 4 ++-- include/boost/smart_ptr/shared_ptr.hpp | 8 ++++---- include/boost/smart_ptr/weak_ptr.hpp | 6 +++--- make_shared.html | 2 +- test/allocate_shared_array_args_test.cpp | 2 +- test/intrusive_ptr_move_test.cpp | 4 ++-- test/make_shared_array_args_test.cpp | 2 +- test/make_shared_perfect_forwarding_test.cpp | 6 +++--- test/shared_ptr_move_test.cpp | 4 ++-- test/weak_ptr_move_test.cpp | 4 ++-- 14 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index e91179d..f055fd0 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -382,7 +382,7 @@ public: if( pi_ != 0 ) pi_->add_ref_copy(); } -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) shared_count(shared_count && r): pi_(r.pi_) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) @@ -494,7 +494,7 @@ public: // Move support -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) weak_count(weak_count && r): pi_(r.pi_) // nothrow #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) diff --git a/include/boost/smart_ptr/detail/sp_forward.hpp b/include/boost/smart_ptr/detail/sp_forward.hpp index 25c4d48..5f1d190 100644 --- a/include/boost/smart_ptr/detail/sp_forward.hpp +++ b/include/boost/smart_ptr/detail/sp_forward.hpp @@ -23,7 +23,7 @@ namespace boost namespace detail { -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT { diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index ffb2dba..64a2923 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -108,7 +108,7 @@ public: // Move support -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px ) { diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp index aff19b9..5986be2 100644 --- a/include/boost/smart_ptr/make_shared_object.hpp +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -199,7 +199,7 @@ template< class T, class A > typename boost::detail::sp_if_not_array< T >::type return boost::shared_ptr< T >( pt, pt2 ); } -#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS ) +#if defined( BOOST_HAS_VARIADIC_TMPL ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // Variadic templates, rvalue reference @@ -237,7 +237,7 @@ template< class T, class A, class Arg1, class... Args > typename boost::detail:: return boost::shared_ptr< T >( pt, pt2 ); } -#elif defined( BOOST_HAS_RVALUE_REFS ) +#elif !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // For example MSVC 10.0 diff --git a/include/boost/smart_ptr/shared_array.hpp b/include/boost/smart_ptr/shared_array.hpp index f54f481..38047ff 100644 --- a/include/boost/smart_ptr/shared_array.hpp +++ b/include/boost/smart_ptr/shared_array.hpp @@ -86,7 +86,7 @@ public: // generated copy constructor, destructor are fine... -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // ... except in C++0x, move disables the implicit copy @@ -145,7 +145,7 @@ public: #endif -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT { diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index fa29116..2d903a3 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -389,7 +389,7 @@ public: // generated copy constructor, destructor are fine... -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // ... except in C++0x, move disables the implicit copy @@ -452,7 +452,7 @@ public: boost::detail::sp_deleter_construct( this, tmp ); } -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template shared_ptr( std::auto_ptr && r ): px(r.get()), pn() @@ -527,7 +527,7 @@ public: return *this; } -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template shared_ptr & operator=( std::auto_ptr && r ) @@ -562,7 +562,7 @@ public: // Move support -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn() { diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index 59cdd45..e3e9ad9 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -37,7 +37,7 @@ public: // generated copy constructor, assignment, destructor are fine... -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // ... except in C++0x, move disables the implicit copy @@ -86,7 +86,7 @@ public: boost::detail::sp_assert_convertible< Y, T >(); } -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) @@ -149,7 +149,7 @@ public: return *this; } -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT diff --git a/make_shared.html b/make_shared.html index e47fe2a..094a7be 100644 --- a/make_shared.html +++ b/make_shared.html @@ -41,7 +41,7 @@ template<typename T, typename A> shared_ptr<T> allocate_shared( A const & ); -#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS ) // C++0x prototypes +#if defined( BOOST_HAS_VARIADIC_TMPL ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // C++0x prototypes template<typename T, typename... Args> shared_ptr<T> make_shared( Args && ... args ); diff --git a/test/allocate_shared_array_args_test.cpp b/test/allocate_shared_array_args_test.cpp index 1226b94..5732c64 100644 --- a/test/allocate_shared_array_args_test.cpp +++ b/test/allocate_shared_array_args_test.cpp @@ -57,7 +57,7 @@ int main() BOOST_TEST( X::instances == 0 ); } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if defined( BOOST_HAS_VARIADIC_TMPL ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) { boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1 ); diff --git a/test/intrusive_ptr_move_test.cpp b/test/intrusive_ptr_move_test.cpp index 3faf16e..0e89764 100644 --- a/test/intrusive_ptr_move_test.cpp +++ b/test/intrusive_ptr_move_test.cpp @@ -32,7 +32,7 @@ #include #include -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) namespace N { @@ -173,7 +173,7 @@ int main() return boost::report_errors(); } -#else // !defined( BOOST_HAS_RVALUE_REFS ) +#else // defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) int main() { diff --git a/test/make_shared_array_args_test.cpp b/test/make_shared_array_args_test.cpp index c308c7a..b215096 100644 --- a/test/make_shared_array_args_test.cpp +++ b/test/make_shared_array_args_test.cpp @@ -56,7 +56,7 @@ int main() BOOST_TEST( X::instances == 0 ); } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if defined( BOOST_HAS_VARIADIC_TMPL ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) { boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1 ); diff --git a/test/make_shared_perfect_forwarding_test.cpp b/test/make_shared_perfect_forwarding_test.cpp index bd5f5c5..b7ad05d 100644 --- a/test/make_shared_perfect_forwarding_test.cpp +++ b/test/make_shared_perfect_forwarding_test.cpp @@ -12,14 +12,14 @@ #include #include -#if !defined( BOOST_HAS_RVALUE_REFS ) +#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) int main() { return 0; } -#else // BOOST_HAS_RVALUE_REFS +#else // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) class myarg { @@ -95,4 +95,4 @@ int main() return boost::report_errors(); } -#endif // BOOST_HAS_RVALUE_REFS +#endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) diff --git a/test/shared_ptr_move_test.cpp b/test/shared_ptr_move_test.cpp index 82ba9d6..e659b24 100644 --- a/test/shared_ptr_move_test.cpp +++ b/test/shared_ptr_move_test.cpp @@ -12,7 +12,7 @@ #include #include -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) struct X { @@ -97,7 +97,7 @@ int main() return boost::report_errors(); } -#else // !defined( BOOST_HAS_RVALUE_REFS ) +#else // defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) int main() { diff --git a/test/weak_ptr_move_test.cpp b/test/weak_ptr_move_test.cpp index 4df3691..dbf2629 100644 --- a/test/weak_ptr_move_test.cpp +++ b/test/weak_ptr_move_test.cpp @@ -12,7 +12,7 @@ #include #include -#if defined( BOOST_HAS_RVALUE_REFS ) +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) struct X { @@ -112,7 +112,7 @@ int main() return boost::report_errors(); } -#else // !defined( BOOST_HAS_RVALUE_REFS ) +#else // defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) int main() { From 1c070b3a3222c313373847a880a9757b34e400d8 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 13 Dec 2012 16:57:55 +0000 Subject: [PATCH 173/210] Replace use of BOOST_HAS_VARIADIC_TMPL with !BOOST_NO_CXX11_VARIADIC_TEMPLATES. [SVN r81901] --- include/boost/smart_ptr/make_shared_object.hpp | 2 +- make_shared.html | 2 +- test/allocate_shared_array_args_test.cpp | 2 +- test/make_shared_array_args_test.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp index 5986be2..89a7116 100644 --- a/include/boost/smart_ptr/make_shared_object.hpp +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -199,7 +199,7 @@ template< class T, class A > typename boost::detail::sp_if_not_array< T >::type return boost::shared_ptr< T >( pt, pt2 ); } -#if defined( BOOST_HAS_VARIADIC_TMPL ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) +#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // Variadic templates, rvalue reference diff --git a/make_shared.html b/make_shared.html index 094a7be..e2335d3 100644 --- a/make_shared.html +++ b/make_shared.html @@ -41,7 +41,7 @@ template<typename T, typename A> shared_ptr<T> allocate_shared( A const & ); -#if defined( BOOST_HAS_VARIADIC_TMPL ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // C++0x prototypes +#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // C++0x prototypes template<typename T, typename... Args> shared_ptr<T> make_shared( Args && ... args ); diff --git a/test/allocate_shared_array_args_test.cpp b/test/allocate_shared_array_args_test.cpp index 5732c64..f3d38b6 100644 --- a/test/allocate_shared_array_args_test.cpp +++ b/test/allocate_shared_array_args_test.cpp @@ -57,7 +57,7 @@ int main() BOOST_TEST( X::instances == 0 ); } -#if defined( BOOST_HAS_VARIADIC_TMPL ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) +#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) { boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator(), 2, 1 ); diff --git a/test/make_shared_array_args_test.cpp b/test/make_shared_array_args_test.cpp index b215096..8a89429 100644 --- a/test/make_shared_array_args_test.cpp +++ b/test/make_shared_array_args_test.cpp @@ -56,7 +56,7 @@ int main() BOOST_TEST( X::instances == 0 ); } -#if defined( BOOST_HAS_VARIADIC_TMPL ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) +#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) { boost::shared_ptr< X[] > px = boost::make_shared< X[] >( 2, 1 ); From e36689bd5ed47bb53772ccf7be0e87e2ed93d615 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Thu, 13 Dec 2012 18:02:25 +0000 Subject: [PATCH 174/210] Correct call to init_list in make_shared and allocate_shared. Move g++ failing case into separate test to not mask other issues. [SVN r81905] --- .../boost/smart_ptr/allocate_shared_array.hpp | 4 ++-- include/boost/smart_ptr/make_shared_array.hpp | 4 ++-- test/Jamfile.v2 | 2 ++ test/allocate_shared_arrays_create_test.cpp | 7 ------ test/allocate_shared_arrays_init_test.cpp | 23 +++++++++++++++++++ test/make_shared_arrays_create_test.cpp | 7 ------ test/make_shared_arrays_init_test.cpp | 23 +++++++++++++++++++ 7 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 test/allocate_shared_arrays_init_test.cpp create mode 100644 test/make_shared_arrays_init_test.cpp diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 2eb5ba5..3ee1655 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -118,7 +118,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_list(p2, p3); + d2->template init_list(p2, p3); return boost::shared_ptr(s1, p1); } template @@ -142,7 +142,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_list(p2, p3); + d2->template init_list(p2, p3); return boost::shared_ptr(s1, p1); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 609a098..eb0578d 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -118,7 +118,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_list(p2, p3); + d2->template init_list(p2, p3); return boost::shared_ptr(s1, p1); } template @@ -141,7 +141,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); D2 d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->init_list(p2, p3); + d2->template init_list(p2, p3); return boost::shared_ptr(s1, p1); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 9f08375..1ed197a 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -139,6 +139,7 @@ import testing ; [ run make_shared_array_create_test.cpp ] [ run make_shared_array_init_test.cpp ] [ run make_shared_arrays_create_test.cpp ] + [ run make_shared_arrays_init_test.cpp ] [ run make_shared_array_throws_test.cpp ] [ run make_shared_array_esft_test.cpp ] [ run make_shared_array_args_test.cpp ] @@ -147,6 +148,7 @@ import testing ; [ run allocate_shared_array_create_test.cpp ] [ run allocate_shared_array_init_test.cpp ] [ run allocate_shared_arrays_create_test.cpp ] + [ run allocate_shared_arrays_init_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_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index 8a2a7d8..a7e95d7 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -72,13 +72,6 @@ int main() { 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] == 0); - BOOST_TEST(a1[0][1] == 1); - BOOST_TEST(a1[1][0] == 2); - BOOST_TEST(a1[1][1] == 3); - } #endif #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) { diff --git a/test/allocate_shared_arrays_init_test.cpp b/test/allocate_shared_arrays_init_test.cpp new file mode 100644 index 0000000..76173fa --- /dev/null +++ b/test/allocate_shared_arrays_init_test.cpp @@ -0,0 +1,23 @@ +/* + * 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_UNIFIED_INITIALIZATION_SYNTAX) && !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); + } +#endif + return boost::report_errors(); +} diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp index ba22e4a..c6a1b4f 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -72,13 +72,6 @@ int main() { 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] == 0); - BOOST_TEST(a1[0][1] == 1); - BOOST_TEST(a1[1][0] == 2); - BOOST_TEST(a1[1][1] == 3); - } #endif #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) { diff --git a/test/make_shared_arrays_init_test.cpp b/test/make_shared_arrays_init_test.cpp new file mode 100644 index 0000000..1646d5a --- /dev/null +++ b/test/make_shared_arrays_init_test.cpp @@ -0,0 +1,23 @@ +/* + * 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_UNIFIED_INITIALIZATION_SYNTAX) && !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); + } +#endif + return boost::report_errors(); +} From bb700870c001aa66877be2a587fd5b0c977e0aa6 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 14 Dec 2012 20:05:03 +0000 Subject: [PATCH 175/210] Specify -fno-deduce-init-list for gcc-4.6.3 only. [SVN r81950] --- test/Jamfile.v2 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 1ed197a..6d2394a 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -137,18 +137,18 @@ import testing ; [ 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_arrays_init_test.cpp ] + [ run make_shared_array_init_test.cpp : : : gcc-4.6.3:-fno-deduce-init-list ] + [ run make_shared_arrays_create_test.cpp : : : gcc-4.6.3:-fno-deduce-init-list ] + [ run make_shared_arrays_init_test.cpp : : : gcc-4.6.3:-fno-deduce-init-list ] [ 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_arrays_init_test.cpp ] + [ run allocate_shared_array_init_test.cpp : : : gcc-4.6.3:-fno-deduce-init-list ] + [ run allocate_shared_arrays_create_test.cpp : : : gcc-4.6.3:-fno-deduce-init-list ] + [ run allocate_shared_arrays_init_test.cpp : : : gcc-4.6.3:-fno-deduce-init-list ] [ run allocate_shared_array_throws_test.cpp ] [ run allocate_shared_array_esft_test.cpp ] [ run allocate_shared_array_args_test.cpp ] From 63834f7233a18f6ac348309cb2de7e1772c44891 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 16 Dec 2012 23:03:30 +0000 Subject: [PATCH 176/210] Specify gcc-4.6 instead of gcc-4.6.3 for toolset [SVN r82038] --- test/Jamfile.v2 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 6d2394a..47b2a1b 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -137,18 +137,18 @@ import testing ; [ 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 : : : gcc-4.6.3:-fno-deduce-init-list ] - [ run make_shared_arrays_create_test.cpp : : : gcc-4.6.3:-fno-deduce-init-list ] - [ run make_shared_arrays_init_test.cpp : : : gcc-4.6.3:-fno-deduce-init-list ] + [ run make_shared_array_init_test.cpp : : : gcc-4.6:-fno-deduce-init-list ] + [ run make_shared_arrays_create_test.cpp : : : gcc-4.6:-fno-deduce-init-list ] + [ run make_shared_arrays_init_test.cpp : : : gcc-4.6:-fno-deduce-init-list ] [ 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 : : : gcc-4.6.3:-fno-deduce-init-list ] - [ run allocate_shared_arrays_create_test.cpp : : : gcc-4.6.3:-fno-deduce-init-list ] - [ run allocate_shared_arrays_init_test.cpp : : : gcc-4.6.3:-fno-deduce-init-list ] + [ run allocate_shared_array_init_test.cpp : : : gcc-4.6:-fno-deduce-init-list ] + [ run allocate_shared_arrays_create_test.cpp : : : gcc-4.6:-fno-deduce-init-list ] + [ run allocate_shared_arrays_init_test.cpp : : : gcc-4.6:-fno-deduce-init-list ] [ run allocate_shared_array_throws_test.cpp ] [ run allocate_shared_array_esft_test.cpp ] [ run allocate_shared_array_args_test.cpp ] From 66f34142be7b2284b12085b7669c751b26cb6be3 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 18 Dec 2012 09:24:31 +0000 Subject: [PATCH 177/210] Fix cxxflags in smart_ptr/test/Jamfile.v2 [SVN r82070] --- test/Jamfile.v2 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 47b2a1b..d4f7af1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -137,18 +137,18 @@ import testing ; [ 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 : : : gcc-4.6:-fno-deduce-init-list ] - [ run make_shared_arrays_create_test.cpp : : : gcc-4.6:-fno-deduce-init-list ] - [ run make_shared_arrays_init_test.cpp : : : gcc-4.6:-fno-deduce-init-list ] + [ run make_shared_array_init_test.cpp : : : gcc-4.6.3_0x:-fno-deduce-init-list ] + [ run make_shared_arrays_create_test.cpp : : : gcc-4.6.3_0x:-fno-deduce-init-list ] + [ run make_shared_arrays_init_test.cpp : : : gcc-4.6.3_0x:-fno-deduce-init-list ] [ 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 : : : gcc-4.6:-fno-deduce-init-list ] - [ run allocate_shared_arrays_create_test.cpp : : : gcc-4.6:-fno-deduce-init-list ] - [ run allocate_shared_arrays_init_test.cpp : : : gcc-4.6:-fno-deduce-init-list ] + [ run allocate_shared_array_init_test.cpp : : : gcc-4.6.3_0x:-fno-deduce-init-list ] + [ run allocate_shared_arrays_create_test.cpp : : : gcc-4.6.3_0x:-fno-deduce-init-list ] + [ run allocate_shared_arrays_init_test.cpp : : : gcc-4.6.3_0x:-fno-deduce-init-list ] [ run allocate_shared_array_throws_test.cpp ] [ run allocate_shared_array_esft_test.cpp ] [ run allocate_shared_array_args_test.cpp ] From e8be24c003ca4391410097b14f37d47b637dd28d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 23 Dec 2012 16:05:00 +0000 Subject: [PATCH 178/210] Untabify. [SVN r82188] --- .../boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp | 2 +- include/boost/smart_ptr/shared_ptr.hpp | 8 ++++---- test/array_fail_upa_sp_a.cpp | 2 +- test/array_fail_upa_sp_c.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp index a043e02..56ed79f 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp @@ -30,7 +30,7 @@ namespace detail inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ ) { - return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_); + return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_); } inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv ) diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 2d903a3..b34b0ac 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -910,12 +910,12 @@ public: deleter_ = deleter; } - template D* get_deleter() const BOOST_NOEXCEPT + template D* get_deleter() const BOOST_NOEXCEPT { return boost::detail::basic_get_deleter( deleter_ ); } - template< class T> void operator()( T* ) + template< class T> void operator()( T* ) { BOOST_ASSERT( deleter_.use_count() <= 1 ); deleter_.reset(); @@ -928,7 +928,7 @@ template D * get_deleter( shared_ptr const & p ) BOOST_NOEX { D *del = boost::detail::basic_get_deleter(p); - if(del == 0) + if(del == 0) { boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter(p); // The following get_deleter method call is fully qualified because @@ -936,7 +936,7 @@ template D * get_deleter( shared_ptr const & p ) BOOST_NOEX if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter(); } - return del; + return del; } // atomic access diff --git a/test/array_fail_upa_sp_a.cpp b/test/array_fail_upa_sp_a.cpp index b44e07e..4d87fdd 100644 --- a/test/array_fail_upa_sp_a.cpp +++ b/test/array_fail_upa_sp_a.cpp @@ -15,6 +15,6 @@ struct X int main() { - std::unique_ptr px; + 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 index fe62044..259fda0 100644 --- a/test/array_fail_upa_sp_c.cpp +++ b/test/array_fail_upa_sp_c.cpp @@ -15,6 +15,6 @@ struct X int main() { - std::unique_ptr px; + std::unique_ptr px; boost::shared_ptr px2( px ); } From 43b43aa83a8e3419b734a9024593d83405375857 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 4 Jan 2013 14:26:56 +0000 Subject: [PATCH 179/210] Update documentation for nullptr, owner_before, explicit operator bool. [SVN r82349] --- shared_ptr.htm | 94 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 24 deletions(-) diff --git a/shared_ptr.htm b/shared_ptr.htm index 87e61b4..c534dd7 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -45,9 +45,10 @@ shared_ptr<void> p2( new int(5) ); to "break cycles."

    The class template is parameterized on T, the type of the object pointed to. shared_ptr and most of its member functions place no - requirements on T; it is allowed to be an incomplete type, or - void. Member functions that do place additional requirements (constructors, - reset) are explicitly documented below.

    + requirements on T; it is allowed to be an incomplete type, or + void. Member functions that do place additional requirements + (constructors, reset) are explicitly + documented below.

    shared_ptr<T> can be implicitly converted to shared_ptr<U> whenever T* can be implicitly converted to U*. In particular, shared_ptr<T> is implicitly convertible @@ -119,10 +120,13 @@ void bad() typedef see below element_type; shared_ptr(); // never throws + shared_ptr(std::nullptr_t); // never throws template<class Y> explicit shared_ptr(Y * p); template<class Y, class D> shared_ptr(Y * p, D d); template<class Y, class D, class A> shared_ptr(Y * p, D d, A a); + template<class D> shared_ptr(std::nullptr_t p, D d); + template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a); ~shared_ptr(); // never throws @@ -152,6 +156,8 @@ void bad() template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r); + shared_ptr & operator=(std::nullptr_t); // never throws + void reset(); // never throws template<class Y> void reset(Y * p); @@ -163,19 +169,19 @@ void bad() T & operator*() const; // never throws; only valid when T is not an array type T * operator->() const; // never throws; only valid when T is not an array type - element_type & operator[]( std::ptrdiff_t i ) const; // never throws; only valid when T is an array type + element_type & operator[](std::ptrdiff_t i) const; // never throws; only valid when T is an array type element_type * get() const; // never throws bool unique() const; // never throws long use_count() const; // never throws - operator unspecified-bool-type() const; // never throws + explicit operator bool() const; // never throws void swap(shared_ptr & b); // never throws - template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const; // never throws - template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const; // never throws + template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const; // never throws + template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const; // never throws }; template<class T, class U> @@ -187,6 +193,18 @@ void bad() template<class T, class U> bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws + template<class T> + bool operator==(shared_ptr<T> const & p, std::nullptr_t); // never throws + + template<class T> + bool operator==(std::nullptr_t, shared_ptr<T> const & p); // never throws + + template<class T> + bool operator!=(shared_ptr<T> const & p, std::nullptr_t); // never throws + + template<class T> + bool operator!=(std::nullptr_t, shared_ptr<T> const & p); // never throws + template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws template<class T> typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p); // never throws @@ -217,7 +235,8 @@ void bad() and U when T is U[] or U[N].

    default constructor

    -
    shared_ptr(); // never throws
    +
    shared_ptr(); // never throws
    +shared_ptr(std::nullptr_t); // never throws
    @@ -422,147 +508,143 @@ q = p; bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

    Returns: an unspecified value such that

    -
      -
    • - operator< is a strict weak ordering as described in section 25.3 [lib.alg.sorting] - of the C++ standard; -
    • - under the equivalence relation defined by operator<, !(a - < b) && !(b < a), two shared_ptr instances - are equivalent if and only if they share ownership or are both empty.
    +
      +
    • + operator< is a strict weak ordering as described in section 25.3 [lib.alg.sorting] + of the C++ standard;
    • +
    • + under the equivalence relation defined by operator<, !(a + < b) && !(b < a), two shared_ptr instances + are equivalent if and only if they share ownership or are both empty.

    Throws: nothing.

    -

    Notes: Allows shared_ptr objects to be used as keys in - associative containers.

    +

    Notes: Allows shared_ptr objects to be used as keys in + associative containers.

    -

    [Operator< has been preferred over a std::less - specialization for consistency and legality reasons, as std::less - is required to return the results of operator<, and many - standard algorithms use operator< instead of std::less - for comparisons when a predicate is not supplied. Composite objects, like std::pair, - also implement their operator< in terms of their contained - subobjects' operator<.

    -

    The rest of the comparison operators are omitted by design.]

    -

    swap

    +

    [Operator< has been preferred over a std::less + specialization for consistency and legality reasons, as std::less + is required to return the results of operator<, and many + standard algorithms use operator< instead of std::less + for comparisons when a predicate is not supplied. Composite objects, like std::pair, + also implement their operator< in terms of their contained + subobjects' operator<.

    +

    The rest of the comparison operators are omitted by design.]

    +

    swap

    template<class T>
       void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws
    -
    -

    Effects: Equivalent to a.swap(b).

    -

    Throws: nothing.

    -

    Notes: Matches the interface of std::swap. Provided as an aid to - generic programming.

    -
    -

    [swap is defined in the same namespace as shared_ptr - as this is currently the only legal way to supply a swap function - that has a chance to be used by the standard library.]

    -

    get_pointer

    +
    +

    Effects: Equivalent to a.swap(b).

    +

    Throws: nothing.

    +

    Notes: Matches the interface of std::swap. Provided as an aid to + generic programming.

    +
    +

    [swap is defined in the same namespace as shared_ptr + as this is currently the only legal way to supply a swap function + that has a chance to be used by the standard library.]

    +

    get_pointer

    template<class T>
    -  T * get_pointer(shared_ptr<T> const & p); // never throws
    -
    -

    Returns: p.get().

    -

    Throws: nothing.

    -

    Notes: Provided as an aid to generic programming. Used by - mem_fn.

    -
    -

    static_pointer_cast

    + typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p); // never throws +
    +

    Returns: p.get().

    +

    Throws: nothing.

    +

    Notes: Provided as an aid to generic programming. Used by + mem_fn.

    +
    +

    static_pointer_cast

    template<class T, class U>
       shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws
    -
    -

    Requires: The expression static_cast<T*>(r.get()) - must be well-formed.

    -

    Returns: If r is empty, an empty shared_ptr<T>; - otherwise, a shared_ptr<T> object that stores a copy of - static_cast<T*>(r.get()) and shares ownership with r.

    -

    Throws: nothing.

    -

    Notes: the seemingly equivalent expression

    -

    shared_ptr<T>(static_cast<T*>(r.get()))

    -

    will eventually result in undefined behavior, attempting to delete the same +

    +

    Requires: The expression static_cast<T*>( (U*)0 ) + must be well-formed.

    +

    Returns: shared_ptr<T>( r, static_cast<typename shared_ptr<T>::element_type*>(r.get()) ).

    +

    Throws: nothing.

    +

    Notes: the seemingly equivalent expression + shared_ptr<T>(static_cast<T*>(r.get())) + will eventually result in undefined behavior, attempting to delete the same object twice.

    -
    -

    const_pointer_cast

    +
    +

    const_pointer_cast

    template<class T, class U>
       shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws
    -
    -

    Requires: The expression const_cast<T*>(r.get()) - must be well-formed.

    -

    Returns: If r is empty, an empty shared_ptr<T>; - otherwise, a shared_ptr<T> object that stores a copy of - const_cast<T*>(r.get()) and shares ownership with r.

    -

    Throws: nothing.

    -

    Notes: the seemingly equivalent expression

    -

    shared_ptr<T>(const_cast<T*>(r.get()))

    -

    will eventually result in undefined behavior, attempting to delete the same - object twice.

    -
    -

    dynamic_pointer_cast

    +
    +

    Requires: The expression const_cast<T*>( (U*)0 ) + must be well-formed.

    +

    Returns: shared_ptr<T>( r, const_cast<typename shared_ptr<T>::element_type*>(r.get()) ).

    +

    Throws: nothing.

    +
    +

    dynamic_pointer_cast

    template<class T, class U>
       shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r);
    -
    -

    Requires: The expression dynamic_cast<T*>(r.get()) - must be well-formed and its behavior defined.

    -

    Returns:

    -
      -
    • - When dynamic_cast<T*>(r.get()) returns a nonzero value, a - shared_ptr<T> object that stores a copy of it and shares - ownership with r; -
    • - Otherwise, an empty shared_ptr<T> object.
    -

    Throws: nothing.

    -

    Notes: the seemingly equivalent expression

    -

    shared_ptr<T>(dynamic_cast<T*>(r.get()))

    -

    will eventually result in undefined behavior, attempting to delete the same - object twice.

    -
    -

    operator<<

    +
    +

    Requires: The expression dynamic_cast<T*>( (U*)0 ) + must be well-formed.

    +

    Returns:

    +
      +
    • + When dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()) returns a nonzero value p, + shared_ptr<T>(r, p);
    • +
    • + Otherwise, shared_ptr<T>().
    +

    Throws: nothing.

    +
    +

    reinterpret_pointer_cast

    +
    template<class T, class U>
    +  shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r); // never throws
    +
    +

    Requires: The expression reinterpret_cast<T*>( (U*)0 ) + must be well-formed.

    +

    Returns: shared_ptr<T>( r, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()) ).

    +

    Throws: nothing.

    +
    +

    operator<<

    template<class E, class T, class Y>
         std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);
    -
    -

    Effects: os << p.get();.

    -

    Returns: os.

    -
    -

    get_deleter

    +
    +

    Effects: os << p.get();.

    +

    Returns: os.

    +
    +

    get_deleter

    template<class D, class T>
         D * get_deleter(shared_ptr<T> const & p);
    -
    -

    Returns: If *this owns a deleter d - of type (cv-unqualified) D, returns &d; - otherwise returns 0.

    -

    Throws: nothing.

    -
    -

    Example

    -

    See shared_ptr_example.cpp for a - complete example program. The program builds a std::vector and std::set - of shared_ptr objects.

    -

    Note that after the containers have been populated, some of the shared_ptr +

    +

    Returns: If *this owns a deleter d + of type (cv-unqualified) D, returns &d; + otherwise returns 0.

    +

    Throws: nothing.

    +
    +

    Example

    +

    See shared_ptr_example.cpp for a + complete example program. The program builds a std::vector and std::set + of shared_ptr objects.

    +

    Note that after the containers have been populated, some of the shared_ptr objects will have a use count of 1 rather than a use count of 2, since the set - is a std::set rather than a std::multiset, and thus does not + is a std::set rather than a std::multiset, and thus does not contain duplicate entries. Furthermore, the use count may be even higher at - various times while push_back and insert container operations are + various times while push_back and insert container operations are performed. More complicated yet, the container operations may throw exceptions under a variety of circumstances. Getting the memory management and exception handling in this example right without a smart pointer would be a nightmare.

    -

    Handle/Body Idiom

    -

    One common usage of shared_ptr is to implement a handle/body (also called +

    Handle/Body Idiom

    +

    One common usage of shared_ptr is to implement a handle/body (also called pimpl) idiom which avoids exposing the body (implementation) in the header file.

    -

    The shared_ptr_example2_test.cpp - sample program includes a header file, shared_ptr_example2.hpp, - which uses a shared_ptr<> to an incomplete type to hide the +

    The shared_ptr_example2_test.cpp + sample program includes a header file, shared_ptr_example2.hpp, + which uses a shared_ptr to an incomplete type to hide the implementation. The instantiation of member functions which require a complete - type occurs in the shared_ptr_example2.cpp + type occurs in the shared_ptr_example2.cpp implementation file. Note that there is no need for an explicit destructor. - Unlike ~scoped_ptr, ~shared_ptr does not require that T be a complete + Unlike ~scoped_ptr, ~shared_ptr does not require that T be a complete type.

    -

    Thread Safety

    -

    shared_ptr objects offer the same level of thread safety as - built-in types. A shared_ptr instance can be "read" (accessed - using only const operations) simultaneously by multiple threads. Different shared_ptr - instances can be "written to" (accessed using mutable operations such as operator= - or reset) simultaneosly by multiple threads (even +

    Thread Safety

    +

    shared_ptr objects offer the same level of thread safety as + built-in types. A shared_ptr instance can be "read" (accessed + using only const operations) simultaneously by multiple threads. Different shared_ptr + instances can be "written to" (accessed using mutable operations such as operator= + or reset) simultaneosly by multiple threads (even when these instances are copies, and share the same reference count underneath.)

    -

    Any other simultaneous accesses result in undefined behavior.

    -

    Examples:

    +

    Any other simultaneous accesses result in undefined behavior.

    +

    Examples:

    shared_ptr<int> p(new int(42));
     
     //--- Example 1 ---
    @@ -606,89 +688,78 @@ p3.reset(new int(1));
     p3.reset(new int(2)); // undefined, multiple writes
     

     

    -

    Starting with Boost release 1.33.0, shared_ptr uses a lock-free - implementation on the following platforms:

    -
      -
    • - GNU GCC on x86 or x86-64; -
    • - GNU GCC on IA64; -
    • - Metrowerks CodeWarrior on PowerPC; -
    • - GNU GCC on PowerPC; -
    • - Windows.
    -

    If your program is single-threaded and does not link to any libraries that might - have used shared_ptr in its default configuration, you can - #define the macro BOOST_SP_DISABLE_THREADS on a - project-wide basis to switch to ordinary non-atomic reference count updates.

    -

    (Defining BOOST_SP_DISABLE_THREADS in some, but not all, +

    Starting with Boost release 1.33.0, shared_ptr uses a lock-free + implementation on most common platforms.

    +

    If your program is single-threaded and does not link to any libraries that might + have used shared_ptr in its default configuration, you can + #define the macro BOOST_SP_DISABLE_THREADS on a + project-wide basis to switch to ordinary non-atomic reference count updates.

    +

    (Defining BOOST_SP_DISABLE_THREADS in some, but not all, translation units is technically a violation of the One Definition Rule and undefined behavior. Nevertheless, the implementation attempts to do its best to accommodate the request to use non-atomic updates in those translation units. - No guarantees, though.)

    -

    You can define the macro BOOST_SP_USE_PTHREADS to turn off the - lock-free platform-specific implementation and fall back to the generic pthread_mutex_t-based - code.

    -

    Frequently Asked Questions

    -

    Q. There are several variations of shared pointers, with different + No guarantees, though.)

    +

    You can define the macro BOOST_SP_USE_PTHREADS to turn off the + lock-free platform-specific implementation and fall back to the generic + pthread_mutex_t-based code.

    +

    Frequently Asked Questions

    +

    Q. There are several variations of shared pointers, with different tradeoffs; why does the smart pointer library supply only a single implementation? It would be useful to be able to experiment with each type so - as to find the most suitable for the job at hand?

    -

    - A. An important goal of shared_ptr is to provide a + as to find the most suitable for the job at hand?

    +

    + A. An important goal of shared_ptr is to provide a standard shared-ownership pointer. Having a single pointer type is important for stable library interfaces, since different shared pointers typically cannot interoperate, i.e. a reference counted pointer (used by library A) cannot share - ownership with a linked pointer (used by library B.)
    -

    -

    Q. Why doesn't shared_ptr have template parameters supplying - traits or policies to allow extensive user customization?

    -

    - A. Parameterization discourages users. The shared_ptr template is + ownership with a linked pointer (used by library B.) +

    +

    Q. Why doesn't shared_ptr have template parameters supplying + traits or policies to allow extensive user customization?

    +

    + A. Parameterization discourages users. The shared_ptr template is carefully crafted to meet common needs without extensive parameterization. Some day a highly configurable smart pointer may be invented that is also very easy - to use and very hard to misuse. Until then, shared_ptr is the smart + to use and very hard to misuse. Until then, shared_ptr is the smart pointer of choice for a wide range of applications. (Those interested in policy - based smart pointers should read - Modern C++ Design by Andrei Alexandrescu.)
    -

    -

    Q. I am not convinced. Default parameters can be used where appropriate - to hide the complexity. Again, why not policies?

    -

    - A. Template parameters affect the type. See the answer to the first - question above.
    -

    -

    Q. Why doesn't shared_ptr use a linked list implementation?

    -

    + based smart pointers should read + Modern C++ Design by Andrei Alexandrescu.) +

    +

    Q. I am not convinced. Default parameters can be used where appropriate + to hide the complexity. Again, why not policies?

    +

    + A. Template parameters affect the type. See the answer to the first + question above. +

    +

    Q. Why doesn't shared_ptr use a linked list implementation?

    +

    A. A linked list implementation does not offer enough advantages to - offset the added cost of an extra pointer. See timings + offset the added cost of an extra pointer. See timings page. In addition, it is expensive to make a linked list implementation thread - safe.
    -

    -

    Q. Why doesn't shared_ptr (or any of the other Boost smart - pointers) supply an automatic conversion to T*?

    -

    - A. Automatic conversion is believed to be too error prone.
    -

    -

    Q. Why does shared_ptr supply use_count()?

    -

    + safe. +

    +

    Q. Why doesn't shared_ptr (or any of the other Boost smart + pointers) supply an automatic conversion to T*?

    +

    + A. Automatic conversion is believed to be too error prone. +

    +

    Q. Why does shared_ptr supply use_count()?

    +

    A. As an aid to writing test cases and debugging displays. One of the - progenitors had use_count(), and it was useful in tracking down bugs in a - complex project that turned out to have cyclic-dependencies.
    -

    -

    Q. Why doesn't shared_ptr specify complexity requirements?

    -

    + progenitors had use_count(), and it was useful in tracking down bugs in a + complex project that turned out to have cyclic-dependencies. +

    +

    Q. Why doesn't shared_ptr specify complexity requirements?

    +

    A. Because complexity requirements limit implementors and complicate the - specification without apparent benefit to shared_ptr users. For example, + specification without apparent benefit to shared_ptr users. For example, error-checking implementations might become non-conforming if they had to meet - stringent complexity requirements.
    -

    -

    Q. Why doesn't shared_ptr provide a release() function?

    -

    - A. shared_ptr cannot give away ownership unless it's unique() - because the other copy will still destroy the object.

    + stringent complexity requirements. +

    +

    Q. Why doesn't shared_ptr provide a release() function?

    +

    + A. shared_ptr cannot give away ownership unless it's unique() + because the other copy will still destroy the object.

    Consider:

    shared_ptr<int> a(new int);
     shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
    @@ -698,25 +769,22 @@ int * p = a.release();
     // Who owns p now? b will still call delete on it in its destructor.

    Furthermore, the pointer returned by release() would be difficult - to deallocate reliably, as the source shared_ptr could have been created - with a custom deleter.
    + to deallocate reliably, as the source shared_ptr could have been created + with a custom deleter.

    -

    Q. Why is operator->() const, but its return value is a - non-const pointer to the element type?

    -

    +

    Q. Why is operator->() const, but its return value is a + non-const pointer to the element type?

    +

    A. Shallow copy pointers, including raw pointers, typically don't propagate constness. It makes little sense for them to do so, as you can always obtain a non-const pointer from a const one and then proceed to modify the - object through it.shared_ptr is "as close to raw pointers as possible - but no closer".
    -
    -

    -
    -

    - $Date$

    + object through it. shared_ptr is "as close to raw pointers as possible + but no closer". +

    +

    Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - Copyright 2002-2005 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.

    + Copyright 2002-2005, 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.

    From 1209531fe03c0cc2b6742cfc5b83539df205a42f Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 7 Dec 2012 01:53:35 +0000 Subject: [PATCH 154/210] Refactoring in detail array_deleter before adding support for special-casing trivially default-constructible construction and trivially destroyable destruction. [SVN r81748] --- .../boost/smart_ptr/allocate_shared_array.hpp | 1 - .../boost/smart_ptr/detail/array_deleter.hpp | 174 ++++-------------- .../boost/smart_ptr/detail/array_utility.hpp | 109 +++++++++++ include/boost/smart_ptr/make_shared_array.hpp | 1 - 4 files changed, 145 insertions(+), 140 deletions(-) create mode 100644 include/boost/smart_ptr/detail/array_utility.hpp diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index a98d97e..6f77c41 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 40e9d57..f86ae61 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -9,8 +9,8 @@ #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP #define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP -#include -#include +#include +#include namespace boost { namespace detail { @@ -24,97 +24,46 @@ namespace boost { object(0) { } ~array_deleter() { - destroy(size); + if (object) { + array_destroy(object, size); + } } void construct(T* memory) { - std::size_t i = 0; - try { - for (object = memory; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } - } catch (...) { - destroy(i); - throw; - } + array_construct(memory, size); + object = memory; } #if defined(BOOST_HAS_RVALUE_REFS) void construct(T* memory, T&& value) { - std::size_t i = 0; - try { - for (object = memory; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(value); - } - } catch (...) { - destroy(i); - throw; - } + array_construct(memory, size, value); + object = memory; } #if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { - std::size_t i = 0; - try { - for (object = memory; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(args...); - } - } catch (...) { - destroy(i); - throw; - } + array_construct(memory, size, args...); + object = memory; } #endif #endif void construct_list(T* memory, const T* list) { - std::size_t i = 0; - try { - for (object = memory; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i]); - } - } catch (...) { - destroy(i); - throw; - } + array_construct_list(memory, size, list); + object = memory; } void construct_list(T* memory, const T* list, std::size_t n) { - std::size_t i = 0; - try { - for (object = memory; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i % n]); - } - } catch (...) { - destroy(i); - throw; - } + array_construct_list(memory, size, list, n); + object = memory; } void construct_noinit(T* memory) { - std::size_t i = 0; - try { - for (object = memory; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T; - } - } catch (...) { - destroy(i); - throw; - } + array_construct_noinit(memory, size); + object = memory; } void operator()(const void*) { - destroy(size); - } - private: - void destroy(std::size_t n) { if (object) { - for (std::size_t i = n; i > 0; ) { - object[--i].~T(); - } + array_destroy(object, size); object = 0; } } + private: std::size_t size; T* object; }; @@ -125,97 +74,46 @@ namespace boost { : object(0) { } ~array_deleter() { - destroy(N); + if (object) { + array_destroy(object, N); + } } void construct(T* memory) { - std::size_t i = 0; - try { - for (object = memory; i < N; i++) { - void* p1 = memory + i; - ::new(p1) T(); - } - } catch (...) { - destroy(i); - throw; - } + array_construct(memory, N); + object = memory; } #if defined(BOOST_HAS_RVALUE_REFS) void construct(T* memory, T&& value) { - std::size_t i = 0; - try { - for (object = memory; i < N; i++) { - void* p1 = memory + i; - ::new(p1) T(value); - } - } catch (...) { - destroy(i); - throw; - } + array_construct(memory, N, value); + object = memory; } #if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { - std::size_t i = 0; - try { - for (object = memory; i < N; i++) { - void* p1 = memory + i; - ::new(p1) T(args...); - } - } catch (...) { - destroy(i); - throw; - } + array_construct(memory, N, args...); + object = memory; } #endif #endif void construct_list(T* memory, const T* list) { - std::size_t i = 0; - try { - for (object = memory; i < N; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i]); - } - } catch (...) { - destroy(i); - throw; - } + array_construct_list(memory, N, list); + object = memory; } void construct_list(T* memory, const T* list, std::size_t n) { - std::size_t i = 0; - try { - for (object = memory; i < N; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i % n]); - } - } catch (...) { - destroy(i); - throw; - } + array_construct_list(memory, N, list, n); + object = memory; } void construct_noinit(T* memory) { - std::size_t i = 0; - try { - for (object = memory; i < N; i++) { - void* p1 = memory + i; - ::new(p1) T; - } - } catch (...) { - destroy(i); - throw; - } + array_construct_noinit(memory, N); + object = memory; } void operator()(const void*) { - destroy(N); - } - private: - void destroy(std::size_t n) { if (object) { - for (std::size_t i = n; i > 0; ) { - object[--i].~T(); - } + array_destroy(object, N); object = 0; } } + private: T* object; }; } diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp new file mode 100644 index 0000000..d24bea1 --- /dev/null +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -0,0 +1,109 @@ +/* + * 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_UTILITY_HPP +#define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP + +#include +#include +#include + +namespace boost { + namespace detail { + template + inline void array_destroy(T* memory, std::size_t size) { + for (std::size_t i = size; i > 0; ) { + memory[--i].~T(); + } + } + template + inline void array_construct(T* memory, std::size_t size) { + std::size_t i = 0; + try { + for (; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(); + } + } catch (...) { + array_destroy(memory, i); + throw; + } + } +#if defined(BOOST_HAS_RVALUE_REFS) + template + inline void array_construct(T* memory, std::size_t size, T value) { + std::size_t i = 0; + try { + for (; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(value); + } + } catch (...) { + array_destroy(memory, i); + throw; + } + } +#if defined(BOOST_HAS_VARIADIC_TMPL) + template + inline void array_construct(T* memory, std::size_t size, Args... args) { + std::size_t i = 0; + try { + for (; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(args...); + } + } catch (...) { + array_destroy(memory, i); + throw; + } + } +#endif +#endif + template + inline void array_construct_list(T* memory, std::size_t size, const T* list) { + std::size_t i = 0; + try { + for (; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(list[i]); + } + } catch (...) { + array_destroy(memory, i); + throw; + } + } + template + inline void array_construct_list(T* memory, std::size_t size, const T* list, std::size_t n) { + std::size_t i = 0; + try { + for (; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(list[i % n]); + } + } catch (...) { + array_destroy(memory, i); + throw; + } + } + template + inline void array_construct_noinit(T* memory, std::size_t size) { + std::size_t i = 0; + try { + for (; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T; + } + } catch (...) { + array_destroy(memory, i); + throw; + } + } + } +} + +#endif diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index b4fd9f6..8e49b5f 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include From b3f2ebedbcb1003c609b6c891a44c013cb60953c Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 7 Dec 2012 03:10:22 +0000 Subject: [PATCH 155/210] Special case array construction for trivially default-constructible types and array destruction for trivially-destroyable types. [SVN r81749] --- .../boost/smart_ptr/detail/array_utility.hpp | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp index d24bea1..05bca19 100644 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -17,12 +17,32 @@ namespace boost { namespace detail { template inline void array_destroy(T* memory, std::size_t size) { + boost::has_trivial_destructor type; + array_destroy(memory, size, type); + } + template + inline void array_destroy(T*, std::size_t, boost::true_type) { + } + template + inline void array_destroy(T* memory, std::size_t size, boost::false_type) { for (std::size_t i = size; i > 0; ) { memory[--i].~T(); } } template inline void array_construct(T* memory, std::size_t size) { + boost::has_trivial_default_constructor type; + array_construct(memory, size, type); + } + template + inline void array_construct(T* memory, std::size_t size, boost::true_type) { + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(); + } + } + template + inline void array_construct(T* memory, std::size_t size, boost::false_type) { std::size_t i = 0; try { for (; i < size; i++) { @@ -92,6 +112,14 @@ namespace boost { } template inline void array_construct_noinit(T* memory, std::size_t size) { + boost::has_trivial_default_constructor type; + array_construct_noinit(memory, size, type); + } + template + inline void array_construct_noinit(T*, std::size_t, boost::true_type) { + } + template + inline void array_construct_noinit(T* memory, std::size_t size, boost::false_type) { std::size_t i = 0; try { for (; i < size; i++) { From 09e77bc8dfb597f065d0aae6e518ab53b9b75155 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 7 Dec 2012 06:45:26 +0000 Subject: [PATCH 156/210] Optimization in initialization overload of array_construct for compilers to optimize it into the equivalent of a memset [SVN r81750] --- include/boost/smart_ptr/detail/array_utility.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp index 05bca19..bef3942 100644 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -37,8 +37,7 @@ namespace boost { template inline void array_construct(T* memory, std::size_t size, boost::true_type) { for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(); + memory[i] = T(); } } template From ea229828654055f3f876c2a4418a94830023d47e Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 7 Dec 2012 07:42:42 +0000 Subject: [PATCH 157/210] Correctly use r-value reference semantics for Args and T in array utilities [SVN r81752] --- include/boost/smart_ptr/detail/array_deleter.hpp | 8 ++++---- include/boost/smart_ptr/detail/array_utility.hpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index f86ae61..9fb55e1 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -34,13 +34,13 @@ namespace boost { } #if defined(BOOST_HAS_RVALUE_REFS) void construct(T* memory, T&& value) { - array_construct(memory, size, value); + array_construct_value(memory, size, sp_forward(value)); object = memory; } #if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { - array_construct(memory, size, args...); + array_construct_args(memory, size, sp_forward(args)...); object = memory; } #endif @@ -84,13 +84,13 @@ namespace boost { } #if defined(BOOST_HAS_RVALUE_REFS) void construct(T* memory, T&& value) { - array_construct(memory, N, value); + array_construct_value(memory, N, sp_forward(value)); object = memory; } #if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { - array_construct(memory, N, args...); + array_construct_args(memory, N, sp_forward(args)...); object = memory; } #endif diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp index bef3942..d60c867 100644 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -55,7 +55,7 @@ namespace boost { } #if defined(BOOST_HAS_RVALUE_REFS) template - inline void array_construct(T* memory, std::size_t size, T value) { + inline void array_construct_value(T* memory, std::size_t size, T&& value) { std::size_t i = 0; try { for (; i < size; i++) { @@ -69,7 +69,7 @@ namespace boost { } #if defined(BOOST_HAS_VARIADIC_TMPL) template - inline void array_construct(T* memory, std::size_t size, Args... args) { + inline void array_construct_args(T* memory, std::size_t size, Args&&... args) { std::size_t i = 0; try { for (; i < size; i++) { From f390d9e265d93daf259ef9dccab4c461996de415 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 7 Dec 2012 16:40:20 +0000 Subject: [PATCH 158/210] Change ordering of overload definitions in array_utility.hpp [SVN r81759] --- .../boost/smart_ptr/detail/array_utility.hpp | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp index d60c867..633be02 100644 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -15,13 +15,9 @@ namespace boost { namespace detail { - template - inline void array_destroy(T* memory, std::size_t size) { - boost::has_trivial_destructor type; - array_destroy(memory, size, type); - } template inline void array_destroy(T*, std::size_t, boost::true_type) { + // do nothing } template inline void array_destroy(T* memory, std::size_t size, boost::false_type) { @@ -30,9 +26,9 @@ namespace boost { } } template - inline void array_construct(T* memory, std::size_t size) { - boost::has_trivial_default_constructor type; - array_construct(memory, size, type); + inline void array_destroy(T* memory, std::size_t size) { + boost::has_trivial_destructor type; + array_destroy(memory, size, type); } template inline void array_construct(T* memory, std::size_t size, boost::true_type) { @@ -53,6 +49,11 @@ namespace boost { throw; } } + template + inline void array_construct(T* memory, std::size_t size) { + boost::has_trivial_default_constructor type; + array_construct(memory, size, type); + } #if defined(BOOST_HAS_RVALUE_REFS) template inline void array_construct_value(T* memory, std::size_t size, T&& value) { @@ -110,12 +111,8 @@ namespace boost { } } template - inline void array_construct_noinit(T* memory, std::size_t size) { - boost::has_trivial_default_constructor type; - array_construct_noinit(memory, size, type); - } - template inline void array_construct_noinit(T*, std::size_t, boost::true_type) { + // do nothing } template inline void array_construct_noinit(T* memory, std::size_t size, boost::false_type) { @@ -130,6 +127,11 @@ namespace boost { throw; } } + template + inline void array_construct_noinit(T* memory, std::size_t size) { + boost::has_trivial_default_constructor type; + array_construct_noinit(memory, size, type); + } } } From 7a4ad75f5d189063852086ffd519ee424680d548 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 7 Dec 2012 22:42:56 +0000 Subject: [PATCH 159/210] Add more unique_ptr tests. [SVN r81776] --- test/sp_unique_ptr_test.cpp | 63 +++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/test/sp_unique_ptr_test.cpp b/test/sp_unique_ptr_test.cpp index 7656e75..69bbaf9 100644 --- a/test/sp_unique_ptr_test.cpp +++ b/test/sp_unique_ptr_test.cpp @@ -95,6 +95,60 @@ int main() p2 = std::unique_ptr( new X ); BOOST_TEST( X::instances == 1 ); + p2 = std::unique_ptr( new X ); + BOOST_TEST( X::instances == 1 ); + + p2.reset(); + BOOST_TEST( X::instances == 0 ); + } + + { + BOOST_TEST( X::instances == 0 ); + + std::unique_ptr p( new X ); + BOOST_TEST( X::instances == 1 ); + + boost::shared_ptr p2( std::move( p ) ); + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( p.get() == 0 ); + + boost::shared_ptr p3 = p2->shared_from_this(); + BOOST_TEST( p2 == p3 ); + BOOST_TEST( !(p2 < p3) && !(p3 < p2) ); + + p2.reset(); + p3.reset(); + BOOST_TEST( X::instances == 0 ); + + p2 = std::unique_ptr( new X ); + BOOST_TEST( X::instances == 1 ); + + p2 = std::unique_ptr( new X ); + BOOST_TEST( X::instances == 1 ); + + p2.reset(); + BOOST_TEST( X::instances == 0 ); + } + + { + BOOST_TEST( X::instances == 0 ); + + std::unique_ptr p( new X ); + BOOST_TEST( X::instances == 1 ); + + boost::shared_ptr p2( std::move( p ) ); + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( p.get() == 0 ); + + p2.reset(); + BOOST_TEST( X::instances == 0 ); + + p2 = std::unique_ptr( new X ); + BOOST_TEST( X::instances == 1 ); + + p2 = std::unique_ptr( new X ); + BOOST_TEST( X::instances == 1 ); + p2.reset(); BOOST_TEST( X::instances == 0 ); } @@ -115,6 +169,9 @@ int main() p2 = std::unique_ptr( new Y, YD() ); BOOST_TEST( Y::instances == 1 ); + p2 = std::unique_ptr( new Y, YD() ); + BOOST_TEST( Y::instances == 1 ); + p2.reset(); BOOST_TEST( Y::instances == 0 ); } @@ -137,6 +194,9 @@ int main() p2 = std::unique_ptr( new Y, yd ); BOOST_TEST( Y::instances == 1 ); + p2 = std::unique_ptr( new Y, yd ); + BOOST_TEST( Y::instances == 1 ); + p2.reset(); BOOST_TEST( Y::instances == 0 ); } @@ -159,6 +219,9 @@ int main() p2 = std::unique_ptr( new Y, yd ); BOOST_TEST( Y::instances == 1 ); + p2 = std::unique_ptr( new Y, yd ); + BOOST_TEST( Y::instances == 1 ); + p2.reset(); BOOST_TEST( Y::instances == 0 ); } From 8093967da70802f6bbbd7944c0757b1e04b6067c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 8 Dec 2012 00:51:59 +0000 Subject: [PATCH 160/210] Use explicit operator bool when available; add nullptr support to shared_ptr. Refs #4116. [SVN r81780] --- .../boost/smart_ptr/detail/operator_bool.hpp | 11 +- include/boost/smart_ptr/intrusive_ptr.hpp | 24 +++ include/boost/smart_ptr/scoped_array.hpp | 25 ++++ include/boost/smart_ptr/scoped_ptr.hpp | 25 ++++ include/boost/smart_ptr/shared_array.hpp | 24 +++ include/boost/smart_ptr/shared_ptr.hpp | 60 +++++++- test/Jamfile.v2 | 2 + test/sp_nullptr_test.cpp | 140 ++++++++++++++++++ test/sp_zero_compare_test.cpp | 78 ++++++++++ 9 files changed, 386 insertions(+), 3 deletions(-) create mode 100644 test/sp_nullptr_test.cpp create mode 100644 test/sp_zero_compare_test.cpp diff --git a/include/boost/smart_ptr/detail/operator_bool.hpp b/include/boost/smart_ptr/detail/operator_bool.hpp index e38593f..8ae1527 100644 --- a/include/boost/smart_ptr/detail/operator_bool.hpp +++ b/include/boost/smart_ptr/detail/operator_bool.hpp @@ -1,12 +1,19 @@ // This header intentionally has no include guards. // -// Copyright (c) 2001-2009 Peter Dimov +// Copyright (c) 2001-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 -#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__) +#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR ) + + explicit operator bool () const BOOST_NOEXCEPT + { + return px != 0; + } + +#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__) operator bool () const BOOST_NOEXCEPT { diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index 01e2429..ffb2dba 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -218,6 +218,30 @@ template inline bool operator!=(intrusive_ptr const & a, intrusive_p #endif +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +template inline bool operator==( intrusive_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator==( std::nullptr_t, intrusive_ptr const & p ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator!=( intrusive_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +template inline bool operator!=( std::nullptr_t, intrusive_ptr const & p ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +#endif + template inline bool operator<(intrusive_ptr const & a, intrusive_ptr const & b) { return std::less()(a.get(), b.get()); diff --git a/include/boost/smart_ptr/scoped_array.hpp b/include/boost/smart_ptr/scoped_array.hpp index 83352e2..1ddaa07 100644 --- a/include/boost/smart_ptr/scoped_array.hpp +++ b/include/boost/smart_ptr/scoped_array.hpp @@ -11,6 +11,7 @@ // http://www.boost.org/libs/smart_ptr/scoped_array.htm // +#include #include #include #include // in case ptrdiff_t not in std @@ -97,6 +98,30 @@ public: } }; +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +template inline bool operator==( scoped_array const & p, std::nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator==( std::nullptr_t, scoped_array const & p ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator!=( scoped_array const & p, std::nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +template inline bool operator!=( std::nullptr_t, scoped_array const & p ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +#endif + template inline void swap(scoped_array & a, scoped_array & b) BOOST_NOEXCEPT { a.swap(b); diff --git a/include/boost/smart_ptr/scoped_ptr.hpp b/include/boost/smart_ptr/scoped_ptr.hpp index 3ccf697..a75f91f 100644 --- a/include/boost/smart_ptr/scoped_ptr.hpp +++ b/include/boost/smart_ptr/scoped_ptr.hpp @@ -11,6 +11,7 @@ // http://www.boost.org/libs/smart_ptr/scoped_ptr.htm // +#include #include #include #include @@ -114,6 +115,30 @@ public: } }; +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +template inline bool operator==( scoped_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator==( std::nullptr_t, scoped_ptr const & p ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator!=( scoped_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +template inline bool operator!=( std::nullptr_t, scoped_ptr const & p ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +#endif + template inline void swap(scoped_ptr & a, scoped_ptr & b) BOOST_NOEXCEPT { a.swap(b); diff --git a/include/boost/smart_ptr/shared_array.hpp b/include/boost/smart_ptr/shared_array.hpp index ac64099..f54f481 100644 --- a/include/boost/smart_ptr/shared_array.hpp +++ b/include/boost/smart_ptr/shared_array.hpp @@ -243,6 +243,30 @@ template inline bool operator!=(shared_array const & a, shared_array return a.get() != b.get(); } +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +template inline bool operator==( shared_array const & p, std::nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator==( std::nullptr_t, shared_array const & p ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator!=( shared_array const & p, std::nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +template inline bool operator!=( std::nullptr_t, shared_array const & p ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +#endif + template inline bool operator<(shared_array const & a, shared_array const & b) BOOST_NOEXCEPT { return std::less()(a.get(), b.get()); diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 6a09c28..ad7a92a 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -41,7 +41,7 @@ #include // for std::swap #include // for std::less #include // for std::bad_cast -#include // for std::size_t +#include // for std::size_t, std::nullptr_t #if !defined(BOOST_NO_IOSTREAM) #if !defined(BOOST_NO_IOSFWD) @@ -339,6 +339,14 @@ public: { } +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + shared_ptr( std::nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws + { + } + +#endif + template explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete { @@ -356,6 +364,14 @@ public: boost::detail::sp_deleter_construct( this, p ); } +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + template shared_ptr( std::nullptr_t p, D d ): px( p ), pn( p, d ) + { + } + +#endif + // 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 ) @@ -363,6 +379,14 @@ public: boost::detail::sp_deleter_construct( this, p ); } +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + template shared_ptr( std::nullptr_t p, D d, A a ): px( p ), pn( p, d, a ) + { + } + +#endif + // generated copy constructor, destructor are fine... #if defined( BOOST_HAS_RVALUE_REFS ) @@ -577,6 +601,16 @@ public: return *this; } +#endif + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + shared_ptr & operator=( std::nullptr_t ) BOOST_NOEXCEPT // never throws + { + this_type().swap(*this); + return *this; + } + #endif void reset() BOOST_NOEXCEPT // never throws in 1.30+ @@ -711,6 +745,30 @@ template inline bool operator!=(shared_ptr const & a, shared_ptr #endif +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +template inline bool operator==( shared_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator==( std::nullptr_t, shared_ptr const & p ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator!=( shared_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +template inline bool operator!=( std::nullptr_t, shared_ptr const & p ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +#endif + template inline bool operator<(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT { return a.owner_before( b ); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 2c95dd9..9f08375 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -75,6 +75,8 @@ import testing ; [ run sp_convertible_test.cpp ] [ run sp_array_n_test.cpp ] [ run sp_array_cast_test.cpp ] + [ run sp_zero_compare_test.cpp ] + [ run sp_nullptr_test.cpp ] [ compile-fail array_fail_spa_sp_c.cpp ] [ compile-fail array_fail_sp_spa_c.cpp ] diff --git a/test/sp_nullptr_test.cpp b/test/sp_nullptr_test.cpp new file mode 100644 index 0000000..a1779bb --- /dev/null +++ b/test/sp_nullptr_test.cpp @@ -0,0 +1,140 @@ +// +// sp_nullptr_test.cpp +// +// Copyright 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 + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +struct X +{ + static int instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + +private: + + X( X const & ); + X & operator=( X const & ); +}; + +int X::instances = 0; + +void f( std::nullptr_t ) +{ +} + +int main() +{ + { + boost::shared_ptr p( nullptr ); + + BOOST_TEST( p.get() == 0 ); + BOOST_TEST( p.use_count() == 0 ); + + BOOST_TEST( p == nullptr ); + BOOST_TEST( nullptr == p ); + BOOST_TEST( !( p != nullptr ) ); + BOOST_TEST( !( nullptr != p ) ); + } + + { + boost::shared_ptr p( nullptr, f ); + + BOOST_TEST( p.get() == 0 ); + BOOST_TEST( p.use_count() == 1 ); + + BOOST_TEST( p == nullptr ); + BOOST_TEST( nullptr == p ); + BOOST_TEST( !( p != nullptr ) ); + BOOST_TEST( !( nullptr != p ) ); + } + + { + boost::shared_ptr p( nullptr, f, std::allocator() ); + + BOOST_TEST( p.get() == 0 ); + BOOST_TEST( p.use_count() == 1 ); + + BOOST_TEST( p == nullptr ); + BOOST_TEST( nullptr == p ); + BOOST_TEST( !( p != nullptr ) ); + BOOST_TEST( !( nullptr != p ) ); + } + + { + boost::shared_ptr p( new int ); + + BOOST_TEST( p.get() != 0 ); + BOOST_TEST( p.use_count() == 1 ); + + BOOST_TEST( p != nullptr ); + BOOST_TEST( nullptr != p ); + BOOST_TEST( !( p == nullptr ) ); + BOOST_TEST( !( nullptr == p ) ); + + p = nullptr; + + BOOST_TEST( p.get() == 0 ); + BOOST_TEST( p.use_count() == 0 ); + + BOOST_TEST( p == nullptr ); + BOOST_TEST( nullptr == p ); + BOOST_TEST( !( p != nullptr ) ); + BOOST_TEST( !( nullptr != p ) ); + } + + { + BOOST_TEST( X::instances == 0 ); + + boost::shared_ptr p( new X ); + BOOST_TEST( X::instances == 1 ); + + BOOST_TEST( p.get() != 0 ); + BOOST_TEST( p.use_count() == 1 ); + + BOOST_TEST( p != nullptr ); + BOOST_TEST( nullptr != p ); + BOOST_TEST( !( p == nullptr ) ); + BOOST_TEST( !( nullptr == p ) ); + + p = nullptr; + BOOST_TEST( X::instances == 0 ); + + BOOST_TEST( p.get() == 0 ); + BOOST_TEST( p.use_count() == 0 ); + + BOOST_TEST( p == nullptr ); + BOOST_TEST( nullptr == p ); + BOOST_TEST( !( p != nullptr ) ); + BOOST_TEST( !( nullptr != p ) ); + } + + return boost::report_errors(); +} + +#else + +int main() +{ + return 0; +} + +#endif diff --git a/test/sp_zero_compare_test.cpp b/test/sp_zero_compare_test.cpp new file mode 100644 index 0000000..e326d34 --- /dev/null +++ b/test/sp_zero_compare_test.cpp @@ -0,0 +1,78 @@ +// +// sp_zero_compare_test.cpp - == 0, != 0 +// +// Copyright 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 + +struct W +{ +}; + +void intrusive_ptr_add_ref( W* ) +{ +} + +void intrusive_ptr_release( W* ) +{ +} + +int main() +{ + { + boost::scoped_ptr p; + + BOOST_TEST( p == 0 ); + BOOST_TEST( 0 == p ); + BOOST_TEST( !( p != 0 ) ); + BOOST_TEST( !( 0 != p ) ); + } + + { + boost::scoped_array p; + + BOOST_TEST( p == 0 ); + BOOST_TEST( 0 == p ); + BOOST_TEST( !( p != 0 ) ); + BOOST_TEST( !( 0 != p ) ); + } + + { + boost::shared_ptr p; + + BOOST_TEST( p == 0 ); + BOOST_TEST( 0 == p ); + BOOST_TEST( !( p != 0 ) ); + BOOST_TEST( !( 0 != p ) ); + } + + { + boost::shared_array p; + + BOOST_TEST( p == 0 ); + BOOST_TEST( 0 == p ); + BOOST_TEST( !( p != 0 ) ); + BOOST_TEST( !( 0 != p ) ); + } + + { + boost::intrusive_ptr p; + + BOOST_TEST( p == 0 ); + BOOST_TEST( 0 == p ); + BOOST_TEST( !( p != 0 ) ); + BOOST_TEST( !( 0 != p ) ); + } + + return boost::report_errors(); +} From 6b0d96af96593284029f9a05b2831c71ea1b3bea Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 8 Dec 2012 05:25:50 +0000 Subject: [PATCH 161/210] Convert function parameter for inner array size into template parameter and make identifiers in array_deleter consistent with those in array_utility [SVN r81782] --- .../boost/smart_ptr/allocate_shared_array.hpp | 4 ++-- .../boost/smart_ptr/detail/array_deleter.hpp | 18 ++++++++++-------- .../boost/smart_ptr/detail/array_utility.hpp | 12 +++++------- include/boost/smart_ptr/make_shared_array.hpp | 4 ++-- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 6f77c41..dc24ca2 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -141,7 +141,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_list(p2, p3, M); + d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } template @@ -165,7 +165,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_list(p2, p3, M); + d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } #if defined(BOOST_HAS_RVALUE_REFS) diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 9fb55e1..8ef0d11 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -34,13 +34,13 @@ namespace boost { } #if defined(BOOST_HAS_RVALUE_REFS) void construct(T* memory, T&& value) { - array_construct_value(memory, size, sp_forward(value)); + array_construct(memory, size, sp_forward(value)); object = memory; } #if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { - array_construct_args(memory, size, sp_forward(args)...); + array_construct(memory, size, sp_forward(args)...); object = memory; } #endif @@ -49,8 +49,9 @@ namespace boost { array_construct_list(memory, size, list); object = memory; } - void construct_list(T* memory, const T* list, std::size_t n) { - array_construct_list(memory, size, list, n); + template + void construct_list(T* memory, const T* list) { + array_construct_list(memory, size, list); object = memory; } void construct_noinit(T* memory) { @@ -84,13 +85,13 @@ namespace boost { } #if defined(BOOST_HAS_RVALUE_REFS) void construct(T* memory, T&& value) { - array_construct_value(memory, N, sp_forward(value)); + array_construct(memory, N, sp_forward(value)); object = memory; } #if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { - array_construct_args(memory, N, sp_forward(args)...); + array_construct(memory, N, sp_forward(args)...); object = memory; } #endif @@ -99,8 +100,9 @@ namespace boost { array_construct_list(memory, N, list); object = memory; } - void construct_list(T* memory, const T* list, std::size_t n) { - array_construct_list(memory, N, list, n); + template + void construct_list(T* memory, const T* list) { + array_construct_list(memory, N, list); object = memory; } void construct_noinit(T* memory) { diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp index 633be02..b584599 100644 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -17,7 +17,6 @@ namespace boost { namespace detail { template inline void array_destroy(T*, std::size_t, boost::true_type) { - // do nothing } template inline void array_destroy(T* memory, std::size_t size, boost::false_type) { @@ -56,7 +55,7 @@ namespace boost { } #if defined(BOOST_HAS_RVALUE_REFS) template - inline void array_construct_value(T* memory, std::size_t size, T&& value) { + inline void array_construct(T* memory, std::size_t size, T&& value) { std::size_t i = 0; try { for (; i < size; i++) { @@ -70,7 +69,7 @@ namespace boost { } #if defined(BOOST_HAS_VARIADIC_TMPL) template - inline void array_construct_args(T* memory, std::size_t size, Args&&... args) { + inline void array_construct(T* memory, std::size_t size, Args&&... args) { std::size_t i = 0; try { for (; i < size; i++) { @@ -97,13 +96,13 @@ namespace boost { throw; } } - template - inline void array_construct_list(T* memory, std::size_t size, const T* list, std::size_t n) { + template + inline void array_construct_list(T* memory, std::size_t size, const T* list) { std::size_t i = 0; try { for (; i < size; i++) { void* p1 = memory + i; - ::new(p1) T(list[i % n]); + ::new(p1) T(list[i % N]); } } catch (...) { array_destroy(memory, i); @@ -112,7 +111,6 @@ namespace boost { } template inline void array_construct_noinit(T*, std::size_t, boost::true_type) { - // do nothing } template inline void array_construct_noinit(T* memory, std::size_t size, boost::false_type) { diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 8e49b5f..cf63ecb 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -140,7 +140,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_list(p2, p3, M); + d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } template @@ -163,7 +163,7 @@ namespace boost { p3 = reinterpret_cast(list); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct_list(p2, p3, M); + d2->construct_list(p2, p3); return boost::shared_ptr(s1, p1); } #if defined(BOOST_HAS_RVALUE_REFS) From 9863467152f23005e8494476e2c7ce365e27fc6f Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 10 Dec 2012 23:48:00 +0000 Subject: [PATCH 162/210] Correct link to http://www.stroustrup.com/wrapper.pdf in sp_techniques.html [SVN r81844] --- sp_techniques.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sp_techniques.html b/sp_techniques.html index 4b7363b..f869279 100644 --- a/sp_techniques.html +++ b/sp_techniques.html @@ -624,7 +624,7 @@ public:

    Using shared_ptr to wrap member function calls

    shared_ptr implements the ownership semantics required from the Wrap/CallProxy scheme described in Bjarne Stroustrup's article "Wrapping C++ Member Function - Calls" (available online at http://www.research.att.com/~bs/wrapper.pdf). + Calls" (available online at http://www.stroustrup.com/wrapper.pdf). An implementation is given below:

    template<class T> class pointer
     {
    
    From ecceb710de2c175a4f125f5ab83ad05cc42db124 Mon Sep 17 00:00:00 2001
    From: Glen Fernandes 
    Date: Tue, 11 Dec 2012 17:42:47 +0000
    Subject: [PATCH 163/210] Add overloads of allocate_shared_noinit to complement
     make_shared_noinit
    
    [SVN r81858]
    ---
     .../boost/smart_ptr/allocate_shared_array.hpp | 36 +++++++++
     make_shared_array.html                        | 14 +++-
     test/allocate_shared_array_esft_test.cpp      | 10 +++
     test/allocate_shared_array_test.cpp           | 74 +++++++++++++++++++
     test/allocate_shared_array_throws_test.cpp    | 14 ++++
     test/allocate_shared_arrays_test.cpp          | 56 ++++++++++++++
     6 files changed, 202 insertions(+), 2 deletions(-)
    
    diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp
    index dc24ca2..9aaacc7 100644
    --- a/include/boost/smart_ptr/allocate_shared_array.hpp
    +++ b/include/boost/smart_ptr/allocate_shared_array.hpp
    @@ -209,6 +209,42 @@ namespace boost {
         }
     #endif
     #endif
    +    template
    +    inline typename boost::detail::sp_if_array::type
    +    allocate_shared_noinit(const A& allocator, std::size_t size) {
    +        typedef typename boost::detail::array_inner::type T1;
    +        typedef typename boost::detail::array_base::type T2;
    +        T1* p1 = 0;
    +        T2* p2 = 0;
    +        std::size_t n1 = size * boost::detail::array_total::size;
    +        boost::detail::allocate_array_helper a1(allocator, n1, &p2);
    +        boost::detail::array_deleter d1(n1);
    +        boost::shared_ptr s1(p1, d1, a1);
    +        boost::detail::array_deleter* d2;
    +        p1 = reinterpret_cast(p2);        
    +        d2 = get_deleter >(s1);
    +        d2->construct_noinit(p2);
    +        return boost::shared_ptr(s1, p1);
    +    }
    +    template
    +    inline typename boost::detail::sp_if_size_array::type
    +    allocate_shared_noinit(const A& allocator) {
    +        typedef typename boost::detail::array_inner::type T1;
    +        typedef typename boost::detail::array_base::type T2;
    +        enum { 
    +            N = boost::detail::array_total::size 
    +        };
    +        T1* p1 = 0;
    +        T2* p2 = 0;
    +        boost::detail::allocate_array_helper a1(allocator, &p2);
    +        boost::detail::array_deleter d1;
    +        boost::shared_ptr s1(p1, d1, a1);
    +        boost::detail::array_deleter* d2;
    +        p1 = reinterpret_cast(p2);     
    +        d2 = get_deleter >(s1);
    +        d2->construct_noinit(p2);
    +        return boost::shared_ptr(s1, p1);
    +    }
     }
     
     #endif
    diff --git a/make_shared_array.html b/make_shared_array.html
    index c1db41f..6f34519 100644
    --- a/make_shared_array.html
    +++ b/make_shared_array.html
    @@ -96,6 +96,12 @@
     
         template<typename T>
         shared_ptr<T[N]> make_shared_noinit();
    +    
    +    template<typename T, typename A>
    +    shared_ptr<T[]> allocate_shared_noinit(const A& allocator, size_t size);
    +
    +    template<typename T, typename A>
    +    shared_ptr<T[N]> allocate_shared_noinit(const A& allocator);
     }

    Free Functions

    template<typename T, typename... Args>
    @@ -197,13 +203,17 @@ template<typename T, typename A>
             fixed size array.

    Effects: Constructs an empty shared_ptr.

    Postconditions: use_count() == 0 && get() == 0.

    @@ -260,7 +279,9 @@ void bad() not have a virtual destructor, or is void.]

    constructors taking a deleter

    template<class Y, class D> shared_ptr(Y * p, D d);
    -template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);
    +template<class Y, class D, class A> shared_ptr(Y * p, D d, A a); +template<class D> shared_ptr(std::nullptr_t p, D d); +template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a);

    Requirements: D must be CopyConstructible. The copy constructor and destructor @@ -273,8 +294,8 @@ template<class Y, class D, class A> shared_ptr(Y * p, D d, A a); otherwise, Y* must be convertible to T*.

    Effects: Constructs a shared_ptr that owns the pointer - p and the deleter d. The second constructor allocates - memory using a copy of a.

    + p
    and the deleter d. The constructors taking an allocator a + allocate memory using a copy of a.

    Postconditions: use_count() == 1 && get() == p.

    Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

    @@ -350,8 +371,8 @@ template<class Y> shared_ptr(std::auto_ptr<Y> && r);

    Requires: Y* should be convertible to T*.

    Effects: - Equivalent to shared_ptr( r.release(), r.get_deleter() ) when D is not a reference type. - Otherwise, equivalent to shared_ptr( r.release(), del ), where del is a deleter + Equivalent to shared_ptr(r.release(), r.get_deleter()) when D is not a reference type. + Otherwise, equivalent to shared_ptr(r.release(), del), where del is a deleter that stores the reference rd returned from r.get_deleter() and del(p) calls rd(p).

    Postconditions: use_count() == 1.

    Throws: std::bad_alloc, or an implementation-defined @@ -401,7 +422,12 @@ template<class Y> shared_ptr & operator=(shared_ptr<Y> && template<class Y> shared_ptr & operator=(std::auto_ptr<Y> && r); template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r);

    -

    Effects: Equivalent to shared_ptr( std::move(r) ).swap(*this).

    +

    Effects: Equivalent to shared_ptr(std::move(r)).swap(*this).

    +

    Returns: *this.

    +
    +
    shared_ptr & operator=(std::nullptr_t); // never throws
    +
    +

    Effects: Equivalent to shared_ptr().swap(*this).

    Returns: *this.

    reset

    @@ -438,11 +464,11 @@ template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y

    Returns: the stored pointer.

    Throws: nothing.

    -
    element_type & operator[]( std::ptrdiff_t i ) const; // never throws
    +
    element_type & operator[](std::ptrdiff_t i) const; // never throws

    Requirements: T should be an array type. The stored pointer must not be 0. i >= 0. If T is U[N], i < N.

    -

    Returns: get()[ i ].

    +

    Returns: get()[i].

    Throws: nothing.

    get

    @@ -471,15 +497,12 @@ template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y for debugging and testing purposes, not for production code.

    conversions

    -
    operator unspecified-bool-type () const; // never throws
    +
    explicit operator bool() const; // never throws
    -

    Returns: an unspecified value that, when used in boolean contexts, is - equivalent to get() != 0.

    +

    Returns: get() != 0.

    Throws: nothing.

    Notes: This conversion operator allows shared_ptr objects to be - used in boolean contexts, like if (p && p->valid()) {}. - The actual target type is typically a pointer to a member function, avoiding - many of the implicit conversion pitfalls.

    + used in boolean contexts, like if(p && p->valid()) {}.

    [The conversion to bool is not merely syntactic sugar. It allows shared_ptrs to be declared in conditions when using dynamic_pointer_cast @@ -490,6 +513,13 @@ template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y

    Effects: Exchanges the contents of the two smart pointers.

    Throws: nothing.

    +

    swap

    +
    template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const; // never throws
    +template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const; // never throws
    +
    +

    Effects: See the description of operator<.

    +

    Throws: nothing.

    +

    Free Functions

    comparison

    template<class T, class U>
    @@ -504,6 +534,22 @@ template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y
     			

    Returns: a.get() != b.get().

    Throws: nothing.

    +
    template<class T>
    +  bool operator==(shared_ptr<T> const & p, std::nullptr_t); // never throws
    +template<class T>
    +  bool operator==(std::nullptr_t, shared_ptr<T> const & p); // never throws
    +
    +

    Returns: p.get() == 0.

    +

    Throws: nothing.

    +
    +
    template<class T>
    +  bool operator!=(shared_ptr<T> const & p, std::nullptr_t); // never throws
    +template<class T>
    +  bool operator!=(std::nullptr_t, shared_ptr<T> const & p); // never throws
    +
    +

    Returns: p.get() != 0.

    +

    Throws: nothing.

    +
    template<class T, class U>
       bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
    @@ -743,7 +789,7 @@ p3.reset(new int(2)); // undefined, multiple writes

    A. Automatic conversion is believed to be too error prone.

    -

    Q. Why does shared_ptr supply use_count()?

    +

    Q. Why does shared_ptr supply use_count()?

    A. As an aid to writing test cases and debugging displays. One of the progenitors had use_count(), and it was useful in tracking down bugs in a @@ -783,7 +829,7 @@ int * p = a.release();


    Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. - Copyright 2002-2005, 2012 Peter Dimov. Distributed under the Boost Software License, + Copyright 2002-2005, 2012, 2013 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.

    From ef817e91d21a8396ebb63fe76448088ff3a55388 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 4 Jan 2013 15:41:13 +0000 Subject: [PATCH 180/210] Replace std::nullptr_t with boost::detail::sp_nullptr_t. [SVN r82351] --- .../boost/smart_ptr/detail/sp_nullptr_t.hpp | 45 +++++++++++++++++++ include/boost/smart_ptr/intrusive_ptr.hpp | 9 ++-- include/boost/smart_ptr/scoped_array.hpp | 10 ++--- include/boost/smart_ptr/scoped_ptr.hpp | 9 ++-- include/boost/smart_ptr/shared_array.hpp | 9 ++-- include/boost/smart_ptr/shared_ptr.hpp | 19 ++++---- 6 files changed, 75 insertions(+), 26 deletions(-) create mode 100644 include/boost/smart_ptr/detail/sp_nullptr_t.hpp diff --git a/include/boost/smart_ptr/detail/sp_nullptr_t.hpp b/include/boost/smart_ptr/detail/sp_nullptr_t.hpp new file mode 100644 index 0000000..ccbb123 --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_nullptr_t.hpp @@ -0,0 +1,45 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_nullptr_t.hpp +// +// Copyright 2013 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 + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +namespace boost +{ + +namespace detail +{ + +#if defined( __clang__ ) && !defined( _LIBCPP_VERSION ) && !defined( BOOST_NO_CXX11_DECLTYPE ) + + typedef decltype(nullptr) sp_nullptr_t; + +#else + + typedef std::nullptr_t sp_nullptr_t; + +#endif + +} // namespace detail + +} // namespace boost + +#endif // !defined( BOOST_NO_CXX11_NULLPTR ) + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index 64a2923..b6f5bcd 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include // for std::less @@ -220,22 +221,22 @@ template inline bool operator!=(intrusive_ptr const & a, intrusive_p #if !defined( BOOST_NO_CXX11_NULLPTR ) -template inline bool operator==( intrusive_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +template inline bool operator==( intrusive_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT { return p.get() == 0; } -template inline bool operator==( std::nullptr_t, intrusive_ptr const & p ) BOOST_NOEXCEPT +template inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr const & p ) BOOST_NOEXCEPT { return p.get() == 0; } -template inline bool operator!=( intrusive_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +template inline bool operator!=( intrusive_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT { return p.get() != 0; } -template inline bool operator!=( std::nullptr_t, intrusive_ptr const & p ) BOOST_NOEXCEPT +template inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr const & p ) BOOST_NOEXCEPT { return p.get() != 0; } diff --git a/include/boost/smart_ptr/scoped_array.hpp b/include/boost/smart_ptr/scoped_array.hpp index 1ddaa07..e395e28 100644 --- a/include/boost/smart_ptr/scoped_array.hpp +++ b/include/boost/smart_ptr/scoped_array.hpp @@ -14,7 +14,7 @@ #include #include #include -#include // in case ptrdiff_t not in std +#include #include @@ -100,22 +100,22 @@ public: #if !defined( BOOST_NO_CXX11_NULLPTR ) -template inline bool operator==( scoped_array const & p, std::nullptr_t ) BOOST_NOEXCEPT +template inline bool operator==( scoped_array const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT { return p.get() == 0; } -template inline bool operator==( std::nullptr_t, scoped_array const & p ) BOOST_NOEXCEPT +template inline bool operator==( boost::detail::sp_nullptr_t, scoped_array const & p ) BOOST_NOEXCEPT { return p.get() == 0; } -template inline bool operator!=( scoped_array const & p, std::nullptr_t ) BOOST_NOEXCEPT +template inline bool operator!=( scoped_array const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT { return p.get() != 0; } -template inline bool operator!=( std::nullptr_t, scoped_array const & p ) BOOST_NOEXCEPT +template inline bool operator!=( boost::detail::sp_nullptr_t, scoped_array const & p ) BOOST_NOEXCEPT { return p.get() != 0; } diff --git a/include/boost/smart_ptr/scoped_ptr.hpp b/include/boost/smart_ptr/scoped_ptr.hpp index a75f91f..be6722d 100644 --- a/include/boost/smart_ptr/scoped_ptr.hpp +++ b/include/boost/smart_ptr/scoped_ptr.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #ifndef BOOST_NO_AUTO_PTR @@ -117,22 +118,22 @@ public: #if !defined( BOOST_NO_CXX11_NULLPTR ) -template inline bool operator==( scoped_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +template inline bool operator==( scoped_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT { return p.get() == 0; } -template inline bool operator==( std::nullptr_t, scoped_ptr const & p ) BOOST_NOEXCEPT +template inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr const & p ) BOOST_NOEXCEPT { return p.get() == 0; } -template inline bool operator!=( scoped_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +template inline bool operator!=( scoped_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT { return p.get() != 0; } -template inline bool operator!=( std::nullptr_t, scoped_ptr const & p ) BOOST_NOEXCEPT +template inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr const & p ) BOOST_NOEXCEPT { return p.get() != 0; } diff --git a/include/boost/smart_ptr/shared_array.hpp b/include/boost/smart_ptr/shared_array.hpp index 38047ff..73a07ae 100644 --- a/include/boost/smart_ptr/shared_array.hpp +++ b/include/boost/smart_ptr/shared_array.hpp @@ -27,6 +27,7 @@ #include #include +#include #include #include // for std::ptrdiff_t @@ -245,22 +246,22 @@ template inline bool operator!=(shared_array const & a, shared_array #if !defined( BOOST_NO_CXX11_NULLPTR ) -template inline bool operator==( shared_array const & p, std::nullptr_t ) BOOST_NOEXCEPT +template inline bool operator==( shared_array const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT { return p.get() == 0; } -template inline bool operator==( std::nullptr_t, shared_array const & p ) BOOST_NOEXCEPT +template inline bool operator==( boost::detail::sp_nullptr_t, shared_array const & p ) BOOST_NOEXCEPT { return p.get() == 0; } -template inline bool operator!=( shared_array const & p, std::nullptr_t ) BOOST_NOEXCEPT +template inline bool operator!=( shared_array const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT { return p.get() != 0; } -template inline bool operator!=( std::nullptr_t, shared_array const & p ) BOOST_NOEXCEPT +template inline bool operator!=( boost::detail::sp_nullptr_t, shared_array const & p ) BOOST_NOEXCEPT { return p.get() != 0; } diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index b34b0ac..d2781c1 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #if !defined(BOOST_SP_NO_ATOMIC_ACCESS) #include @@ -41,7 +42,7 @@ #include // for std::swap #include // for std::less #include // for std::bad_cast -#include // for std::size_t, std::nullptr_t +#include // for std::size_t #if !defined(BOOST_NO_IOSTREAM) #if !defined(BOOST_NO_IOSFWD) @@ -341,7 +342,7 @@ public: #if !defined( BOOST_NO_CXX11_NULLPTR ) - shared_ptr( std::nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws + shared_ptr( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws { } @@ -366,7 +367,7 @@ public: #if !defined( BOOST_NO_CXX11_NULLPTR ) - template shared_ptr( std::nullptr_t p, D d ): px( p ), pn( p, d ) + template shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d ) { } @@ -381,7 +382,7 @@ public: #if !defined( BOOST_NO_CXX11_NULLPTR ) - template shared_ptr( std::nullptr_t p, D d, A a ): px( p ), pn( p, d, a ) + template shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a ) { } @@ -605,7 +606,7 @@ public: #if !defined( BOOST_NO_CXX11_NULLPTR ) - shared_ptr & operator=( std::nullptr_t ) BOOST_NOEXCEPT // never throws + shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT // never throws { this_type().swap(*this); return *this; @@ -752,22 +753,22 @@ template inline bool operator!=(shared_ptr const & a, shared_ptr #if !defined( BOOST_NO_CXX11_NULLPTR ) -template inline bool operator==( shared_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +template inline bool operator==( shared_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT { return p.get() == 0; } -template inline bool operator==( std::nullptr_t, shared_ptr const & p ) BOOST_NOEXCEPT +template inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr const & p ) BOOST_NOEXCEPT { return p.get() == 0; } -template inline bool operator!=( shared_ptr const & p, std::nullptr_t ) BOOST_NOEXCEPT +template inline bool operator!=( shared_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT { return p.get() != 0; } -template inline bool operator!=( std::nullptr_t, shared_ptr const & p ) BOOST_NOEXCEPT +template inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr const & p ) BOOST_NOEXCEPT { return p.get() != 0; } From 32a28ec462f806954b803baba3f8ebe5db903dcb Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 8 Jan 2013 21:39:54 +0000 Subject: [PATCH 181/210] Support BOOST_NO_EXCEPTIONS in detail/array_utility.hpp to allow use when exceptions are disabled [SVN r82408] --- .../boost/smart_ptr/detail/array_utility.hpp | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp index 35694f0..3cf36d7 100644 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -37,6 +37,7 @@ namespace boost { } template inline void array_init(T* memory, std::size_t size, boost::false_type) { +#if !defined(BOOST_NO_EXCEPTIONS) std::size_t i = 0; try { for (; i < size; i++) { @@ -47,6 +48,12 @@ namespace boost { array_destroy(memory, i); throw; } +#else + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(); + } +#endif } template inline void array_init(T* memory, std::size_t size) { @@ -56,6 +63,7 @@ namespace boost { #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template inline void array_init_value(T* memory, std::size_t size, T&& value) { +#if !defined(BOOST_NO_EXCEPTIONS) std::size_t i = 0; try { for (; i < size; i++) { @@ -66,10 +74,17 @@ namespace boost { array_destroy(memory, i); throw; } +#else + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(value); + } +#endif } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template inline void array_init_args(T* memory, std::size_t size, Args&&... args) { +#if !defined(BOOST_NO_EXCEPTIONS) std::size_t i = 0; try { for (; i < size; i++) { @@ -80,11 +95,18 @@ namespace boost { array_destroy(memory, i); throw; } +#else + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(args...); + } +#endif } #endif #endif template inline void array_init_list(T* memory, std::size_t size, const T* list) { +#if !defined(BOOST_NO_EXCEPTIONS) std::size_t i = 0; try { for (; i < size; i++) { @@ -95,9 +117,16 @@ namespace boost { array_destroy(memory, i); throw; } +#else + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(list[i]); + } +#endif } template inline void array_init_list(T* memory, std::size_t size, const T* list) { +#if !defined(BOOST_NO_EXCEPTIONS) std::size_t i = 0; try { for (; i < size; i++) { @@ -108,12 +137,19 @@ namespace boost { array_destroy(memory, i); throw; } +#else + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(list[i % N]); + } +#endif } template inline void array_noinit(T*, std::size_t, boost::true_type) { } template inline void array_noinit(T* memory, std::size_t size, boost::false_type) { +#if !defined(BOOST_NO_EXCEPTIONS) std::size_t i = 0; try { for (; i < size; i++) { @@ -124,6 +160,12 @@ namespace boost { array_destroy(memory, i); throw; } +#else + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T; + } +#endif } template inline void array_noinit(T* memory, std::size_t size) { From 06c4dacaf2254dac26c67e2e69546053308457d4 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 20 Jan 2013 00:09:27 +0000 Subject: [PATCH 182/210] Correct link in documentation [SVN r82552] --- make_shared_array.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make_shared_array.html b/make_shared_array.html index fb75790..326bb10 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -18,7 +18,7 @@ allocate_shared were for efficient allocation of single objects only. There was a need to have efficient, single, allocation of arrays. One criticism of shared_array was - always the lack of a make_shared utility + always the lack of a make_shared utility which ensures only a single allocation for an array.

    The header files <boost/smart_ptr/make_shared_array.hpp> and <boost/smart_ptr/allocate_shared_array.hpp> provide new function From e5950adc434e84143c813c62d7ec9b9f6b462d04 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 16 Feb 2013 17:18:17 +0000 Subject: [PATCH 183/210] Check for BOOST_NO_CXX11_RVALUE_REFERENCES in addition to BOOST_NO_CXX11_SMART_PTR. Refs #8055. [SVN r82927] --- include/boost/smart_ptr/shared_ptr.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index d2781c1..9259ca0 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -485,7 +485,7 @@ public: #endif // BOOST_NO_AUTO_PTR -#if !defined( BOOST_NO_CXX11_SMART_PTR ) +#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template< class Y, class D > shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn() @@ -550,7 +550,7 @@ public: #endif // BOOST_NO_AUTO_PTR -#if !defined( BOOST_NO_CXX11_SMART_PTR ) +#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template shared_ptr & operator=( std::unique_ptr && r ) From 46d119c38560ae0a04e02b78cb9a3ae6e079afa2 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 18 Feb 2013 09:33:18 +0000 Subject: [PATCH 184/210] Identifier renaming in allocate_array_helper, array_deleter, make_array_helper function parameters to satisfy higher warning levels. [SVN r82971] --- .../smart_ptr/detail/allocate_array_helper.hpp | 14 +++++++------- include/boost/smart_ptr/detail/array_deleter.hpp | 4 ++-- .../boost/smart_ptr/detail/make_array_helper.hpp | 14 +++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/boost/smart_ptr/detail/allocate_array_helper.hpp b/include/boost/smart_ptr/detail/allocate_array_helper.hpp index f7c64fe..2eeea2d 100644 --- a/include/boost/smart_ptr/detail/allocate_array_helper.hpp +++ b/include/boost/smart_ptr/detail/allocate_array_helper.hpp @@ -33,10 +33,10 @@ namespace boost { 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 A& allocator_, std::size_t size_, T** data_) + : allocator(allocator_), + size(sizeof(T) * size_), + data(data_) { } template allocate_array_helper(const allocate_array_helper& other) @@ -107,9 +107,9 @@ namespace boost { struct rebind { typedef allocate_array_helper other; }; - allocate_array_helper(const A& allocator, T** data) - : allocator(allocator), - data(data) { + allocate_array_helper(const A& allocator_, T** data_) + : allocator(allocator_), + data(data_) { } template allocate_array_helper(const allocate_array_helper& other) diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 11f23fa..20f84d1 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -19,8 +19,8 @@ namespace boost { template class array_deleter { public: - array_deleter(std::size_t size) - : size(size), + array_deleter(std::size_t size_) + : size(size_), object(0) { } ~array_deleter() { diff --git a/include/boost/smart_ptr/detail/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp index 38c9dc9..6cf0483 100644 --- a/include/boost/smart_ptr/detail/make_array_helper.hpp +++ b/include/boost/smart_ptr/detail/make_array_helper.hpp @@ -31,9 +31,9 @@ namespace boost { 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(std::size_t size_, T** data_) + : size(sizeof(T) * size_), + data(data_) { } template make_array_helper(const make_array_helper& other) @@ -72,7 +72,7 @@ namespace boost { memory->~Y(); } template - bool operator==(const make_array_helper& other) const { + bool operator==(const make_array_helper&) const { return true; } template @@ -99,8 +99,8 @@ namespace boost { struct rebind { typedef make_array_helper other; }; - make_array_helper(T** data) - : data(data) { + make_array_helper(T** data_) + : data(data_) { } template make_array_helper(const make_array_helper& other) @@ -138,7 +138,7 @@ namespace boost { memory->~Y(); } template - bool operator==(const make_array_helper& other) const { + bool operator==(const make_array_helper&) const { return true; } template From 82e178f04396db11410754a9f977d089e1c530a4 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 28 Feb 2013 08:02:09 +0000 Subject: [PATCH 185/210] Avoid stack overflow in make_shared. Refs #4256. [SVN r83198] --- include/boost/smart_ptr/detail/shared_count.hpp | 8 ++++---- include/boost/smart_ptr/make_shared_object.hpp | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index f055fd0..8e1dd48 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -200,7 +200,7 @@ public: } catch( ... ) { - D()( p ); // delete p + D::operator_fn( p ); // delete p throw; } @@ -210,7 +210,7 @@ public: if( pi_ == 0 ) { - D()( p ); // delete p + D::operator_fn( p ); // delete p boost::throw_exception( std::bad_alloc() ); } @@ -286,7 +286,7 @@ public: } catch(...) { - D()( p ); + D::operator_fn( p ); if( pi_ != 0 ) { @@ -306,7 +306,7 @@ public: } else { - D()( p ); + D::operator_fn( p ); boost::throw_exception( std::bad_alloc() ); } diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp index 89a7116..52a00ce 100644 --- a/include/boost/smart_ptr/make_shared_object.hpp +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -87,6 +87,10 @@ public: destroy(); } + static void operator_fn( T* ) // operator() can't be static + { + } + void * address() BOOST_NOEXCEPT { return storage_.data_; From 2d56e85174975622d66b1950245b135f8dec5d52 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 10 Apr 2013 05:00:52 +0000 Subject: [PATCH 186/210] Small improvements to make_shared documentation. [SVN r83827] --- make_shared_array.html | 186 ++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 93 deletions(-) diff --git a/make_shared_array.html b/make_shared_array.html index 326bb10..2b9b5bd 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -29,85 +29,85 @@ allowing finer control.

    Synopsis

    namespace boost {
    -    template<typename T>
    -    shared_ptr<T[]> make_shared(size_t size);
    +    template<typename U> // U = T[]
    +    shared_ptr<U> make_shared(size_t size);
     
    -    template<typename T, typename A>
    -    shared_ptr<T[]> allocate_shared(const A& allocator, size_t size);
    -    
    -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    -    template<typename T, typename... Args>
    -    shared_ptr<T[]> make_shared(size_t size, Args&&... args);
    +    template<typename U, typename A> // U = T[]
    +    shared_ptr<U> allocate_shared(const A& allocator, size_t size);
     
    -    template<typename T, typename... Args>
    -    shared_ptr<T[N]> make_shared(Args&&... args);
    +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)   
    +    template<typename U, typename... Args> // U = T[]
    +    shared_ptr<U> 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);
    +    template<typename U, typename... Args> // U = T[N]
    +    shared_ptr<U> make_shared(Args&&... args);
     
    -    template<typename T, typename A, typename... Args>
    -    shared_ptr<T[N]> allocate_shared(const A& allocator, Args&&... args);
    +    template<typename U, typename A, typename... Args> // U = T[]
    +    shared_ptr<U> allocate_shared(const A& allocator, size_t size, Args&&... args);
    +
    +    template<typename U, typename A, typename... Args> // U = T[N]
    +    shared_ptr<U> allocate_shared(const A& allocator, Args&&... args);
     #endif
    -        
    -#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
    -    template<typename T, typename... Args>
    -    shared_ptr<T[N]> make_shared(const T (&list)[N]);
     
    -    template<typename T, typename... Args>
    -    shared_ptr<T[][N]> make_shared(size_t size, const T (&list)[N]);
    +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)    
    +    template<typename U, typename... Args> // U = T[N]
    +    shared_ptr<U> make_shared(const T (&list)[N]);
     
    -    template<typename T, typename... Args>
    -    shared_ptr<T[M][N]> make_shared(const T (&list)[N]);
    +    template<typename U, typename... Args> // U = T[][N]
    +    shared_ptr<U> make_shared(size_t size, const T (&list)[N]);
     
    -    template<typename T, typename A, typename... Args>
    -    shared_ptr<T[N]> allocate_shared(const A& allocator, const T (&list)[N]);
    +    template<typename U, typename... Args> // U = T[M][N]
    +    shared_ptr<U> make_shared(const T (&list)[N]);
     
    -    template<typename T, typename A, typename... Args>
    -    shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);
    +    template<typename U, typename A, typename... Args> // U = T[N]
    +    shared_ptr<T[> allocate_shared(const A& allocator, const T (&list)[N]);
     
    -    template<typename T, typename A, typename... Args>
    -    shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]);
    +    template<typename U, typename A, typename... Args> // U = T[][N]
    +    shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);
    +
    +    template<typename U, typename A, typename... Args> // U = T[M][N]
    +    shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);
     
     #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
    -    template<typename T, typename... Args>
    -    shared_ptr<T[]> make_shared(initializer_list<T> list);
    +    template<typename U, typename... Args> // U = T[]
    +    shared_ptr<U> make_shared(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 U, typename A, typename... Args> // U = T[]
    +    shared_ptr<U> allocate_shared(const A& allocator, initializer_list<T> list);
     #endif
     
    -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    -    template<typename T>
    -    shared_ptr<T[]> make_shared(size_t size, T&& value);
    +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)    
    +    template<typename U> // U = T[]
    +    shared_ptr<U> make_shared(size_t size, T&& value);
     
    -    template<typename T>
    -    shared_ptr<T[N]> make_shared(T&& value);
    +    template<typename U> // U = T[N]
    +    shared_ptr<U> make_shared(T&& value);
     
    -    template<typename T, typename A>
    -    shared_ptr<T[]> allocate_shared(const A& allocator, size_t size, T&& value);
    +    template<typename U, typename A> // U = T[]
    +    shared_ptr<U> allocate_shared(const A& allocator, size_t size, T&& value);
     
    -    template<typename T, typename A>
    -    shared_ptr<T[N]> allocate_shared(const A& allocator, T&& value);    
    +    template<typename U, typename A> // U = T[N]
    +    shared_ptr<U> allocate_shared(const A& allocator, T&& value);
     #endif
     #endif
     
    -    template<typename T>
    -    shared_ptr<T[]> make_shared_noinit(size_t size);
    +    template<typename U> // U = T[]
    +    shared_ptr<U> make_shared_noinit(size_t size);
     
    -    template<typename T>
    -    shared_ptr<T[N]> make_shared_noinit();
    -    
    -    template<typename T, typename A>
    -    shared_ptr<T[]> allocate_shared_noinit(const A& allocator, size_t size);
    +    template<typename U> // U = T[N]
    +    shared_ptr<U> make_shared_noinit();
     
    -    template<typename T, typename A>
    -    shared_ptr<T[N]> allocate_shared_noinit(const A& allocator);
    +    template<typename U, typename A> // U = T[]
    +    shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);
    +
    +    template<typename U, typename A> // U = T[N]
    +    shared_ptr<U> allocate_shared_noinit(const A& allocator);
     }

    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);
    +
    template<typename U, typename... Args>
    +    shared_ptr<U> make_shared(size_t size, Args&&... args);
    +template<typename U, typename A, typename... Args>
    +    shared_ptr<U> allocate_shared(const A& allocator, size_t size, Args&&... args);

    Requires: The expression new(pointer) T(forward<Args>(args)...), where @@ -121,7 +121,7 @@ template<typename T, typename A, typename... Args> 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)...). + new(pointer) T(args...). allocate_shared uses a copy of allocator to allocate memory. If an exception is thrown, has no effect.

    @@ -146,74 +146,74 @@ template<typename T, typename A, typename... Args> take any constructor arguments. These overloads invoke the default constructor of T for each array element.

    -
    template<typename T, typename... Args>
    -    shared_ptr<T[N]> make_shared(Args&&... args);
    -template<typename T, typename A, typename... Args>
    -    shared_ptr<T[N]> allocate_shared(const A& allocator, Args&&... args);
    +
    template<typename U, typename... Args>
    +    shared_ptr<U> make_shared(Args&&... args);
    +template<typename U, typename A, typename... Args>
    +    shared_ptr<U> allocate_shared(const A& allocator, Args&&... args);

    Description: These overloads of the utilities above are for a fixed size array.

    -
    template<typename T, typename... Args>
    -    shared_ptr<T[]> make_shared(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 U, typename... Args>
    +    shared_ptr<U> make_shared(initializer_list<T> list);
    +template<typename U, typename A, typename... Args>
    +    shared_ptr<U> allocate_shared(const A& allocator, initializer_list<T> list);

    Description: These overloads initialize the array elements from the initializer list.

    -
    template<typename T, typename... Args>
    -    shared_ptr<T[N]> make_shared(const T (&list)[N]);
    -template<typename T, typename A, typename... Args>
    -    shared_ptr<T[N]> allocate_shared(const A& allocator, const T (&list)[N]);
    +
    template<typename U, typename... Args>
    +    shared_ptr<U> make_shared(const T (&list)[N]);
    +template<typename U, typename A, typename... Args>
    +    shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);

    Description: These overloads of the utilities above are for a fixed size array.

    -
    template<typename T, typename... Args>
    -    shared_ptr<T[][N]> make_shared(size_t size, const T (&list)[N]);
    -template<typename T, typename A, typename... Args>
    -    shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);
    +
    template<typename U, typename... Args>
    +    shared_ptr<U> make_shared(size_t size, const T (&list)[N]);
    +template<typename U, typename A, typename... Args>
    +    shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);

    Description: These overloads initialize inner array elements from the initializer list.

    -
    template<typename T, typename... Args>
    -    shared_ptr<T[M][N]> make_shared(const T (&list)[N]);
    -template<typename T, typename A, typename... Args>
    -    shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]);
    +
    template<typename U, typename... Args> // U = T[M][N]
    +    shared_ptr<U> make_shared(const T (&list)[N]);
    +template<typename U, typename A, typename... Args> // U = T[M][N]
    +    shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);

    Description: These overloads of the utilities above are for a fixed size array.

    -
    -
    template<typename T>
    -    shared_ptr<T[]> make_shared(size_t size, T&& value);
    -template<typename T, typename A>
    -    shared_ptr<T[]> allocate_shared(const A& allocator, size_t size, T&& value);
    +
    +
    template<typename U>
    +    shared_ptr<U> make_shared(size_t size, T&& value);
    +template<typename U, typename A>
    +    shared_ptr<U> allocate_shared(const A& allocator, size_t size, T&& value);

    Description: These overloads initialize array elements with the given value.

    -
    template<typename T>
    -    shared_ptr<T[N]> make_shared(T&& value);
    -template<typename T, typename A>
    -    shared_ptr<T[N]> allocate_shared(const A& allocator, T&& value);
    +
    template<typename U>
    +    shared_ptr<U> make_shared(T&& value);
    +template<typename U, typename A>
    +    shared_ptr<U> allocate_shared(const A& allocator, T&& value);

    Description: These overloads of the utilities above are for a fixed size array.

    -
    template<typename T>
    -    shared_ptr<T[]> make_shared_noinit(size_t size);
    -template<typename T, typename A>
    -    shared_ptr<T[]> allocate_shared_noinit(const A& allocator, size_t size);
    +
    template<typename U>
    +    shared_ptr<U> make_shared_noinit(size_t size);
    +template<typename U, typename A>
    +    shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);

    Description: These overloads do not perform any value initialization of elements.

    -
    template<typename T>
    -    shared_ptr<T[N]> make_shared_noinit();
    -template<typename T, typename A>
    -    shared_ptr<T[N]> allocate_shared_noinit(const A& allocator);
    +
    template<typename U>
    +    shared_ptr<U> make_shared_noinit();
    +template<typename U, typename A>
    +    shared_ptr<U> allocate_shared_noinit(const A& allocator);

    Description: These overloads of the utilities above are for a fixed size array.

    @@ -221,7 +221,7 @@ template<typename T, typename A>

    Example

    An example of each overload of make_shared for arrays:

    -
    boost::shared_ptr<point[]> a1 = boost::make_shared<point[]>(size);
    +    
    boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size);
     boost::shared_ptr<point[]> a2 = boost::make_shared<point[]>(size, x, y);
     boost::shared_ptr<point[5]> a3 = boost::make_shared<point[5]>(x, y);
     boost::shared_ptr<int[]> a4 = boost::make_shared<int[]>({1, 2, 3});
    
    From 6df3a0295ee583c0ca008e2bf0214aeedd1193a1 Mon Sep 17 00:00:00 2001
    From: Glen Fernandes 
    Date: Wed, 10 Apr 2013 05:16:09 +0000
    Subject: [PATCH 187/210] More small cosmetic documentation changes.
    
    [SVN r83829]
    ---
     make_shared_array.html | 86 +++++++++++++++++++++++-------------------
     1 file changed, 48 insertions(+), 38 deletions(-)
    
    diff --git a/make_shared_array.html b/make_shared_array.html
    index 2b9b5bd..3437e9e 100644
    --- a/make_shared_array.html
    +++ b/make_shared_array.html
    @@ -104,10 +104,11 @@
         shared_ptr<U> allocate_shared_noinit(const A& allocator);
     }

    Free Functions

    -
    template<typename U, typename... Args>
    -    shared_ptr<U> make_shared(size_t size, Args&&... args);
    -template<typename U, typename A, typename... Args>
    -    shared_ptr<U> allocate_shared(const A& allocator, size_t size, Args&&... args);
    +
    template<typename U, typename... Args> // U = T[]
    +shared_ptr<U> make_shared(size_t size, Args&&... args);
    +
    +template<typename U, typename A, typename... Args> // U = T[]
    +shared_ptr<U> allocate_shared(const A& allocator, size_t size, Args&&... args);

    Requires: The expression new(pointer) T(forward<Args>(args)...), where @@ -146,74 +147,83 @@ template<typename U, typename A, typename... Args> take any constructor arguments. These overloads invoke the default constructor of T for each array element.

    -
    template<typename U, typename... Args>
    -    shared_ptr<U> make_shared(Args&&... args);
    -template<typename U, typename A, typename... Args>
    -    shared_ptr<U> allocate_shared(const A& allocator, Args&&... args);
    +
    template<typename U, typename... Args> // U = T[N]
    +shared_ptr<U> make_shared(Args&&... args);
    +
    +template<typename U, typename A, typename... Args> // U = T[N]
    +shared_ptr<U> allocate_shared(const A& allocator, Args&&... args);

    Description: These overloads of the utilities above are for a fixed size array.

    -
    template<typename U, typename... Args>
    -    shared_ptr<U> make_shared(initializer_list<T> list);
    -template<typename U, typename A, typename... Args>
    -    shared_ptr<U> allocate_shared(const A& allocator, initializer_list<T> list);
    +
    template<typename U, typename... Args> // U = T[]
    +shared_ptr<U> make_shared(initializer_list<T> list);
    +
    +template<typename U, typename A, typename... Args> // U = T[]
    +shared_ptr<U> allocate_shared(const A& allocator, initializer_list<T> list);

    Description: These overloads initialize the array elements from the initializer list.

    -
    template<typename U, typename... Args>
    -    shared_ptr<U> make_shared(const T (&list)[N]);
    -template<typename U, typename A, typename... Args>
    -    shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);
    +
    template<typename U, typename... Args> // U = T[N]
    +shared_ptr<U> make_shared(const T (&list)[N]);
    +
    +template<typename U, typename A, typename... Args> // U = T[N]
    +shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);

    Description: These overloads of the utilities above are for a fixed size array.

    -
    template<typename U, typename... Args>
    -    shared_ptr<U> make_shared(size_t size, const T (&list)[N]);
    -template<typename U, typename A, typename... Args>
    -    shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);
    +
    template<typename U, typename... Args> // U = T[][N]
    +shared_ptr<U> make_shared(size_t size, const T (&list)[N]);
    +
    +template<typename U, typename A, typename... Args> // U = T[][N]
    +shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);

    Description: These overloads initialize inner array elements from the initializer list.

    template<typename U, typename... Args> // U = T[M][N]
    -    shared_ptr<U> make_shared(const T (&list)[N]);
    +shared_ptr<U> make_shared(const T (&list)[N]);
    +
     template<typename U, typename A, typename... Args> // U = T[M][N]
    -    shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);
    +shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);

    Description: These overloads of the utilities above are for a fixed size array.

    -
    template<typename U>
    -    shared_ptr<U> make_shared(size_t size, T&& value);
    -template<typename U, typename A>
    -    shared_ptr<U> allocate_shared(const A& allocator, size_t size, T&& value);
    +
    template<typename U> // U = T[]
    +shared_ptr<U> make_shared(size_t size, T&& value);
    +
    +template<typename U, typename A> // U = T[]
    +shared_ptr<U> allocate_shared(const A& allocator, size_t size, T&& value);

    Description: These overloads initialize array elements with the given value.

    -
    template<typename U>
    -    shared_ptr<U> make_shared(T&& value);
    -template<typename U, typename A>
    -    shared_ptr<U> allocate_shared(const A& allocator, T&& value);
    +
    template<typename U> // U = T[N]
    +shared_ptr<U> make_shared(T&& value);
    +
    +template<typename U, typename A> // U = T[N]
    +shared_ptr<U> allocate_shared(const A& allocator, T&& value);

    Description: These overloads of the utilities above are for a fixed size array.

    -
    template<typename U>
    -    shared_ptr<U> make_shared_noinit(size_t size);
    -template<typename U, typename A>
    -    shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);
    +
    template<typename U> // U = T[]
    +shared_ptr<U> make_shared_noinit(size_t size);
    +
    +template<typename U, typename A> // U = T[]
    +shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);

    Description: These overloads do not perform any value initialization of elements.

    -
    template<typename U>
    -    shared_ptr<U> make_shared_noinit();
    -template<typename U, typename A>
    -    shared_ptr<U> allocate_shared_noinit(const A& allocator);
    +
    template<typename U> // U = T[N]
    +shared_ptr<U> make_shared_noinit();
    +
    +template<typename U, typename A> // U = T[N]
    +shared_ptr<U> allocate_shared_noinit(const A& allocator);

    Description: These overloads of the utilities above are for a fixed size array.

    From d61e675caf0799268b8a7c1ad36b69e848c2e208 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 15 Apr 2013 15:11:29 +0000 Subject: [PATCH 188/210] Fix new double(n) to new double[n]. [SVN r83914] --- shared_ptr.htm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared_ptr.htm b/shared_ptr.htm index c534dd7..6c0e999 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -61,8 +61,8 @@ shared_ptr<void> p2( new int(5) ); the template parameter. There is almost no difference between using an unsized array, T[], and a sized array, T[N]; the latter just enables operator[] to perform a range check on the index.

    -
    Example:
    shared_ptr<double[1024]> p1( new double(1024) );
    -shared_ptr<double[]> p2( new double(n) );
    +		
    Example:
    shared_ptr<double[1024]> p1( new double[1024] );
    +shared_ptr<double[]> p2( new double[n] );
     

    Best Practices

    From 172afff6ca1757f6d5c81a05c149b1079f32817a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 26 May 2013 13:34:40 +0000 Subject: [PATCH 189/210] Document that constructors initialize enable_shared_from_this. Refs #8573. [SVN r84506] --- shared_ptr.htm | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/shared_ptr.htm b/shared_ptr.htm index 6c0e999..675fe26 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -262,8 +262,12 @@ shared_ptr(std::nullptr_t); // never throws
    the pointer p. Otherwise, constructs a shared_ptr that owns p and a deleter of an unspecified type that calls delete[] p.

    -

    Postconditions: use_count() == 1 && get() == p.

    -

    Throws: std::bad_alloc, or an implementation-defined +

    Postconditions: use_count() == 1 && get() == p. + If T is not an array type and p is unambiguously convertible to + enable_shared_from_this<V>* + for some V, p->shared_from_this() returns a copy of + *this.

    +

    Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

    Exception safety: If an exception is thrown, the constructor calls delete[] p, when T is an array type, @@ -296,7 +300,11 @@ template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a);

    Effects: Constructs a shared_ptr that owns the pointer p and the deleter d. The constructors taking an allocator a allocate memory using a copy of a.

    -

    Postconditions: use_count() == 1 && get() == p.

    +

    Postconditions: use_count() == 1 && get() == p. + If T is not an array type and p is unambiguously convertible to + enable_shared_from_this<V>* + for some V, p->shared_from_this() returns a copy of + *this.

    Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

    Exception safety: If an exception is thrown, d(p) is called.

    From a7d96b47629506a321fbe4c8dbc2d7eaa0a49fde Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 31 Aug 2013 19:54:11 +0000 Subject: [PATCH 190/210] Extracted intrusive_ref_counter from Boost.Log. The extracted version supports customizing the reference counter nature, two policies provided: thread_unsafe_counter and thread_safe_counter. [SVN r85535] --- .../boost/smart_ptr/intrusive_ref_counter.hpp | 176 ++++++++++++++++++ intrusive_ptr.html | 4 +- intrusive_ref_counter.html | 92 +++++++++ test/Jamfile.v2 | 1 + test/intrusive_ref_counter_test.cpp | 146 +++++++++++++++ 5 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 include/boost/smart_ptr/intrusive_ref_counter.hpp create mode 100644 intrusive_ref_counter.html create mode 100644 test/intrusive_ref_counter_test.cpp diff --git a/include/boost/smart_ptr/intrusive_ref_counter.hpp b/include/boost/smart_ptr/intrusive_ref_counter.hpp new file mode 100644 index 0000000..53aeee9 --- /dev/null +++ b/include/boost/smart_ptr/intrusive_ref_counter.hpp @@ -0,0 +1,176 @@ +/* + * Copyright Andrey Semashev 2007 - 2013. + * 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) + */ +/*! + * \file intrusive_ref_counter.hpp + * \author Andrey Semashev + * \date 12.03.2009 + * + * This header contains a reference counter class for \c intrusive_ptr. + */ + +#ifndef BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_ +#define BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { + +namespace sp_adl_block { + +/*! + * \brief Thread unsafe reference counter policy for \c basic_intrusive_ref_counter + * + * The policy instructs the \c basic_intrusive_ref_counter base class to implement + * a reference counter suitable for single threaded use only. Pointers to the same + * object with this kind of reference counter must not be used by different threads. + */ +struct thread_unsafe_counter +{ + typedef unsigned int type; + + static unsigned int load(unsigned int const& counter) BOOST_NOEXCEPT + { + return counter; + } + + static void increment(unsigned int& counter) BOOST_NOEXCEPT + { + ++counter; + } + + static unsigned int decrement(unsigned int& counter) BOOST_NOEXCEPT + { + return --counter; + } +}; + +/*! + * \brief Thread safe reference counter policy for \c basic_intrusive_ref_counter + * + * The policy instructs the \c basic_intrusive_ref_counter base class to implement + * a thread-safe reference counter, if the target platform supports multithreading. + */ +struct thread_safe_counter +{ + typedef boost::detail::atomic_count type; + + static unsigned int load(boost::detail::atomic_count const& counter) BOOST_NOEXCEPT + { + return static_cast< unsigned int >(static_cast< long >(counter)); + } + + static void increment(boost::detail::atomic_count& counter) BOOST_NOEXCEPT + { + ++counter; + } + + static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_NOEXCEPT + { + return --counter; + } +}; + +template< typename CounterPolicyT > +class basic_intrusive_ref_counter; + +template< typename CounterPolicyT > +void intrusive_ptr_add_ref(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT; +template< typename CounterPolicyT > +void intrusive_ptr_release(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT; + +/*! + * \brief A reference counter base class + * + * This base class can be used with user-defined classes to add support + * for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT + * and a virtual destructor, which makes the derived class polymorphic. + * Upon releasing the last \c intrusive_ptr referencing the object + * derived from the \c basic_intrusive_ref_counter class, operator \c delete + * is automatically called on the pointer to the object. + */ +template< typename CounterPolicyT > +class basic_intrusive_ref_counter +{ +private: + //! Reference counter type + typedef typename CounterPolicyT::type counter_type; + //! Reference counter + mutable counter_type m_ref_counter; + +public: + /*! + * Default constructor + * + * \post use_count() == 0 + */ + basic_intrusive_ref_counter() : m_ref_counter(0) + { + } + + /*! + * Copy constructor + * + * \post use_count() == 0 + */ + basic_intrusive_ref_counter(basic_intrusive_ref_counter const&) : m_ref_counter(0) + { + } + + /*! + * Virtual destructor + */ + virtual ~basic_intrusive_ref_counter() {} + + /*! + * Assignment + * + * \post The reference counter is not modified after assignment + */ + basic_intrusive_ref_counter& operator= (basic_intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; } + + /*! + * \return The reference counter + */ + unsigned int use_count() const BOOST_NOEXCEPT + { + return CounterPolicyT::load(m_ref_counter); + } + + friend void intrusive_ptr_add_ref< CounterPolicyT >(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT; + friend void intrusive_ptr_release< CounterPolicyT >(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT; +}; + +template< typename CounterPolicyT > +inline void intrusive_ptr_add_ref(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT +{ + CounterPolicyT::increment(p->m_ref_counter); +} + +template< typename CounterPolicyT > +inline void intrusive_ptr_release(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT +{ + if (CounterPolicyT::decrement(p->m_ref_counter) == 0) + delete p; +} + +} // namespace sp_adl_block + +using sp_adl_block::basic_intrusive_ref_counter; +using sp_adl_block::thread_unsafe_counter; +using sp_adl_block::thread_safe_counter; + +//! Convenience typedef for the default reference counter type +typedef basic_intrusive_ref_counter< thread_safe_counter > intrusive_ref_counter; + +} // namespace boost + +#endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_ diff --git a/intrusive_ptr.html b/intrusive_ptr.html index 16097dd..c37a5b2 100644 --- a/intrusive_ptr.html +++ b/intrusive_ptr.html @@ -24,7 +24,9 @@ compilers that support argument-dependent lookup, intrusive_ptr_add_ref and intrusive_ptr_release should be defined in the namespace that corresponds to their parameter; otherwise, the definitions need to go in - namespace boost.

    + namespace boost. The library provides a helper base class template + basic_intrusive_ref_counter which may + help adding support for intrusive_ptr to user's types.

    The class template is parameterized on T, the type of the object pointed to. intrusive_ptr<T> can be implicitly converted to intrusive_ptr<U> whenever T* can be implicitly converted to U*.

    diff --git a/intrusive_ref_counter.html b/intrusive_ref_counter.html new file mode 100644 index 0000000..30be3af --- /dev/null +++ b/intrusive_ref_counter.html @@ -0,0 +1,92 @@ + + + + basic_intrusive_ref_counter + + + +

    boost.png (6897 bytes)basic_intrusive_ref_counter class template

    +

    + Introduction
    + Synopsis
    + Members
    +

    +

    Introduction

    +

    The basic_intrusive_ref_counter class template implements a reference counter for a defived + user's class that is intended to be used with intrusive_ptr. + The base class has associated intrusive_ptr_add_ref and intrusive_ptr_release functions + which modify the reference counter as needed and destroy the user's object when the counter drops to zero.

    +

    The class template is parameterized on CounterPolicyT, which is a policy that defines the nature of the reference counter. + Boost.SmartPtr provides two such policies: thread_unsafe_counter and thread_safe_counter. The former + instructs the basic_intrusive_ref_counter base class to use a counter only suitable for a single-threaded use. + Pointers to a single object that uses this kind of reference counter must not be used in different threads. The latter policy + makes the reference counter thread-safe, unless the target platform doesn't support threading. Since in modern systems support for + threading is common, a shorthand intrusive_ref_counter is provided, which is an alias for + basic_intrusive_ref_counter<thread_safe_counter>.

    +

    Synopsis

    +
    namespace boost {
    +
    +  template<class CounterPolicyT> class basic_intrusive_ref_counter {
    +
    +    public:
    +
    +      basic_intrusive_ref_counter();
    +      basic_intrusive_ref_counter(basic_intrusive_ref_counter const & r);
    +
    +      virtual ~basic_intrusive_ref_counter();
    +
    +      basic_intrusive_ref_counter & operator=(basic_intrusive_ref_counter const & r) noexcept;
    +
    +      unsigned int use_count() const noexcept;
    +  };
    +
    +  struct thread_unsafe_counter;
    +  struct thread_safe_counter;
    +
    +  typedef basic_intrusive_ref_counter<thread_safe_counter> intrusive_ref_counter;
    +
    +}
    +

    Members

    +

    constructors

    +
    basic_intrusive_ref_counter();
    +
    +

    Postconditions: use_count() == 0.

    +

    Throws: nothing.

    +

    Notes: The pointer to the constructed object is expected to be passed to intrusive_ptr + constructor, assignment operator or reset() method, which would increment the reference counter.

    +
    +
    basic_intrusive_ref_counter(basic_intrusive_ref_counter const &);
    +
    +

    Postconditions: use_count() == 0.

    +

    Throws: nothing.

    +

    Notes: The pointer to the constructed object is expected to be passed to intrusive_ptr + constructor, assignment operator or reset() method, which would increment the reference counter.

    +
    +

    destructor

    +
    virtual ~basic_intrusive_ref_counter();
    +
    +

    Effects: Destroys the counter object.

    +
    +

    assignment

    +
    basic_intrusive_ref_counter & operator=(basic_intrusive_ref_counter const & r) noexcept;
    +
    +

    Effects: Does nothing, reference counter is not modified.

    +

    Returns: *this.

    +
    +

    use_count

    +
    unsigned int use_count() const noexcept;
    +
    +

    Returns: The current value of the reference counter.

    +

    Throws: nothing.

    +

    Notes: The returned value may not be actual in multi-threaded applications.

    +
    +
    +

    + $Date: 2013-08-31 23:37:43 +0400 (Sat, 31 Aug 2013) $

    +

    + Copyright © 2013 Andrey Semashev. 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 d4f7af1..874968a 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -21,6 +21,7 @@ import testing ; [ run get_deleter_test.cpp ] [ run intrusive_ptr_test.cpp ] [ run intrusive_ptr_move_test.cpp ] + [ run intrusive_ref_counter_test.cpp ] [ run atomic_count_test.cpp ] [ run lw_mutex_test.cpp ] [ compile-fail shared_ptr_assign_fail.cpp ] diff --git a/test/intrusive_ref_counter_test.cpp b/test/intrusive_ref_counter_test.cpp new file mode 100644 index 0000000..4f2ab88 --- /dev/null +++ b/test/intrusive_ref_counter_test.cpp @@ -0,0 +1,146 @@ +/* + * Copyright Andrey Semashev 2013. + * 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) + */ +/*! + * \file intrusive_ref_counter_test.cpp + * \author Andrey Semashev + * \date 31.08.2013 + * + * This file contains tests for the \c intrusive_ref_counter base class. + */ + +#include + +#if defined(BOOST_MSVC) + +#pragma warning(disable: 4786) // identifier truncated in debug info +#pragma warning(disable: 4710) // function not inlined +#pragma warning(disable: 4711) // function selected for automatic inline expansion +#pragma warning(disable: 4514) // unreferenced inline removed +#pragma warning(disable: 4355) // 'this' : used in base member initializer list +#pragma warning(disable: 4511) // copy constructor could not be generated +#pragma warning(disable: 4512) // assignment operator could not be generated + +#if (BOOST_MSVC >= 1310) +#pragma warning(disable: 4675) // resolved overload found with Koenig lookup +#endif + +#endif + +#include +#include +#include +#include + +namespace N1 { + +class my_class : + public boost::intrusive_ref_counter +{ +public: + static unsigned int destructor_count; + + ~my_class() + { + ++destructor_count; + } +}; + +unsigned int my_class::destructor_count = 0; + +} // namespace N1 + +namespace N2 { + +class my_class : + public boost::basic_intrusive_ref_counter< boost::thread_unsafe_counter > +{ +public: + static unsigned int destructor_count; + + ~my_class() + { + ++destructor_count; + } +}; + +unsigned int my_class::destructor_count = 0; + +} // namespace N2 + +namespace N3 { + +struct X : + public virtual boost::intrusive_ref_counter +{ +}; + +} // namespace N3 + +namespace N4 { + +struct Y : + public virtual boost::intrusive_ref_counter +{ +}; + +} // namespace N4 + +namespace N5 { + +struct Z : + public N3::X, + public N4::Y +{ + static unsigned int destructor_count; + + ~Z() + { + ++destructor_count; + } +}; + +unsigned int Z::destructor_count = 0; + +} // namespace N5 + + +int main() +{ + // The test check that ADL works + { + boost::intrusive_ptr< N1::my_class > p = new N1::my_class(); + p = NULL; + BOOST_TEST(N1::my_class::destructor_count == 1); + } + { + boost::intrusive_ptr< N2::my_class > p = new N2::my_class(); + p = NULL; + BOOST_TEST(N2::my_class::destructor_count == 1); + } + { + N1::my_class* p = new N1::my_class(); + intrusive_ptr_add_ref(p); + intrusive_ptr_release(p); + BOOST_TEST(N1::my_class::destructor_count == 2); + } + + // The test checks that destroying through the base class works + { + boost::intrusive_ptr< N5::Z > p1 = new N5::Z(); + BOOST_TEST(p1->use_count() == 1); + BOOST_TEST(N5::Z::destructor_count == 0); + boost::intrusive_ptr< boost::intrusive_ref_counter > p2 = p1; + BOOST_TEST(p1->use_count() == 2); + BOOST_TEST(N5::Z::destructor_count == 0); + p1 = NULL; + BOOST_TEST(N5::Z::destructor_count == 0); + p2 = NULL; + BOOST_TEST(N5::Z::destructor_count == 1); + } + + return boost::report_errors(); +} From 7b9354fcf34919057950dfca11ff6280ffce2775 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sun, 1 Sep 2013 21:05:14 +0000 Subject: [PATCH 191/210] Changed intrusive_ref_counter to follow CRTP design. [SVN r85547] --- .../boost/smart_ptr/intrusive_ref_counter.hpp | 67 +++++++++---------- intrusive_ptr.html | 2 +- intrusive_ref_counter.html | 55 ++++++++------- test/intrusive_ref_counter_test.cpp | 40 ++++++----- 4 files changed, 88 insertions(+), 76 deletions(-) diff --git a/include/boost/smart_ptr/intrusive_ref_counter.hpp b/include/boost/smart_ptr/intrusive_ref_counter.hpp index 53aeee9..8714153 100644 --- a/include/boost/smart_ptr/intrusive_ref_counter.hpp +++ b/include/boost/smart_ptr/intrusive_ref_counter.hpp @@ -27,9 +27,9 @@ namespace boost { namespace sp_adl_block { /*! - * \brief Thread unsafe reference counter policy for \c basic_intrusive_ref_counter + * \brief Thread unsafe reference counter policy for \c intrusive_ref_counter * - * The policy instructs the \c basic_intrusive_ref_counter base class to implement + * The policy instructs the \c intrusive_ref_counter base class to implement * a reference counter suitable for single threaded use only. Pointers to the same * object with this kind of reference counter must not be used by different threads. */ @@ -54,9 +54,9 @@ struct thread_unsafe_counter }; /*! - * \brief Thread safe reference counter policy for \c basic_intrusive_ref_counter + * \brief Thread safe reference counter policy for \c intrusive_ref_counter * - * The policy instructs the \c basic_intrusive_ref_counter base class to implement + * The policy instructs the \c intrusive_ref_counter base class to implement * a thread-safe reference counter, if the target platform supports multithreading. */ struct thread_safe_counter @@ -79,26 +79,27 @@ struct thread_safe_counter } }; -template< typename CounterPolicyT > -class basic_intrusive_ref_counter; +template< typename DerivedT, typename CounterPolicyT = thread_safe_counter > +class intrusive_ref_counter; -template< typename CounterPolicyT > -void intrusive_ptr_add_ref(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT; -template< typename CounterPolicyT > -void intrusive_ptr_release(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT; +template< typename DerivedT, typename CounterPolicyT > +void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT; +template< typename DerivedT, typename CounterPolicyT > +void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT; /*! * \brief A reference counter base class * * This base class can be used with user-defined classes to add support - * for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT - * and a virtual destructor, which makes the derived class polymorphic. + * for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT. * Upon releasing the last \c intrusive_ptr referencing the object - * derived from the \c basic_intrusive_ref_counter class, operator \c delete + * derived from the \c intrusive_ref_counter class, operator \c delete * is automatically called on the pointer to the object. + * + * The other template parameter, \c DerivedT, is the user's class that derives from \c intrusive_ref_counter. */ -template< typename CounterPolicyT > -class basic_intrusive_ref_counter +template< typename DerivedT, typename CounterPolicyT > +class intrusive_ref_counter { private: //! Reference counter type @@ -112,7 +113,7 @@ public: * * \post use_count() == 0 */ - basic_intrusive_ref_counter() : m_ref_counter(0) + intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0) { } @@ -121,21 +122,16 @@ public: * * \post use_count() == 0 */ - basic_intrusive_ref_counter(basic_intrusive_ref_counter const&) : m_ref_counter(0) + intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0) { } - /*! - * Virtual destructor - */ - virtual ~basic_intrusive_ref_counter() {} - /*! * Assignment * * \post The reference counter is not modified after assignment */ - basic_intrusive_ref_counter& operator= (basic_intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; } + intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; } /*! * \return The reference counter @@ -145,32 +141,35 @@ public: return CounterPolicyT::load(m_ref_counter); } - friend void intrusive_ptr_add_ref< CounterPolicyT >(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT; - friend void intrusive_ptr_release< CounterPolicyT >(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT; +protected: + /*! + * Destructor + */ + BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {}) + + friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT; + friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT; }; -template< typename CounterPolicyT > -inline void intrusive_ptr_add_ref(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT +template< typename DerivedT, typename CounterPolicyT > +inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT { CounterPolicyT::increment(p->m_ref_counter); } -template< typename CounterPolicyT > -inline void intrusive_ptr_release(const basic_intrusive_ref_counter< CounterPolicyT >* p) BOOST_NOEXCEPT +template< typename DerivedT, typename CounterPolicyT > +inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT { if (CounterPolicyT::decrement(p->m_ref_counter) == 0) - delete p; + delete static_cast< const DerivedT* >(p); } } // namespace sp_adl_block -using sp_adl_block::basic_intrusive_ref_counter; +using sp_adl_block::intrusive_ref_counter; using sp_adl_block::thread_unsafe_counter; using sp_adl_block::thread_safe_counter; -//! Convenience typedef for the default reference counter type -typedef basic_intrusive_ref_counter< thread_safe_counter > intrusive_ref_counter; - } // namespace boost #endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_ diff --git a/intrusive_ptr.html b/intrusive_ptr.html index c37a5b2..562d27a 100644 --- a/intrusive_ptr.html +++ b/intrusive_ptr.html @@ -25,7 +25,7 @@ and intrusive_ptr_release should be defined in the namespace that corresponds to their parameter; otherwise, the definitions need to go in namespace boost. The library provides a helper base class template - basic_intrusive_ref_counter which may + intrusive_ref_counter which may help adding support for intrusive_ptr to user's types.

    The class template is parameterized on T, the type of the object pointed to. intrusive_ptr<T> can be implicitly converted to intrusive_ptr<U> diff --git a/intrusive_ref_counter.html b/intrusive_ref_counter.html index 30be3af..72a46e0 100644 --- a/intrusive_ref_counter.html +++ b/intrusive_ref_counter.html @@ -1,7 +1,7 @@ - basic_intrusive_ref_counter + intrusive_ref_counter @@ -13,50 +13,51 @@ Members

    Introduction

    -

    The basic_intrusive_ref_counter class template implements a reference counter for a defived +

    The intrusive_ref_counter class template implements a reference counter for a derived user's class that is intended to be used with intrusive_ptr. The base class has associated intrusive_ptr_add_ref and intrusive_ptr_release functions which modify the reference counter as needed and destroy the user's object when the counter drops to zero.

    -

    The class template is parameterized on CounterPolicyT, which is a policy that defines the nature of the reference counter. +

    The class template is parameterized on DerivedT and CounterPolicyT parameters. + The first parameter is the user's class that derives from intrusive_ref_counter. This type + is needed in order to destroy the object correctly when there are no references to it left.

    +

    The second parameter is a policy that defines the nature of the reference counter. Boost.SmartPtr provides two such policies: thread_unsafe_counter and thread_safe_counter. The former - instructs the basic_intrusive_ref_counter base class to use a counter only suitable for a single-threaded use. + instructs the intrusive_ref_counter base class to use a counter only suitable for a single-threaded use. Pointers to a single object that uses this kind of reference counter must not be used in different threads. The latter policy makes the reference counter thread-safe, unless the target platform doesn't support threading. Since in modern systems support for - threading is common, a shorthand intrusive_ref_counter is provided, which is an alias for - basic_intrusive_ref_counter<thread_safe_counter>.

    + threading is common, the default counter policy is thread_safe_counter.

    Synopsis

    namespace boost {
     
    -  template<class CounterPolicyT> class basic_intrusive_ref_counter {
    -
    -    public:
    -
    -      basic_intrusive_ref_counter();
    -      basic_intrusive_ref_counter(basic_intrusive_ref_counter const & r);
    -
    -      virtual ~basic_intrusive_ref_counter();
    -
    -      basic_intrusive_ref_counter & operator=(basic_intrusive_ref_counter const & r) noexcept;
    -
    -      unsigned int use_count() const noexcept;
    -  };
    -
       struct thread_unsafe_counter;
       struct thread_safe_counter;
     
    -  typedef basic_intrusive_ref_counter<thread_safe_counter> intrusive_ref_counter;
    +  template<class DerivedT, class CounterPolicyT = thread_safe_counter>
    +  class intrusive_ref_counter
    +  {
    +  public:
    +      intrusive_ref_counter() = noexcept;
    +      intrusive_ref_counter(intrusive_ref_counter const & r) = noexcept;
    +
    +      intrusive_ref_counter & operator=(intrusive_ref_counter const & r) noexcept;
    +
    +      unsigned int use_count() const noexcept;
    +
    +  protected:
    +      ~intrusive_ref_counter() = default;
    +  };
     
     }

    Members

    constructors

    -
    basic_intrusive_ref_counter();
    +
    intrusive_ref_counter();

    Postconditions: use_count() == 0.

    Throws: nothing.

    Notes: The pointer to the constructed object is expected to be passed to intrusive_ptr constructor, assignment operator or reset() method, which would increment the reference counter.

    -
    basic_intrusive_ref_counter(basic_intrusive_ref_counter const &);
    +
    intrusive_ref_counter(intrusive_ref_counter const &);

    Postconditions: use_count() == 0.

    Throws: nothing.

    @@ -64,12 +65,14 @@ constructor, assignment operator or reset() method, which would increment the reference counter.

    destructor

    -
    virtual ~basic_intrusive_ref_counter();
    +
    ~intrusive_ref_counter();
    +

    Throws: nothing.

    Effects: Destroys the counter object.

    +

    Notes: The destructor is protected so that the object can only be destroyed through the DerivedT class.

    assignment

    -
    basic_intrusive_ref_counter & operator=(basic_intrusive_ref_counter const & r) noexcept;
    +
    intrusive_ref_counter & operator=(intrusive_ref_counter const & r) noexcept;

    Effects: Does nothing, reference counter is not modified.

    Returns: *this.

    @@ -83,7 +86,7 @@

    - $Date: 2013-08-31 23:37:43 +0400 (Sat, 31 Aug 2013) $

    + $Date$

    Copyright © 2013 Andrey Semashev. Distributed under the Boost Software License, Version 1.0. See accompanying file LICENSE_1_0.txt or diff --git a/test/intrusive_ref_counter_test.cpp b/test/intrusive_ref_counter_test.cpp index 4f2ab88..53d0bd3 100644 --- a/test/intrusive_ref_counter_test.cpp +++ b/test/intrusive_ref_counter_test.cpp @@ -38,7 +38,7 @@ namespace N1 { class my_class : - public boost::intrusive_ref_counter + public boost::intrusive_ref_counter< my_class > { public: static unsigned int destructor_count; @@ -56,7 +56,7 @@ unsigned int my_class::destructor_count = 0; namespace N2 { class my_class : - public boost::basic_intrusive_ref_counter< boost::thread_unsafe_counter > + public boost::intrusive_ref_counter< my_class, boost::thread_unsafe_counter > { public: static unsigned int destructor_count; @@ -73,17 +73,18 @@ unsigned int my_class::destructor_count = 0; namespace N3 { -struct X : - public virtual boost::intrusive_ref_counter +struct root : + public boost::intrusive_ref_counter< root > { + virtual ~root() {} }; } // namespace N3 namespace N4 { -struct Y : - public virtual boost::intrusive_ref_counter +struct X : + public virtual N3::root { }; @@ -91,9 +92,18 @@ struct Y : namespace N5 { +struct Y : + public virtual N3::root +{ +}; + +} // namespace N5 + +namespace N6 { + struct Z : - public N3::X, - public N4::Y + public N4::X, + public N5::Y { static unsigned int destructor_count; @@ -105,7 +115,7 @@ struct Z : unsigned int Z::destructor_count = 0; -} // namespace N5 +} // namespace N6 int main() @@ -130,16 +140,16 @@ int main() // The test checks that destroying through the base class works { - boost::intrusive_ptr< N5::Z > p1 = new N5::Z(); + boost::intrusive_ptr< N6::Z > p1 = new N6::Z(); BOOST_TEST(p1->use_count() == 1); - BOOST_TEST(N5::Z::destructor_count == 0); - boost::intrusive_ptr< boost::intrusive_ref_counter > p2 = p1; + BOOST_TEST(N6::Z::destructor_count == 0); + boost::intrusive_ptr< N3::root > p2 = p1; BOOST_TEST(p1->use_count() == 2); - BOOST_TEST(N5::Z::destructor_count == 0); + BOOST_TEST(N6::Z::destructor_count == 0); p1 = NULL; - BOOST_TEST(N5::Z::destructor_count == 0); + BOOST_TEST(N6::Z::destructor_count == 0); p2 = NULL; - BOOST_TEST(N5::Z::destructor_count == 1); + BOOST_TEST(N6::Z::destructor_count == 1); } return boost::report_errors(); From 0dc1faa6d3db89394c6b43a00650030a9583db9c Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Thu, 5 Sep 2013 17:23:33 +0000 Subject: [PATCH 192/210] Disabled bogus MSVC warning. [SVN r85575] --- include/boost/smart_ptr/intrusive_ref_counter.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/boost/smart_ptr/intrusive_ref_counter.hpp b/include/boost/smart_ptr/intrusive_ref_counter.hpp index 8714153..82fa8bc 100644 --- a/include/boost/smart_ptr/intrusive_ref_counter.hpp +++ b/include/boost/smart_ptr/intrusive_ref_counter.hpp @@ -22,6 +22,14 @@ #pragma once #endif +#if defined(_MSC_VER) +#pragma warning(push) +// This is a bogus MSVC warning, which is flagged by friend declarations of intrusive_ptr_add_ref and intrusive_ptr_release in intrusive_ref_counter: +// 'name' : the inline specifier cannot be used when a friend declaration refers to a specialization of a function template +// Note that there is no inline specifier in the declarations. +#pragma warning(disable: 4396) +#endif + namespace boost { namespace sp_adl_block { @@ -172,4 +180,8 @@ using sp_adl_block::thread_safe_counter; } // namespace boost +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + #endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_ From 7d1c527ac010fa1e443ee8c63065b208fe9fb05d Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 26 Sep 2013 09:39:50 +0000 Subject: [PATCH 193/210] SmartPtr: Remove obsolete MSVC version checks. [SVN r85929] --- include/boost/smart_ptr/detail/shared_count.hpp | 7 ------- .../boost/smart_ptr/detail/sp_counted_base_w32.hpp | 12 ------------ include/boost/smart_ptr/detail/spinlock_w32.hpp | 2 +- include/boost/smart_ptr/detail/yield_k.hpp | 2 +- include/boost/smart_ptr/intrusive_ptr.hpp | 6 ------ include/boost/smart_ptr/shared_ptr.hpp | 6 ------ include/boost/smart_ptr/weak_ptr.hpp | 4 ---- 7 files changed, 2 insertions(+), 37 deletions(-) diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index 8e1dd48..2b48cec 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -148,18 +148,11 @@ public: #endif } -#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) - template shared_count( Y * p, D d ): pi_(0) -#else template shared_count( P p, D d ): pi_(0) -#endif #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif { -#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) - typedef Y* P; -#endif #ifndef BOOST_NO_EXCEPTIONS try diff --git a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp index ff394dc..109deb5 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp @@ -80,19 +80,7 @@ public: { long tmp = static_cast< long const volatile& >( use_count_ ); if( tmp == 0 ) return false; - -#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 ) - - // work around a code generation bug - - long tmp2 = tmp + 1; - if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true; - -#else - if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true; - -#endif } } diff --git a/include/boost/smart_ptr/detail/spinlock_w32.hpp b/include/boost/smart_ptr/detail/spinlock_w32.hpp index fb97629..57c85e1 100644 --- a/include/boost/smart_ptr/detail/spinlock_w32.hpp +++ b/include/boost/smart_ptr/detail/spinlock_w32.hpp @@ -24,7 +24,7 @@ #define BOOST_COMPILER_FENCE __memory_barrier(); -#elif defined( _MSC_VER ) && _MSC_VER >= 1310 +#elif defined( _MSC_VER ) extern "C" void _ReadWriteBarrier(); #pragma intrinsic( _ReadWriteBarrier ) diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index 23eadd8..464b595 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -27,7 +27,7 @@ // BOOST_SMT_PAUSE -#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) +#if defined(_MSC_VER) && ( defined(_M_IX86) || defined(_M_X64) ) extern "C" void _mm_pause(); #pragma intrinsic( _mm_pause ) diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index b6f5bcd..3cd3dc7 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -292,13 +292,7 @@ template std::ostream & operator<< (std::ostream & os, intrusive_ptr // in STLport's no-iostreams mode no iostream symbols can be used #ifndef _STLP_NO_IOSTREAMS -# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) -// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL -using std::basic_ostream; -template basic_ostream & operator<< (basic_ostream & os, intrusive_ptr const & p) -# else template std::basic_ostream & operator<< (std::basic_ostream & os, intrusive_ptr const & p) -# endif { os << p.get(); return os; diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 9259ca0..106e349 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -849,13 +849,7 @@ template std::ostream & operator<< (std::ostream & os, shared_ptr co // in STLport's no-iostreams mode no iostream symbols can be used #ifndef _STLP_NO_IOSTREAMS -# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) -// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL -using std::basic_ostream; -template basic_ostream & operator<< (basic_ostream & os, shared_ptr const & p) -# else template std::basic_ostream & operator<< (std::basic_ostream & os, shared_ptr const & p) -# endif { os << p.get(); return os; diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index e3e9ad9..cc0cdca 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -136,8 +136,6 @@ public: boost::detail::sp_assert_convertible< Y, T >(); } -#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) - template weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT { @@ -171,8 +169,6 @@ public: return *this; } -#endif - shared_ptr lock() const BOOST_NOEXCEPT { return shared_ptr( *this, boost::detail::sp_nothrow_tag() ); From e4f24e4d3d9d3e04318c375e8c3dd2124e630c29 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 26 Sep 2013 13:02:51 +0000 Subject: [PATCH 194/210] Remove obsolete MSVC check from pragma guard git grep -h -B1 "^#\s*pragma once" | grep -v pragma | sort | uniq is now clean. [SVN r85952] --- include/boost/detail/atomic_count.hpp | 2 +- include/boost/detail/lightweight_mutex.hpp | 2 +- include/boost/detail/sp_typeinfo.hpp | 2 +- include/boost/memory_order.hpp | 2 +- include/boost/smart_ptr/bad_weak_ptr.hpp | 2 +- include/boost/smart_ptr/detail/atomic_count.hpp | 2 +- include/boost/smart_ptr/detail/atomic_count_win32.hpp | 2 +- include/boost/smart_ptr/detail/lightweight_mutex.hpp | 2 +- include/boost/smart_ptr/detail/lwm_nop.hpp | 2 +- include/boost/smart_ptr/detail/lwm_pthreads.hpp | 2 +- include/boost/smart_ptr/detail/lwm_win32_cs.hpp | 2 +- include/boost/smart_ptr/detail/quick_allocator.hpp | 2 +- include/boost/smart_ptr/detail/shared_count.hpp | 2 +- include/boost/smart_ptr/detail/sp_convertible.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_nt.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_pt.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_spin.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_sync.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_w32.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_impl.hpp | 2 +- include/boost/smart_ptr/detail/sp_forward.hpp | 2 +- include/boost/smart_ptr/detail/sp_has_sync.hpp | 2 +- include/boost/smart_ptr/detail/sp_nullptr_t.hpp | 2 +- include/boost/smart_ptr/detail/spinlock.hpp | 2 +- include/boost/smart_ptr/detail/spinlock_nt.hpp | 2 +- include/boost/smart_ptr/detail/spinlock_pool.hpp | 2 +- include/boost/smart_ptr/detail/spinlock_pt.hpp | 2 +- include/boost/smart_ptr/detail/spinlock_sync.hpp | 2 +- include/boost/smart_ptr/detail/spinlock_w32.hpp | 2 +- include/boost/smart_ptr/detail/yield_k.hpp | 2 +- 38 files changed, 38 insertions(+), 38 deletions(-) diff --git a/include/boost/detail/atomic_count.hpp b/include/boost/detail/atomic_count.hpp index 5411c7a..d035dd9 100644 --- a/include/boost/detail/atomic_count.hpp +++ b/include/boost/detail/atomic_count.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/detail/lightweight_mutex.hpp b/include/boost/detail/lightweight_mutex.hpp index b7a7f6d..be764f0 100644 --- a/include/boost/detail/lightweight_mutex.hpp +++ b/include/boost/detail/lightweight_mutex.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/detail/sp_typeinfo.hpp b/include/boost/detail/sp_typeinfo.hpp index 43fae78..9e4c01b 100644 --- a/include/boost/detail/sp_typeinfo.hpp +++ b/include/boost/detail/sp_typeinfo.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/memory_order.hpp b/include/boost/memory_order.hpp index 4945af6..e352f6f 100644 --- a/include/boost/memory_order.hpp +++ b/include/boost/memory_order.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/bad_weak_ptr.hpp b/include/boost/smart_ptr/bad_weak_ptr.hpp index 3e0a1b7..b1e8825 100644 --- a/include/boost/smart_ptr/bad_weak_ptr.hpp +++ b/include/boost/smart_ptr/bad_weak_ptr.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/atomic_count.hpp b/include/boost/smart_ptr/detail/atomic_count.hpp index cc44ac2..b384475 100644 --- a/include/boost/smart_ptr/detail/atomic_count.hpp +++ b/include/boost/smart_ptr/detail/atomic_count.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/atomic_count_win32.hpp b/include/boost/smart_ptr/detail/atomic_count_win32.hpp index 60a0569..e7b99c3 100644 --- a/include/boost/smart_ptr/detail/atomic_count_win32.hpp +++ b/include/boost/smart_ptr/detail/atomic_count_win32.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/lightweight_mutex.hpp b/include/boost/smart_ptr/detail/lightweight_mutex.hpp index d46b193..cf7d0cf 100644 --- a/include/boost/smart_ptr/detail/lightweight_mutex.hpp +++ b/include/boost/smart_ptr/detail/lightweight_mutex.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/lwm_nop.hpp b/include/boost/smart_ptr/detail/lwm_nop.hpp index 521a88e..5a59a1d 100644 --- a/include/boost/smart_ptr/detail/lwm_nop.hpp +++ b/include/boost/smart_ptr/detail/lwm_nop.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/lwm_pthreads.hpp b/include/boost/smart_ptr/detail/lwm_pthreads.hpp index 8eda518..a361b13 100644 --- a/include/boost/smart_ptr/detail/lwm_pthreads.hpp +++ b/include/boost/smart_ptr/detail/lwm_pthreads.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/lwm_win32_cs.hpp b/include/boost/smart_ptr/detail/lwm_win32_cs.hpp index 00477e4..f252a2b 100644 --- a/include/boost/smart_ptr/detail/lwm_win32_cs.hpp +++ b/include/boost/smart_ptr/detail/lwm_win32_cs.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/quick_allocator.hpp b/include/boost/smart_ptr/detail/quick_allocator.hpp index 159bd5e..d78dc70 100644 --- a/include/boost/smart_ptr/detail/quick_allocator.hpp +++ b/include/boost/smart_ptr/detail/quick_allocator.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index 2b48cec..5a0bab3 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp index 31b2627..00d0b53 100644 --- a/include/boost/smart_ptr/detail/sp_convertible.hpp +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp index 9ced2b9..b49c663 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp index 6c268e8..8482ae7 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp index 81eba6f..f234099 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp index 545c8ae..b9f745d 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp index 2e5bc0e..01d21cf 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp index c6d20ce..f2f8454 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp index 173dce5..ad27870 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp index 5c901f9..b059785 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp index a742c3d..970d954 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp index 56ed79f..c32377a 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp @@ -2,7 +2,7 @@ #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp index 77734e7..a9f73da 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp index fafed0e..22802a7 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp index 109deb5..04cb239 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/include/boost/smart_ptr/detail/sp_counted_impl.hpp index d15cd3c..ce5ce5a 100644 --- a/include/boost/smart_ptr/detail/sp_counted_impl.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_forward.hpp b/include/boost/smart_ptr/detail/sp_forward.hpp index 5f1d190..5de47dd 100644 --- a/include/boost/smart_ptr/detail/sp_forward.hpp +++ b/include/boost/smart_ptr/detail/sp_forward.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp index 16de21d..fec2d20 100644 --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_nullptr_t.hpp b/include/boost/smart_ptr/detail/sp_nullptr_t.hpp index ccbb123..1584a8f 100644 --- a/include/boost/smart_ptr/detail/sp_nullptr_t.hpp +++ b/include/boost/smart_ptr/detail/sp_nullptr_t.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock.hpp b/include/boost/smart_ptr/detail/spinlock.hpp index 88d7ad6..6cff398 100644 --- a/include/boost/smart_ptr/detail/spinlock.hpp +++ b/include/boost/smart_ptr/detail/spinlock.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock_nt.hpp b/include/boost/smart_ptr/detail/spinlock_nt.hpp index 1f399d0..41f5071 100644 --- a/include/boost/smart_ptr/detail/spinlock_nt.hpp +++ b/include/boost/smart_ptr/detail/spinlock_nt.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock_pool.hpp b/include/boost/smart_ptr/detail/spinlock_pool.hpp index f09d5c6..64a47e3 100644 --- a/include/boost/smart_ptr/detail/spinlock_pool.hpp +++ b/include/boost/smart_ptr/detail/spinlock_pool.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock_pt.hpp b/include/boost/smart_ptr/detail/spinlock_pt.hpp index f9cabfc..e5eeb54 100644 --- a/include/boost/smart_ptr/detail/spinlock_pt.hpp +++ b/include/boost/smart_ptr/detail/spinlock_pt.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock_sync.hpp b/include/boost/smart_ptr/detail/spinlock_sync.hpp index a7145c5..3442d11 100644 --- a/include/boost/smart_ptr/detail/spinlock_sync.hpp +++ b/include/boost/smart_ptr/detail/spinlock_sync.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock_w32.hpp b/include/boost/smart_ptr/detail/spinlock_w32.hpp index 57c85e1..f383537 100644 --- a/include/boost/smart_ptr/detail/spinlock_w32.hpp +++ b/include/boost/smart_ptr/detail/spinlock_w32.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index 464b595..1bce751 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif From 382fb54a52efba643aaa05046c2214479dee618e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 29 Sep 2013 10:43:15 +0000 Subject: [PATCH 195/210] Revert MSC_VER changes. [SVN r85993] --- include/boost/smart_ptr/detail/spinlock_w32.hpp | 2 +- include/boost/smart_ptr/detail/yield_k.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/detail/spinlock_w32.hpp b/include/boost/smart_ptr/detail/spinlock_w32.hpp index f383537..fac21fe 100644 --- a/include/boost/smart_ptr/detail/spinlock_w32.hpp +++ b/include/boost/smart_ptr/detail/spinlock_w32.hpp @@ -24,7 +24,7 @@ #define BOOST_COMPILER_FENCE __memory_barrier(); -#elif defined( _MSC_VER ) +#elif defined( _MSC_VER ) && _MSC_VER >= 1310 extern "C" void _ReadWriteBarrier(); #pragma intrinsic( _ReadWriteBarrier ) diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index 1bce751..e3610f1 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -27,7 +27,7 @@ // BOOST_SMT_PAUSE -#if defined(_MSC_VER) && ( defined(_M_IX86) || defined(_M_X64) ) +#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) extern "C" void _mm_pause(); #pragma intrinsic( _mm_pause ) From fa91b7d0205ca4abcf0eef0bb7771248e16ab080 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 29 Sep 2013 11:31:17 +0000 Subject: [PATCH 196/210] Remove #pragma intrinsic( _mm_pause ); not needed, not supported on Intel. Refs #6646, #7318. [SVN r85995] --- include/boost/smart_ptr/detail/yield_k.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index e3610f1..3c8be4c 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -30,7 +30,6 @@ #if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) extern "C" void _mm_pause(); -#pragma intrinsic( _mm_pause ) #define BOOST_SMT_PAUSE _mm_pause(); From 14be9eb90f737c2290ad0025cb8e289024c2195c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 30 Sep 2013 15:56:52 +0000 Subject: [PATCH 197/210] Remove use of obsolete BOOST_NO_TEMPLATED_STREAMS macro. It was only defined for no-longer-supported-gcc. [SVN r86062] --- include/boost/smart_ptr/intrusive_ptr.hpp | 2 +- include/boost/smart_ptr/shared_ptr.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index 3cd3dc7..43930a3 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -279,7 +279,7 @@ template intrusive_ptr dynamic_pointer_cast(intrusive_ptr std::ostream & operator<< (std::ostream & os, intrusive_ptr const & p) { diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 106e349..22816df 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -836,7 +836,7 @@ template inline typename shared_ptr::element_type * get_pointer(shar #if !defined(BOOST_NO_IOSTREAM) -#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) ) +#if ( defined(__GNUC__) && (__GNUC__ < 3) ) template std::ostream & operator<< (std::ostream & os, shared_ptr const & p) { From 0e6ddb843ed343796fdc5250a25064264ba2f6a7 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 30 Sep 2013 15:57:14 +0000 Subject: [PATCH 198/210] SmartPointer: Remove obsolete GCC version checks. [SVN r86063] --- .../boost/smart_ptr/detail/sp_convertible.hpp | 4 --- include/boost/smart_ptr/intrusive_ptr.hpp | 23 --------------- include/boost/smart_ptr/shared_ptr.hpp | 29 ++----------------- 3 files changed, 2 insertions(+), 54 deletions(-) diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp index 00d0b53..868eba6 100644 --- a/include/boost/smart_ptr/detail/sp_convertible.hpp +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp @@ -21,10 +21,6 @@ # define BOOST_SP_NO_SP_CONVERTIBLE #endif -#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 ) -# define BOOST_SP_NO_SP_CONVERTIBLE -#endif - #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 ) # define BOOST_SP_NO_SP_CONVERTIBLE #endif diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index 43930a3..a855a10 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -208,17 +208,6 @@ template inline bool operator!=(T * a, intrusive_ptr const return a != b.get(); } -#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 - -// Resolve the ambiguity between our op!= and the one in rel_ops - -template inline bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) -{ - return a.get() != b.get(); -} - -#endif - #if !defined( BOOST_NO_CXX11_NULLPTR ) template inline bool operator==( intrusive_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT @@ -279,16 +268,6 @@ template intrusive_ptr dynamic_pointer_cast(intrusive_ptr std::ostream & operator<< (std::ostream & os, intrusive_ptr const & p) -{ - os << p.get(); - return os; -} - -#else - // in STLport's no-iostreams mode no iostream symbols can be used #ifndef _STLP_NO_IOSTREAMS @@ -300,8 +279,6 @@ template std::basic_ostream & operator<< (std:: #endif // _STLP_NO_IOSTREAMS -#endif // __GNUC__ < 3 - #endif // !defined(BOOST_NO_IOSTREAM) // hash_value diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 22816df..a06d9e7 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -740,17 +740,6 @@ template inline bool operator!=(shared_ptr const & a, share return a.get() != b.get(); } -#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 - -// Resolve the ambiguity between our op!= and the one in rel_ops - -template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT -{ - return a.get() != b.get(); -} - -#endif - #if !defined( BOOST_NO_CXX11_NULLPTR ) template inline bool operator==( shared_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT @@ -836,16 +825,6 @@ template inline typename shared_ptr::element_type * get_pointer(shar #if !defined(BOOST_NO_IOSTREAM) -#if ( defined(__GNUC__) && (__GNUC__ < 3) ) - -template std::ostream & operator<< (std::ostream & os, shared_ptr const & p) -{ - os << p.get(); - return os; -} - -#else - // in STLport's no-iostreams mode no iostream symbols can be used #ifndef _STLP_NO_IOSTREAMS @@ -857,8 +836,6 @@ template std::basic_ostream & operator<< (std:: #endif // _STLP_NO_IOSTREAMS -#endif // __GNUC__ < 3 - #endif // !defined(BOOST_NO_IOSTREAM) // get_deleter @@ -866,12 +843,10 @@ template std::basic_ostream & operator<< (std:: namespace detail { -#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \ - ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \ +#if ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \ ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) ) -// g++ 2.9x doesn't allow static_cast(void *) -// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it +// EDG 2.38 and HP aCC A.03.35 don't allow static_cast(void *) template D * basic_get_deleter(shared_ptr const & p) { From 8767b9580e415f44a285705a09f2dc097033f864 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 11 Oct 2013 23:15:00 +0000 Subject: [PATCH 199/210] Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION Process #ifndef...#endif conditions. [SVN r86244] --- include/boost/smart_ptr/make_shared_object.hpp | 2 -- include/boost/smart_ptr/shared_ptr.hpp | 14 -------------- 2 files changed, 16 deletions(-) diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp index 52a00ce..06875d9 100644 --- a/include/boost/smart_ptr/make_shared_object.hpp +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -107,7 +107,6 @@ 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[] > { @@ -121,7 +120,6 @@ template< class T, std::size_t N > struct sp_if_not_array< T[N] > #endif -#endif } // namespace detail diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index a06d9e7..1bfecc7 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -70,7 +70,6 @@ template< class T > struct sp_element typedef T type; }; -#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) template< class T > struct sp_element< T[] > { @@ -86,7 +85,6 @@ template< class T, std::size_t N > struct sp_element< T[N] > #endif -#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_dereference, return type of operator* @@ -119,7 +117,6 @@ template<> struct sp_dereference< void const volatile > #endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) -#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) template< class T > struct sp_dereference< T[] > { @@ -135,7 +132,6 @@ template< class T, std::size_t N > struct sp_dereference< T[N] > #endif -#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_member_access, return type of operator-> @@ -144,7 +140,6 @@ 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[] > { @@ -160,7 +155,6 @@ template< class T, std::size_t N > struct sp_member_access< T[N] > #endif -#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_array_access, return type of operator[] @@ -169,7 +163,6 @@ 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[] > { @@ -185,7 +178,6 @@ template< class T, std::size_t N > struct sp_array_access< T[N] > #endif -#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_extent, for operator[] index check @@ -194,14 +186,12 @@ 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 @@ -277,7 +267,6 @@ template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr 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 ) { @@ -291,7 +280,6 @@ template< class T, std::size_t N, class Y > inline void sp_pointer_construct( bo boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); } -#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // deleter constructor helper @@ -300,7 +288,6 @@ template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr 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*/ ) { @@ -312,7 +299,6 @@ template< class T, std::size_t N, class Y > inline void sp_deleter_construct( bo sp_assert_convertible< Y[N], T[N] >(); } -#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) } // namespace detail From f5e6e4063e456ea2490fe94c8de35d7d9100368b Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 11 Oct 2013 23:20:59 +0000 Subject: [PATCH 200/210] Simplify multi-component ifdefs containing BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION [SVN r86248] --- include/boost/smart_ptr/make_shared.hpp | 2 +- include/boost/smart_ptr/shared_ptr.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp index 8d0e3ea..82dcae3 100644 --- a/include/boost/smart_ptr/make_shared.hpp +++ b/include/boost/smart_ptr/make_shared.hpp @@ -14,7 +14,7 @@ #include -#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE ) +#if !defined( BOOST_NO_SFINAE ) # include # include #endif diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 1bfecc7..bbfb896 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -226,7 +226,7 @@ inline void sp_enable_shared_from_this( ... ) #endif // _MANAGED -#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR ) +#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_AUTO_PTR ) // rvalue auto_ptr support based on a technique by Dave Abrahams From 56b08538876d67a22e3c64aa2025a4613365fb3f Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 11 Oct 2013 23:22:36 +0000 Subject: [PATCH 201/210] Remove remaining occurances of BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION These evaded scripting. [SVN r86249] --- include/boost/smart_ptr/shared_ptr.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index bbfb896..2a05ead 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -452,7 +452,7 @@ public: boost::detail::sp_deleter_construct( this, tmp ); } -#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) +#elif !defined( BOOST_NO_SFINAE ) template explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr::type = 0 ): px( r.get() ), pn() @@ -467,7 +467,7 @@ public: boost::detail::sp_deleter_construct( this, tmp ); } -#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#endif // BOOST_NO_SFINAE #endif // BOOST_NO_AUTO_PTR @@ -523,7 +523,7 @@ public: return *this; } -#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) +#elif !defined( BOOST_NO_SFINAE ) template typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r ) @@ -532,7 +532,7 @@ public: return *this; } -#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#endif // BOOST_NO_SFINAE #endif // BOOST_NO_AUTO_PTR From 2549b818c5cb95a6557a8170ce7f94a79f35a5ce Mon Sep 17 00:00:00 2001 From: Michel Morin Date: Wed, 30 Oct 2013 12:51:24 +0000 Subject: [PATCH 202/210] Correct broken links to C++ standard papers. Refs #9212. [SVN r86524] --- smart_ptr.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smart_ptr.htm b/smart_ptr.htm index 10fe5d6..2aba306 100644 --- a/smart_ptr.htm +++ b/smart_ptr.htm @@ -190,7 +190,7 @@ the full committee, counted_ptr was rejected and surprising transfer-of-ownership semantics were added to auto_ptr.

    References

    -

    [Col-94] Gregory Colvin, +

    [Col-94] Gregory Colvin, Exception Safe Smart Pointers, C++ committee document 94-168/N0555, July, 1994.

    [E&D-94] John R. Ellis & David L. Detlefs, From 85d805636848dc13eb52149822459d1f96b0a8cf Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 7 Dec 2013 19:19:46 +0200 Subject: [PATCH 203/210] Revert "Remove remaining occurances of BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION" This reverts commit 56b08538876d67a22e3c64aa2025a4613365fb3f. --- include/boost/smart_ptr/shared_ptr.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 2a05ead..bbfb896 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -452,7 +452,7 @@ public: boost::detail::sp_deleter_construct( this, tmp ); } -#elif !defined( BOOST_NO_SFINAE ) +#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) template explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr::type = 0 ): px( r.get() ), pn() @@ -467,7 +467,7 @@ public: boost::detail::sp_deleter_construct( this, tmp ); } -#endif // BOOST_NO_SFINAE +#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #endif // BOOST_NO_AUTO_PTR @@ -523,7 +523,7 @@ public: return *this; } -#elif !defined( BOOST_NO_SFINAE ) +#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) template typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r ) @@ -532,7 +532,7 @@ public: return *this; } -#endif // BOOST_NO_SFINAE +#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #endif // BOOST_NO_AUTO_PTR From 00aee2c7dcd0eaf65ccdd7a32ca593f202ddcdd7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 7 Dec 2013 19:20:12 +0200 Subject: [PATCH 204/210] Revert "Simplify multi-component ifdefs containing BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION" This reverts commit f5e6e4063e456ea2490fe94c8de35d7d9100368b. --- include/boost/smart_ptr/make_shared.hpp | 2 +- include/boost/smart_ptr/shared_ptr.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/make_shared.hpp b/include/boost/smart_ptr/make_shared.hpp index 82dcae3..8d0e3ea 100644 --- a/include/boost/smart_ptr/make_shared.hpp +++ b/include/boost/smart_ptr/make_shared.hpp @@ -14,7 +14,7 @@ #include -#if !defined( BOOST_NO_SFINAE ) +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE ) # include # include #endif diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index bbfb896..1bfecc7 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -226,7 +226,7 @@ inline void sp_enable_shared_from_this( ... ) #endif // _MANAGED -#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_AUTO_PTR ) +#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR ) // rvalue auto_ptr support based on a technique by Dave Abrahams From 70ffd2921f14920cedcb722eeed8aa2fd10447cd Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 7 Dec 2013 19:20:36 +0200 Subject: [PATCH 205/210] Revert "Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION" This reverts commit 8767b9580e415f44a285705a09f2dc097033f864. --- include/boost/smart_ptr/make_shared_object.hpp | 2 ++ include/boost/smart_ptr/shared_ptr.hpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp index 06875d9..52a00ce 100644 --- a/include/boost/smart_ptr/make_shared_object.hpp +++ b/include/boost/smart_ptr/make_shared_object.hpp @@ -107,6 +107,7 @@ 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[] > { @@ -120,6 +121,7 @@ template< class T, std::size_t N > struct sp_if_not_array< T[N] > #endif +#endif } // namespace detail diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 1bfecc7..a06d9e7 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -70,6 +70,7 @@ template< class T > struct sp_element typedef T type; }; +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) template< class T > struct sp_element< T[] > { @@ -85,6 +86,7 @@ template< class T, std::size_t N > struct sp_element< T[N] > #endif +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_dereference, return type of operator* @@ -117,6 +119,7 @@ template<> struct sp_dereference< void const volatile > #endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) template< class T > struct sp_dereference< T[] > { @@ -132,6 +135,7 @@ template< class T, std::size_t N > struct sp_dereference< T[N] > #endif +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_member_access, return type of operator-> @@ -140,6 +144,7 @@ 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[] > { @@ -155,6 +160,7 @@ template< class T, std::size_t N > struct sp_member_access< T[N] > #endif +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_array_access, return type of operator[] @@ -163,6 +169,7 @@ 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[] > { @@ -178,6 +185,7 @@ template< class T, std::size_t N > struct sp_array_access< T[N] > #endif +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // sp_extent, for operator[] index check @@ -186,12 +194,14 @@ 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 @@ -267,6 +277,7 @@ template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr 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 ) { @@ -280,6 +291,7 @@ template< class T, std::size_t N, class Y > inline void sp_pointer_construct( bo boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); } +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) // deleter constructor helper @@ -288,6 +300,7 @@ template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr 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*/ ) { @@ -299,6 +312,7 @@ template< class T, std::size_t N, class Y > inline void sp_deleter_construct( bo sp_assert_convertible< Y[N], T[N] >(); } +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) } // namespace detail From 5f69684c8fffb0c89266b1219bda26f1885deef5 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 7 Dec 2013 19:21:06 +0200 Subject: [PATCH 206/210] Revert "SmartPointer: Remove obsolete GCC version checks." This reverts commit 0e6ddb843ed343796fdc5250a25064264ba2f6a7. --- .../boost/smart_ptr/detail/sp_convertible.hpp | 4 +++ include/boost/smart_ptr/intrusive_ptr.hpp | 23 +++++++++++++++ include/boost/smart_ptr/shared_ptr.hpp | 29 +++++++++++++++++-- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp index 868eba6..00d0b53 100644 --- a/include/boost/smart_ptr/detail/sp_convertible.hpp +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp @@ -21,6 +21,10 @@ # define BOOST_SP_NO_SP_CONVERTIBLE #endif +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 ) +# define BOOST_SP_NO_SP_CONVERTIBLE +#endif + #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 ) # define BOOST_SP_NO_SP_CONVERTIBLE #endif diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index a855a10..43930a3 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -208,6 +208,17 @@ template inline bool operator!=(T * a, intrusive_ptr const return a != b.get(); } +#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 + +// Resolve the ambiguity between our op!= and the one in rel_ops + +template inline bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) +{ + return a.get() != b.get(); +} + +#endif + #if !defined( BOOST_NO_CXX11_NULLPTR ) template inline bool operator==( intrusive_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT @@ -268,6 +279,16 @@ template intrusive_ptr dynamic_pointer_cast(intrusive_ptr std::ostream & operator<< (std::ostream & os, intrusive_ptr const & p) +{ + os << p.get(); + return os; +} + +#else + // in STLport's no-iostreams mode no iostream symbols can be used #ifndef _STLP_NO_IOSTREAMS @@ -279,6 +300,8 @@ template std::basic_ostream & operator<< (std:: #endif // _STLP_NO_IOSTREAMS +#endif // __GNUC__ < 3 + #endif // !defined(BOOST_NO_IOSTREAM) // hash_value diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index a06d9e7..22816df 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -740,6 +740,17 @@ template inline bool operator!=(shared_ptr const & a, share return a.get() != b.get(); } +#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 + +// Resolve the ambiguity between our op!= and the one in rel_ops + +template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT +{ + return a.get() != b.get(); +} + +#endif + #if !defined( BOOST_NO_CXX11_NULLPTR ) template inline bool operator==( shared_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT @@ -825,6 +836,16 @@ template inline typename shared_ptr::element_type * get_pointer(shar #if !defined(BOOST_NO_IOSTREAM) +#if ( defined(__GNUC__) && (__GNUC__ < 3) ) + +template std::ostream & operator<< (std::ostream & os, shared_ptr const & p) +{ + os << p.get(); + return os; +} + +#else + // in STLport's no-iostreams mode no iostream symbols can be used #ifndef _STLP_NO_IOSTREAMS @@ -836,6 +857,8 @@ template std::basic_ostream & operator<< (std:: #endif // _STLP_NO_IOSTREAMS +#endif // __GNUC__ < 3 + #endif // !defined(BOOST_NO_IOSTREAM) // get_deleter @@ -843,10 +866,12 @@ template std::basic_ostream & operator<< (std:: namespace detail { -#if ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \ +#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \ + ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \ ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) ) -// EDG 2.38 and HP aCC A.03.35 don't allow static_cast(void *) +// g++ 2.9x doesn't allow static_cast(void *) +// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it template D * basic_get_deleter(shared_ptr const & p) { From 182452e057e2e60103116a094b4e70fc2e25975e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 7 Dec 2013 19:21:31 +0200 Subject: [PATCH 207/210] Revert "Remove use of obsolete BOOST_NO_TEMPLATED_STREAMS macro." This reverts commit 14be9eb90f737c2290ad0025cb8e289024c2195c. --- include/boost/smart_ptr/intrusive_ptr.hpp | 2 +- include/boost/smart_ptr/shared_ptr.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index 43930a3..3cd3dc7 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -279,7 +279,7 @@ template intrusive_ptr dynamic_pointer_cast(intrusive_ptr std::ostream & operator<< (std::ostream & os, intrusive_ptr const & p) { diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 22816df..106e349 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -836,7 +836,7 @@ template inline typename shared_ptr::element_type * get_pointer(shar #if !defined(BOOST_NO_IOSTREAM) -#if ( defined(__GNUC__) && (__GNUC__ < 3) ) +#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) ) template std::ostream & operator<< (std::ostream & os, shared_ptr const & p) { From d9b29beebe86f3722d9bbad53ca2a7794aaa71a7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 7 Dec 2013 19:22:43 +0200 Subject: [PATCH 208/210] Revert "Remove obsolete MSVC check from pragma guard" This reverts commit e4f24e4d3d9d3e04318c375e8c3dd2124e630c29. --- include/boost/detail/atomic_count.hpp | 2 +- include/boost/detail/lightweight_mutex.hpp | 2 +- include/boost/detail/sp_typeinfo.hpp | 2 +- include/boost/memory_order.hpp | 2 +- include/boost/smart_ptr/bad_weak_ptr.hpp | 2 +- include/boost/smart_ptr/detail/atomic_count.hpp | 2 +- include/boost/smart_ptr/detail/atomic_count_win32.hpp | 2 +- include/boost/smart_ptr/detail/lightweight_mutex.hpp | 2 +- include/boost/smart_ptr/detail/lwm_nop.hpp | 2 +- include/boost/smart_ptr/detail/lwm_pthreads.hpp | 2 +- include/boost/smart_ptr/detail/lwm_win32_cs.hpp | 2 +- include/boost/smart_ptr/detail/quick_allocator.hpp | 2 +- include/boost/smart_ptr/detail/shared_count.hpp | 2 +- include/boost/smart_ptr/detail/sp_convertible.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_nt.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_pt.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_spin.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_sync.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_base_w32.hpp | 2 +- include/boost/smart_ptr/detail/sp_counted_impl.hpp | 2 +- include/boost/smart_ptr/detail/sp_forward.hpp | 2 +- include/boost/smart_ptr/detail/sp_has_sync.hpp | 2 +- include/boost/smart_ptr/detail/sp_nullptr_t.hpp | 2 +- include/boost/smart_ptr/detail/spinlock.hpp | 2 +- include/boost/smart_ptr/detail/spinlock_nt.hpp | 2 +- include/boost/smart_ptr/detail/spinlock_pool.hpp | 2 +- include/boost/smart_ptr/detail/spinlock_pt.hpp | 2 +- include/boost/smart_ptr/detail/spinlock_sync.hpp | 2 +- include/boost/smart_ptr/detail/spinlock_w32.hpp | 2 +- include/boost/smart_ptr/detail/yield_k.hpp | 2 +- 38 files changed, 38 insertions(+), 38 deletions(-) diff --git a/include/boost/detail/atomic_count.hpp b/include/boost/detail/atomic_count.hpp index d035dd9..5411c7a 100644 --- a/include/boost/detail/atomic_count.hpp +++ b/include/boost/detail/atomic_count.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/detail/lightweight_mutex.hpp b/include/boost/detail/lightweight_mutex.hpp index be764f0..b7a7f6d 100644 --- a/include/boost/detail/lightweight_mutex.hpp +++ b/include/boost/detail/lightweight_mutex.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/detail/sp_typeinfo.hpp b/include/boost/detail/sp_typeinfo.hpp index 9e4c01b..43fae78 100644 --- a/include/boost/detail/sp_typeinfo.hpp +++ b/include/boost/detail/sp_typeinfo.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/memory_order.hpp b/include/boost/memory_order.hpp index e352f6f..4945af6 100644 --- a/include/boost/memory_order.hpp +++ b/include/boost/memory_order.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/bad_weak_ptr.hpp b/include/boost/smart_ptr/bad_weak_ptr.hpp index b1e8825..3e0a1b7 100644 --- a/include/boost/smart_ptr/bad_weak_ptr.hpp +++ b/include/boost/smart_ptr/bad_weak_ptr.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/atomic_count.hpp b/include/boost/smart_ptr/detail/atomic_count.hpp index b384475..cc44ac2 100644 --- a/include/boost/smart_ptr/detail/atomic_count.hpp +++ b/include/boost/smart_ptr/detail/atomic_count.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/atomic_count_win32.hpp b/include/boost/smart_ptr/detail/atomic_count_win32.hpp index e7b99c3..60a0569 100644 --- a/include/boost/smart_ptr/detail/atomic_count_win32.hpp +++ b/include/boost/smart_ptr/detail/atomic_count_win32.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/lightweight_mutex.hpp b/include/boost/smart_ptr/detail/lightweight_mutex.hpp index cf7d0cf..d46b193 100644 --- a/include/boost/smart_ptr/detail/lightweight_mutex.hpp +++ b/include/boost/smart_ptr/detail/lightweight_mutex.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/lwm_nop.hpp b/include/boost/smart_ptr/detail/lwm_nop.hpp index 5a59a1d..521a88e 100644 --- a/include/boost/smart_ptr/detail/lwm_nop.hpp +++ b/include/boost/smart_ptr/detail/lwm_nop.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/lwm_pthreads.hpp b/include/boost/smart_ptr/detail/lwm_pthreads.hpp index a361b13..8eda518 100644 --- a/include/boost/smart_ptr/detail/lwm_pthreads.hpp +++ b/include/boost/smart_ptr/detail/lwm_pthreads.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/lwm_win32_cs.hpp b/include/boost/smart_ptr/detail/lwm_win32_cs.hpp index f252a2b..00477e4 100644 --- a/include/boost/smart_ptr/detail/lwm_win32_cs.hpp +++ b/include/boost/smart_ptr/detail/lwm_win32_cs.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/quick_allocator.hpp b/include/boost/smart_ptr/detail/quick_allocator.hpp index d78dc70..159bd5e 100644 --- a/include/boost/smart_ptr/detail/quick_allocator.hpp +++ b/include/boost/smart_ptr/detail/quick_allocator.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index 5a0bab3..2b48cec 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_convertible.hpp b/include/boost/smart_ptr/detail/sp_convertible.hpp index 00d0b53..31b2627 100644 --- a/include/boost/smart_ptr/detail/sp_convertible.hpp +++ b/include/boost/smart_ptr/detail/sp_convertible.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp index b49c663..9ced2b9 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp index 8482ae7..6c268e8 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp index f234099..81eba6f 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp index b9f745d..545c8ae 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp index 01d21cf..2e5bc0e 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp index f2f8454..c6d20ce 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp index ad27870..173dce5 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp index b059785..5c901f9 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp index 970d954..a742c3d 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp index c32377a..56ed79f 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp @@ -2,7 +2,7 @@ #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp index a9f73da..77734e7 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp index 22802a7..fafed0e 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp index 04cb239..109deb5 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/include/boost/smart_ptr/detail/sp_counted_impl.hpp index ce5ce5a..d15cd3c 100644 --- a/include/boost/smart_ptr/detail/sp_counted_impl.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_forward.hpp b/include/boost/smart_ptr/detail/sp_forward.hpp index 5de47dd..5f1d190 100644 --- a/include/boost/smart_ptr/detail/sp_forward.hpp +++ b/include/boost/smart_ptr/detail/sp_forward.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync.hpp index fec2d20..16de21d 100644 --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp +++ b/include/boost/smart_ptr/detail/sp_has_sync.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/sp_nullptr_t.hpp b/include/boost/smart_ptr/detail/sp_nullptr_t.hpp index 1584a8f..ccbb123 100644 --- a/include/boost/smart_ptr/detail/sp_nullptr_t.hpp +++ b/include/boost/smart_ptr/detail/sp_nullptr_t.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock.hpp b/include/boost/smart_ptr/detail/spinlock.hpp index 6cff398..88d7ad6 100644 --- a/include/boost/smart_ptr/detail/spinlock.hpp +++ b/include/boost/smart_ptr/detail/spinlock.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock_nt.hpp b/include/boost/smart_ptr/detail/spinlock_nt.hpp index 41f5071..1f399d0 100644 --- a/include/boost/smart_ptr/detail/spinlock_nt.hpp +++ b/include/boost/smart_ptr/detail/spinlock_nt.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock_pool.hpp b/include/boost/smart_ptr/detail/spinlock_pool.hpp index 64a47e3..f09d5c6 100644 --- a/include/boost/smart_ptr/detail/spinlock_pool.hpp +++ b/include/boost/smart_ptr/detail/spinlock_pool.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock_pt.hpp b/include/boost/smart_ptr/detail/spinlock_pt.hpp index e5eeb54..f9cabfc 100644 --- a/include/boost/smart_ptr/detail/spinlock_pt.hpp +++ b/include/boost/smart_ptr/detail/spinlock_pt.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock_sync.hpp b/include/boost/smart_ptr/detail/spinlock_sync.hpp index 3442d11..a7145c5 100644 --- a/include/boost/smart_ptr/detail/spinlock_sync.hpp +++ b/include/boost/smart_ptr/detail/spinlock_sync.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/spinlock_w32.hpp b/include/boost/smart_ptr/detail/spinlock_w32.hpp index fac21fe..fb97629 100644 --- a/include/boost/smart_ptr/detail/spinlock_w32.hpp +++ b/include/boost/smart_ptr/detail/spinlock_w32.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index 3c8be4c..14af524 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif From 832ed079b9ca16bd3e383d6cc40d83a70f4aaa87 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 7 Dec 2013 19:24:44 +0200 Subject: [PATCH 209/210] Revert "Revert MSC_VER changes." This reverts commit 382fb54a52efba643aaa05046c2214479dee618e. --- include/boost/smart_ptr/detail/spinlock_w32.hpp | 2 +- include/boost/smart_ptr/detail/yield_k.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/detail/spinlock_w32.hpp b/include/boost/smart_ptr/detail/spinlock_w32.hpp index fb97629..57c85e1 100644 --- a/include/boost/smart_ptr/detail/spinlock_w32.hpp +++ b/include/boost/smart_ptr/detail/spinlock_w32.hpp @@ -24,7 +24,7 @@ #define BOOST_COMPILER_FENCE __memory_barrier(); -#elif defined( _MSC_VER ) && _MSC_VER >= 1310 +#elif defined( _MSC_VER ) extern "C" void _ReadWriteBarrier(); #pragma intrinsic( _ReadWriteBarrier ) diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index 14af524..686d1f0 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -27,7 +27,7 @@ // BOOST_SMT_PAUSE -#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) +#if defined(_MSC_VER) && ( defined(_M_IX86) || defined(_M_X64) ) extern "C" void _mm_pause(); From a4f853bfbc4b035701947ccf15b36f3a0cb691da Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 7 Dec 2013 19:25:05 +0200 Subject: [PATCH 210/210] Revert "SmartPtr: Remove obsolete MSVC version checks." This reverts commit 7d1c527ac010fa1e443ee8c63065b208fe9fb05d. --- include/boost/smart_ptr/detail/shared_count.hpp | 7 +++++++ .../boost/smart_ptr/detail/sp_counted_base_w32.hpp | 12 ++++++++++++ include/boost/smart_ptr/detail/spinlock_w32.hpp | 2 +- include/boost/smart_ptr/detail/yield_k.hpp | 2 +- include/boost/smart_ptr/intrusive_ptr.hpp | 6 ++++++ include/boost/smart_ptr/shared_ptr.hpp | 6 ++++++ include/boost/smart_ptr/weak_ptr.hpp | 4 ++++ 7 files changed, 37 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index 2b48cec..8e1dd48 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -148,11 +148,18 @@ public: #endif } +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) + template shared_count( Y * p, D d ): pi_(0) +#else template shared_count( P p, D d ): pi_(0) +#endif #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif { +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) + typedef Y* P; +#endif #ifndef BOOST_NO_EXCEPTIONS try diff --git a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp index 109deb5..ff394dc 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp @@ -80,7 +80,19 @@ public: { long tmp = static_cast< long const volatile& >( use_count_ ); if( tmp == 0 ) return false; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 ) + + // work around a code generation bug + + long tmp2 = tmp + 1; + if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true; + +#else + if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true; + +#endif } } diff --git a/include/boost/smart_ptr/detail/spinlock_w32.hpp b/include/boost/smart_ptr/detail/spinlock_w32.hpp index 57c85e1..fb97629 100644 --- a/include/boost/smart_ptr/detail/spinlock_w32.hpp +++ b/include/boost/smart_ptr/detail/spinlock_w32.hpp @@ -24,7 +24,7 @@ #define BOOST_COMPILER_FENCE __memory_barrier(); -#elif defined( _MSC_VER ) +#elif defined( _MSC_VER ) && _MSC_VER >= 1310 extern "C" void _ReadWriteBarrier(); #pragma intrinsic( _ReadWriteBarrier ) diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index 686d1f0..14af524 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -27,7 +27,7 @@ // BOOST_SMT_PAUSE -#if defined(_MSC_VER) && ( defined(_M_IX86) || defined(_M_X64) ) +#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) extern "C" void _mm_pause(); diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index 3cd3dc7..b6f5bcd 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -292,7 +292,13 @@ template std::ostream & operator<< (std::ostream & os, intrusive_ptr // in STLport's no-iostreams mode no iostream symbols can be used #ifndef _STLP_NO_IOSTREAMS +# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) +// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL +using std::basic_ostream; +template basic_ostream & operator<< (basic_ostream & os, intrusive_ptr const & p) +# else template std::basic_ostream & operator<< (std::basic_ostream & os, intrusive_ptr const & p) +# endif { os << p.get(); return os; diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 106e349..9259ca0 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -849,7 +849,13 @@ template std::ostream & operator<< (std::ostream & os, shared_ptr co // in STLport's no-iostreams mode no iostream symbols can be used #ifndef _STLP_NO_IOSTREAMS +# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) +// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL +using std::basic_ostream; +template basic_ostream & operator<< (basic_ostream & os, shared_ptr const & p) +# else template std::basic_ostream & operator<< (std::basic_ostream & os, shared_ptr const & p) +# endif { os << p.get(); return os; diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index cc0cdca..e3e9ad9 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -136,6 +136,8 @@ public: boost::detail::sp_assert_convertible< Y, T >(); } +#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) + template weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT { @@ -169,6 +171,8 @@ public: return *this; } +#endif + shared_ptr lock() const BOOST_NOEXCEPT { return shared_ptr( *this, boost::detail::sp_nothrow_tag() );