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