File indexing completed on 2025-01-18 09:51:43
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/sp_noexcept.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 * ) BOOST_SP_NOEXCEPT
0056 {
0057 return 0;
0058 }
0059
0060 template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_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() BOOST_SP_NOEXCEPT BOOST_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 & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0093 {
0094 return 0;
0095 }
0096
0097 void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0098 {
0099 return 0;
0100 }
0101
0102 void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_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
0137
0138
0139 #ifdef __CODEGUARD__
0140 # pragma option push -Vx-
0141 #endif
0142
0143 template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public sp_counted_base
0144 {
0145 private:
0146
0147 P ptr;
0148 D del;
0149
0150 sp_counted_impl_pd( sp_counted_impl_pd const & );
0151 sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
0152
0153 typedef sp_counted_impl_pd<P, D> this_type;
0154
0155 public:
0156
0157
0158
0159 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
0160
0161 sp_counted_impl_pd( P p, D & d ): ptr( p ), del( static_cast< D&& >( d ) )
0162 {
0163 }
0164
0165 #else
0166
0167 sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
0168 {
0169 }
0170
0171 #endif
0172
0173 sp_counted_impl_pd( P p ): ptr( p ), del()
0174 {
0175 }
0176
0177 void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0178 {
0179 del( ptr );
0180 }
0181
0182 void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0183 {
0184 return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0;
0185 }
0186
0187 void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0188 {
0189 return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
0190 }
0191
0192 void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0193 {
0194 return &reinterpret_cast<char&>( del );
0195 }
0196
0197 #if defined(BOOST_SP_USE_STD_ALLOCATOR)
0198
0199 void * operator new( std::size_t )
0200 {
0201 return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
0202 }
0203
0204 void operator delete( void * p )
0205 {
0206 std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
0207 }
0208
0209 #endif
0210
0211 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
0212
0213 void * operator new( std::size_t )
0214 {
0215 return quick_allocator<this_type>::alloc();
0216 }
0217
0218 void operator delete( void * p )
0219 {
0220 quick_allocator<this_type>::dealloc( p );
0221 }
0222
0223 #endif
0224 };
0225
0226 template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base
0227 {
0228 private:
0229
0230 P p_;
0231 D d_;
0232 A a_;
0233
0234 sp_counted_impl_pda( sp_counted_impl_pda const & );
0235 sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
0236
0237 typedef sp_counted_impl_pda<P, D, A> this_type;
0238
0239 public:
0240
0241
0242
0243 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
0244
0245 sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( static_cast< D&& >( d ) ), a_( a )
0246 {
0247 }
0248
0249 #else
0250
0251 sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
0252 {
0253 }
0254
0255 #endif
0256
0257 sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
0258 {
0259 }
0260
0261 void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0262 {
0263 d_( p_ );
0264 }
0265
0266 void destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0267 {
0268 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
0269
0270 typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
0271
0272 #else
0273
0274 typedef typename A::template rebind< this_type >::other A2;
0275
0276 #endif
0277
0278 A2 a2( a_ );
0279
0280 this->~this_type();
0281
0282 a2.deallocate( this, 1 );
0283 }
0284
0285 void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0286 {
0287 return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0;
0288 }
0289
0290 void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0291 {
0292 return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
0293 }
0294
0295 void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
0296 {
0297 return &reinterpret_cast<char&>( d_ );
0298 }
0299 };
0300
0301 #ifdef __CODEGUARD__
0302 # pragma option pop
0303 #endif
0304
0305 }
0306
0307 }
0308
0309 #endif