From 08e589451029534009bcedc37c14ba1f3465a6f5 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 5 Dec 2012 04:28:20 +0000 Subject: [PATCH] Merged revisions 81700,81703 from trunk: Add overloads of make_shared and allocate_shared for arrays for E&& where E is typename boost::detail::array_base::type ........ Update documentation and remove unused code. ........ [SVN r81716] --- .../boost/smart_ptr/allocate_shared_array.hpp | 40 +++++++++++++++++++ .../boost/smart_ptr/detail/array_deleter.hpp | 32 ++++++++++++++- .../boost/smart_ptr/detail/array_traits.hpp | 12 ++---- .../boost/smart_ptr/detail/sp_if_array.hpp | 6 +-- include/boost/smart_ptr/make_shared_array.hpp | 39 ++++++++++++++++++ make_shared_array.html | 36 ++++++++++++++++- test/allocate_shared_arrays_create_test.cpp | 27 +++++++++++++ test/make_shared_arrays_create_test.cpp | 27 +++++++++++++ 8 files changed, 203 insertions(+), 16 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 0c17edd..a98d97e 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -169,6 +169,46 @@ namespace boost { d2->construct_list(p2, p3, M); return boost::shared_ptr(s1, p1); } +#if defined(BOOST_HAS_RVALUE_REFS) + template + inline typename boost::detail::sp_if_array::type + allocate_shared(const A& allocator, std::size_t size, + typename boost::detail::array_base::type&& value) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = size * boost::detail::array_total::size; + boost::detail::allocate_array_helper a1(allocator, n1, &p2); + boost::detail::array_deleter d1(n1); + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, boost::detail::sp_forward(value)); + return boost::shared_ptr(s1, p1); + } + template + inline typename boost::detail::sp_if_size_array::type + allocate_shared(const A& allocator, + typename boost::detail::array_base::type&& value) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + enum { + N = boost::detail::array_total::size + }; + T1* p1 = 0; + T2* p2 = 0; + boost::detail::allocate_array_helper a1(allocator, &p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, boost::detail::sp_forward(value)); + return boost::shared_ptr(s1, p1); + } +#endif #endif } diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index b07b00a..40e9d57 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -38,7 +38,20 @@ namespace boost { throw; } } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if defined(BOOST_HAS_RVALUE_REFS) + void construct(T* memory, T&& value) { + std::size_t i = 0; + try { + for (object = memory; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(value); + } + } catch (...) { + destroy(i); + throw; + } + } +#if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { std::size_t i = 0; @@ -52,6 +65,7 @@ namespace boost { throw; } } +#endif #endif void construct_list(T* memory, const T* list) { std::size_t i = 0; @@ -125,7 +139,20 @@ namespace boost { throw; } } -#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) +#if defined(BOOST_HAS_RVALUE_REFS) + void construct(T* memory, T&& value) { + std::size_t i = 0; + try { + for (object = memory; i < N; i++) { + void* p1 = memory + i; + ::new(p1) T(value); + } + } catch (...) { + destroy(i); + throw; + } + } +#if defined(BOOST_HAS_VARIADIC_TMPL) template void construct(T* memory, Args&&... args) { std::size_t i = 0; @@ -139,6 +166,7 @@ namespace boost { throw; } } +#endif #endif void construct_list(T* memory, const T* list) { std::size_t i = 0; diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index 3ef482a..8ef7874 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -17,19 +17,15 @@ namespace boost { struct array_base { typedef typename boost::remove_cv::type type; }; + template + struct array_base { + typedef typename array_base::type type; + }; template struct array_base { typedef typename array_base::type type; }; template - struct array_size; - template - struct array_size { - enum { - size = N - }; - }; - template struct array_total { enum { size = 1 diff --git a/include/boost/smart_ptr/detail/sp_if_array.hpp b/include/boost/smart_ptr/detail/sp_if_array.hpp index 3ba3a0e..661e178 100644 --- a/include/boost/smart_ptr/detail/sp_if_array.hpp +++ b/include/boost/smart_ptr/detail/sp_if_array.hpp @@ -14,15 +14,13 @@ namespace boost { namespace detail { template - struct sp_if_array { - }; + struct sp_if_array; template struct sp_if_array { typedef boost::shared_ptr type; }; template - struct sp_if_size_array { - }; + struct sp_if_size_array; template struct sp_if_size_array { typedef boost::shared_ptr type; diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 89ff8f1..b4fd9f6 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -167,6 +167,45 @@ namespace boost { d2->construct_list(p2, p3, M); return boost::shared_ptr(s1, p1); } +#if defined(BOOST_HAS_RVALUE_REFS) + template + inline typename boost::detail::sp_if_array::type + make_shared(std::size_t size, + typename boost::detail::array_base::type&& value) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + T1* p1 = 0; + T2* p2 = 0; + std::size_t n1 = size * boost::detail::array_total::size; + boost::detail::make_array_helper a1(n1, &p2); + boost::detail::array_deleter d1(n1); + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, boost::detail::sp_forward(value)); + return boost::shared_ptr(s1, p1); + } + template + inline typename boost::detail::sp_if_size_array::type + make_shared(typename boost::detail::array_base::type&& value) { + typedef typename boost::detail::array_inner::type T1; + typedef typename boost::detail::array_base::type T2; + enum { + N = boost::detail::array_total::size + }; + T1* p1 = 0; + T2* p2 = 0; + boost::detail::make_array_helper a1(&p2); + boost::detail::array_deleter d1; + boost::shared_ptr s1(p1, d1, a1); + boost::detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, boost::detail::sp_forward(value)); + return boost::shared_ptr(s1, p1); + } +#endif #endif template inline typename boost::detail::sp_if_array::type diff --git a/make_shared_array.html b/make_shared_array.html index b42d28a..c1db41f 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -75,6 +75,20 @@ template<typename T, typename A, typename... Args> shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]); + +#if defined(BOOST_HAS_RVALUE_REFS) + template<typename T> + shared_ptr<T[]> make_shared(size_t size, T&& value); + + template<typename T> + shared_ptr<T[N]> make_shared(T&& value); + + template<typename T, typename A> + shared_ptr<T[]> allocate_shared(const A& allocator, size_t size, T&& value); + + template<typename T, typename A> + shared_ptr<T[N]> allocate_shared(const A& allocator, T&& value); +#endif #endif template<typename T> @@ -162,6 +176,22 @@ template<typename T, typename A, typename... Args> shared_ptr<T[M][N]> make_shared(const T (&list)[N]); template<typename T, typename A, typename... Args> shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]); +
+

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

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

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

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

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

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

History

November 2012. Glen Fernandes contributed implementations of diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index 8645179..4c53e91 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -9,6 +9,17 @@ #include #include +class type { +public: + type(int x, int y) + : x(x), y(y) { + } + const int x; + const int y; +private: + type& operator=(const type&); +}; + int main() { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) { @@ -69,6 +80,22 @@ int main() { BOOST_TEST(a1[1][1][0] == 2); BOOST_TEST(a1[1][1][1] == 3); } +#if defined(BOOST_HAS_RVALUE_REFS) + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 4, {1, 2}); + BOOST_TEST(a1[0].x == 1); + BOOST_TEST(a1[1].y == 2); + BOOST_TEST(a1[2].x == 1); + BOOST_TEST(a1[3].y == 2); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), {1, 2}); + BOOST_TEST(a1[0].x == 1); + BOOST_TEST(a1[1].y == 2); + BOOST_TEST(a1[2].x == 1); + BOOST_TEST(a1[3].y == 2); + } +#endif #endif return boost::report_errors(); } diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp index eb08759..7fc36bd 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -9,6 +9,17 @@ #include #include +class type { +public: + type(int x, int y) + : x(x), y(y) { + } + const int x; + const int y; +private: + type& operator=(const type&); +}; + int main() { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) { @@ -69,6 +80,22 @@ int main() { BOOST_TEST(a1[1][1][0] == 2); BOOST_TEST(a1[1][1][1] == 3); } +#if defined(BOOST_HAS_RVALUE_REFS) + { + boost::shared_ptr a1 = boost::make_shared(4, {1, 2}); + BOOST_TEST(a1[0].x == 1); + BOOST_TEST(a1[1].y == 2); + BOOST_TEST(a1[2].x == 1); + BOOST_TEST(a1[3].y == 2); + } + { + boost::shared_ptr a1 = boost::make_shared({1, 2}); + BOOST_TEST(a1[0].x == 1); + BOOST_TEST(a1[1].y == 2); + BOOST_TEST(a1[2].x == 1); + BOOST_TEST(a1[3].y == 2); + } +#endif #endif return boost::report_errors(); }