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;
86 typedef typename AllocTraits::size_type size_type;
88 null_scoped_deallocator(pointer, Allocator&, size_type)
97 void set(const pointer &)
101 //!A deleter for scoped_ptr that deallocates the memory
102 //!allocated for an array of objects using a STL allocator.
103 template <class Allocator>
104 struct scoped_array_deallocator
106 typedef boost::container::allocator_traits<Allocator> AllocTraits;
107 typedef typename AllocTraits::pointer pointer;
108 typedef typename AllocTraits::size_type size_type;
110 scoped_array_deallocator(pointer p, Allocator& a, size_type length)
111 : m_ptr(p), m_alloc(a), m_length(length) {}
113 ~scoped_array_deallocator()
114 { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); }
125 template <class Allocator>
126 struct null_scoped_array_deallocator
128 typedef boost::container::allocator_traits<Allocator> AllocTraits;
129 typedef typename AllocTraits::pointer pointer;
130 typedef typename AllocTraits::size_type size_type;
132 null_scoped_array_deallocator(pointer, Allocator&, size_type)
139 template <class Allocator>
140 struct scoped_destroy_deallocator
142 typedef boost::container::allocator_traits<Allocator> AllocTraits;
143 typedef typename AllocTraits::pointer pointer;
144 typedef typename AllocTraits::size_type size_type;
145 typedef dtl::integral_constant<unsigned,
146 boost::container::dtl::
147 version<Allocator>::value> alloc_version;
149 scoped_destroy_deallocator(pointer p, Allocator& a)
150 : m_ptr(p), m_alloc(a) {}
152 ~scoped_destroy_deallocator()
155 AllocTraits::destroy(m_alloc, boost::movelib::to_raw_pointer(m_ptr));
156 priv_deallocate(m_ptr, alloc_version());
165 void priv_deallocate(const pointer &p, version_1)
166 { AllocTraits::deallocate(m_alloc, p, 1); }
168 void priv_deallocate(const pointer &p, version_2)
169 { m_alloc.deallocate_one(p); }
176 //!A deleter for scoped_ptr that destroys
177 //!an object using a STL allocator.
178 template <class Allocator>
179 struct scoped_destructor_n
181 typedef boost::container::allocator_traits<Allocator> AllocTraits;
182 typedef typename AllocTraits::pointer pointer;
183 typedef typename AllocTraits::value_type value_type;
184 typedef typename AllocTraits::size_type size_type;
186 scoped_destructor_n(pointer p, Allocator& a, size_type n)
187 : m_p(p), m_a(a), m_n(n)
193 void increment_size(size_type inc)
196 void increment_size_backwards(size_type inc)
197 { m_n += inc; m_p -= inc; }
199 void shrink_forward(size_type inc)
200 { m_n -= inc; m_p += inc; }
202 ~scoped_destructor_n()
205 value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);
207 AllocTraits::destroy(m_a, raw_ptr++);
217 //!A deleter for scoped_ptr that destroys
218 //!an object using a STL allocator.
219 template <class Allocator>
220 struct null_scoped_destructor_n
222 typedef boost::container::allocator_traits<Allocator> AllocTraits;
223 typedef typename AllocTraits::pointer pointer;
224 typedef typename AllocTraits::size_type size_type;
226 null_scoped_destructor_n(pointer, Allocator&, size_type)
229 void increment_size(size_type)
232 void increment_size_backwards(size_type)
235 void shrink_forward(size_type)
242 template<class Allocator>
243 class scoped_destructor
245 typedef boost::container::allocator_traits<Allocator> AllocTraits;
247 typedef typename Allocator::value_type value_type;
248 scoped_destructor(Allocator &a, value_type *pv)
255 AllocTraits::destroy(a_, pv_);
263 void set(value_type *ptr) { pv_ = ptr; }
265 value_type *get() const { return pv_; }
273 template<class Allocator, class Value = typename Allocator::value_type>
274 class value_destructor
276 typedef boost::container::allocator_traits<Allocator> AllocTraits;
278 typedef Value value_type;
279 value_destructor(Allocator &a, value_type &rv)
285 AllocTraits::destroy(a_, &rv_);
293 template <class Allocator>
294 class allocator_destroyer
296 typedef boost::container::allocator_traits<Allocator> AllocTraits;
297 typedef typename AllocTraits::value_type value_type;
298 typedef typename AllocTraits::pointer pointer;
299 typedef dtl::integral_constant<unsigned,
300 boost::container::dtl::
301 version<Allocator>::value> alloc_version;
307 void priv_deallocate(const pointer &p, version_1)
308 { AllocTraits::deallocate(a_,p, 1); }
310 void priv_deallocate(const pointer &p, version_2)
311 { a_.deallocate_one(p); }
314 explicit allocator_destroyer(Allocator &a)
318 void operator()(const pointer &p)
320 AllocTraits::destroy(a_, boost::movelib::to_raw_pointer(p));
321 this->priv_deallocate(p, alloc_version());
325 template <class Allocator>
326 class allocator_destroyer_and_chain_builder
328 typedef allocator_traits<Allocator> allocator_traits_type;
329 typedef typename allocator_traits_type::value_type value_type;
330 typedef typename Allocator::multiallocation_chain multiallocation_chain;
333 multiallocation_chain &c_;
336 allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
340 void operator()(const typename Allocator::pointer &p)
342 allocator_traits<Allocator>::destroy(a_, boost::movelib::to_raw_pointer(p));
347 template <class Allocator>
348 class allocator_multialloc_chain_node_deallocator
350 typedef allocator_traits<Allocator> allocator_traits_type;
351 typedef typename allocator_traits_type::value_type value_type;
352 typedef typename Allocator::multiallocation_chain multiallocation_chain;
353 typedef allocator_destroyer_and_chain_builder<Allocator> chain_builder;
356 multiallocation_chain c_;
359 allocator_multialloc_chain_node_deallocator(Allocator &a)
363 chain_builder get_chain_builder()
364 { return chain_builder(a_, c_); }
366 ~allocator_multialloc_chain_node_deallocator()
368 a_.deallocate_individual(c_);
373 } //namespace container {
374 } //namespace boost {
376 #include <boost/container/detail/config_end.hpp>
378 #endif //#ifndef BOOST_CONTAINER_DESTROYERS_HPP