CppCMS
booster/smart_ptr/sp_counted_impl.h
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