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);