2 * Copyright (c) 2012 Glen Joseph Fernandes
3 * glenfe at live dot com
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)
9 #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
10 #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
12 #include <boost/smart_ptr/shared_ptr.hpp>
13 #include <boost/smart_ptr/detail/allocate_array_helper.hpp>
14 #include <boost/smart_ptr/detail/array_deleter.hpp>
15 #include <boost/smart_ptr/detail/array_traits.hpp>
16 #include <boost/smart_ptr/detail/sp_if_array.hpp>
17 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
18 #include <initializer_list>
22 template<typename T, typename A>
23 inline typename boost::detail::sp_if_array<T>::type
24 allocate_shared(const A& allocator, std::size_t size) {
25 typedef typename boost::detail::array_inner<T>::type T1;
26 typedef typename boost::detail::array_base<T1>::type T2;
29 std::size_t n1 = size * boost::detail::array_total<T1>::size;
30 boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
31 boost::detail::array_deleter<T2[]> d1(n1);
32 boost::shared_ptr<T> s1(p1, d1, a1);
33 typedef boost::detail::array_deleter<T2[]>* D2;
34 p1 = reinterpret_cast<T1*>(p2);
35 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
37 return boost::shared_ptr<T>(s1, p1);
39 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
40 template<typename T, typename A, typename... Args>
41 inline typename boost::detail::sp_if_array<T>::type
42 allocate_shared(const A& allocator, std::size_t size, Args&&... args) {
43 typedef typename boost::detail::array_inner<T>::type T1;
44 typedef typename boost::detail::array_base<T1>::type T2;
47 std::size_t n1 = size * boost::detail::array_total<T1>::size;
48 boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
49 boost::detail::array_deleter<T2[]> d1(n1);
50 boost::shared_ptr<T> s1(p1, d1, a1);
51 typedef boost::detail::array_deleter<T2[]>* D2;
52 p1 = reinterpret_cast<T1*>(p2);
53 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
54 d2->init(p2, boost::detail::sp_forward<Args>(args)...);
55 return boost::shared_ptr<T>(s1, p1);
57 template<typename T, typename A, typename... Args>
58 inline typename boost::detail::sp_if_size_array<T>::type
59 allocate_shared(const A& allocator, Args&&... args) {
60 typedef typename boost::detail::array_inner<T>::type T1;
61 typedef typename boost::detail::array_base<T1>::type T2;
63 N = boost::detail::array_total<T>::size
67 boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
68 boost::detail::array_deleter<T2[N]> d1;
69 boost::shared_ptr<T> s1(p1, d1, a1);
70 typedef boost::detail::array_deleter<T2[N]>* D2;
71 p1 = reinterpret_cast<T1*>(p2);
72 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
73 d2->init(p2, boost::detail::sp_forward<Args>(args)...);
74 return boost::shared_ptr<T>(s1, p1);
77 #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
78 template<typename T, typename A>
79 inline typename boost::detail::sp_if_size_array<T>::type
80 allocate_shared(const A& allocator, const T& list) {
81 typedef typename boost::detail::array_inner<T>::type T1;
82 typedef typename boost::detail::array_base<T1>::type T2;
85 N = boost::detail::array_total<T>::size
90 boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
91 boost::detail::array_deleter<T2[N]> d1;
92 boost::shared_ptr<T> s1(p1, d1, a1);
93 typedef boost::detail::array_deleter<T2[N]>* D2;
94 p3 = reinterpret_cast<T3*>(list);
95 p1 = reinterpret_cast<T1*>(p2);
96 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
97 d2->init_list(p2, p3);
98 return boost::shared_ptr<T>(s1, p1);
100 template<typename T, typename A>
101 inline typename boost::detail::sp_if_array<T>::type
102 allocate_shared(const A& allocator, std::size_t size,
103 const typename boost::detail::array_inner<T>::type& list) {
104 typedef typename boost::detail::array_inner<T>::type T1;
105 typedef typename boost::detail::array_base<T1>::type T2;
108 M = boost::detail::array_total<T1>::size
113 std::size_t n1 = M * size;
114 boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
115 boost::detail::array_deleter<T2[]> d1(n1);
116 boost::shared_ptr<T> s1(p1, d1, a1);
117 typedef boost::detail::array_deleter<T2[]>* D2;
118 p3 = reinterpret_cast<T3*>(list);
119 p1 = reinterpret_cast<T1*>(p2);
120 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
121 d2->template init_list<M>(p2, p3);
122 return boost::shared_ptr<T>(s1, p1);
124 template<typename T, typename A>
125 inline typename boost::detail::sp_if_size_array<T>::type
126 allocate_shared(const A& allocator,
127 const typename boost::detail::array_inner<T>::type& list) {
128 typedef typename boost::detail::array_inner<T>::type T1;
129 typedef typename boost::detail::array_base<T1>::type T2;
132 M = boost::detail::array_total<T1>::size,
133 N = boost::detail::array_total<T>::size
138 boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
139 boost::detail::array_deleter<T2[N]> d1;
140 boost::shared_ptr<T> s1(p1, d1, a1);
141 typedef boost::detail::array_deleter<T2[N]>* D2;
142 p3 = reinterpret_cast<T3*>(list);
143 p1 = reinterpret_cast<T1*>(p2);
144 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
145 d2->template init_list<M>(p2, p3);
146 return boost::shared_ptr<T>(s1, p1);
148 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
149 template<typename T, typename A>
150 inline typename boost::detail::sp_if_array<T>::type
151 allocate_shared(const A& allocator,
152 std::initializer_list<typename boost::detail::array_inner<T>::type> list) {
153 typedef typename boost::detail::array_inner<T>::type T1;
154 typedef typename boost::detail::array_base<T1>::type T2;
159 std::size_t n1 = list.size() * boost::detail::array_total<T1>::size;
160 boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
161 boost::detail::array_deleter<T2[]> d1(n1);
162 boost::shared_ptr<T> s1(p1, d1, a1);
163 typedef boost::detail::array_deleter<T2[]>* D2;
164 p3 = reinterpret_cast<T3*>(list.begin());
165 p1 = reinterpret_cast<T1*>(p2);
166 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
167 d2->init_list(p2, p3);
168 return boost::shared_ptr<T>(s1, p1);
171 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
172 template<typename T, typename A>
173 inline typename boost::detail::sp_if_array<T>::type
174 allocate_shared(const A& allocator, std::size_t size,
175 typename boost::detail::array_base<T>::type&& value) {
176 typedef typename boost::detail::array_inner<T>::type T1;
177 typedef typename boost::detail::array_base<T1>::type T2;
180 std::size_t n1 = size * boost::detail::array_total<T1>::size;
181 boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
182 boost::detail::array_deleter<T2[]> d1(n1);
183 boost::shared_ptr<T> s1(p1, d1, a1);
184 typedef boost::detail::array_deleter<T2[]>* D2;
185 p1 = reinterpret_cast<T1*>(p2);
186 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
187 d2->init(p2, boost::detail::sp_forward<T2>(value));
188 return boost::shared_ptr<T>(s1, p1);
190 template<typename T, typename A>
191 inline typename boost::detail::sp_if_size_array<T>::type
192 allocate_shared(const A& allocator,
193 typename boost::detail::array_base<T>::type&& value) {
194 typedef typename boost::detail::array_inner<T>::type T1;
195 typedef typename boost::detail::array_base<T1>::type T2;
197 N = boost::detail::array_total<T>::size
201 boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
202 boost::detail::array_deleter<T2[N]> d1;
203 boost::shared_ptr<T> s1(p1, d1, a1);
204 typedef boost::detail::array_deleter<T2[N]>* D2;
205 p1 = reinterpret_cast<T1*>(p2);
206 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
207 d2->init(p2, boost::detail::sp_forward<T2>(value));
208 return boost::shared_ptr<T>(s1, p1);
212 template<typename T, typename A>
213 inline typename boost::detail::sp_if_array<T>::type
214 allocate_shared_noinit(const A& allocator, std::size_t size) {
215 typedef typename boost::detail::array_inner<T>::type T1;
216 typedef typename boost::detail::array_base<T1>::type T2;
219 std::size_t n1 = size * boost::detail::array_total<T1>::size;
220 boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
221 boost::detail::array_deleter<T2[]> d1(n1);
222 boost::shared_ptr<T> s1(p1, d1, a1);
223 typedef boost::detail::array_deleter<T2[]>* D2;
224 p1 = reinterpret_cast<T1*>(p2);
225 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
227 return boost::shared_ptr<T>(s1, p1);
229 template<typename T, typename A>
230 inline typename boost::detail::sp_if_size_array<T>::type
231 allocate_shared_noinit(const A& allocator) {
232 typedef typename boost::detail::array_inner<T>::type T1;
233 typedef typename boost::detail::array_base<T1>::type T2;
235 N = boost::detail::array_total<T>::size
239 boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
240 boost::detail::array_deleter<T2[N]> d1;
241 boost::shared_ptr<T> s1(p1, d1, a1);
242 typedef boost::detail::array_deleter<T2[N]>* D2;
243 p1 = reinterpret_cast<T1*>(p2);
244 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
246 return boost::shared_ptr<T>(s1, p1);