]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/allocate_local_shared_array.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / smart_ptr / allocate_local_shared_array.hpp
1 /*
2 Copyright 2017 Glen Joseph Fernandes
3 (glenjofe@gmail.com)
4
5 Distributed under the Boost Software License, Version 1.0.
6 (http://www.boost.org/LICENSE_1_0.txt)
7 */
8 #ifndef BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
9 #define BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
10
11 #include <boost/smart_ptr/allocate_shared_array.hpp>
12 #include <boost/smart_ptr/local_shared_ptr.hpp>
13
14 namespace boost {
15 namespace detail {
16
17 template<class>
18 struct lsp_if_array { };
19
20 template<class T>
21 struct lsp_if_array<T[]> {
22 typedef boost::local_shared_ptr<T[]> type;
23 };
24
25 template<class>
26 struct lsp_if_size_array { };
27
28 template<class T, std::size_t N>
29 struct lsp_if_size_array<T[N]> {
30 typedef boost::local_shared_ptr<T[N]> type;
31 };
32
33 class lsp_array_base
34 : public local_counted_base {
35 public:
36 void set(sp_counted_base* base) BOOST_SP_NOEXCEPT {
37 count_ = shared_count(base);
38 }
39
40 virtual void local_cb_destroy() BOOST_SP_NOEXCEPT {
41 shared_count().swap(count_);
42 }
43
44 virtual shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT {
45 return count_;
46 }
47
48 private:
49 shared_count count_;
50 };
51
52 template<class A>
53 class lsp_array_state
54 : public sp_array_state<A> {
55 public:
56 template<class U>
57 lsp_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
58 : sp_array_state<A>(other, size) { }
59
60 lsp_array_base& base() BOOST_SP_NOEXCEPT {
61 return base_;
62 }
63
64 private:
65 lsp_array_base base_;
66 };
67
68 template<class A, std::size_t N>
69 class lsp_size_array_state
70 : public sp_size_array_state<A, N> {
71 public:
72 template<class U>
73 lsp_size_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
74 : sp_size_array_state<A, N>(other, size) { }
75
76 lsp_array_base& base() BOOST_SP_NOEXCEPT {
77 return base_;
78 }
79
80 private:
81 lsp_array_base base_;
82 };
83
84 } /* detail */
85
86 template<class T, class A>
87 inline typename detail::lsp_if_array<T>::type
88 allocate_local_shared(const A& allocator, std::size_t count)
89 {
90 typedef typename detail::sp_array_element<T>::type type;
91 typedef typename detail::sp_array_scalar<T>::type scalar;
92 typedef typename detail::sp_bind_allocator<A, scalar>::type other;
93 typedef detail::lsp_array_state<other> state;
94 typedef detail::sp_array_base<state> base;
95 std::size_t size = count * detail::sp_array_count<type>::value;
96 detail::sp_array_result<other, base> result(allocator, size);
97 base* node = result.get();
98 scalar* start = detail::sp_array_start<base, scalar>(node);
99 ::new(static_cast<void*>(node)) base(allocator, size, start);
100 detail::lsp_array_base& local = node->state().base();
101 local.set(node);
102 result.release();
103 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
104 reinterpret_cast<type*>(start), &local);
105 }
106
107 template<class T, class A>
108 inline typename detail::lsp_if_size_array<T>::type
109 allocate_local_shared(const A& allocator)
110 {
111 enum {
112 size = detail::sp_array_count<T>::value
113 };
114 typedef typename detail::sp_array_element<T>::type type;
115 typedef typename detail::sp_array_scalar<T>::type scalar;
116 typedef typename detail::sp_bind_allocator<A, scalar>::type other;
117 typedef detail::lsp_size_array_state<other, size> state;
118 typedef detail::sp_array_base<state> base;
119 detail::sp_array_result<other, base> result(allocator, size);
120 base* node = result.get();
121 scalar* start = detail::sp_array_start<base, scalar>(node);
122 ::new(static_cast<void*>(node)) base(allocator, size, start);
123 detail::lsp_array_base& local = node->state().base();
124 local.set(node);
125 result.release();
126 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
127 reinterpret_cast<type*>(start), &local);
128 }
129
130 template<class T, class A>
131 inline typename detail::lsp_if_array<T>::type
132 allocate_local_shared(const A& allocator, std::size_t count,
133 const typename detail::sp_array_element<T>::type& value)
134 {
135 typedef typename detail::sp_array_element<T>::type type;
136 typedef typename detail::sp_array_scalar<T>::type scalar;
137 typedef typename detail::sp_bind_allocator<A, scalar>::type other;
138 typedef detail::lsp_array_state<other> state;
139 typedef detail::sp_array_base<state> base;
140 std::size_t size = count * detail::sp_array_count<type>::value;
141 detail::sp_array_result<other, base> result(allocator, size);
142 base* node = result.get();
143 scalar* start = detail::sp_array_start<base, scalar>(node);
144 ::new(static_cast<void*>(node)) base(allocator, size,
145 reinterpret_cast<const scalar*>(&value),
146 detail::sp_array_count<type>::value, start);
147 detail::lsp_array_base& local = node->state().base();
148 local.set(node);
149 result.release();
150 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
151 reinterpret_cast<type*>(start), &local);
152 }
153
154 template<class T, class A>
155 inline typename detail::lsp_if_size_array<T>::type
156 allocate_local_shared(const A& allocator,
157 const typename detail::sp_array_element<T>::type& value)
158 {
159 enum {
160 size = detail::sp_array_count<T>::value
161 };
162 typedef typename detail::sp_array_element<T>::type type;
163 typedef typename detail::sp_array_scalar<T>::type scalar;
164 typedef typename detail::sp_bind_allocator<A, scalar>::type other;
165 typedef detail::lsp_size_array_state<other, size> state;
166 typedef detail::sp_array_base<state> base;
167 detail::sp_array_result<other, base> result(allocator, size);
168 base* node = result.get();
169 scalar* start = detail::sp_array_start<base, scalar>(node);
170 ::new(static_cast<void*>(node)) base(allocator, size,
171 reinterpret_cast<const scalar*>(&value),
172 detail::sp_array_count<type>::value, start);
173 detail::lsp_array_base& local = node->state().base();
174 local.set(node);
175 result.release();
176 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
177 reinterpret_cast<type*>(start), &local);
178 }
179
180 template<class T, class A>
181 inline typename detail::lsp_if_array<T>::type
182 allocate_local_shared_noinit(const A& allocator, std::size_t count)
183 {
184 typedef typename detail::sp_array_element<T>::type type;
185 typedef typename detail::sp_array_scalar<T>::type scalar;
186 typedef typename detail::sp_bind_allocator<A, scalar>::type other;
187 typedef detail::lsp_array_state<other> state;
188 typedef detail::sp_array_base<state, false> base;
189 std::size_t size = count * detail::sp_array_count<type>::value;
190 detail::sp_array_result<other, base> result(allocator, size);
191 base* node = result.get();
192 scalar* start = detail::sp_array_start<base, scalar>(node);
193 ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
194 size, start);
195 detail::lsp_array_base& local = node->state().base();
196 local.set(node);
197 result.release();
198 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
199 reinterpret_cast<type*>(start), &local);
200 }
201
202 template<class T, class A>
203 inline typename detail::lsp_if_size_array<T>::type
204 allocate_local_shared_noinit(const A& allocator)
205 {
206 enum {
207 size = detail::sp_array_count<T>::value
208 };
209 typedef typename detail::sp_array_element<T>::type type;
210 typedef typename detail::sp_array_scalar<T>::type scalar;
211 typedef typename detail::sp_bind_allocator<A, scalar>::type other;
212 typedef detail::lsp_size_array_state<other, size> state;
213 typedef detail::sp_array_base<state, false> base;
214 detail::sp_array_result<other, base> result(allocator, size);
215 base* node = result.get();
216 scalar* start = detail::sp_array_start<base, scalar>(node);
217 ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
218 size, start);
219 detail::lsp_array_base& local = node->state().base();
220 local.set(node);
221 result.release();
222 return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
223 reinterpret_cast<type*>(start), &local);
224 }
225
226 } /* boost */
227
228 #endif