CppCMS
|
00001 #ifndef BOOSTER_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED 00002 #define BOOSTER_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED 00003 00004 // 00005 // detail/sp_counted_impl.hpp 00006 // 00007 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 00008 // Copyright 2004-2005 Peter Dimov 00009 // 00010 // Distributed under the Boost Software License, Version 1.0. (See 00011 // accompanying file LICENSE_1_0.txt or copy at 00012 // http://www.boost.org/LICENSE_1_0.txt) 00013 // 00014 00015 #include <booster/config.h> 00016 00017 #include <booster/checked_delete.h> 00018 #include <booster/smart_ptr/sp_counted_base.h> 00019 00020 #if defined(BOOSTER_SP_USE_STD_ALLOCATOR) 00021 #include <memory> // std::allocator 00022 #endif 00023 00024 #include <cstddef> // std::size_t 00025 00026 namespace booster 00027 { 00028 00029 namespace detail 00030 { 00031 00032 template<class X> class sp_counted_impl_p: public sp_counted_base 00033 { 00034 private: 00035 00036 X * px_; 00037 00038 sp_counted_impl_p( sp_counted_impl_p const & ); 00039 sp_counted_impl_p & operator= ( sp_counted_impl_p const & ); 00040 00041 typedef sp_counted_impl_p<X> this_type; 00042 00043 public: 00044 00045 explicit sp_counted_impl_p( X * px ): px_( px ) 00046 { 00047 } 00048 00049 virtual void dispose() // nothrow 00050 { 00051 booster::checked_delete( px_ ); 00052 } 00053 00054 virtual void * get_deleter( detail::sp_typeinfo const & ) 00055 { 00056 return 0; 00057 } 00058 00059 void * operator new( std::size_t ) 00060 { 00061 return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) ); 00062 } 00063 00064 void operator delete( void * p ) 00065 { 00066 std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 ); 00067 } 00068 }; 00069 00070 // 00071 // Borland's Codeguard trips up over the -Vx- option here: 00072 // 00073 #ifdef __CODEGUARD__ 00074 # pragma option push -Vx- 00075 #endif 00076 00077 template<class P, class D> class sp_counted_impl_pd: public sp_counted_base 00078 { 00079 private: 00080 00081 P ptr; // copy constructor must not throw 00082 D del; // copy constructor must not throw 00083 00084 sp_counted_impl_pd( sp_counted_impl_pd const & ); 00085 sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); 00086 00087 typedef sp_counted_impl_pd<P, D> this_type; 00088 00089 public: 00090 00091 // pre: d(p) must not throw 00092 00093 sp_counted_impl_pd( P p, D d ): ptr(p), del(d) 00094 { 00095 } 00096 00097 virtual void dispose() // nothrow 00098 { 00099 del( ptr ); 00100 } 00101 00102 virtual void * get_deleter( detail::sp_typeinfo const & ti ) 00103 { 00104 return ti == BOOSTER_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0; 00105 } 00106 00107 void * operator new( std::size_t ) 00108 { 00109 return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) ); 00110 } 00111 00112 void operator delete( void * p ) 00113 { 00114 std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 ); 00115 } 00116 00117 }; 00118 00119 template<class P, class D, class A> class sp_counted_impl_pda: public sp_counted_base 00120 { 00121 private: 00122 00123 P p_; // copy constructor must not throw 00124 D d_; // copy constructor must not throw 00125 A a_; // copy constructor must not throw 00126 00127 sp_counted_impl_pda( sp_counted_impl_pda const & ); 00128 sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & ); 00129 00130 typedef sp_counted_impl_pda<P, D, A> this_type; 00131 00132 public: 00133 00134 // pre: d( p ) must not throw 00135 00136 sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a ) 00137 { 00138 } 00139 00140 virtual void dispose() // nothrow 00141 { 00142 d_( p_ ); 00143 } 00144 00145 virtual void destroy() // nothrow 00146 { 00147 typedef typename A::template rebind< this_type >::other A2; 00148 00149 A2 a2( a_ ); 00150 00151 this->~this_type(); 00152 a2.deallocate( this, 1 ); 00153 } 00154 00155 virtual void * get_deleter( detail::sp_typeinfo const & ti ) 00156 { 00157 return ti == BOOSTER_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0; 00158 } 00159 }; 00160 00161 #ifdef __CODEGUARD__ 00162 # pragma option pop 00163 #endif 00164 00165 } // namespace detail 00166 00167 } // namespace boost 00168 00169 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED