1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2013.
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
9 // See http://www.boost.org/libs/container for documentation.
11 //////////////////////////////////////////////////////////////////////////////
13 #ifndef BOOST_CONTAINER_DESTROYERS_HPP
14 #define BOOST_CONTAINER_DESTROYERS_HPP
16 #ifndef BOOST_CONFIG_HPP
17 # include <boost/config.hpp>
20 #if defined(BOOST_HAS_PRAGMA_ONCE)
24 #include <boost/container/detail/config_begin.hpp>
25 #include <boost/container/detail/workaround.hpp>
27 #include <boost/container/allocator_traits.hpp>
28 #include <boost/move/detail/to_raw_pointer.hpp>
29 #include <boost/container/detail/version_type.hpp>
35 //!A deleter for scoped_ptr that deallocates the memory
36 //!allocated for an object using a STL allocator.
37 template <class Allocator>
38 struct scoped_deallocator
40 typedef allocator_traits<Allocator> allocator_traits_type;
41 typedef typename allocator_traits_type::pointer pointer;
42 typedef dtl::integral_constant<unsigned,
43 boost::container::dtl::
44 version<Allocator>::value> alloc_version;
47 void priv_deallocate(version_1)
48 { m_alloc.deallocate(m_ptr, 1); }
50 void priv_deallocate(version_2)
51 { m_alloc.deallocate_one(m_ptr); }
53 BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
60 scoped_deallocator(pointer p, Allocator& a)
61 : m_ptr(p), m_alloc(a)
65 { if (m_ptr)priv_deallocate(alloc_version()); }
67 scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
68 : m_ptr(o.m_ptr), m_alloc(o.m_alloc)
74 void set(const pointer &p)
81 template <class Allocator>
82 struct null_scoped_deallocator
84 typedef boost::container::allocator_traits<Allocator> AllocTraits;
85 typedef typename AllocTraits::pointer pointer;
87 null_scoped_deallocator(pointer, Allocator&, std::size_t)
96 void set(const pointer &)
100 //!A deleter for scoped_ptr that deallocates the memory
101 //!allocated for an array of objects using a STL allocator.
102 template <class Allocator>
103 struct scoped_array_deallocator
105 typedef boost::container::allocator_traits<Allocator> AllocTraits;
106 typedef typename AllocTraits::pointer pointer;
107 typedef typename AllocTraits::size_type size_type;
109 scoped_array_deallocator(pointer p, Allocator& a, std::size_t length)
110 : m_ptr(p), m_alloc(a), m_length(length) {}
112 ~scoped_array_deallocator()
113 { if (m_ptr) m_alloc.deallocate(m_ptr, size_type(m_length)); }
121 std::size_t m_length;
124 template <class Allocator>
125 struct null_scoped_array_deallocator
127 typedef boost::container::allocator_traits<Allocator> AllocTraits;
128 typedef typename AllocTraits::pointer pointer;
130 null_scoped_array_deallocator(pointer, Allocator&, std::size_t)
137 template <class Allocator>
138 struct scoped_node_destroy_deallocator
140 typedef boost::container::allocator_traits<Allocator> AllocTraits;
141 typedef typename AllocTraits::pointer pointer;
142 typedef dtl::integral_constant<unsigned,
143 boost::container::dtl::
144 version<Allocator>::value> alloc_version;
146 scoped_node_destroy_deallocator(pointer p, Allocator& a)
147 : m_ptr(p), m_alloc(a) {}
149 ~scoped_node_destroy_deallocator()
152 boost::movelib::to_raw_pointer(m_ptr)->destructor(m_alloc);
153 priv_deallocate(m_ptr, alloc_version());
162 void priv_deallocate(const pointer &p, version_1)
163 { AllocTraits::deallocate(m_alloc, p, 1); }
165 void priv_deallocate(const pointer &p, version_2)
166 { m_alloc.deallocate_one(p); }
173 //!A deleter for scoped_ptr that destroys
174 //!an object using a STL allocator.
175 template <class Allocator>
176 struct scoped_destructor_n
178 typedef boost::container::allocator_traits<Allocator> AllocTraits;
179 typedef typename AllocTraits::pointer pointer;
180 typedef typename AllocTraits::value_type value_type;
182 BOOST_CONTAINER_FORCEINLINE scoped_destructor_n(pointer p, Allocator& a, std::size_t n)
183 : m_p(p), m_a(a), m_n(n)
186 BOOST_CONTAINER_FORCEINLINE void release()
187 { m_p = 0; m_n = 0; }
189 BOOST_CONTAINER_FORCEINLINE void increment_size(std::size_t inc)
192 BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(std::size_t inc)
193 { m_n += inc; m_p -= std::ptrdiff_t(inc); }
195 BOOST_CONTAINER_FORCEINLINE void shrink_forward(std::size_t inc)
196 { m_n -= inc; m_p += std::ptrdiff_t(inc); }
198 ~scoped_destructor_n()
201 value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);
204 AllocTraits::destroy(m_a, raw_ptr);
216 //!A deleter for scoped_ptr that destroys
217 //!an object using a STL allocator.
218 template <class Allocator>
219 struct null_scoped_destructor_n
221 typedef boost::container::allocator_traits<Allocator> AllocTraits;
222 typedef typename AllocTraits::pointer pointer;
224 BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_n(pointer, Allocator&, std::size_t)
227 BOOST_CONTAINER_FORCEINLINE void increment_size(std::size_t)
230 BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(std::size_t)
233 BOOST_CONTAINER_FORCEINLINE void shrink_forward(std::size_t)
236 BOOST_CONTAINER_FORCEINLINE void release()
241 //!A deleter for scoped_ptr that destroys
242 //!an object using a STL allocator.
243 template <class Allocator>
244 struct scoped_destructor_range
246 typedef boost::container::allocator_traits<Allocator> AllocTraits;
247 typedef typename AllocTraits::pointer pointer;
248 typedef typename AllocTraits::value_type value_type;
250 BOOST_CONTAINER_FORCEINLINE scoped_destructor_range(pointer p, pointer e, Allocator& a)
251 : m_p(p), m_e(e), m_a(a)
254 BOOST_CONTAINER_FORCEINLINE void release()
255 { m_p = pointer(); m_e = pointer(); }
257 BOOST_CONTAINER_FORCEINLINE void set_end(pointer e)
260 BOOST_CONTAINER_FORCEINLINE void set_begin(pointer b)
263 BOOST_CONTAINER_FORCEINLINE void set_range(pointer b, pointer e)
264 { m_p = b; m_e = e; }
266 ~scoped_destructor_range()
269 value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);
270 AllocTraits::destroy(m_a, raw_ptr);
281 //!A deleter for scoped_ptr that destroys
282 //!an object using a STL allocator.
283 template <class Allocator>
284 struct null_scoped_destructor_range
286 typedef boost::container::allocator_traits<Allocator> AllocTraits;
287 typedef typename AllocTraits::pointer pointer;
289 BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_range(pointer, pointer, Allocator&)
292 BOOST_CONTAINER_FORCEINLINE void release()
295 BOOST_CONTAINER_FORCEINLINE void set_end(pointer)
298 BOOST_CONTAINER_FORCEINLINE void set_begin(pointer)
301 BOOST_CONTAINER_FORCEINLINE void set_range(pointer, pointer)
306 template<class Allocator>
307 class scoped_destructor
309 typedef boost::container::allocator_traits<Allocator> AllocTraits;
311 typedef typename Allocator::value_type value_type;
312 BOOST_CONTAINER_FORCEINLINE scoped_destructor(Allocator &a, value_type *pv)
316 BOOST_CONTAINER_FORCEINLINE ~scoped_destructor()
319 AllocTraits::destroy(a_, pv_);
323 BOOST_CONTAINER_FORCEINLINE void release()
327 BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; }
329 BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; }
337 template<class Allocator, class Value = typename Allocator::value_type>
338 class value_destructor
340 typedef boost::container::allocator_traits<Allocator> AllocTraits;
342 typedef Value value_type;
343 BOOST_CONTAINER_FORCEINLINE value_destructor(Allocator &a, value_type &rv)
347 BOOST_CONTAINER_FORCEINLINE ~value_destructor()
349 AllocTraits::destroy(a_, &rv_);
357 template <class Allocator>
358 class allocator_node_destroyer
360 typedef boost::container::allocator_traits<Allocator> AllocTraits;
361 typedef typename AllocTraits::value_type value_type;
362 typedef typename AllocTraits::pointer pointer;
363 typedef dtl::integral_constant<unsigned,
364 boost::container::dtl::
365 version<Allocator>::value> alloc_version;
371 BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_1)
372 { AllocTraits::deallocate(a_,p, 1); }
374 BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_2)
375 { a_.deallocate_one(p); }
378 BOOST_CONTAINER_FORCEINLINE explicit allocator_node_destroyer(Allocator &a)
382 BOOST_CONTAINER_FORCEINLINE void operator()(const pointer &p)
384 boost::movelib::to_raw_pointer(p)->destructor(a_);
385 this->priv_deallocate(p, alloc_version());
389 template<class Allocator>
390 class scoped_node_destructor
392 typedef boost::container::allocator_traits<Allocator> AllocTraits;
394 typedef typename Allocator::value_type value_type;
395 BOOST_CONTAINER_FORCEINLINE scoped_node_destructor(Allocator &a, value_type *pv)
399 BOOST_CONTAINER_FORCEINLINE ~scoped_node_destructor()
406 BOOST_CONTAINER_FORCEINLINE void release()
410 BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; }
412 BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; }
421 template <class Allocator>
422 class allocator_node_destroyer_and_chain_builder
424 typedef allocator_traits<Allocator> allocator_traits_type;
425 typedef typename allocator_traits_type::value_type value_type;
426 typedef typename Allocator::multiallocation_chain multiallocation_chain;
429 multiallocation_chain &c_;
432 BOOST_CONTAINER_FORCEINLINE allocator_node_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
436 BOOST_CONTAINER_FORCEINLINE void operator()(const typename Allocator::pointer &p)
438 boost::movelib::to_raw_pointer(p)->destructor(a_);
443 template <class Allocator>
444 class allocator_multialloc_chain_node_deallocator
446 typedef allocator_traits<Allocator> allocator_traits_type;
447 typedef typename allocator_traits_type::value_type value_type;
448 typedef typename Allocator::multiallocation_chain multiallocation_chain;
449 typedef allocator_node_destroyer_and_chain_builder<Allocator> chain_builder;
452 multiallocation_chain c_;
455 BOOST_CONTAINER_FORCEINLINE allocator_multialloc_chain_node_deallocator(Allocator &a)
459 BOOST_CONTAINER_FORCEINLINE chain_builder get_chain_builder()
460 { return chain_builder(a_, c_); }
462 BOOST_CONTAINER_FORCEINLINE ~allocator_multialloc_chain_node_deallocator()
464 a_.deallocate_individual(c_);
469 } //namespace container {
470 } //namespace boost {
472 #include <boost/container/detail/config_end.hpp>
474 #endif //#ifndef BOOST_CONTAINER_DESTROYERS_HPP