diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index c3ca93e..cb29bf6 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -18,12 +18,12 @@ namespace boost { template inline typename detail::sp_if_array::type - allocate_shared(const A& allocator, size_t size) { + allocate_shared(const A& allocator, std::size_t size) { typedef typename detail::array_inner::type T1; typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - size_t n1 = size * detail::array_total::size; + std::size_t n1 = size * detail::array_total::size; detail::allocate_array_helper a1(allocator, n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -36,12 +36,12 @@ namespace boost { #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) template inline typename detail::sp_if_array::type - allocate_shared(const A& allocator, size_t size, Args&&... args) { + allocate_shared(const A& allocator, std::size_t size, Args&&... args) { typedef typename detail::array_inner::type T1; typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - size_t n1 = size * detail::array_total::size; + std::size_t n1 = size * detail::array_total::size; detail::allocate_array_helper a1(allocator, n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -58,7 +58,7 @@ namespace boost { typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - size_t n1 = detail::array_total::size; + std::size_t n1 = detail::array_total::size; detail::allocate_array_helper a1(allocator, n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -79,7 +79,7 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - size_t n1 = list.size() * detail::array_total::size; + std::size_t n1 = list.size() * detail::array_total::size; detail::allocate_array_helper a1(allocator, n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -87,7 +87,7 @@ namespace boost { p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, p3); + d2->construct_list(p2, n1, p3); return shared_ptr(s1, p1); } template @@ -100,7 +100,7 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - size_t n1 = detail::array_total::size; + std::size_t n1 = detail::array_total::size; detail::allocate_array_helper a1(allocator, n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -108,7 +108,28 @@ namespace boost { p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, p3); + d2->construct_list(p2, n1, p3); + return shared_ptr(s1, p1); + } + template + inline typename detail::sp_if_array::type + allocate_shared(const A& allocator, std::size_t size, typename detail::inner_list::type list) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + typedef const T2 T3; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n0 = detail::array_total::size; + std::size_t n1 = n0 * list.size(); + detail::allocate_array_helper a1(allocator, n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p3 = reinterpret_cast(list.begin()); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, n1, p3, n0); return shared_ptr(s1, p1); } #endif diff --git a/include/boost/smart_ptr/detail/allocate_array_helper.hpp b/include/boost/smart_ptr/detail/allocate_array_helper.hpp index 3314e6c..bfb4dec 100644 --- a/include/boost/smart_ptr/detail/allocate_array_helper.hpp +++ b/include/boost/smart_ptr/detail/allocate_array_helper.hpp @@ -10,7 +10,6 @@ #define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP #include -#include namespace boost { namespace detail { diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 70d7479..273dcac 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -39,12 +39,18 @@ namespace boost { } #endif #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void construct(T* memory, std::size_t count, const T* list) { + void construct_list(T* memory, std::size_t count, const T* list) { for (object = memory; size < count; size++) { void* p1 = object + size; ::new(p1) T(list[size]); } } + void construct_list(T* memory, std::size_t count, const T* list, std::size_t n) { + for (object = memory; size < count; size++) { + void* p1 = object + size; + ::new(p1) T(list[size % n]); + } + } #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 6343f71..14bdf01 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -68,6 +68,13 @@ namespace boost { struct array_list { typedef std::initializer_list type; }; + template + struct inner_list { + }; + template + struct inner_list { + typedef std::initializer_list type; + }; #endif } } diff --git a/include/boost/smart_ptr/detail/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp index 34cc2e7..96fa3f9 100644 --- a/include/boost/smart_ptr/detail/make_array_helper.hpp +++ b/include/boost/smart_ptr/detail/make_array_helper.hpp @@ -10,7 +10,6 @@ #define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP #include -#include namespace boost { namespace detail { diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 9e96412..7cb9e7a 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -23,7 +23,7 @@ namespace boost { typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - size_t n1 = size * detail::array_total::size; + std::size_t n1 = size * detail::array_total::size; detail::make_array_helper a1(n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -41,7 +41,7 @@ namespace boost { typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - size_t n1 = size * detail::array_total::size; + std::size_t n1 = size * detail::array_total::size; detail::make_array_helper a1(n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -58,7 +58,7 @@ namespace boost { typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - size_t n1 = detail::array_total::size; + std::size_t n1 = detail::array_total::size; detail::make_array_helper a1(n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -79,7 +79,7 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - size_t n1 = list.size() * detail::array_total::size; + std::size_t n1 = list.size() * detail::array_total::size; detail::make_array_helper a1(n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -87,7 +87,7 @@ namespace boost { p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, p3); + d2->construct_list(p2, n1, p3); return shared_ptr(s1, p1); } template @@ -100,7 +100,7 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; T3* p3 = 0; - size_t n1 = detail::array_total::size; + std::size_t n1 = detail::array_total::size; detail::make_array_helper a1(n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -108,7 +108,28 @@ namespace boost { p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); - d2->construct(p2, n1, p3); + d2->construct_list(p2, n1, p3); + return shared_ptr(s1, p1); + } + template + inline typename detail::sp_if_array::type + make_shared(std::size_t size, typename detail::inner_list::type list) { + typedef typename detail::array_inner::type T1; + typedef typename detail::array_base::type T2; + typedef const T2 T3; + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = 0; + std::size_t n0 = detail::array_total::size; + std::size_t n1 = n0 * size; + detail::make_array_helper a1(n1, &p2); + detail::array_deleter d1; + shared_ptr s1(p1, d1, a1); + detail::array_deleter* d2; + p3 = reinterpret_cast(list.begin()); + p1 = reinterpret_cast(p2); + d2 = get_deleter >(s1); + d2->construct_list(p2, n1, p3, n0); return shared_ptr(s1, p1); } #endif @@ -119,7 +140,7 @@ namespace boost { typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - size_t n1 = size * detail::array_total::size; + std::size_t n1 = size * detail::array_total::size; detail::make_array_helper a1(n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); @@ -136,7 +157,7 @@ namespace boost { typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; - size_t n1 = detail::array_total::size; + std::size_t n1 = detail::array_total::size; detail::make_array_helper a1(n1, &p2); detail::array_deleter d1; shared_ptr s1(p1, d1, a1); diff --git a/make_shared_array.html b/make_shared_array.html index 5553f41..4739b3a 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -49,16 +49,22 @@ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template<typename T, typename... Args> - shared_ptr<T[]> make_shared(std::initializer_list<T> list); + shared_ptr<T[]> make_shared(initializer_list<T> list); template<typename T, typename... Args> - shared_ptr<T[N]> make_shared(std::initializer_list<T> list); + shared_ptr<T[N]> make_shared(initializer_list<T> list); + + template<typename T, typename... Args> + shared_ptr<T[][N]> make_shared(size_t size, initializer_list<T> list); template<typename T, typename A, typename... Args> - shared_ptr<T[]> allocate_shared(const A& allocator, std::initializer_list<T> list); + shared_ptr<T[]> allocate_shared(const A& allocator, initializer_list<T> list); template<typename T, typename A, typename... Args> - shared_ptr<T[N]> allocate_shared(const A& allocator, std::initializer_list<T> list); + shared_ptr<T[N]> allocate_shared(const A& allocator, initializer_list<T> list); + + template<typename T, typename A, typename... Args> + shared_ptr<T[][N]> allocate_shared(const A& allocator, size_t size, initializer_list<T> list); #endif template<typename T> @@ -74,7 +80,7 @@ template<typename T, typename A, typename... Args> shared_ptr<T> allocate_shared(const A& allocator, size_t size, Args&&... args);

Requires: The expression - new(pointer) T(std::forward<Args>(args)...), where + new(pointer) T(forward<Args>(args)...), where pointer is a void* pointing to storage suitable to hold an object of type T, shall be well-formed. A shall be an Allocator, as @@ -85,7 +91,7 @@ template<typename T, typename A, typename... Args> T and size size and constructs an array of objects in it via the placement new expression new(pointer) T() or - new(pointer) T(std::forward<Args>(args)...). + new(pointer) T(forward<Args>(args)...). allocate_shared uses a copy of allocator to allocate memory. If an exception is thrown, has no effect.

diff --git a/test/allocate_shared_arrays_create_test.cpp b/test/allocate_shared_arrays_create_test.cpp index d88a428..fd44aa0 100644 --- a/test/allocate_shared_arrays_create_test.cpp +++ b/test/allocate_shared_arrays_create_test.cpp @@ -25,6 +25,20 @@ int main() { BOOST_TEST(a1[1][0] == 2); BOOST_TEST(a1[1][1] == 3); } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, {0, 1}); + BOOST_TEST(a1[0][0] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 0); + BOOST_TEST(a1[1][1] == 1); + } + { + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, { {0, 1}, {2, 3} }); + BOOST_TEST(a1[0][0][0] == 0); + BOOST_TEST(a1[0][0][1] == 1); + BOOST_TEST(a1[1][1][0] == 2); + BOOST_TEST(a1[1][1][1] == 3); + } #endif return boost::report_errors(); } diff --git a/test/make_shared_arrays_create_test.cpp b/test/make_shared_arrays_create_test.cpp index 5e773a5..b5b96d5 100644 --- a/test/make_shared_arrays_create_test.cpp +++ b/test/make_shared_arrays_create_test.cpp @@ -8,6 +8,7 @@ */ #include #include +#include int main() { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -25,6 +26,20 @@ int main() { BOOST_TEST(a1[1][0] == 2); BOOST_TEST(a1[1][1] == 3); } + { + boost::shared_ptr a1 = boost::make_shared(2, {0, 1}); + BOOST_TEST(a1[0][0] == 0); + BOOST_TEST(a1[0][1] == 1); + BOOST_TEST(a1[1][0] == 0); + BOOST_TEST(a1[1][1] == 1); + } + { + boost::shared_ptr a1 = boost::make_shared(2, { {0, 1}, {2, 3} }); + BOOST_TEST(a1[0][0][0] == 0); + BOOST_TEST(a1[0][0][1] == 1); + BOOST_TEST(a1[1][1][0] == 2); + BOOST_TEST(a1[1][1][1] == 3); + } #endif return boost::report_errors(); }