blob: 3a78bd2e4bc2184564dc6b7d47e4783dbf2130a5 [file] [log] [blame]
Jeff Thompsonf7d49942013-08-01 16:47:40 -07001/*
2 * Copyright (c) 2012 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
Jeff Thompson2277ce52013-08-01 17:34:11 -070012#include <ndnboost/smart_ptr/shared_ptr.hpp>
13#include <ndnboost/smart_ptr/detail/allocate_array_helper.hpp>
14#include <ndnboost/smart_ptr/detail/array_deleter.hpp>
15#include <ndnboost/smart_ptr/detail/array_traits.hpp>
16#include <ndnboost/smart_ptr/detail/sp_if_array.hpp>
Jeff Thompsonf7d49942013-08-01 16:47:40 -070017#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
18#include <initializer_list>
19#endif
20
21namespace ndnboost {
22 template<typename T, typename A>
23 inline typename ndnboost::detail::sp_if_array<T>::type
24 allocate_shared(const A& allocator, std::size_t size) {
25 typedef typename ndnboost::detail::array_inner<T>::type T1;
26 typedef typename ndnboost::detail::array_base<T1>::type T2;
27 T1* p1 = 0;
28 T2* p2 = 0;
29 std::size_t n1 = size * ndnboost::detail::array_total<T1>::size;
30 ndnboost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
31 ndnboost::detail::array_deleter<T2[]> d1(n1);
32 ndnboost::shared_ptr<T> s1(p1, d1, a1);
33 typedef ndnboost::detail::array_deleter<T2[]>* D2;
34 p1 = reinterpret_cast<T1*>(p2);
35 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
36 d2->init(p2);
37 return ndnboost::shared_ptr<T>(s1, p1);
38 }
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 ndnboost::detail::sp_if_array<T>::type
42 allocate_shared(const A& allocator, std::size_t size, Args&&... args) {
43 typedef typename ndnboost::detail::array_inner<T>::type T1;
44 typedef typename ndnboost::detail::array_base<T1>::type T2;
45 T1* p1 = 0;
46 T2* p2 = 0;
47 std::size_t n1 = size * ndnboost::detail::array_total<T1>::size;
48 ndnboost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
49 ndnboost::detail::array_deleter<T2[]> d1(n1);
50 ndnboost::shared_ptr<T> s1(p1, d1, a1);
51 typedef ndnboost::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, ndnboost::detail::sp_forward<Args>(args)...);
55 return ndnboost::shared_ptr<T>(s1, p1);
56 }
57 template<typename T, typename A, typename... Args>
58 inline typename ndnboost::detail::sp_if_size_array<T>::type
59 allocate_shared(const A& allocator, Args&&... args) {
60 typedef typename ndnboost::detail::array_inner<T>::type T1;
61 typedef typename ndnboost::detail::array_base<T1>::type T2;
62 enum {
63 N = ndnboost::detail::array_total<T>::size
64 };
65 T1* p1 = 0;
66 T2* p2 = 0;
67 ndnboost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
68 ndnboost::detail::array_deleter<T2[N]> d1;
69 ndnboost::shared_ptr<T> s1(p1, d1, a1);
70 typedef ndnboost::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, ndnboost::detail::sp_forward<Args>(args)...);
74 return ndnboost::shared_ptr<T>(s1, p1);
75 }
76#endif
77#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
78 template<typename T, typename A>
79 inline typename ndnboost::detail::sp_if_size_array<T>::type
80 allocate_shared(const A& allocator, const T& list) {
81 typedef typename ndnboost::detail::array_inner<T>::type T1;
82 typedef typename ndnboost::detail::array_base<T1>::type T2;
83 typedef const T2 T3;
84 enum {
85 N = ndnboost::detail::array_total<T>::size
86 };
87 T1* p1 = 0;
88 T2* p2 = 0;
89 T3* p3 = 0;
90 ndnboost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
91 ndnboost::detail::array_deleter<T2[N]> d1;
92 ndnboost::shared_ptr<T> s1(p1, d1, a1);
93 typedef ndnboost::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 ndnboost::shared_ptr<T>(s1, p1);
99 }
100 template<typename T, typename A>
101 inline typename ndnboost::detail::sp_if_array<T>::type
102 allocate_shared(const A& allocator, std::size_t size,
103 const typename ndnboost::detail::array_inner<T>::type& list) {
104 typedef typename ndnboost::detail::array_inner<T>::type T1;
105 typedef typename ndnboost::detail::array_base<T1>::type T2;
106 typedef const T2 T3;
107 enum {
108 M = ndnboost::detail::array_total<T1>::size
109 };
110 T1* p1 = 0;
111 T2* p2 = 0;
112 T3* p3 = 0;
113 std::size_t n1 = M * size;
114 ndnboost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
115 ndnboost::detail::array_deleter<T2[]> d1(n1);
116 ndnboost::shared_ptr<T> s1(p1, d1, a1);
117 typedef ndnboost::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 ndnboost::shared_ptr<T>(s1, p1);
123 }
124 template<typename T, typename A>
125 inline typename ndnboost::detail::sp_if_size_array<T>::type
126 allocate_shared(const A& allocator,
127 const typename ndnboost::detail::array_inner<T>::type& list) {
128 typedef typename ndnboost::detail::array_inner<T>::type T1;
129 typedef typename ndnboost::detail::array_base<T1>::type T2;
130 typedef const T2 T3;
131 enum {
132 M = ndnboost::detail::array_total<T1>::size,
133 N = ndnboost::detail::array_total<T>::size
134 };
135 T1* p1 = 0;
136 T2* p2 = 0;
137 T3* p3 = 0;
138 ndnboost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
139 ndnboost::detail::array_deleter<T2[N]> d1;
140 ndnboost::shared_ptr<T> s1(p1, d1, a1);
141 typedef ndnboost::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 ndnboost::shared_ptr<T>(s1, p1);
147 }
148#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
149 template<typename T, typename A>
150 inline typename ndnboost::detail::sp_if_array<T>::type
151 allocate_shared(const A& allocator,
152 std::initializer_list<typename ndnboost::detail::array_inner<T>::type> list) {
153 typedef typename ndnboost::detail::array_inner<T>::type T1;
154 typedef typename ndnboost::detail::array_base<T1>::type T2;
155 typedef const T2 T3;
156 T1* p1 = 0;
157 T2* p2 = 0;
158 T3* p3 = 0;
159 std::size_t n1 = list.size() * ndnboost::detail::array_total<T1>::size;
160 ndnboost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
161 ndnboost::detail::array_deleter<T2[]> d1(n1);
162 ndnboost::shared_ptr<T> s1(p1, d1, a1);
163 typedef ndnboost::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 ndnboost::shared_ptr<T>(s1, p1);
169 }
170#endif
171#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
172 template<typename T, typename A>
173 inline typename ndnboost::detail::sp_if_array<T>::type
174 allocate_shared(const A& allocator, std::size_t size,
175 typename ndnboost::detail::array_base<T>::type&& value) {
176 typedef typename ndnboost::detail::array_inner<T>::type T1;
177 typedef typename ndnboost::detail::array_base<T1>::type T2;
178 T1* p1 = 0;
179 T2* p2 = 0;
180 std::size_t n1 = size * ndnboost::detail::array_total<T1>::size;
181 ndnboost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
182 ndnboost::detail::array_deleter<T2[]> d1(n1);
183 ndnboost::shared_ptr<T> s1(p1, d1, a1);
184 typedef ndnboost::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, ndnboost::detail::sp_forward<T2>(value));
188 return ndnboost::shared_ptr<T>(s1, p1);
189 }
190 template<typename T, typename A>
191 inline typename ndnboost::detail::sp_if_size_array<T>::type
192 allocate_shared(const A& allocator,
193 typename ndnboost::detail::array_base<T>::type&& value) {
194 typedef typename ndnboost::detail::array_inner<T>::type T1;
195 typedef typename ndnboost::detail::array_base<T1>::type T2;
196 enum {
197 N = ndnboost::detail::array_total<T>::size
198 };
199 T1* p1 = 0;
200 T2* p2 = 0;
201 ndnboost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
202 ndnboost::detail::array_deleter<T2[N]> d1;
203 ndnboost::shared_ptr<T> s1(p1, d1, a1);
204 typedef ndnboost::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, ndnboost::detail::sp_forward<T2>(value));
208 return ndnboost::shared_ptr<T>(s1, p1);
209 }
210#endif
211#endif
212 template<typename T, typename A>
213 inline typename ndnboost::detail::sp_if_array<T>::type
214 allocate_shared_noinit(const A& allocator, std::size_t size) {
215 typedef typename ndnboost::detail::array_inner<T>::type T1;
216 typedef typename ndnboost::detail::array_base<T1>::type T2;
217 T1* p1 = 0;
218 T2* p2 = 0;
219 std::size_t n1 = size * ndnboost::detail::array_total<T1>::size;
220 ndnboost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
221 ndnboost::detail::array_deleter<T2[]> d1(n1);
222 ndnboost::shared_ptr<T> s1(p1, d1, a1);
223 typedef ndnboost::detail::array_deleter<T2[]>* D2;
224 p1 = reinterpret_cast<T1*>(p2);
225 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
226 d2->noinit(p2);
227 return ndnboost::shared_ptr<T>(s1, p1);
228 }
229 template<typename T, typename A>
230 inline typename ndnboost::detail::sp_if_size_array<T>::type
231 allocate_shared_noinit(const A& allocator) {
232 typedef typename ndnboost::detail::array_inner<T>::type T1;
233 typedef typename ndnboost::detail::array_base<T1>::type T2;
234 enum {
235 N = ndnboost::detail::array_total<T>::size
236 };
237 T1* p1 = 0;
238 T2* p2 = 0;
239 ndnboost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
240 ndnboost::detail::array_deleter<T2[N]> d1;
241 ndnboost::shared_ptr<T> s1(p1, d1, a1);
242 typedef ndnboost::detail::array_deleter<T2[N]>* D2;
243 p1 = reinterpret_cast<T1*>(p2);
244 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
245 d2->noinit(p2);
246 return ndnboost::shared_ptr<T>(s1, p1);
247 }
248}
249
250#endif