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