1 /* 2 * Copyright (c) 2012-2014 Glen Joseph Fernandes 3 * glenfe at live dot com 4 * 5 * Distributed under the Boost Software License, 6 * Version 1.0. (See accompanying file LICENSE_1_0.txt 7 * or copy at http://boost.org/LICENSE_1_0.txt) 8 */ 9 #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP 10 #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP 11 12 #include <boost/smart_ptr/detail/array_count_impl.hpp> 13 #include <boost/smart_ptr/detail/sp_if_array.hpp> 14 15 namespace boost { 16 template<class T, class A> 17 inline typename boost::detail::sp_if_array<T>::type allocate_shared(const A & allocator,std::size_t size)18 allocate_shared(const A& allocator, std::size_t size) { 19 typedef typename boost::detail::array_inner<T>::type T1; 20 typedef typename boost::detail::array_base<T1>::type T2; 21 typedef boost::detail::ms_init_tag R1; 22 typedef boost::detail::as_allocator<A, T, R1> A1; 23 typedef boost::detail::ms_in_allocator_tag D1; 24 std::size_t n1 = size * boost::detail::array_total<T1>::size; 25 T1* p1 = 0; 26 T2* p2 = 0; 27 D1 d1; 28 A1 a1(allocator, size, &p2); 29 shared_ptr<T> s1(p1, d1, a1); 30 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 31 a2->set(0); 32 #if !defined(BOOST_NO_CXX11_ALLOCATOR) 33 boost::detail::as_init(allocator, p2, n1); 34 #else 35 boost::detail::ms_init(p2, n1); 36 #endif 37 a2->set(p2); 38 p1 = reinterpret_cast<T1*>(p2); 39 return shared_ptr<T>(s1, p1); 40 } 41 42 template<class T, class A> 43 inline typename boost::detail::sp_if_size_array<T>::type allocate_shared(const A & allocator)44 allocate_shared(const A& allocator) { 45 typedef typename boost::detail::array_inner<T>::type T1; 46 typedef typename boost::detail::array_base<T1>::type T2; 47 typedef boost::detail::ms_init_tag R1; 48 typedef boost::detail::as_allocator<A, T, R1> A1; 49 typedef boost::detail::ms_in_allocator_tag D1; 50 enum { 51 N = boost::detail::array_total<T>::size 52 }; 53 T1* p1 = 0; 54 T2* p2 = 0; 55 D1 d1; 56 A1 a1(allocator, &p2); 57 shared_ptr<T> s1(p1, d1, a1); 58 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 59 a2->set(0); 60 #if !defined(BOOST_NO_CXX11_ALLOCATOR) 61 boost::detail::as_init(allocator, p2, N); 62 #else 63 boost::detail::ms_init(p2, N); 64 #endif 65 a2->set(p2); 66 p1 = reinterpret_cast<T1*>(p2); 67 return shared_ptr<T>(s1, p1); 68 } 69 70 template<class T, class A> 71 inline typename boost::detail::sp_if_array<T>::type allocate_shared(const A & allocator,std::size_t size,const typename boost::detail::array_inner<T>::type & value)72 allocate_shared(const A& allocator, std::size_t size, 73 const typename boost::detail::array_inner<T>::type& value) { 74 typedef typename boost::detail::array_inner<T>::type T1; 75 typedef typename boost::detail::array_base<T1>::type T2; 76 typedef const T2 T3; 77 typedef boost::detail::ms_init_tag R1; 78 typedef boost::detail::as_allocator<A, T, R1> A1; 79 typedef boost::detail::ms_in_allocator_tag D1; 80 enum { 81 M = boost::detail::array_total<T1>::size 82 }; 83 std::size_t n1 = M * size; 84 T1* p1 = 0; 85 T2* p2 = 0; 86 T3* p3 = reinterpret_cast<T3*>(&value); 87 D1 d1; 88 A1 a1(allocator, size, &p2); 89 shared_ptr<T> s1(p1, d1, a1); 90 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 91 a2->set(0); 92 #if !defined(BOOST_NO_CXX11_ALLOCATOR) 93 boost::detail::as_init<T2, A, M>(allocator, p2, n1, p3); 94 #else 95 boost::detail::ms_init<T2, M>(p2, n1, p3); 96 #endif 97 a2->set(p2); 98 p1 = reinterpret_cast<T1*>(p2); 99 return shared_ptr<T>(s1, p1); 100 } 101 102 template<class T, class A> 103 inline typename boost::detail::sp_if_size_array<T>::type allocate_shared(const A & allocator,const typename boost::detail::array_inner<T>::type & value)104 allocate_shared(const A& allocator, 105 const typename boost::detail::array_inner<T>::type& value) { 106 typedef typename boost::detail::array_inner<T>::type T1; 107 typedef typename boost::detail::array_base<T1>::type T2; 108 typedef const T2 T3; 109 typedef boost::detail::ms_init_tag R1; 110 typedef boost::detail::as_allocator<A, T, R1> A1; 111 typedef boost::detail::ms_in_allocator_tag D1; 112 enum { 113 N = boost::detail::array_total<T>::size, 114 M = boost::detail::array_total<T1>::size 115 }; 116 T1* p1 = 0; 117 T2* p2 = 0; 118 T3* p3 = reinterpret_cast<T3*>(&value); 119 D1 d1; 120 A1 a1(allocator, &p2); 121 shared_ptr<T> s1(p1, d1, a1); 122 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 123 a2->set(0); 124 #if !defined(BOOST_NO_CXX11_ALLOCATOR) 125 boost::detail::as_init<T2, A, M>(allocator, p2, N, p3); 126 #else 127 boost::detail::ms_init<T2, M>(p2, N, p3); 128 #endif 129 a2->set(p2); 130 p1 = reinterpret_cast<T1*>(p2); 131 return shared_ptr<T>(s1, p1); 132 } 133 134 template<class T, class A> 135 inline typename boost::detail::sp_if_array<T>::type allocate_shared_noinit(const A & allocator,std::size_t size)136 allocate_shared_noinit(const A& allocator, std::size_t size) { 137 typedef typename boost::detail::array_inner<T>::type T1; 138 typedef typename boost::detail::array_base<T1>::type T2; 139 typedef boost::detail::ms_noinit_tag R1; 140 typedef boost::detail::as_allocator<A, T, R1> A1; 141 typedef boost::detail::ms_in_allocator_tag D1; 142 std::size_t n1 = size * boost::detail::array_total<T1>::size; 143 T1* p1 = 0; 144 T2* p2 = 0; 145 D1 d1; 146 A1 a1(allocator, size, &p2); 147 shared_ptr<T> s1(p1, d1, a1); 148 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 149 a2->set(0); 150 boost::detail::ms_noinit(p2, n1); 151 a2->set(p2); 152 p1 = reinterpret_cast<T1*>(p2); 153 return shared_ptr<T>(s1, p1); 154 } 155 156 template<class T, class A> 157 inline typename boost::detail::sp_if_size_array<T>::type allocate_shared_noinit(const A & allocator)158 allocate_shared_noinit(const A& allocator) { 159 typedef typename boost::detail::array_inner<T>::type T1; 160 typedef typename boost::detail::array_base<T1>::type T2; 161 typedef boost::detail::ms_noinit_tag R1; 162 typedef boost::detail::as_allocator<A, T, R1> A1; 163 typedef boost::detail::ms_in_allocator_tag D1; 164 enum { 165 N = boost::detail::array_total<T>::size 166 }; 167 T1* p1 = 0; 168 T2* p2 = 0; 169 D1 d1; 170 A1 a1(allocator, &p2); 171 shared_ptr<T> s1(p1, d1, a1); 172 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 173 a2->set(0); 174 boost::detail::ms_noinit(p2, N); 175 a2->set(p2); 176 p1 = reinterpret_cast<T1*>(p2); 177 return shared_ptr<T>(s1, p1); 178 } 179 } 180 181 #endif 182