/* * Copyright (c) 2012 Glen Joseph Fernandes * glenfe at live dot com * * Distributed under the Boost Software License, * Version 1.0. (See accompanying file LICENSE_1_0.txt * or copy at http://boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #include #include #include #include #include #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include #endif namespace boost { template inline typename detail::sp_if_array::type 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; 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); detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); d2->construct(p2, n1); return shared_ptr(s1, p1); } #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS) template inline typename detail::sp_if_array::type 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; 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); detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); d2->construct(p2, n1, std::forward(args)...); return shared_ptr(s1, p1); } template inline typename detail::sp_if_size_array::type allocate_shared(const A& allocator, Args&&... args) { typedef typename detail::array_inner::type T1; typedef typename detail::array_base::type T2; T1* p1 = 0; T2* p2 = 0; 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); detail::array_deleter* d2; p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); 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 allocate_shared(const A& allocator, std::initializer_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 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); detail::array_deleter* d2; p3 = reinterpret_cast(list.begin()); p1 = reinterpret_cast(p2); d2 = get_deleter >(s1); d2->construct_list(p2, n1, p3); return shared_ptr(s1, p1); } template inline typename detail::sp_if_size_array::type allocate_shared(const A& allocator, std::initializer_list::type> list) { BOOST_ASSERT(list.size() == detail::array_size::size); 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 n1 = detail::array_total::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); return shared_ptr(s1, p1); } template inline typename detail::sp_if_array::type allocate_shared(const A& allocator, std::size_t size, std::initializer_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 } #endif