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