Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@101
|
3 // (C) Copyright Ion Gaztanaga 2005-2013.
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
6 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //
|
Chris@16
|
9 // See http://www.boost.org/libs/container for documentation.
|
Chris@16
|
10 //
|
Chris@16
|
11 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef BOOST_CONTAINER_DESTROYERS_HPP
|
Chris@16
|
14 #define BOOST_CONTAINER_DESTROYERS_HPP
|
Chris@16
|
15
|
Chris@101
|
16 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
17 # include <boost/config.hpp>
|
Chris@101
|
18 #endif
|
Chris@101
|
19
|
Chris@101
|
20 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@16
|
21 # pragma once
|
Chris@16
|
22 #endif
|
Chris@16
|
23
|
Chris@101
|
24 #include <boost/container/detail/config_begin.hpp>
|
Chris@16
|
25 #include <boost/container/detail/workaround.hpp>
|
Chris@101
|
26
|
Chris@101
|
27 #include <boost/container/allocator_traits.hpp>
|
Chris@101
|
28 #include <boost/container/detail/to_raw_pointer.hpp>
|
Chris@16
|
29 #include <boost/container/detail/version_type.hpp>
|
Chris@16
|
30
|
Chris@16
|
31 namespace boost {
|
Chris@16
|
32 namespace container {
|
Chris@16
|
33 namespace container_detail {
|
Chris@16
|
34
|
Chris@16
|
35 //!A deleter for scoped_ptr that deallocates the memory
|
Chris@16
|
36 //!allocated for an object using a STL allocator.
|
Chris@101
|
37 template <class Allocator>
|
Chris@16
|
38 struct scoped_deallocator
|
Chris@16
|
39 {
|
Chris@101
|
40 typedef allocator_traits<Allocator> allocator_traits_type;
|
Chris@16
|
41 typedef typename allocator_traits_type::pointer pointer;
|
Chris@16
|
42 typedef container_detail::integral_constant<unsigned,
|
Chris@16
|
43 boost::container::container_detail::
|
Chris@101
|
44 version<Allocator>::value> alloc_version;
|
Chris@16
|
45
|
Chris@16
|
46 private:
|
Chris@101
|
47 void priv_deallocate(version_1)
|
Chris@16
|
48 { m_alloc.deallocate(m_ptr, 1); }
|
Chris@16
|
49
|
Chris@101
|
50 void priv_deallocate(version_2)
|
Chris@16
|
51 { m_alloc.deallocate_one(m_ptr); }
|
Chris@16
|
52
|
Chris@16
|
53 BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
|
Chris@16
|
54
|
Chris@16
|
55 public:
|
Chris@16
|
56
|
Chris@16
|
57 pointer m_ptr;
|
Chris@101
|
58 Allocator& m_alloc;
|
Chris@16
|
59
|
Chris@101
|
60 scoped_deallocator(pointer p, Allocator& a)
|
Chris@16
|
61 : m_ptr(p), m_alloc(a)
|
Chris@16
|
62 {}
|
Chris@16
|
63
|
Chris@16
|
64 ~scoped_deallocator()
|
Chris@16
|
65 { if (m_ptr)priv_deallocate(alloc_version()); }
|
Chris@16
|
66
|
Chris@16
|
67 scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
|
Chris@16
|
68 : m_ptr(o.m_ptr), m_alloc(o.m_alloc)
|
Chris@16
|
69 { o.release(); }
|
Chris@16
|
70
|
Chris@16
|
71 pointer get() const
|
Chris@16
|
72 { return m_ptr; }
|
Chris@16
|
73
|
Chris@16
|
74 void set(const pointer &p)
|
Chris@16
|
75 { m_ptr = p; }
|
Chris@16
|
76
|
Chris@16
|
77 void release()
|
Chris@16
|
78 { m_ptr = 0; }
|
Chris@16
|
79 };
|
Chris@16
|
80
|
Chris@16
|
81 template <class Allocator>
|
Chris@16
|
82 struct null_scoped_deallocator
|
Chris@16
|
83 {
|
Chris@16
|
84 typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
Chris@16
|
85 typedef typename AllocTraits::pointer pointer;
|
Chris@16
|
86 typedef typename AllocTraits::size_type size_type;
|
Chris@16
|
87
|
Chris@16
|
88 null_scoped_deallocator(pointer, Allocator&, size_type)
|
Chris@16
|
89 {}
|
Chris@16
|
90
|
Chris@16
|
91 void release()
|
Chris@16
|
92 {}
|
Chris@16
|
93
|
Chris@16
|
94 pointer get() const
|
Chris@16
|
95 { return pointer(); }
|
Chris@16
|
96
|
Chris@16
|
97 void set(const pointer &)
|
Chris@16
|
98 {}
|
Chris@16
|
99 };
|
Chris@16
|
100
|
Chris@16
|
101 //!A deleter for scoped_ptr that deallocates the memory
|
Chris@16
|
102 //!allocated for an array of objects using a STL allocator.
|
Chris@16
|
103 template <class Allocator>
|
Chris@16
|
104 struct scoped_array_deallocator
|
Chris@16
|
105 {
|
Chris@16
|
106 typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
Chris@16
|
107 typedef typename AllocTraits::pointer pointer;
|
Chris@16
|
108 typedef typename AllocTraits::size_type size_type;
|
Chris@16
|
109
|
Chris@16
|
110 scoped_array_deallocator(pointer p, Allocator& a, size_type length)
|
Chris@16
|
111 : m_ptr(p), m_alloc(a), m_length(length) {}
|
Chris@16
|
112
|
Chris@16
|
113 ~scoped_array_deallocator()
|
Chris@16
|
114 { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); }
|
Chris@16
|
115
|
Chris@16
|
116 void release()
|
Chris@16
|
117 { m_ptr = 0; }
|
Chris@16
|
118
|
Chris@16
|
119 private:
|
Chris@16
|
120 pointer m_ptr;
|
Chris@16
|
121 Allocator& m_alloc;
|
Chris@16
|
122 size_type m_length;
|
Chris@16
|
123 };
|
Chris@16
|
124
|
Chris@16
|
125 template <class Allocator>
|
Chris@16
|
126 struct null_scoped_array_deallocator
|
Chris@16
|
127 {
|
Chris@16
|
128 typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
Chris@16
|
129 typedef typename AllocTraits::pointer pointer;
|
Chris@16
|
130 typedef typename AllocTraits::size_type size_type;
|
Chris@16
|
131
|
Chris@16
|
132 null_scoped_array_deallocator(pointer, Allocator&, size_type)
|
Chris@16
|
133 {}
|
Chris@16
|
134
|
Chris@16
|
135 void release()
|
Chris@16
|
136 {}
|
Chris@16
|
137 };
|
Chris@16
|
138
|
Chris@16
|
139 template <class Allocator>
|
Chris@16
|
140 struct scoped_destroy_deallocator
|
Chris@16
|
141 {
|
Chris@16
|
142 typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
Chris@16
|
143 typedef typename AllocTraits::pointer pointer;
|
Chris@16
|
144 typedef typename AllocTraits::size_type size_type;
|
Chris@16
|
145 typedef container_detail::integral_constant<unsigned,
|
Chris@16
|
146 boost::container::container_detail::
|
Chris@16
|
147 version<Allocator>::value> alloc_version;
|
Chris@16
|
148
|
Chris@16
|
149 scoped_destroy_deallocator(pointer p, Allocator& a)
|
Chris@16
|
150 : m_ptr(p), m_alloc(a) {}
|
Chris@16
|
151
|
Chris@16
|
152 ~scoped_destroy_deallocator()
|
Chris@16
|
153 {
|
Chris@16
|
154 if(m_ptr){
|
Chris@16
|
155 AllocTraits::destroy(m_alloc, container_detail::to_raw_pointer(m_ptr));
|
Chris@16
|
156 priv_deallocate(m_ptr, alloc_version());
|
Chris@16
|
157 }
|
Chris@16
|
158 }
|
Chris@16
|
159
|
Chris@16
|
160 void release()
|
Chris@16
|
161 { m_ptr = 0; }
|
Chris@16
|
162
|
Chris@16
|
163 private:
|
Chris@16
|
164
|
Chris@101
|
165 void priv_deallocate(const pointer &p, version_1)
|
Chris@16
|
166 { AllocTraits::deallocate(m_alloc, p, 1); }
|
Chris@16
|
167
|
Chris@101
|
168 void priv_deallocate(const pointer &p, version_2)
|
Chris@16
|
169 { m_alloc.deallocate_one(p); }
|
Chris@16
|
170
|
Chris@16
|
171 pointer m_ptr;
|
Chris@16
|
172 Allocator& m_alloc;
|
Chris@16
|
173 };
|
Chris@16
|
174
|
Chris@16
|
175
|
Chris@16
|
176 //!A deleter for scoped_ptr that destroys
|
Chris@16
|
177 //!an object using a STL allocator.
|
Chris@16
|
178 template <class Allocator>
|
Chris@16
|
179 struct scoped_destructor_n
|
Chris@16
|
180 {
|
Chris@16
|
181 typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
Chris@16
|
182 typedef typename AllocTraits::pointer pointer;
|
Chris@16
|
183 typedef typename AllocTraits::value_type value_type;
|
Chris@16
|
184 typedef typename AllocTraits::size_type size_type;
|
Chris@16
|
185
|
Chris@16
|
186 scoped_destructor_n(pointer p, Allocator& a, size_type n)
|
Chris@16
|
187 : m_p(p), m_a(a), m_n(n)
|
Chris@16
|
188 {}
|
Chris@16
|
189
|
Chris@16
|
190 void release()
|
Chris@16
|
191 { m_p = 0; }
|
Chris@16
|
192
|
Chris@16
|
193 void increment_size(size_type inc)
|
Chris@16
|
194 { m_n += inc; }
|
Chris@16
|
195
|
Chris@16
|
196 void increment_size_backwards(size_type inc)
|
Chris@16
|
197 { m_n += inc; m_p -= inc; }
|
Chris@16
|
198
|
Chris@16
|
199 void shrink_forward(size_type inc)
|
Chris@16
|
200 { m_n -= inc; m_p += inc; }
|
Chris@101
|
201
|
Chris@16
|
202 ~scoped_destructor_n()
|
Chris@16
|
203 {
|
Chris@16
|
204 if(!m_p) return;
|
Chris@16
|
205 value_type *raw_ptr = container_detail::to_raw_pointer(m_p);
|
Chris@16
|
206 while(m_n--){
|
Chris@101
|
207 AllocTraits::destroy(m_a, raw_ptr++);
|
Chris@16
|
208 }
|
Chris@16
|
209 }
|
Chris@16
|
210
|
Chris@16
|
211 private:
|
Chris@16
|
212 pointer m_p;
|
Chris@16
|
213 Allocator & m_a;
|
Chris@16
|
214 size_type m_n;
|
Chris@16
|
215 };
|
Chris@16
|
216
|
Chris@16
|
217 //!A deleter for scoped_ptr that destroys
|
Chris@16
|
218 //!an object using a STL allocator.
|
Chris@16
|
219 template <class Allocator>
|
Chris@16
|
220 struct null_scoped_destructor_n
|
Chris@16
|
221 {
|
Chris@16
|
222 typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
Chris@16
|
223 typedef typename AllocTraits::pointer pointer;
|
Chris@16
|
224 typedef typename AllocTraits::size_type size_type;
|
Chris@16
|
225
|
Chris@16
|
226 null_scoped_destructor_n(pointer, Allocator&, size_type)
|
Chris@16
|
227 {}
|
Chris@16
|
228
|
Chris@16
|
229 void increment_size(size_type)
|
Chris@16
|
230 {}
|
Chris@16
|
231
|
Chris@16
|
232 void increment_size_backwards(size_type)
|
Chris@16
|
233 {}
|
Chris@16
|
234
|
Chris@101
|
235 void shrink_forward(size_type)
|
Chris@101
|
236 {}
|
Chris@101
|
237
|
Chris@16
|
238 void release()
|
Chris@16
|
239 {}
|
Chris@16
|
240 };
|
Chris@16
|
241
|
Chris@101
|
242 template<class Allocator>
|
Chris@16
|
243 class scoped_destructor
|
Chris@16
|
244 {
|
Chris@101
|
245 typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
Chris@16
|
246 public:
|
Chris@101
|
247 typedef typename Allocator::value_type value_type;
|
Chris@101
|
248 scoped_destructor(Allocator &a, value_type *pv)
|
Chris@16
|
249 : pv_(pv), a_(a)
|
Chris@16
|
250 {}
|
Chris@16
|
251
|
Chris@16
|
252 ~scoped_destructor()
|
Chris@16
|
253 {
|
Chris@16
|
254 if(pv_){
|
Chris@16
|
255 AllocTraits::destroy(a_, pv_);
|
Chris@16
|
256 }
|
Chris@16
|
257 }
|
Chris@16
|
258
|
Chris@16
|
259 void release()
|
Chris@16
|
260 { pv_ = 0; }
|
Chris@16
|
261
|
Chris@16
|
262
|
Chris@16
|
263 void set(value_type *ptr) { pv_ = ptr; }
|
Chris@16
|
264
|
Chris@16
|
265 value_type *get() const { return pv_; }
|
Chris@16
|
266
|
Chris@16
|
267 private:
|
Chris@16
|
268 value_type *pv_;
|
Chris@101
|
269 Allocator &a_;
|
Chris@16
|
270 };
|
Chris@16
|
271
|
Chris@16
|
272
|
Chris@101
|
273 template<class Allocator>
|
Chris@16
|
274 class value_destructor
|
Chris@16
|
275 {
|
Chris@101
|
276 typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
Chris@16
|
277 public:
|
Chris@101
|
278 typedef typename Allocator::value_type value_type;
|
Chris@101
|
279 value_destructor(Allocator &a, value_type &rv)
|
Chris@16
|
280 : rv_(rv), a_(a)
|
Chris@16
|
281 {}
|
Chris@16
|
282
|
Chris@16
|
283 ~value_destructor()
|
Chris@16
|
284 {
|
Chris@16
|
285 AllocTraits::destroy(a_, &rv_);
|
Chris@16
|
286 }
|
Chris@16
|
287
|
Chris@16
|
288 private:
|
Chris@16
|
289 value_type &rv_;
|
Chris@101
|
290 Allocator &a_;
|
Chris@16
|
291 };
|
Chris@16
|
292
|
Chris@16
|
293 template <class Allocator>
|
Chris@16
|
294 class allocator_destroyer
|
Chris@16
|
295 {
|
Chris@16
|
296 typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
Chris@16
|
297 typedef typename AllocTraits::value_type value_type;
|
Chris@16
|
298 typedef typename AllocTraits::pointer pointer;
|
Chris@16
|
299 typedef container_detail::integral_constant<unsigned,
|
Chris@16
|
300 boost::container::container_detail::
|
Chris@16
|
301 version<Allocator>::value> alloc_version;
|
Chris@16
|
302
|
Chris@16
|
303 private:
|
Chris@16
|
304 Allocator & a_;
|
Chris@16
|
305
|
Chris@16
|
306 private:
|
Chris@101
|
307 void priv_deallocate(const pointer &p, version_1)
|
Chris@16
|
308 { AllocTraits::deallocate(a_,p, 1); }
|
Chris@16
|
309
|
Chris@101
|
310 void priv_deallocate(const pointer &p, version_2)
|
Chris@16
|
311 { a_.deallocate_one(p); }
|
Chris@16
|
312
|
Chris@16
|
313 public:
|
Chris@101
|
314 explicit allocator_destroyer(Allocator &a)
|
Chris@16
|
315 : a_(a)
|
Chris@16
|
316 {}
|
Chris@16
|
317
|
Chris@16
|
318 void operator()(const pointer &p)
|
Chris@16
|
319 {
|
Chris@16
|
320 AllocTraits::destroy(a_, container_detail::to_raw_pointer(p));
|
Chris@16
|
321 this->priv_deallocate(p, alloc_version());
|
Chris@16
|
322 }
|
Chris@16
|
323 };
|
Chris@16
|
324
|
Chris@101
|
325 template <class Allocator>
|
Chris@16
|
326 class allocator_destroyer_and_chain_builder
|
Chris@16
|
327 {
|
Chris@101
|
328 typedef allocator_traits<Allocator> allocator_traits_type;
|
Chris@16
|
329 typedef typename allocator_traits_type::value_type value_type;
|
Chris@101
|
330 typedef typename Allocator::multiallocation_chain multiallocation_chain;
|
Chris@16
|
331
|
Chris@101
|
332 Allocator & a_;
|
Chris@16
|
333 multiallocation_chain &c_;
|
Chris@16
|
334
|
Chris@16
|
335 public:
|
Chris@101
|
336 allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
|
Chris@16
|
337 : a_(a), c_(c)
|
Chris@16
|
338 {}
|
Chris@16
|
339
|
Chris@101
|
340 void operator()(const typename Allocator::pointer &p)
|
Chris@16
|
341 {
|
Chris@101
|
342 allocator_traits<Allocator>::destroy(a_, container_detail::to_raw_pointer(p));
|
Chris@16
|
343 c_.push_back(p);
|
Chris@16
|
344 }
|
Chris@16
|
345 };
|
Chris@16
|
346
|
Chris@101
|
347 template <class Allocator>
|
Chris@16
|
348 class allocator_multialloc_chain_node_deallocator
|
Chris@16
|
349 {
|
Chris@101
|
350 typedef allocator_traits<Allocator> allocator_traits_type;
|
Chris@16
|
351 typedef typename allocator_traits_type::value_type value_type;
|
Chris@101
|
352 typedef typename Allocator::multiallocation_chain multiallocation_chain;
|
Chris@101
|
353 typedef allocator_destroyer_and_chain_builder<Allocator> chain_builder;
|
Chris@16
|
354
|
Chris@101
|
355 Allocator & a_;
|
Chris@16
|
356 multiallocation_chain c_;
|
Chris@16
|
357
|
Chris@16
|
358 public:
|
Chris@101
|
359 allocator_multialloc_chain_node_deallocator(Allocator &a)
|
Chris@16
|
360 : a_(a), c_()
|
Chris@16
|
361 {}
|
Chris@16
|
362
|
Chris@16
|
363 chain_builder get_chain_builder()
|
Chris@16
|
364 { return chain_builder(a_, c_); }
|
Chris@16
|
365
|
Chris@16
|
366 ~allocator_multialloc_chain_node_deallocator()
|
Chris@16
|
367 {
|
Chris@16
|
368 a_.deallocate_individual(c_);
|
Chris@16
|
369 }
|
Chris@16
|
370 };
|
Chris@16
|
371
|
Chris@16
|
372 } //namespace container_detail {
|
Chris@16
|
373 } //namespace container {
|
Chris@16
|
374 } //namespace boost {
|
Chris@16
|
375
|
Chris@16
|
376 #include <boost/container/detail/config_end.hpp>
|
Chris@16
|
377
|
Chris@16
|
378 #endif //#ifndef BOOST_CONTAINER_DESTROYERS_HPP
|