#ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED #define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif // // This file is the adaptation for shared memory memory mapped // files of boost/detail/sp_counted_impl.hpp // // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. // Copyright 2004-2005 Peter Dimov // Copyright 2006 Ion Gaztanaga // // 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) // #include #include #include #include #include #include #include namespace boost { namespace interprocess { namespace ipcdetail { //!A deleter for scoped_ptr that deallocates the memory //!allocated for an object using a STL allocator. template struct scoped_ptr_dealloc_functor { typedef typename Allocator::pointer pointer; typedef ipcdetail::integral_constant::value> alloc_version; typedef ipcdetail::integral_constant allocator_v1; typedef ipcdetail::integral_constant allocator_v2; private: void priv_deallocate(const typename Allocator::pointer &p, allocator_v1) { m_alloc.deallocate(p, 1); } void priv_deallocate(const typename Allocator::pointer &p, allocator_v2) { m_alloc.deallocate_one(p); } public: Allocator& m_alloc; scoped_ptr_dealloc_functor(Allocator& a) : m_alloc(a) {} void operator()(pointer ptr) { if (ptr) priv_deallocate(ptr, alloc_version()); } }; template class sp_counted_impl_pd : public sp_counted_base , boost::container::allocator_traits::template portable_rebind_alloc< sp_counted_impl_pd >::type , D // copy constructor must not throw { private: typedef sp_counted_impl_pd this_type; typedef typename boost::container:: allocator_traits::template portable_rebind_alloc < this_type >::type this_allocator; typedef typename boost::container:: allocator_traits::template portable_rebind_alloc < const this_type >::type const_this_allocator; typedef typename this_allocator::pointer this_pointer; sp_counted_impl_pd( sp_counted_impl_pd const & ); sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); typedef typename boost::intrusive:: pointer_traits::template rebind_pointer::type const_deleter_pointer; typedef typename boost::intrusive:: pointer_traits::template rebind_pointer::type const_allocator_pointer; typedef typename D::pointer pointer; pointer m_ptr; public: // pre: d(p) must not throw template sp_counted_impl_pd(const Ptr & p, const A &a, const D &d ) : this_allocator(a), D(d), m_ptr(p) {} const_deleter_pointer get_deleter() const { return const_deleter_pointer(&static_cast(*this)); } const_allocator_pointer get_allocator() const { return const_allocator_pointer(&static_cast(*this)); } void dispose() // nothrow { static_cast(*this)(m_ptr); } void destroy() // nothrow { //Self destruction, so get a copy of the allocator //(in the future we could move it) this_allocator a_copy(*this); BOOST_ASSERT(a_copy == *this); this_pointer this_ptr (this); //Do it now! scoped_ptr< this_type, scoped_ptr_dealloc_functor > deleter(this_ptr, a_copy); typedef typename this_allocator::value_type value_type; ipcdetail::to_raw_pointer(this_ptr)->~value_type(); } void release() // nothrow { if(this->ref_release()){ this->dispose(); this->weak_release(); } } void weak_release() // nothrow { if(sp_counted_base::weak_release()){ this->destroy(); } } }; } // namespace ipcdetail } // namespace interprocess } // namespace boost #include #endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED