| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 | ////////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga 2005-2013.//// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/container for documentation.////////////////////////////////////////////////////////////////////////////////#ifndef BOOST_CONTAINER_DESTROYERS_HPP#define BOOST_CONTAINER_DESTROYERS_HPP#ifndef BOOST_CONFIG_HPP#  include <boost/config.hpp>#endif#if defined(BOOST_HAS_PRAGMA_ONCE)#  pragma once#endif#include <boost/container/detail/config_begin.hpp>#include <boost/container/detail/workaround.hpp>#include <boost/container/allocator_traits.hpp>#include <boost/move/detail/to_raw_pointer.hpp>#include <boost/container/detail/version_type.hpp>namespace boost {namespace container {namespace dtl {//!A deleter for scoped_ptr that deallocates the memory//!allocated for an object using a STL allocator.template <class Allocator>struct scoped_deallocator{   typedef allocator_traits<Allocator> allocator_traits_type;   typedef typename allocator_traits_type::pointer pointer;   typedef dtl::integral_constant<unsigned,      boost::container::dtl::         version<Allocator>::value>                   alloc_version;   private:   void priv_deallocate(version_1)   {  m_alloc.deallocate(m_ptr, 1); }   void priv_deallocate(version_2)   {  m_alloc.deallocate_one(m_ptr); }   BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)   public:   pointer     m_ptr;   Allocator&  m_alloc;   scoped_deallocator(pointer p, Allocator& a)      : m_ptr(p), m_alloc(a)   {}   ~scoped_deallocator()   {  if (m_ptr)priv_deallocate(alloc_version());  }   scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)      :  m_ptr(o.m_ptr), m_alloc(o.m_alloc)   {  o.release();  }   pointer get() const   {  return m_ptr;  }   void set(const pointer &p)   {  m_ptr = p;  }   void release()   {  m_ptr = 0; }};template <class Allocator>struct null_scoped_deallocator{   typedef boost::container::allocator_traits<Allocator> AllocTraits;   typedef typename AllocTraits::pointer    pointer;   typedef typename AllocTraits::size_type  size_type;   null_scoped_deallocator(pointer, Allocator&, size_type)   {}   void release()   {}   pointer get() const   {  return pointer();  }   void set(const pointer &)   {}};//!A deleter for scoped_ptr that deallocates the memory//!allocated for an array of objects using a STL allocator.template <class Allocator>struct scoped_array_deallocator{   typedef boost::container::allocator_traits<Allocator> AllocTraits;   typedef typename AllocTraits::pointer    pointer;   typedef typename AllocTraits::size_type  size_type;   scoped_array_deallocator(pointer p, Allocator& a, size_type length)      : m_ptr(p), m_alloc(a), m_length(length) {}   ~scoped_array_deallocator()   {  if (m_ptr) m_alloc.deallocate(m_ptr, m_length);  }   void release()   {  m_ptr = 0; }   private:   pointer     m_ptr;   Allocator&  m_alloc;   size_type   m_length;};template <class Allocator>struct null_scoped_array_deallocator{   typedef boost::container::allocator_traits<Allocator> AllocTraits;   typedef typename AllocTraits::pointer    pointer;   typedef typename AllocTraits::size_type  size_type;   null_scoped_array_deallocator(pointer, Allocator&, size_type)   {}   void release()   {}};template <class Allocator>struct scoped_destroy_deallocator{   typedef boost::container::allocator_traits<Allocator> AllocTraits;   typedef typename AllocTraits::pointer    pointer;   typedef typename AllocTraits::size_type  size_type;   typedef dtl::integral_constant<unsigned,      boost::container::dtl::         version<Allocator>::value>                          alloc_version;   scoped_destroy_deallocator(pointer p, Allocator& a)      : m_ptr(p), m_alloc(a) {}   ~scoped_destroy_deallocator()   {      if(m_ptr){         AllocTraits::destroy(m_alloc, boost::movelib::to_raw_pointer(m_ptr));         priv_deallocate(m_ptr, alloc_version());      }   }   void release()   {  m_ptr = 0; }   private:   void priv_deallocate(const pointer &p, version_1)   {  AllocTraits::deallocate(m_alloc, p, 1); }   void priv_deallocate(const pointer &p, version_2)   {  m_alloc.deallocate_one(p); }   pointer     m_ptr;   Allocator&  m_alloc;};//!A deleter for scoped_ptr that destroys//!an object using a STL allocator.template <class Allocator>struct scoped_destructor_n{   typedef boost::container::allocator_traits<Allocator> AllocTraits;   typedef typename AllocTraits::pointer    pointer;   typedef typename AllocTraits::value_type value_type;   typedef typename AllocTraits::size_type  size_type;   scoped_destructor_n(pointer p, Allocator& a, size_type n)      : m_p(p), m_a(a), m_n(n)   {}   void release()   {  m_p = 0; }   void increment_size(size_type inc)   {  m_n += inc;   }   void increment_size_backwards(size_type inc)   {  m_n += inc;   m_p -= inc;  }   void shrink_forward(size_type inc)   {  m_n -= inc;   m_p += inc;  }   ~scoped_destructor_n()   {      if(!m_p) return;      value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);      while(m_n--){         AllocTraits::destroy(m_a, raw_ptr++);      }   }   private:   pointer     m_p;   Allocator & m_a;   size_type   m_n;};//!A deleter for scoped_ptr that destroys//!an object using a STL allocator.template <class Allocator>struct null_scoped_destructor_n{   typedef boost::container::allocator_traits<Allocator> AllocTraits;   typedef typename AllocTraits::pointer pointer;   typedef typename AllocTraits::size_type size_type;   null_scoped_destructor_n(pointer, Allocator&, size_type)   {}   void increment_size(size_type)   {}   void increment_size_backwards(size_type)   {}   void shrink_forward(size_type)   {}   void release()   {}};template<class Allocator>class scoped_destructor{   typedef boost::container::allocator_traits<Allocator> AllocTraits;   public:   typedef typename Allocator::value_type value_type;   scoped_destructor(Allocator &a, value_type *pv)      : pv_(pv), a_(a)   {}   ~scoped_destructor()   {      if(pv_){         AllocTraits::destroy(a_, pv_);      }   }   void release()   {  pv_ = 0; }   void set(value_type *ptr) { pv_ = ptr; }   value_type *get() const { return pv_; }   private:   value_type *pv_;   Allocator &a_;};template<class Allocator, class Value = typename Allocator::value_type>class value_destructor{   typedef boost::container::allocator_traits<Allocator> AllocTraits;   public:   typedef Value value_type;   value_destructor(Allocator &a, value_type &rv)      : rv_(rv), a_(a)   {}   ~value_destructor()   {      AllocTraits::destroy(a_, &rv_);   }   private:   value_type &rv_;   Allocator &a_;};template <class Allocator>class allocator_destroyer{   typedef boost::container::allocator_traits<Allocator> AllocTraits;   typedef typename AllocTraits::value_type value_type;   typedef typename AllocTraits::pointer    pointer;   typedef dtl::integral_constant<unsigned,      boost::container::dtl::         version<Allocator>::value>                           alloc_version;   private:   Allocator & a_;   private:   void priv_deallocate(const pointer &p, version_1)   {  AllocTraits::deallocate(a_,p, 1); }   void priv_deallocate(const pointer &p, version_2)   {  a_.deallocate_one(p); }   public:   explicit allocator_destroyer(Allocator &a)      : a_(a)   {}   void operator()(const pointer &p)   {      AllocTraits::destroy(a_, boost::movelib::to_raw_pointer(p));      this->priv_deallocate(p, alloc_version());   }};template <class Allocator>class allocator_destroyer_and_chain_builder{   typedef allocator_traits<Allocator> allocator_traits_type;   typedef typename allocator_traits_type::value_type value_type;   typedef typename Allocator::multiallocation_chain    multiallocation_chain;   Allocator & a_;   multiallocation_chain &c_;   public:   allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)      :  a_(a), c_(c)   {}   void operator()(const typename Allocator::pointer &p)   {      allocator_traits<Allocator>::destroy(a_, boost::movelib::to_raw_pointer(p));      c_.push_back(p);   }};template <class Allocator>class allocator_multialloc_chain_node_deallocator{   typedef allocator_traits<Allocator> allocator_traits_type;   typedef typename allocator_traits_type::value_type value_type;   typedef typename Allocator::multiallocation_chain    multiallocation_chain;   typedef allocator_destroyer_and_chain_builder<Allocator> chain_builder;   Allocator & a_;   multiallocation_chain c_;   public:   allocator_multialloc_chain_node_deallocator(Allocator &a)      :  a_(a), c_()   {}   chain_builder get_chain_builder()   {  return chain_builder(a_, c_);  }   ~allocator_multialloc_chain_node_deallocator()   {      a_.deallocate_individual(c_);   }};}  //namespace dtl {}  //namespace container {}  //namespace boost {#include <boost/container/detail/config_end.hpp>#endif   //#ifndef BOOST_CONTAINER_DESTROYERS_HPP
 |