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_MAKE_SHARED_ARRAY_HPP
10 #define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
12 #include <boost/smart_ptr/shared_ptr.hpp>
13 #include <boost/smart_ptr/detail/array_deleter.hpp>
14 #include <boost/smart_ptr/detail/array_traits.hpp>
15 #include <boost/smart_ptr/detail/make_array_helper.hpp>
16 #include <boost/smart_ptr/detail/sp_if_array.hpp>
17 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
18 #include <initializer_list>
23 inline typename boost::detail::sp_if_array<T>::type
24 make_shared(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::make_array_helper<T2[]> a1(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... Args>
41 inline typename boost::detail::sp_if_array<T>::type
42 make_shared(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::make_array_helper<T2[]> a1(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... Args>
58 inline typename boost::detail::sp_if_size_array<T>::type
59 make_shared(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::make_array_helper<T2[N]> a1(&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)
79 inline typename boost::detail::sp_if_size_array<T>::type
80 make_shared(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::make_array_helper<T2[N]> a1(&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);
101 inline typename boost::detail::sp_if_array<T>::type
102 make_shared(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::make_array_helper<T2[]> a1(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);
125 inline typename boost::detail::sp_if_size_array<T>::type
126 make_shared(const typename boost::detail::array_inner<T>::type& list) {
127 typedef typename boost::detail::array_inner<T>::type T1;
128 typedef typename boost::detail::array_base<T1>::type T2;
131 M = boost::detail::array_total<T1>::size,
132 N = boost::detail::array_total<T>::size
137 boost::detail::make_array_helper<T2[N]> a1(&p2);
138 boost::detail::array_deleter<T2[N]> d1;
139 boost::shared_ptr<T> s1(p1, d1, a1);
140 typedef boost::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 boost::shared_ptr<T>(s1, p1);
147 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
149 inline typename boost::detail::sp_if_array<T>::type
150 make_shared(std::initializer_list<typename boost::detail::array_inner<T>::type> list) {
151 typedef typename boost::detail::array_inner<T>::type T1;
152 typedef typename boost::detail::array_base<T1>::type T2;
157 std::size_t n1 = list.size() * boost::detail::array_total<T1>::size;
158 boost::detail::make_array_helper<T2[]> a1(n1, &p2);
159 boost::detail::array_deleter<T2[]> d1(n1);
160 boost::shared_ptr<T> s1(p1, d1, a1);
161 typedef boost::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 boost::shared_ptr<T>(s1, p1);
169 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
171 inline typename boost::detail::sp_if_array<T>::type
172 make_shared(std::size_t size,
173 typename boost::detail::array_base<T>::type&& value) {
174 typedef typename boost::detail::array_inner<T>::type T1;
175 typedef typename boost::detail::array_base<T1>::type T2;
178 std::size_t n1 = size * boost::detail::array_total<T1>::size;
179 boost::detail::make_array_helper<T2[]> a1(n1, &p2);
180 boost::detail::array_deleter<T2[]> d1(n1);
181 boost::shared_ptr<T> s1(p1, d1, a1);
182 typedef boost::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, boost::detail::sp_forward<T2>(value));
186 return boost::shared_ptr<T>(s1, p1);
189 inline typename boost::detail::sp_if_size_array<T>::type
190 make_shared(typename boost::detail::array_base<T>::type&& value) {
191 typedef typename boost::detail::array_inner<T>::type T1;
192 typedef typename boost::detail::array_base<T1>::type T2;
194 N = boost::detail::array_total<T>::size
198 boost::detail::make_array_helper<T2[N]> a1(&p2);
199 boost::detail::array_deleter<T2[N]> d1;
200 boost::shared_ptr<T> s1(p1, d1, a1);
201 typedef boost::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, boost::detail::sp_forward<T2>(value));
205 return boost::shared_ptr<T>(s1, p1);
210 inline typename boost::detail::sp_if_array<T>::type
211 make_shared_noinit(std::size_t size) {
212 typedef typename boost::detail::array_inner<T>::type T1;
213 typedef typename boost::detail::array_base<T1>::type T2;
216 std::size_t n1 = size * boost::detail::array_total<T1>::size;
217 boost::detail::make_array_helper<T2[]> a1(n1, &p2);
218 boost::detail::array_deleter<T2[]> d1(n1);
219 boost::shared_ptr<T> s1(p1, d1, a1);
220 typedef boost::detail::array_deleter<T2[]>* D2;
221 p1 = reinterpret_cast<T1*>(p2);
222 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
224 return boost::shared_ptr<T>(s1, p1);
227 inline typename boost::detail::sp_if_size_array<T>::type
228 make_shared_noinit() {
229 typedef typename boost::detail::array_inner<T>::type T1;
230 typedef typename boost::detail::array_base<T1>::type T2;
232 N = boost::detail::array_total<T>::size
236 boost::detail::make_array_helper<T2[N]> a1(&p2);
237 boost::detail::array_deleter<T2[N]> d1;
238 boost::shared_ptr<T> s1(p1, d1, a1);
239 typedef boost::detail::array_deleter<T2[N]>* D2;
240 p1 = reinterpret_cast<T1*>(p2);
241 D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
243 return boost::shared_ptr<T>(s1, p1);