#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 <boost/interprocess/detail/config_begin.hpp> | |
#include <boost/interprocess/detail/workaround.hpp> | |
#include <boost/interprocess/smart_ptr/detail/sp_counted_base.hpp> | |
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp> | |
#include <boost/interprocess/detail/utilities.hpp> | |
#include <boost/pointer_to_other.hpp> | |
namespace boost { | |
namespace interprocess { | |
namespace detail { | |
//!A deleter for scoped_ptr that deallocates the memory | |
//!allocated for an object using a STL allocator. | |
template <class Allocator> | |
struct scoped_ptr_dealloc_functor | |
{ | |
typedef typename Allocator::pointer pointer; | |
typedef detail::integral_constant<unsigned, | |
boost::interprocess::version<Allocator>::value> alloc_version; | |
typedef detail::integral_constant<unsigned, 1> allocator_v1; | |
typedef detail::integral_constant<unsigned, 2> 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 A, class D> | |
class sp_counted_impl_pd | |
: public sp_counted_base | |
, A::template rebind< sp_counted_impl_pd<A, D> >::other | |
, D // copy constructor must not throw | |
{ | |
private: | |
typedef sp_counted_impl_pd<A, D> this_type; | |
typedef typename A::template rebind | |
<this_type>::other this_allocator; | |
typedef typename A::template rebind | |
<const this_type>::other 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::pointer_to_other | |
<typename A::pointer, const D>::type const_deleter_pointer; | |
typedef typename boost::pointer_to_other | |
<typename A::pointer, const A>::type const_allocator_pointer; | |
typedef typename D::pointer pointer; | |
pointer m_ptr; | |
public: | |
// pre: d(p) must not throw | |
template<class Ptr> | |
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<const D&>(*this)); } | |
const_allocator_pointer get_allocator() const | |
{ return const_allocator_pointer(&static_cast<const A&>(*this)); } | |
void dispose() // nothrow | |
{ static_cast<D&>(*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<this_allocator> > | |
deleter(this_ptr, a_copy); | |
typedef typename this_allocator::value_type value_type; | |
detail::get_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 detail | |
} // namespace interprocess | |
} // namespace boost | |
#include <boost/interprocess/detail/config_end.hpp> | |
#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED |