Go to the documentation of this file.00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
00003
00004
00005
00006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
00007 # pragma once
00008 #endif
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <boost/config.hpp>
00022
00023 #if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
00024 # error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
00025 #endif
00026
00027 #include <boost/checked_delete.hpp>
00028 #include <boost/smart_ptr/detail/sp_counted_base.hpp>
00029
00030 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
00031 #include <boost/smart_ptr/detail/quick_allocator.hpp>
00032 #endif
00033
00034 #if defined(BOOST_SP_USE_STD_ALLOCATOR)
00035 #include <memory>
00036 #endif
00037
00038 #include <cstddef>
00039
00040 namespace boost
00041 {
00042
00043 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00044
00045 void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
00046 void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
00047
00048 #endif
00049
00050 namespace detail
00051 {
00052
00053 template<class X> class sp_counted_impl_p: public sp_counted_base
00054 {
00055 private:
00056
00057 X * px_;
00058
00059 sp_counted_impl_p( sp_counted_impl_p const & );
00060 sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
00061
00062 typedef sp_counted_impl_p<X> this_type;
00063
00064 public:
00065
00066 explicit sp_counted_impl_p( X * px ): px_( px )
00067 {
00068 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00069 boost::sp_scalar_constructor_hook( px, sizeof(X), this );
00070 #endif
00071 }
00072
00073 virtual void dispose()
00074 {
00075 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
00076 boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
00077 #endif
00078 boost::checked_delete( px_ );
00079 }
00080
00081 virtual void * get_deleter( detail::sp_typeinfo const & )
00082 {
00083 return 0;
00084 }
00085
00086 #if defined(BOOST_SP_USE_STD_ALLOCATOR)
00087
00088 void * operator new( std::size_t )
00089 {
00090 return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
00091 }
00092
00093 void operator delete( void * p )
00094 {
00095 std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
00096 }
00097
00098 #endif
00099
00100 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
00101
00102 void * operator new( std::size_t )
00103 {
00104 return quick_allocator<this_type>::alloc();
00105 }
00106
00107 void operator delete( void * p )
00108 {
00109 quick_allocator<this_type>::dealloc( p );
00110 }
00111
00112 #endif
00113 };
00114
00115
00116
00117
00118 #ifdef __CODEGUARD__
00119 # pragma option push -Vx-
00120 #endif
00121
00122 template<class P, class D> class sp_counted_impl_pd: public sp_counted_base
00123 {
00124 private:
00125
00126 P ptr;
00127 D del;
00128
00129 sp_counted_impl_pd( sp_counted_impl_pd const & );
00130 sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
00131
00132 typedef sp_counted_impl_pd<P, D> this_type;
00133
00134 public:
00135
00136
00137
00138 sp_counted_impl_pd( P p, D d ): ptr(p), del(d)
00139 {
00140 }
00141
00142 virtual void dispose()
00143 {
00144 del( ptr );
00145 }
00146
00147 virtual void * get_deleter( detail::sp_typeinfo const & ti )
00148 {
00149 return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
00150 }
00151
00152 #if defined(BOOST_SP_USE_STD_ALLOCATOR)
00153
00154 void * operator new( std::size_t )
00155 {
00156 return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
00157 }
00158
00159 void operator delete( void * p )
00160 {
00161 std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
00162 }
00163
00164 #endif
00165
00166 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
00167
00168 void * operator new( std::size_t )
00169 {
00170 return quick_allocator<this_type>::alloc();
00171 }
00172
00173 void operator delete( void * p )
00174 {
00175 quick_allocator<this_type>::dealloc( p );
00176 }
00177
00178 #endif
00179 };
00180
00181 template<class P, class D, class A> class sp_counted_impl_pda: public sp_counted_base
00182 {
00183 private:
00184
00185 P p_;
00186 D d_;
00187 A a_;
00188
00189 sp_counted_impl_pda( sp_counted_impl_pda const & );
00190 sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
00191
00192 typedef sp_counted_impl_pda<P, D, A> this_type;
00193
00194 public:
00195
00196
00197
00198 sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a )
00199 {
00200 }
00201
00202 virtual void dispose()
00203 {
00204 d_( p_ );
00205 }
00206
00207 virtual void destroy()
00208 {
00209 typedef typename A::template rebind< this_type >::other A2;
00210
00211 A2 a2( a_ );
00212
00213 this->~this_type();
00214 a2.deallocate( this, 1 );
00215 }
00216
00217 virtual void * get_deleter( detail::sp_typeinfo const & ti )
00218 {
00219 return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
00220 }
00221 };
00222
00223 #ifdef __CODEGUARD__
00224 # pragma option pop
00225 #endif
00226
00227 }
00228
00229 }
00230
00231 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED