From c7b6e56b30beb587f2693e9748740a8faf15d83a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 21 Nov 2012 15:38:06 +0000 Subject: [PATCH] Merged revision(s) 81368, 81399, 81407-81409, 81419, 81430-81431, 81437 from trunk: Apply BOOST_NOEXCEPT patch. Refs #7523. ........ Replace std::forward with detail::sp_forward. ........ Cosmetic changes in make_shared_array.hpp and allocate_shared_array.hpp ........ Documentation of make_shared_array: Minor corrections ........ Make make_shared_array.hpp and allocate_shared_array.hpp consistent with namespace qualification in rest of smart_ptr. ........ Update smart_ptr.htm with link to make_shared_array.htm which lists the many overloads of make_shared and allocate_shared for arrays. ........ Update documentation for make_shared and allocate_shared array forms. ........ Minor corrections in make_shared_array.html documentation. ........ Borland fixes. ........ [SVN r81457] --- .../boost/smart_ptr/allocate_shared_array.hpp | 159 +++++++------- .../detail/allocate_array_helper.hpp | 4 +- .../smart_ptr/detail/make_array_helper.hpp | 2 +- .../boost/smart_ptr/detail/operator_bool.hpp | 10 +- include/boost/smart_ptr/detail/sp_forward.hpp | 39 ++++ .../smart_ptr/enable_shared_from_this.hpp | 8 +- include/boost/smart_ptr/intrusive_ptr.hpp | 12 +- include/boost/smart_ptr/make_shared_array.hpp | 199 +++++++++--------- .../boost/smart_ptr/make_shared_object.hpp | 22 +- 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 | 92 +++++--- include/boost/smart_ptr/weak_ptr.hpp | 41 ++-- make_shared_array.html | 106 ++++++++-- smart_ptr.htm | 11 + 16 files changed, 448 insertions(+), 317 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..e6fa081 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include @@ -20,146 +21,146 @@ 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, std::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, std::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/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/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/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_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 70083b1..36e0ddd 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include @@ -20,178 +21,178 @@ 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, std::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, std::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); } } diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp index 3872909..c6e28aa 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 @@ -67,12 +68,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,26 +87,17 @@ public: destroy(); } - void * address() + void * address() BOOST_NOEXCEPT { return storage_.data_; } - void set_initialized() + void set_initialized() BOOST_NOEXCEPT { 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; @@ -117,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/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 f9fe0d3..6f4064b 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 @@ -324,7 +340,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 +374,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 +390,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 +409,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 +499,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 +508,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 +542,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 +558,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 +566,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 +581,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 +606,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 +630,7 @@ public: return px[ i ]; } - element_type * get() const // never throws + element_type * get() const BOOST_NOEXCEPT { return px; } @@ -616,28 +638,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 +669,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 +692,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 +706,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 +763,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 +876,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 +955,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); } diff --git a/make_shared_array.html b/make_shared_array.html index 9c46926..2c0d5fc 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, @@ -32,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); - + 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 @@ -50,40 +52,40 @@ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template<typename T, typename... Args> shared_ptr<T[]> make_shared(initializer_list<T> list); - + template<typename T, typename... Args> shared_ptr<T[N]> make_shared(initializer_list<T> list); - + template<typename T, typename... Args> shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T> list); - + template<typename T, typename... 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); - + template<typename T, typename A, typename... Args> shared_ptr<T[N]> allocate_shared(const A& allocator, initializer_list<T> list); - + template<typename T, typename A, typename... Args> shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list); - + 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> - 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(); }

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,16 +124,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);
+
+

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> list);
+template<typename T, typename A, typename... Args>
+    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> list);
+template<typename T, typename A, typename... Args>
+    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.

+
+
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

-
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]>();
+
+

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 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