Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81700 - in trunk: boost/smart_ptr boost/smart_ptr/detail libs/smart_ptr libs/smart_ptr/test
From: glenfe_at_[hidden]
Date: 2012-12-04 01:06:25


Author: glenfe
Date: 2012-12-04 01:06:23 EST (Tue, 04 Dec 2012)
New Revision: 81700
URL: http://svn.boost.org/trac/boost/changeset/81700

Log:
Add overloads of make_shared and allocate_shared for arrays for E&& where E is typename boost::detail::array_base<T>::type
Text files modified:
   trunk/boost/smart_ptr/allocate_shared_array.hpp | 40 ++++++++++++++++++++++++++++++++++++++++
   trunk/boost/smart_ptr/detail/array_deleter.hpp | 32 ++++++++++++++++++++++++++++++--
   trunk/boost/smart_ptr/detail/array_traits.hpp | 4 ++++
   trunk/boost/smart_ptr/detail/sp_if_array.hpp | 6 ++----
   trunk/boost/smart_ptr/make_shared_array.hpp | 39 +++++++++++++++++++++++++++++++++++++++
   trunk/libs/smart_ptr/make_shared_array.html | 36 ++++++++++++++++++++++++++++++++++--
   trunk/libs/smart_ptr/test/allocate_shared_arrays_create_test.cpp | 27 +++++++++++++++++++++++++++
   trunk/libs/smart_ptr/test/make_shared_arrays_create_test.cpp | 27 +++++++++++++++++++++++++++
   8 files changed, 203 insertions(+), 8 deletions(-)

Modified: trunk/boost/smart_ptr/allocate_shared_array.hpp
==============================================================================
--- trunk/boost/smart_ptr/allocate_shared_array.hpp (original)
+++ trunk/boost/smart_ptr/allocate_shared_array.hpp 2012-12-04 01:06:23 EST (Tue, 04 Dec 2012)
@@ -169,6 +169,46 @@
         d2->construct_list(p2, p3, M);
         return boost::shared_ptr<T>(s1, p1);
     }
+#if defined(BOOST_HAS_RVALUE_REFS)
+ template<typename T, typename A>
+ inline typename boost::detail::sp_if_array<T>::type
+ allocate_shared(const A& allocator, std::size_t size,
+ typename boost::detail::array_base<T>::type&& value) {
+ typedef typename boost::detail::array_inner<T>::type T1;
+ typedef typename boost::detail::array_base<T1>::type T2;
+ T1* p1 = 0;
+ T2* p2 = 0;
+ std::size_t n1 = size * boost::detail::array_total<T1>::size;
+ boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
+ boost::detail::array_deleter<T2[]> d1(n1);
+ boost::shared_ptr<T> s1(p1, d1, a1);
+ boost::detail::array_deleter<T2[]>* d2;
+ p1 = reinterpret_cast<T1*>(p2);
+ d2 = get_deleter<boost::detail::array_deleter<T2[]> >(s1);
+ d2->construct(p2, boost::detail::sp_forward<T2>(value));
+ return boost::shared_ptr<T>(s1, p1);
+ }
+ template<typename T, typename A>
+ inline typename boost::detail::sp_if_size_array<T>::type
+ allocate_shared(const A& allocator,
+ typename boost::detail::array_base<T>::type&& value) {
+ typedef typename boost::detail::array_inner<T>::type T1;
+ typedef typename boost::detail::array_base<T1>::type T2;
+ enum {
+ N = boost::detail::array_total<T>::size
+ };
+ T1* p1 = 0;
+ T2* p2 = 0;
+ boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
+ boost::detail::array_deleter<T2[N]> d1;
+ boost::shared_ptr<T> s1(p1, d1, a1);
+ boost::detail::array_deleter<T2[N]>* d2;
+ p1 = reinterpret_cast<T1*>(p2);
+ d2 = get_deleter<boost::detail::array_deleter<T2[N]> >(s1);
+ d2->construct(p2, boost::detail::sp_forward<T2>(value));
+ return boost::shared_ptr<T>(s1, p1);
+ }
+#endif
 #endif
 }
 

Modified: trunk/boost/smart_ptr/detail/array_deleter.hpp
==============================================================================
--- trunk/boost/smart_ptr/detail/array_deleter.hpp (original)
+++ trunk/boost/smart_ptr/detail/array_deleter.hpp 2012-12-04 01:06:23 EST (Tue, 04 Dec 2012)
@@ -38,7 +38,20 @@
                     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<typename... Args>
             void construct(T* memory, Args&&... args) {
                 std::size_t i = 0;
@@ -53,6 +66,7 @@
                 }
             }
 #endif
+#endif
             void construct_list(T* memory, const T* list) {
                 std::size_t i = 0;
                 try {
@@ -125,7 +139,20 @@
                     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<typename... Args>
             void construct(T* memory, Args&&... args) {
                 std::size_t i = 0;
@@ -140,6 +167,7 @@
                 }
             }
 #endif
+#endif
             void construct_list(T* memory, const T* list) {
                 std::size_t i = 0;
                 try {

Modified: trunk/boost/smart_ptr/detail/array_traits.hpp
==============================================================================
--- trunk/boost/smart_ptr/detail/array_traits.hpp (original)
+++ trunk/boost/smart_ptr/detail/array_traits.hpp 2012-12-04 01:06:23 EST (Tue, 04 Dec 2012)
@@ -17,6 +17,10 @@
         struct array_base {
             typedef typename boost::remove_cv<T>::type type;
         };
+ template<typename T>
+ struct array_base<T[]> {
+ typedef typename array_base<T>::type type;
+ };
         template<typename T, std::size_t N>
         struct array_base<T[N]> {
             typedef typename array_base<T>::type type;

Modified: trunk/boost/smart_ptr/detail/sp_if_array.hpp
==============================================================================
--- trunk/boost/smart_ptr/detail/sp_if_array.hpp (original)
+++ trunk/boost/smart_ptr/detail/sp_if_array.hpp 2012-12-04 01:06:23 EST (Tue, 04 Dec 2012)
@@ -14,15 +14,13 @@
 namespace boost {
     namespace detail {
         template<typename T>
- struct sp_if_array {
- };
+ struct sp_if_array;
         template<typename T>
         struct sp_if_array<T[]> {
             typedef boost::shared_ptr<T[]> type;
         };
         template<typename T>
- struct sp_if_size_array {
- };
+ struct sp_if_size_array;
         template<typename T, std::size_t N>
         struct sp_if_size_array<T[N]> {
             typedef boost::shared_ptr<T[N]> type;

Modified: trunk/boost/smart_ptr/make_shared_array.hpp
==============================================================================
--- trunk/boost/smart_ptr/make_shared_array.hpp (original)
+++ trunk/boost/smart_ptr/make_shared_array.hpp 2012-12-04 01:06:23 EST (Tue, 04 Dec 2012)
@@ -167,6 +167,45 @@
         d2->construct_list(p2, p3, M);
         return boost::shared_ptr<T>(s1, p1);
     }
+#if defined(BOOST_HAS_RVALUE_REFS)
+ template<typename T>
+ inline typename boost::detail::sp_if_array<T>::type
+ make_shared(std::size_t size,
+ typename boost::detail::array_base<T>::type&& value) {
+ typedef typename boost::detail::array_inner<T>::type T1;
+ typedef typename boost::detail::array_base<T1>::type T2;
+ T1* p1 = 0;
+ T2* p2 = 0;
+ std::size_t n1 = size * boost::detail::array_total<T1>::size;
+ boost::detail::make_array_helper<T2[]> a1(n1, &p2);
+ boost::detail::array_deleter<T2[]> d1(n1);
+ boost::shared_ptr<T> s1(p1, d1, a1);
+ boost::detail::array_deleter<T2[]>* d2;
+ p1 = reinterpret_cast<T1*>(p2);
+ d2 = get_deleter<boost::detail::array_deleter<T2[]> >(s1);
+ d2->construct(p2, boost::detail::sp_forward<T2>(value));
+ return boost::shared_ptr<T>(s1, p1);
+ }
+ template<typename T>
+ inline typename boost::detail::sp_if_size_array<T>::type
+ make_shared(typename boost::detail::array_base<T>::type&& value) {
+ typedef typename boost::detail::array_inner<T>::type T1;
+ typedef typename boost::detail::array_base<T1>::type T2;
+ enum {
+ N = boost::detail::array_total<T>::size
+ };
+ T1* p1 = 0;
+ T2* p2 = 0;
+ boost::detail::make_array_helper<T2[N]> a1(&p2);
+ boost::detail::array_deleter<T2[N]> d1;
+ boost::shared_ptr<T> s1(p1, d1, a1);
+ boost::detail::array_deleter<T2[N]>* d2;
+ p1 = reinterpret_cast<T1*>(p2);
+ d2 = get_deleter<boost::detail::array_deleter<T2[N]> >(s1);
+ d2->construct(p2, boost::detail::sp_forward<T2>(value));
+ return boost::shared_ptr<T>(s1, p1);
+ }
+#endif
 #endif
     template<typename T>
     inline typename boost::detail::sp_if_array<T>::type

Modified: trunk/libs/smart_ptr/make_shared_array.html
==============================================================================
--- trunk/libs/smart_ptr/make_shared_array.html (original)
+++ trunk/libs/smart_ptr/make_shared_array.html 2012-12-04 01:06:23 EST (Tue, 04 Dec 2012)
@@ -75,6 +75,20 @@
 
     template&lt;typename T, typename A, typename... Args&gt;
     shared_ptr&lt;T[M][N]&gt; allocate_shared(const A&amp; allocator, const T (&amp;list)[N]);
+
+#if defined(BOOST_HAS_RVALUE_REFS)
+ template&lt;typename T&gt;
+ shared_ptr&lt;T[]&gt; make_shared(size_t size, T&amp;&amp; value);
+
+ template&lt;typename T&gt;
+ shared_ptr&lt;T[N]&gt; make_shared(T&amp;&amp; value);
+
+ template&lt;typename T, typename A&gt;
+ shared_ptr&lt;T[]&gt; allocate_shared(const A&amp; allocator, size_t size, T&amp;&amp; value);
+
+ template&lt;typename T, typename A&gt;
+ shared_ptr&lt;T[N]&gt; allocate_shared(const A&amp; allocator, T&amp;&amp; value);
+#endif
 #endif
 
     template&lt;typename T&gt;
@@ -165,6 +179,22 @@
     <blockquote>
       <p><b>Description:</b> These overloads of the utilities above are for a
         fixed size array.</p>
+ </blockquote>
+ <pre>template&lt;typename T&gt;
+ shared_ptr&lt;T[]&gt; make_shared(size_t size, T&amp;&amp; value);
+template&lt;typename T, typename A&gt;
+ shared_ptr&lt;T[]&gt; allocate_shared(const A&amp; allocator, size_t size, T&amp;&amp; value);</pre>
+ <blockquote>
+ <p><b>Description:</b> These overloads initialize array elements with
+ the given value.</p>
+ </blockquote>
+ <pre>template&lt;typename T&gt;
+ shared_ptr&lt;T[N]&gt; make_shared(T&amp;&amp; value);
+template&lt;typename T, typename A&gt;
+ shared_ptr&lt;T[N]&gt; allocate_shared(const A&amp; allocator, T&amp;&amp; value);</pre>
+ <blockquote>
+ <p><b>Description:</b> These overloads of the utilities above are for a
+ fixed size array.</p>
     </blockquote>
     <pre>template&lt;typename T&gt;
     shared_ptr&lt;T[]&gt; make_shared_noinit(size_t size);</pre>
@@ -188,8 +218,10 @@
 boost::shared_ptr&lt;int[3]&gt; a5 = boost::make_shared&lt;int[3]&gt;({1, 2, 3});
 boost::shared_ptr&lt;int[][3]&gt; a6 = boost::make_shared&lt;int[][3]&gt;(size, {1, 2, 3});
 boost::shared_ptr&lt;int[5][3]&gt; a7 = boost::make_shared&lt;int[5][3]&gt;({1, 2, 3});
-boost::shared_ptr&lt;int[]&gt; a8 = boost::make_shared_noinit&lt;int[]&gt;(size);
-boost::shared_ptr&lt;int[5]&gt; a9 = boost::make_shared_noinit&lt;int[5]&gt;();</pre>
+boost::shared_ptr&lt;point[]&gt; a8 = boost::make_shared&lt;point[]&gt;(4, {x, y});
+boost::shared_ptr&lt;point[4]&gt; a9 = boost::make_shared&lt;point[4]&gt;({x, y});
+boost::shared_ptr&lt;int[]&gt; a10 = boost::make_shared_noinit&lt;int[]&gt;(size);
+boost::shared_ptr&lt;int[5]&gt; a11 = boost::make_shared_noinit&lt;int[5]&gt;();</pre>
     </blockquote>
     <h2><a name="history">History</a></h2>
     <p>November 2012. Glen Fernandes contributed implementations of

Modified: trunk/libs/smart_ptr/test/allocate_shared_arrays_create_test.cpp
==============================================================================
--- trunk/libs/smart_ptr/test/allocate_shared_arrays_create_test.cpp (original)
+++ trunk/libs/smart_ptr/test/allocate_shared_arrays_create_test.cpp 2012-12-04 01:06:23 EST (Tue, 04 Dec 2012)
@@ -9,6 +9,17 @@
 #include <boost/detail/lightweight_test.hpp>
 #include <boost/smart_ptr/allocate_shared_array.hpp>
 
+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 @@
         BOOST_TEST(a1[1][1][0] == 2);
         BOOST_TEST(a1[1][1][1] == 3);
     }
+#if defined(BOOST_HAS_RVALUE_REFS)
+ {
+ boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 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<type[4]> a1 = boost::allocate_shared<type[4]>(std::allocator<type>(), {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();
 }

Modified: trunk/libs/smart_ptr/test/make_shared_arrays_create_test.cpp
==============================================================================
--- trunk/libs/smart_ptr/test/make_shared_arrays_create_test.cpp (original)
+++ trunk/libs/smart_ptr/test/make_shared_arrays_create_test.cpp 2012-12-04 01:06:23 EST (Tue, 04 Dec 2012)
@@ -9,6 +9,17 @@
 #include <boost/detail/lightweight_test.hpp>
 #include <boost/smart_ptr/make_shared_array.hpp>
 
+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 @@
         BOOST_TEST(a1[1][1][0] == 2);
         BOOST_TEST(a1[1][1][1] == 3);
     }
+#if defined(BOOST_HAS_RVALUE_REFS)
+ {
+ boost::shared_ptr<type[]> a1 = boost::make_shared<type[]>(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<type[4]> a1 = boost::make_shared<type[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);
+ }
+#endif
 #endif
     return boost::report_errors();
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk