/* * Copyright (c) 2012-2014 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 namespace boost { template inline typename boost::detail::sp_if_array::type allocate_shared(const A& allocator, std::size_t size) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_init_tag R1; typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; T2* p2 = 0; D1 d1; A1 a1(allocator, size, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(0); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1); #else boost::detail::ms_init(p2, n1); #endif a2->set(p2); p1 = reinterpret_cast(p2); return shared_ptr(s1, p1); } template inline typename boost::detail::sp_if_size_array::type allocate_shared(const A& allocator) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_init_tag R1; typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; D1 d1; A1 a1(allocator, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(0); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N); #else boost::detail::ms_init(p2, N); #endif a2->set(p2); p1 = reinterpret_cast(p2); return shared_ptr(s1, p1); } template inline typename boost::detail::sp_if_array::type allocate_shared(const A& allocator, std::size_t size, const typename boost::detail::array_inner::type& value) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; typedef boost::detail::ms_init_tag R1; typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { M = boost::detail::array_total::size }; std::size_t n1 = M * size; T1* p1 = 0; T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; A1 a1(allocator, size, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(0); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1, p3); #else boost::detail::ms_init(p2, n1, p3); #endif a2->set(p2); p1 = reinterpret_cast(p2); return shared_ptr(s1, p1); } template inline typename boost::detail::sp_if_size_array::type allocate_shared(const A& allocator, const typename boost::detail::array_inner::type& value) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef const T2 T3; typedef boost::detail::ms_init_tag R1; typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size, M = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; A1 a1(allocator, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(0); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N, p3); #else boost::detail::ms_init(p2, N, p3); #endif a2->set(p2); p1 = reinterpret_cast(p2); return shared_ptr(s1, p1); } 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; typedef boost::detail::ms_noinit_tag R1; typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; T2* p2 = 0; D1 d1; A1 a1(allocator, size, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(0); boost::detail::ms_noinit(p2, n1); a2->set(p2); p1 = reinterpret_cast(p2); return 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; typedef boost::detail::ms_noinit_tag R1; typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size }; T1* p1 = 0; T2* p2 = 0; D1 d1; A1 a1(allocator, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(0); boost::detail::ms_noinit(p2, N); a2->set(p2); p1 = reinterpret_cast(p2); return shared_ptr(s1, p1); } } #endif