|
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<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();
}
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