From 3d50db11b90de858efc2c8864ed3f113a3ec18b2 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 9 Nov 2012 06:17:05 +0000 Subject: [PATCH] Add C++11 initializer list support for make_shared and allocate_shared array forms. [SVN r81257] --- .../boost/smart_ptr/allocate_shared_array.hpp | 22 +++++++++++++++++++ .../boost/smart_ptr/detail/array_deleter.hpp | 8 +++++++ .../boost/smart_ptr/detail/array_traits.hpp | 18 +++++++++++++++ include/boost/smart_ptr/make_shared_array.hpp | 22 +++++++++++++++++++ test/allocate_shared_array_create_test.cpp | 16 ++++++++++++++ test/make_shared_array_create_test.cpp | 16 ++++++++++++++ 6 files changed, 102 insertions(+) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 25c366e..f83c6e3 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -52,6 +52,28 @@ namespace boost { return shared_ptr(s1, p1); } #endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + inline typename detail::sp_if_array::type + allocate_shared(const A& allocator, size_t size, typename detail::array_list::type list) { + typedef typename shared_ptr::element_type T1; + typedef typename detail::array_type::type T2; + typedef const T1* L1; + typedef const T2* L2; + T1* p1 = 0; + T2* p2 = 0; + L1 l1 = list.begin(); + size_t n1 = size * detail::array_size::size; + detail::allocate_array_helper a1(allocator, n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, n1, L2(l1)); + return 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 05a9991..70d7479 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -37,6 +37,14 @@ namespace boost { ::new(p1) T(args...); } } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void construct(T* memory, std::size_t count, const T* list) { + for (object = memory; size < count; size++) { + void* p1 = object + size; + ::new(p1) T(list[size]); + } + } #endif void construct_noinit(T* memory, std::size_t count) { for (object = memory; size < count; size++) { diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index 46b9933..ba22f61 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -10,6 +10,9 @@ #define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif namespace boost { namespace detail { @@ -17,22 +20,37 @@ namespace boost { struct array_type { typedef typename boost::remove_cv::type type; }; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct array_type { typedef typename array_type::type type; }; +#endif template struct array_size { enum { size = 1 }; }; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct array_size { enum { size = N * array_size::size }; }; +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + struct array_list { + }; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + template + struct array_list { + typedef std::initializer_list type; + }; +#endif +#endif } } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 1a9c7f9..b19edf4 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -51,6 +51,28 @@ namespace boost { d2->construct(p2, n1, std::forward(args)...); return shared_ptr(s1, p1); } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + inline typename detail::sp_if_array::type + make_shared(std::size_t size, typename detail::array_list::type list) { + typedef typename shared_ptr::element_type T1; + typedef typename detail::array_type::type T2; + typedef const T1* L1; + typedef const T2* L2; + T1* p1 = 0; + T2* p2 = 0; + L1 l1 = list.begin(); + size_t n1 = size * detail::array_size::size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct(p2, n1, L2(l1)); + return shared_ptr(s1, p1); + } #endif template inline typename detail::sp_if_array::type diff --git a/test/allocate_shared_array_create_test.cpp b/test/allocate_shared_array_create_test.cpp index 4b45518..5c3f831 100644 --- a/test/allocate_shared_array_create_test.cpp +++ b/test/allocate_shared_array_create_test.cpp @@ -73,6 +73,22 @@ int main() { BOOST_TEST(a1[0][1][0][0].f == 0); BOOST_TEST(a1[1][0][0][0].i == 0); } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 4, { 0, 1, 2, 3 }); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 1); + BOOST_TEST(a1[2] == 2); + BOOST_TEST(a1[3] == 3); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, { {0, 1}, {2, 3} }); + BOOST_TEST(a1[0][0] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 2); + BOOST_TEST(a1[1][1] == 3); + } #endif return boost::report_errors(); } diff --git a/test/make_shared_array_create_test.cpp b/test/make_shared_array_create_test.cpp index 6d1ef71..7510585 100644 --- a/test/make_shared_array_create_test.cpp +++ b/test/make_shared_array_create_test.cpp @@ -73,6 +73,22 @@ int main() { BOOST_TEST(a1[0][1][0][0].f == 0); BOOST_TEST(a1[1][0][0][0].i == 0); } +#endif +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + { + boost::shared_ptr a1 = boost::make_shared(4, { 0, 1, 2, 3 }); + BOOST_TEST(a1[0] == 0); + BOOST_TEST(a1[1] == 1); + BOOST_TEST(a1[2] == 2); + BOOST_TEST(a1[3] == 3); + } + { + boost::shared_ptr a1 = boost::make_shared(2, { {0, 1}, {2, 3} }); + BOOST_TEST(a1[0][0] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 2); + BOOST_TEST(a1[1][1] == 3); + } #endif return boost::report_errors(); }