summaryrefslogtreecommitdiff
path: root/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp')
-rw-r--r--boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp b/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
new file mode 100644
index 0000000000..4e2e664c86
--- /dev/null
+++ b/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
@@ -0,0 +1,155 @@
+#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/container/allocator/allocator_traits.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+
+namespace boost {
+
+namespace interprocess {
+
+namespace ipcdetail {
+
+//!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 ipcdetail::integral_constant<unsigned,
+ boost::interprocess::version<Allocator>::value> alloc_version;
+ typedef ipcdetail::integral_constant<unsigned, 1> allocator_v1;
+ typedef ipcdetail::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
+ , boost::container::allocator_traits<A>::template
+ portable_rebind_alloc< sp_counted_impl_pd<A, D> >::type
+ , D // copy constructor must not throw
+{
+ private:
+ typedef sp_counted_impl_pd<A, D> this_type;
+ typedef typename boost::container::
+ allocator_traits<A>::template
+ portable_rebind_alloc
+ < this_type >::type this_allocator;
+ typedef typename boost::container::
+ allocator_traits<A>::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<typename A::pointer>::template
+ rebind_pointer<const D>::type const_deleter_pointer;
+ typedef typename boost::intrusive::
+ pointer_traits<typename A::pointer>::template
+ rebind_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;
+ 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 <boost/interprocess/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED