Go to the documentation of this file.00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_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
00022
00023
00024
00025
00026
00027 #include <boost/detail/interlocked.hpp>
00028 #include <boost/detail/workaround.hpp>
00029 #include <boost/detail/sp_typeinfo.hpp>
00030
00031 namespace boost
00032 {
00033
00034 namespace detail
00035 {
00036
00037 class sp_counted_base
00038 {
00039 private:
00040
00041 sp_counted_base( sp_counted_base const & );
00042 sp_counted_base & operator= ( sp_counted_base const & );
00043
00044 long use_count_;
00045 long weak_count_;
00046
00047 public:
00048
00049 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00050 {
00051 }
00052
00053 virtual ~sp_counted_base()
00054 {
00055 }
00056
00057
00058
00059
00060 virtual void dispose() = 0;
00061
00062
00063
00064 virtual void destroy()
00065 {
00066 delete this;
00067 }
00068
00069 virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00070
00071 void add_ref_copy()
00072 {
00073 BOOST_INTERLOCKED_INCREMENT( &use_count_ );
00074 }
00075
00076 bool add_ref_lock()
00077 {
00078 for( ;; )
00079 {
00080 long tmp = static_cast< long const volatile& >( use_count_ );
00081 if( tmp == 0 ) return false;
00082
00083 #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
00084
00085
00086
00087 long tmp2 = tmp + 1;
00088 if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
00089
00090 #else
00091
00092 if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
00093
00094 #endif
00095 }
00096 }
00097
00098 void release()
00099 {
00100 if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
00101 {
00102 dispose();
00103 weak_release();
00104 }
00105 }
00106
00107 void weak_add_ref()
00108 {
00109 BOOST_INTERLOCKED_INCREMENT( &weak_count_ );
00110 }
00111
00112 void weak_release()
00113 {
00114 if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
00115 {
00116 destroy();
00117 }
00118 }
00119
00120 long use_count() const
00121 {
00122 return static_cast<long const volatile &>( use_count_ );
00123 }
00124 };
00125
00126 }
00127
00128 }
00129
00130 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED