File indexing completed on 2025-01-18 09:38:30
0001 #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
0002 #define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
0003
0004 #ifndef BOOST_CONFIG_HPP
0005 # include <boost/config.hpp>
0006 #endif
0007 #
0008 #if defined(BOOST_HAS_PRAGMA_ONCE)
0009 # pragma once
0010 #endif
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <boost/interprocess/detail/config_begin.hpp>
0026 #include <boost/interprocess/detail/workaround.hpp>
0027
0028 #include <boost/interprocess/containers/version_type.hpp>
0029 #include <boost/interprocess/smart_ptr/detail/sp_counted_base.hpp>
0030 #include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
0031 #include <boost/interprocess/detail/utilities.hpp>
0032 #include <boost/container/allocator_traits.hpp>
0033 #include <boost/intrusive/pointer_traits.hpp>
0034
0035 namespace boost {
0036
0037 namespace interprocess {
0038
0039 namespace ipcdetail {
0040
0041
0042
0043 template <class Allocator>
0044 struct scoped_ptr_dealloc_functor
0045 {
0046 typedef typename boost::container::
0047 allocator_traits<Allocator>::pointer pointer;
0048
0049 typedef ipcdetail::integral_constant<unsigned,
0050 boost::interprocess::version<Allocator>::value> alloc_version;
0051 typedef ipcdetail::integral_constant<unsigned, 1> allocator_v1;
0052 typedef ipcdetail::integral_constant<unsigned, 2> allocator_v2;
0053
0054 private:
0055 void priv_deallocate(const pointer &p, allocator_v1)
0056 { m_alloc.deallocate(p, 1); }
0057
0058 void priv_deallocate(const pointer &p, allocator_v2)
0059 { m_alloc.deallocate_one(p); }
0060
0061 public:
0062 Allocator& m_alloc;
0063
0064 scoped_ptr_dealloc_functor(Allocator& a)
0065 : m_alloc(a) {}
0066
0067 void operator()(pointer ptr)
0068 { if (ptr) priv_deallocate(ptr, alloc_version()); }
0069 };
0070
0071
0072
0073 template<class A, class D>
0074 class sp_counted_impl_pd
0075 : public sp_counted_base
0076 , boost::container::allocator_traits<A>::template
0077 portable_rebind_alloc< sp_counted_impl_pd<A, D> >::type
0078 , D
0079 {
0080 private:
0081 typedef sp_counted_impl_pd<A, D> this_type;
0082 typedef typename boost::container::
0083 allocator_traits<A>::template
0084 portable_rebind_alloc
0085 < this_type >::type this_allocator;
0086 typedef typename boost::container::
0087 allocator_traits<A>::template
0088 portable_rebind_alloc
0089 < const this_type >::type const_this_allocator;
0090 typedef typename boost::container::
0091 allocator_traits<this_allocator>
0092 ::pointer this_pointer;
0093 typedef typename boost::container::
0094 allocator_traits<A>::pointer a_pointer;
0095 typedef typename boost::intrusive::
0096 pointer_traits<this_pointer> this_pointer_traits;
0097
0098 sp_counted_impl_pd( sp_counted_impl_pd const & );
0099 sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
0100
0101 typedef typename boost::intrusive::
0102 pointer_traits<a_pointer>::template
0103 rebind_pointer<const D>::type const_deleter_pointer;
0104 typedef typename boost::intrusive::
0105 pointer_traits<a_pointer>::template
0106 rebind_pointer<const A>::type const_allocator_pointer;
0107
0108 typedef typename D::pointer pointer;
0109 pointer m_ptr;
0110
0111 public:
0112
0113 template<class Ptr>
0114 sp_counted_impl_pd(const Ptr & p, const A &a, const D &d )
0115 : this_allocator(a), D(d), m_ptr(p)
0116 {}
0117
0118 const_deleter_pointer get_deleter() const
0119 { return const_deleter_pointer(&static_cast<const D&>(*this)); }
0120
0121 const_allocator_pointer get_allocator() const
0122 { return const_allocator_pointer(&static_cast<const A&>(*this)); }
0123
0124 void dispose()
0125 { static_cast<D&>(*this)(m_ptr); }
0126
0127 void destroy()
0128 {
0129
0130 this_allocator a_copy(::boost::move(static_cast<this_allocator&>(*this)));
0131 BOOST_ASSERT(a_copy == *this);
0132 this_pointer this_ptr(this_pointer_traits::pointer_to(*this));
0133
0134 scoped_ptr< this_type, scoped_ptr_dealloc_functor<this_allocator> >
0135 deleter_ptr(this_ptr, a_copy);
0136 ipcdetail::to_raw_pointer(this_ptr)->~this_type();
0137 }
0138
0139 void release()
0140 {
0141 if(this->ref_release()){
0142 this->dispose();
0143 this->weak_release();
0144 }
0145 }
0146
0147 void weak_release()
0148 {
0149 if(sp_counted_base::weak_release()){
0150 this->destroy();
0151 }
0152 }
0153 };
0154
0155
0156 }
0157
0158 }
0159
0160 }
0161
0162 #include <boost/interprocess/detail/config_end.hpp>
0163
0164 #endif