File indexing completed on 2025-09-16 08:49:57
0001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
0003
0004
0005
0006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0007 # pragma once
0008 #endif
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
0022 # error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
0023 #endif
0024
0025 #include <boost/smart_ptr/detail/sp_counted_base.hpp>
0026 #include <boost/smart_ptr/detail/deprecated_macros.hpp>
0027 #include <boost/core/checked_delete.hpp>
0028 #include <boost/core/addressof.hpp>
0029 #include <boost/config.hpp>
0030
0031 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
0032 #include <boost/smart_ptr/detail/quick_allocator.hpp>
0033 #endif
0034
0035 #include <memory> // std::allocator, std::allocator_traits
0036 #include <cstddef> // std::size_t
0037
0038 namespace boost
0039 {
0040
0041 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
0042
0043 void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
0044 void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
0045
0046 #endif
0047
0048 namespace detail
0049 {
0050
0051
0052
0053 template<class D> class local_sp_deleter;
0054
0055 template<class D> D * get_local_deleter( D * ) noexcept
0056 {
0057 return 0;
0058 }
0059
0060 template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) noexcept;
0061
0062
0063
0064 template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counted_base
0065 {
0066 private:
0067
0068 X * px_;
0069
0070 sp_counted_impl_p( sp_counted_impl_p const & );
0071 sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
0072
0073 typedef sp_counted_impl_p<X> this_type;
0074
0075 public:
0076
0077 explicit sp_counted_impl_p( X * px ): px_( px )
0078 {
0079 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
0080 boost::sp_scalar_constructor_hook( px, sizeof(X), this );
0081 #endif
0082 }
0083
0084 void dispose() noexcept override
0085 {
0086 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
0087 boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
0088 #endif
0089 boost::checked_delete( px_ );
0090 }
0091
0092 void * get_deleter( sp_typeinfo_ const & ) noexcept override
0093 {
0094 return 0;
0095 }
0096
0097 void * get_local_deleter( sp_typeinfo_ const & ) noexcept override
0098 {
0099 return 0;
0100 }
0101
0102 void * get_untyped_deleter() noexcept override
0103 {
0104 return 0;
0105 }
0106
0107 #if defined(BOOST_SP_USE_STD_ALLOCATOR)
0108
0109 void * operator new( std::size_t )
0110 {
0111 return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
0112 }
0113
0114 void operator delete( void * p )
0115 {
0116 std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
0117 }
0118
0119 #endif
0120
0121 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
0122
0123 void * operator new( std::size_t )
0124 {
0125 return quick_allocator<this_type>::alloc();
0126 }
0127
0128 void operator delete( void * p )
0129 {
0130 quick_allocator<this_type>::dealloc( p );
0131 }
0132
0133 #endif
0134 };
0135
0136 template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public sp_counted_base
0137 {
0138 private:
0139
0140 P ptr;
0141 D del;
0142
0143 sp_counted_impl_pd( sp_counted_impl_pd const & );
0144 sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
0145
0146 typedef sp_counted_impl_pd<P, D> this_type;
0147
0148 public:
0149
0150
0151
0152 sp_counted_impl_pd( P p, D & d ): ptr( p ), del( static_cast< D&& >( d ) )
0153 {
0154 }
0155
0156 sp_counted_impl_pd( P p ): ptr( p ), del()
0157 {
0158 }
0159
0160 void dispose() noexcept override
0161 {
0162 del( ptr );
0163 }
0164
0165 void * get_deleter( sp_typeinfo_ const & ti ) noexcept override
0166 {
0167 return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0;
0168 }
0169
0170 void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept override
0171 {
0172 return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
0173 }
0174
0175 void * get_untyped_deleter() noexcept override
0176 {
0177 return &reinterpret_cast<char&>( del );
0178 }
0179
0180 #if defined(BOOST_SP_USE_STD_ALLOCATOR)
0181
0182 void * operator new( std::size_t )
0183 {
0184 return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
0185 }
0186
0187 void operator delete( void * p )
0188 {
0189 std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
0190 }
0191
0192 #endif
0193
0194 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
0195
0196 void * operator new( std::size_t )
0197 {
0198 return quick_allocator<this_type>::alloc();
0199 }
0200
0201 void operator delete( void * p )
0202 {
0203 quick_allocator<this_type>::dealloc( p );
0204 }
0205
0206 #endif
0207 };
0208
0209 template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base
0210 {
0211 private:
0212
0213 P p_;
0214 D d_;
0215 A a_;
0216
0217 sp_counted_impl_pda( sp_counted_impl_pda const & );
0218 sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
0219
0220 typedef sp_counted_impl_pda<P, D, A> this_type;
0221
0222 public:
0223
0224
0225
0226 sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( static_cast< D&& >( d ) ), a_( a )
0227 {
0228 }
0229
0230 sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
0231 {
0232 }
0233
0234 void dispose() noexcept override
0235 {
0236 d_( p_ );
0237 }
0238
0239 void destroy() noexcept override
0240 {
0241 typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
0242
0243 A2 a2( a_ );
0244
0245 this->~this_type();
0246
0247 a2.deallocate( this, 1 );
0248 }
0249
0250 void * get_deleter( sp_typeinfo_ const & ti ) noexcept override
0251 {
0252 return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0;
0253 }
0254
0255 void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept override
0256 {
0257 return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
0258 }
0259
0260 void * get_untyped_deleter() noexcept override
0261 {
0262 return &reinterpret_cast<char&>( d_ );
0263 }
0264 };
0265
0266 }
0267
0268 }
0269
0270 #endif