From ecceb710de2c175a4f125f5ab83ad05cc42db124 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 11 Dec 2012 17:42:47 +0000 Subject: [PATCH] Add overloads of allocate_shared_noinit to complement make_shared_noinit [SVN r81858] --- .../boost/smart_ptr/allocate_shared_array.hpp | 36 +++++++++ make_shared_array.html | 14 +++- test/allocate_shared_array_esft_test.cpp | 10 +++ test/allocate_shared_array_test.cpp | 74 +++++++++++++++++++ test/allocate_shared_array_throws_test.cpp | 14 ++++ test/allocate_shared_arrays_test.cpp | 56 ++++++++++++++ 6 files changed, 202 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index dc24ca2..9aaacc7 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -209,6 +209,42 @@ namespace boost { } #endif #endif + template + inline typename boost::detail::sp_if_array::type + allocate_shared_noinit(const A& allocator, std::size_t size) { + 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_noinit(p2); + return boost::shared_ptr(s1, p1); + } + template + inline typename boost::detail::sp_if_size_array::type + allocate_shared_noinit(const A& allocator) { + 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_noinit(p2); + return boost::shared_ptr(s1, p1); + } } #endif diff --git a/make_shared_array.html b/make_shared_array.html index c1db41f..6f34519 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -96,6 +96,12 @@ template<typename T> shared_ptr<T[N]> make_shared_noinit(); + + template<typename T, typename A> + shared_ptr<T[]> allocate_shared_noinit(const A& allocator, size_t size); + + template<typename T, typename A> + shared_ptr<T[N]> allocate_shared_noinit(const A& allocator); }

Free Functions

template<typename T, typename... Args>
@@ -197,13 +203,17 @@ template<typename T, typename A>
         fixed size array.

template<typename T>
-    shared_ptr<T[]> make_shared_noinit(size_t size);
+ shared_ptr<T[]> make_shared_noinit(size_t size); +template<typename T, typename A> + shared_ptr<T[]> make_shared_noinit(const A& allocator, size_t size);

Description: This overload does not perform value initialization of elements.

template<typename T>
-    shared_ptr<T[N]> make_shared_noinit();
+ shared_ptr<T[N]> make_shared_noinit(); +template<typename T, typename A> + shared_ptr<T[N]> make_shared_noinit(const A& allocator);

Description: This overload of the utility above is used for a fixed size array.

diff --git a/test/allocate_shared_array_esft_test.cpp b/test/allocate_shared_array_esft_test.cpp index 2315421..cea73c6 100644 --- a/test/allocate_shared_array_esft_test.cpp +++ b/test/allocate_shared_array_esft_test.cpp @@ -38,5 +38,15 @@ int main() { BOOST_TEST(type::instances == 3); } } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 3); + try { + a1[0].shared_from_this(); + BOOST_ERROR("shared_from_this did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 3); + } + } return boost::report_errors(); } diff --git a/test/allocate_shared_array_test.cpp b/test/allocate_shared_array_test.cpp index 91f3fb5..84ef3a8 100644 --- a/test/allocate_shared_array_test.cpp +++ b/test/allocate_shared_array_test.cpp @@ -121,5 +121,79 @@ int main() { BOOST_TEST(type::instances == 0); } #endif + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 3); + int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + } + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + } + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 3); + const int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + } + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + const int* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 3); + type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = a1; + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = a1; + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 3); + const type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + const type* a2 = a1.get(); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a2 != 0); + BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); + BOOST_TEST(type::instances == 3); + a1.reset(); + BOOST_TEST(type::instances == 0); + } return boost::report_errors(); } diff --git a/test/allocate_shared_array_throws_test.cpp b/test/allocate_shared_array_throws_test.cpp index 65a7985..d300f2c 100644 --- a/test/allocate_shared_array_throws_test.cpp +++ b/test/allocate_shared_array_throws_test.cpp @@ -59,5 +59,19 @@ int main() { BOOST_TEST(type::instances == 0); } #endif + BOOST_TEST(type::instances == 0); + try { + boost::allocate_shared_noinit(std::allocator(), 6); + BOOST_ERROR("allocate_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + try { + boost::allocate_shared_noinit(std::allocator(), 3); + BOOST_ERROR("allocate_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } return boost::report_errors(); } diff --git a/test/allocate_shared_arrays_test.cpp b/test/allocate_shared_arrays_test.cpp index ab22c23..7c719ce 100644 --- a/test/allocate_shared_arrays_test.cpp +++ b/test/allocate_shared_arrays_test.cpp @@ -100,5 +100,61 @@ int main() { BOOST_TEST(type::instances == 0); } #endif + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } + BOOST_TEST(type::instances == 0); + { + boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type::instances == 8); + a1.reset(); + BOOST_TEST(type::instances == 0); + } return boost::report_errors(); }