$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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<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>
@@ -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<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);</pre>
+    <blockquote>
+      <p><b>Description:</b> These overloads initialize array elements with  
+        the given value.</p>
+    </blockquote>
+    <pre>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);</pre>
+    <blockquote>
+      <p><b>Description:</b> These overloads of the utilities above are for a 
+        fixed size array.</p>
     </blockquote>
     <pre>template<typename T>
     shared_ptr<T[]> make_shared_noinit(size_t size);</pre>
@@ -188,8 +218,10 @@
 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]>();</pre>
+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]>();</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();
 }