Chris@16
|
1 /*
|
Chris@101
|
2 * Copyright (c) 2012-2014 Glen Joseph Fernandes
|
Chris@16
|
3 * glenfe at live dot com
|
Chris@16
|
4 *
|
Chris@16
|
5 * Distributed under the Boost Software License,
|
Chris@16
|
6 * Version 1.0. (See accompanying file LICENSE_1_0.txt
|
Chris@16
|
7 * or copy at http://boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 */
|
Chris@16
|
9 #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
Chris@16
|
10 #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
Chris@16
|
11
|
Chris@101
|
12 #include <boost/smart_ptr/detail/array_count_impl.hpp>
|
Chris@16
|
13 #include <boost/smart_ptr/detail/sp_if_array.hpp>
|
Chris@16
|
14
|
Chris@16
|
15 namespace boost {
|
Chris@101
|
16 template<class T, class A>
|
Chris@16
|
17 inline typename boost::detail::sp_if_array<T>::type
|
Chris@16
|
18 allocate_shared(const A& allocator, std::size_t size) {
|
Chris@16
|
19 typedef typename boost::detail::array_inner<T>::type T1;
|
Chris@16
|
20 typedef typename boost::detail::array_base<T1>::type T2;
|
Chris@101
|
21 typedef boost::detail::ms_init_tag R1;
|
Chris@101
|
22 typedef boost::detail::as_allocator<A, T, R1> A1;
|
Chris@101
|
23 typedef boost::detail::ms_in_allocator_tag D1;
|
Chris@101
|
24 std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
Chris@16
|
25 T1* p1 = 0;
|
Chris@16
|
26 T2* p2 = 0;
|
Chris@101
|
27 D1 d1;
|
Chris@101
|
28 A1 a1(allocator, size, &p2);
|
Chris@101
|
29 shared_ptr<T> s1(p1, d1, a1);
|
Chris@101
|
30 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
Chris@101
|
31 a2->set(0);
|
Chris@101
|
32 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
Chris@101
|
33 boost::detail::as_init(allocator, p2, n1);
|
Chris@101
|
34 #else
|
Chris@101
|
35 boost::detail::ms_init(p2, n1);
|
Chris@101
|
36 #endif
|
Chris@101
|
37 a2->set(p2);
|
Chris@16
|
38 p1 = reinterpret_cast<T1*>(p2);
|
Chris@101
|
39 return shared_ptr<T>(s1, p1);
|
Chris@16
|
40 }
|
Chris@101
|
41
|
Chris@101
|
42 template<class T, class A>
|
Chris@101
|
43 inline typename boost::detail::sp_if_size_array<T>::type
|
Chris@101
|
44 allocate_shared(const A& allocator) {
|
Chris@16
|
45 typedef typename boost::detail::array_inner<T>::type T1;
|
Chris@16
|
46 typedef typename boost::detail::array_base<T1>::type T2;
|
Chris@101
|
47 typedef boost::detail::ms_init_tag R1;
|
Chris@101
|
48 typedef boost::detail::as_allocator<A, T, R1> A1;
|
Chris@101
|
49 typedef boost::detail::ms_in_allocator_tag D1;
|
Chris@16
|
50 enum {
|
Chris@16
|
51 N = boost::detail::array_total<T>::size
|
Chris@16
|
52 };
|
Chris@16
|
53 T1* p1 = 0;
|
Chris@16
|
54 T2* p2 = 0;
|
Chris@101
|
55 D1 d1;
|
Chris@101
|
56 A1 a1(allocator, &p2);
|
Chris@101
|
57 shared_ptr<T> s1(p1, d1, a1);
|
Chris@101
|
58 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
Chris@101
|
59 a2->set(0);
|
Chris@101
|
60 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
Chris@101
|
61 boost::detail::as_init(allocator, p2, N);
|
Chris@101
|
62 #else
|
Chris@101
|
63 boost::detail::ms_init(p2, N);
|
Chris@101
|
64 #endif
|
Chris@101
|
65 a2->set(p2);
|
Chris@16
|
66 p1 = reinterpret_cast<T1*>(p2);
|
Chris@101
|
67 return shared_ptr<T>(s1, p1);
|
Chris@16
|
68 }
|
Chris@101
|
69
|
Chris@101
|
70 template<class T, class A>
|
Chris@101
|
71 inline typename boost::detail::sp_if_array<T>::type
|
Chris@101
|
72 allocate_shared(const A& allocator, std::size_t size,
|
Chris@101
|
73 const typename boost::detail::array_inner<T>::type& value) {
|
Chris@16
|
74 typedef typename boost::detail::array_inner<T>::type T1;
|
Chris@16
|
75 typedef typename boost::detail::array_base<T1>::type T2;
|
Chris@16
|
76 typedef const T2 T3;
|
Chris@101
|
77 typedef boost::detail::ms_init_tag R1;
|
Chris@101
|
78 typedef boost::detail::as_allocator<A, T, R1> A1;
|
Chris@101
|
79 typedef boost::detail::ms_in_allocator_tag D1;
|
Chris@101
|
80 enum {
|
Chris@101
|
81 M = boost::detail::array_total<T1>::size
|
Chris@101
|
82 };
|
Chris@101
|
83 std::size_t n1 = M * size;
|
Chris@101
|
84 T1* p1 = 0;
|
Chris@101
|
85 T2* p2 = 0;
|
Chris@101
|
86 T3* p3 = reinterpret_cast<T3*>(&value);
|
Chris@101
|
87 D1 d1;
|
Chris@101
|
88 A1 a1(allocator, size, &p2);
|
Chris@101
|
89 shared_ptr<T> s1(p1, d1, a1);
|
Chris@101
|
90 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
Chris@101
|
91 a2->set(0);
|
Chris@101
|
92 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
Chris@101
|
93 boost::detail::as_init<T2, A, M>(allocator, p2, n1, p3);
|
Chris@101
|
94 #else
|
Chris@101
|
95 boost::detail::ms_init<T2, M>(p2, n1, p3);
|
Chris@101
|
96 #endif
|
Chris@101
|
97 a2->set(p2);
|
Chris@101
|
98 p1 = reinterpret_cast<T1*>(p2);
|
Chris@101
|
99 return shared_ptr<T>(s1, p1);
|
Chris@101
|
100 }
|
Chris@101
|
101
|
Chris@101
|
102 template<class T, class A>
|
Chris@101
|
103 inline typename boost::detail::sp_if_size_array<T>::type
|
Chris@101
|
104 allocate_shared(const A& allocator,
|
Chris@101
|
105 const typename boost::detail::array_inner<T>::type& value) {
|
Chris@101
|
106 typedef typename boost::detail::array_inner<T>::type T1;
|
Chris@101
|
107 typedef typename boost::detail::array_base<T1>::type T2;
|
Chris@101
|
108 typedef const T2 T3;
|
Chris@101
|
109 typedef boost::detail::ms_init_tag R1;
|
Chris@101
|
110 typedef boost::detail::as_allocator<A, T, R1> A1;
|
Chris@101
|
111 typedef boost::detail::ms_in_allocator_tag D1;
|
Chris@101
|
112 enum {
|
Chris@101
|
113 N = boost::detail::array_total<T>::size,
|
Chris@101
|
114 M = boost::detail::array_total<T1>::size
|
Chris@101
|
115 };
|
Chris@101
|
116 T1* p1 = 0;
|
Chris@101
|
117 T2* p2 = 0;
|
Chris@101
|
118 T3* p3 = reinterpret_cast<T3*>(&value);
|
Chris@101
|
119 D1 d1;
|
Chris@101
|
120 A1 a1(allocator, &p2);
|
Chris@101
|
121 shared_ptr<T> s1(p1, d1, a1);
|
Chris@101
|
122 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
Chris@101
|
123 a2->set(0);
|
Chris@101
|
124 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
Chris@101
|
125 boost::detail::as_init<T2, A, M>(allocator, p2, N, p3);
|
Chris@101
|
126 #else
|
Chris@101
|
127 boost::detail::ms_init<T2, M>(p2, N, p3);
|
Chris@101
|
128 #endif
|
Chris@101
|
129 a2->set(p2);
|
Chris@101
|
130 p1 = reinterpret_cast<T1*>(p2);
|
Chris@101
|
131 return shared_ptr<T>(s1, p1);
|
Chris@101
|
132 }
|
Chris@101
|
133
|
Chris@101
|
134 template<class T, class A>
|
Chris@101
|
135 inline typename boost::detail::sp_if_array<T>::type
|
Chris@101
|
136 allocate_shared_noinit(const A& allocator, std::size_t size) {
|
Chris@101
|
137 typedef typename boost::detail::array_inner<T>::type T1;
|
Chris@101
|
138 typedef typename boost::detail::array_base<T1>::type T2;
|
Chris@101
|
139 typedef boost::detail::ms_noinit_tag R1;
|
Chris@101
|
140 typedef boost::detail::as_allocator<A, T, R1> A1;
|
Chris@101
|
141 typedef boost::detail::ms_in_allocator_tag D1;
|
Chris@101
|
142 std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
Chris@101
|
143 T1* p1 = 0;
|
Chris@101
|
144 T2* p2 = 0;
|
Chris@101
|
145 D1 d1;
|
Chris@101
|
146 A1 a1(allocator, size, &p2);
|
Chris@101
|
147 shared_ptr<T> s1(p1, d1, a1);
|
Chris@101
|
148 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
Chris@101
|
149 a2->set(0);
|
Chris@101
|
150 boost::detail::ms_noinit(p2, n1);
|
Chris@101
|
151 a2->set(p2);
|
Chris@101
|
152 p1 = reinterpret_cast<T1*>(p2);
|
Chris@101
|
153 return shared_ptr<T>(s1, p1);
|
Chris@101
|
154 }
|
Chris@101
|
155
|
Chris@101
|
156 template<class T, class A>
|
Chris@101
|
157 inline typename boost::detail::sp_if_size_array<T>::type
|
Chris@101
|
158 allocate_shared_noinit(const A& allocator) {
|
Chris@101
|
159 typedef typename boost::detail::array_inner<T>::type T1;
|
Chris@101
|
160 typedef typename boost::detail::array_base<T1>::type T2;
|
Chris@101
|
161 typedef boost::detail::ms_noinit_tag R1;
|
Chris@101
|
162 typedef boost::detail::as_allocator<A, T, R1> A1;
|
Chris@101
|
163 typedef boost::detail::ms_in_allocator_tag D1;
|
Chris@16
|
164 enum {
|
Chris@16
|
165 N = boost::detail::array_total<T>::size
|
Chris@16
|
166 };
|
Chris@16
|
167 T1* p1 = 0;
|
Chris@16
|
168 T2* p2 = 0;
|
Chris@101
|
169 D1 d1;
|
Chris@101
|
170 A1 a1(allocator, &p2);
|
Chris@101
|
171 shared_ptr<T> s1(p1, d1, a1);
|
Chris@101
|
172 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
Chris@101
|
173 a2->set(0);
|
Chris@101
|
174 boost::detail::ms_noinit(p2, N);
|
Chris@101
|
175 a2->set(p2);
|
Chris@16
|
176 p1 = reinterpret_cast<T1*>(p2);
|
Chris@101
|
177 return shared_ptr<T>(s1, p1);
|
Chris@16
|
178 }
|
Chris@16
|
179 }
|
Chris@16
|
180
|
Chris@16
|
181 #endif
|