blob: 15b092b8f08f0a6f5a723bed0b19c0f852edbec5 [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_MAKE_SHARED_ARRAY_HPP
10#define BOOST_SMART_PTR_MAKE_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/array_deleter.hpp>
14#include <ndnboost/smart_ptr/detail/array_traits.hpp>
15#include <ndnboost/smart_ptr/detail/make_array_helper.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>
23 inline typename ndnboost::detail::sp_if_array<T>::type
24 make_shared(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::make_array_helper<T2[]> a1(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... Args>
41 inline typename ndnboost::detail::sp_if_array<T>::type
42 make_shared(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::make_array_helper<T2[]> a1(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... Args>
58 inline typename ndnboost::detail::sp_if_size_array<T>::type
59 make_shared(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::make_array_helper<T2[N]> a1(&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>
79 inline typename ndnboost::detail::sp_if_size_array<T>::type
80 make_shared(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::make_array_helper<T2[N]> a1(&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>
101 inline typename ndnboost::detail::sp_if_array<T>::type
102 make_shared(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::make_array_helper<T2[]> a1(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>
125 inline typename ndnboost::detail::sp_if_size_array<T>::type
126 make_shared(const typename ndnboost::detail::array_inner<T>::type& list) {
127 typedef typename ndnboost::detail::array_inner<T>::type T1;
128 typedef typename ndnboost::detail::array_base<T1>::type T2;
129 typedef const T2 T3;
130 enum {
131 M = ndnboost::detail::array_total<T1>::size,
132 N = ndnboost::detail::array_total<T>::size
133 };
134 T1* p1 = 0;
135 T2* p2 = 0;
136 T3* p3 = 0;
137 ndnboost::detail::make_array_helper<T2[N]> a1(&p2);
138 ndnboost::detail::array_deleter<T2[N]> d1;
139 ndnboost::shared_ptr<T> s1(p1, d1, a1);
140 typedef ndnboost::detail::array_deleter<T2[N]>* D2;
141 p3 = reinterpret_cast<T3*>(list);
142 p1 = reinterpret_cast<T1*>(p2);
143 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
144 d2->template init_list<M>(p2, p3);
145 return ndnboost::shared_ptr<T>(s1, p1);
146 }
147#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
148 template<typename T>
149 inline typename ndnboost::detail::sp_if_array<T>::type
150 make_shared(std::initializer_list<typename ndnboost::detail::array_inner<T>::type> list) {
151 typedef typename ndnboost::detail::array_inner<T>::type T1;
152 typedef typename ndnboost::detail::array_base<T1>::type T2;
153 typedef const T2 T3;
154 T1* p1 = 0;
155 T2* p2 = 0;
156 T3* p3 = 0;
157 std::size_t n1 = list.size() * ndnboost::detail::array_total<T1>::size;
158 ndnboost::detail::make_array_helper<T2[]> a1(n1, &p2);
159 ndnboost::detail::array_deleter<T2[]> d1(n1);
160 ndnboost::shared_ptr<T> s1(p1, d1, a1);
161 typedef ndnboost::detail::array_deleter<T2[]>* D2;
162 p3 = reinterpret_cast<T3*>(list.begin());
163 p1 = reinterpret_cast<T1*>(p2);
164 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
165 d2->init_list(p2, p3);
166 return ndnboost::shared_ptr<T>(s1, p1);
167 }
168#endif
169#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
170 template<typename T>
171 inline typename ndnboost::detail::sp_if_array<T>::type
172 make_shared(std::size_t size,
173 typename ndnboost::detail::array_base<T>::type&& value) {
174 typedef typename ndnboost::detail::array_inner<T>::type T1;
175 typedef typename ndnboost::detail::array_base<T1>::type T2;
176 T1* p1 = 0;
177 T2* p2 = 0;
178 std::size_t n1 = size * ndnboost::detail::array_total<T1>::size;
179 ndnboost::detail::make_array_helper<T2[]> a1(n1, &p2);
180 ndnboost::detail::array_deleter<T2[]> d1(n1);
181 ndnboost::shared_ptr<T> s1(p1, d1, a1);
182 typedef ndnboost::detail::array_deleter<T2[]>* D2;
183 p1 = reinterpret_cast<T1*>(p2);
184 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
185 d2->init(p2, ndnboost::detail::sp_forward<T2>(value));
186 return ndnboost::shared_ptr<T>(s1, p1);
187 }
188 template<typename T>
189 inline typename ndnboost::detail::sp_if_size_array<T>::type
190 make_shared(typename ndnboost::detail::array_base<T>::type&& value) {
191 typedef typename ndnboost::detail::array_inner<T>::type T1;
192 typedef typename ndnboost::detail::array_base<T1>::type T2;
193 enum {
194 N = ndnboost::detail::array_total<T>::size
195 };
196 T1* p1 = 0;
197 T2* p2 = 0;
198 ndnboost::detail::make_array_helper<T2[N]> a1(&p2);
199 ndnboost::detail::array_deleter<T2[N]> d1;
200 ndnboost::shared_ptr<T> s1(p1, d1, a1);
201 typedef ndnboost::detail::array_deleter<T2[N]>* D2;
202 p1 = reinterpret_cast<T1*>(p2);
203 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
204 d2->init(p2, ndnboost::detail::sp_forward<T2>(value));
205 return ndnboost::shared_ptr<T>(s1, p1);
206 }
207#endif
208#endif
209 template<typename T>
210 inline typename ndnboost::detail::sp_if_array<T>::type
211 make_shared_noinit(std::size_t size) {
212 typedef typename ndnboost::detail::array_inner<T>::type T1;
213 typedef typename ndnboost::detail::array_base<T1>::type T2;
214 T1* p1 = 0;
215 T2* p2 = 0;
216 std::size_t n1 = size * ndnboost::detail::array_total<T1>::size;
217 ndnboost::detail::make_array_helper<T2[]> a1(n1, &p2);
218 ndnboost::detail::array_deleter<T2[]> d1(n1);
219 ndnboost::shared_ptr<T> s1(p1, d1, a1);
220 typedef ndnboost::detail::array_deleter<T2[]>* D2;
221 p1 = reinterpret_cast<T1*>(p2);
222 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
223 d2->noinit(p2);
224 return ndnboost::shared_ptr<T>(s1, p1);
225 }
226 template<typename T>
227 inline typename ndnboost::detail::sp_if_size_array<T>::type
228 make_shared_noinit() {
229 typedef typename ndnboost::detail::array_inner<T>::type T1;
230 typedef typename ndnboost::detail::array_base<T1>::type T2;
231 enum {
232 N = ndnboost::detail::array_total<T>::size
233 };
234 T1* p1 = 0;
235 T2* p2 = 0;
236 ndnboost::detail::make_array_helper<T2[N]> a1(&p2);
237 ndnboost::detail::array_deleter<T2[N]> d1;
238 ndnboost::shared_ptr<T> s1(p1, d1, a1);
239 typedef ndnboost::detail::array_deleter<T2[N]>* D2;
240 p1 = reinterpret_cast<T1*>(p2);
241 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
242 d2->noinit(p2);
243 return ndnboost::shared_ptr<T>(s1, p1);
244 }
245}
246
247#endif