00001 ////////////////////////////////////////////////////////////////////// 00002 // Copyright (c) 2001-2002 David Pritchard <drpritch@alumni.uwaterloo.ca> 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License 00006 // as published by the Free Software Foundation; either 00007 // version 2 of the License, or (at your option) any later 00008 // version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 00019 #ifndef freecloth_resmgt_rcProxyShdPtr_inline_h 00020 #define freecloth_resmgt_rcProxyShdPtr_inline_h 00021 00022 #ifndef freecloth_base_debug_h 00023 #include <freecloth/base/debug.h> 00024 #endif 00025 00026 FREECLOTH_NAMESPACE_START 00027 00028 //////////////////////////////////////////////////////////////////////////////// 00029 // CLASS RCProxyShdPtrBase 00030 00031 //------------------------------------------------------------------------------ 00032 inline RCProxyShdPtrBase::RCProxyShdPtrBase() 00033 : _data( 0 ) 00034 { 00035 } 00036 00037 //////////////////////////////////////////////////////////////////////////////// 00038 // CLASS RCProxyShdPtrBase::Data 00039 00040 //------------------------------------------------------------------------------ 00041 inline RCProxyShdPtrBase::Data::Data( 00042 void* ptr, 00043 UInt32 count 00044 ) : _ptr( ptr ), 00045 _count( count ) 00046 { 00047 } 00048 00049 00050 //////////////////////////////////////////////////////////////////////////////// 00051 // CLASS RCProxyShdPtr 00052 00053 //------------------------------------------------------------------------------ 00054 template <class T> 00055 inline RCProxyShdPtr<T>::RCProxyShdPtr( T* ptr ) 00056 { 00057 //DGFX_TRACE_ENTER( "RCProxyShdPtr<" << typeid(T).name() << "> ctor" ); 00058 //DGFX_TRACE( "ptr = " << static_cast<void *>( ptr ) ); 00059 //DGFX_TRACE( "this = " << this ); 00060 if ( 0 != ptr ) { 00061 _data = new Data( ptr ); 00062 } 00063 //DGFX_TRACE( "count = " << ( _data ? _data->_count : 0 ) ); 00064 } 00065 00066 //------------------------------------------------------------------------------ 00067 template <class T> 00068 inline RCProxyShdPtr<T>::RCProxyShdPtr( const RCProxyShdPtr& rhs ) 00069 { 00070 //DGFX_TRACE_ENTER( "RCProxyShdPtr<" << typeid(T).name() << "> copy ctor" ); 00071 //DGFX_TRACE( "rhs = " << &rhs ); 00072 acquire( rhs._data ); 00073 } 00074 00075 //------------------------------------------------------------------------------ 00076 template <class T> 00077 inline RCProxyShdPtr<T>::~RCProxyShdPtr() 00078 { 00079 //DGFX_TRACE_ENTER( "RCProxyShdPtr<" << typeid(T).name() << "> dtor" ); 00080 //DGFX_TRACE( "this = " << this ); 00081 release(); 00082 } 00083 00084 //------------------------------------------------------------------------------ 00085 template <class T> 00086 inline RCProxyShdPtr<T>& 00087 RCProxyShdPtr<T>::operator=( const RCProxyShdPtr<T>& rhs ) 00088 { 00089 //DGFX_TRACE_ENTER( "RCProxyShdPtr<" << typeid(T).name() << ">::operator=" ); 00090 //DGFX_TRACE( "this = " << this ); 00091 //DGFX_TRACE( "rhs = " << &rhs ); 00092 if ( this != &rhs ) { 00093 release(); 00094 acquire( rhs._data ); 00095 } 00096 return *this; 00097 } 00098 00099 //------------------------------------------------------------------------------ 00100 template <class T> 00101 inline bool RCProxyShdPtr<T>::operator==( const RCProxyShdPtr<T>& rhs ) const 00102 { 00103 return _data == rhs._data; 00104 } 00105 00106 //------------------------------------------------------------------------------ 00107 template <class T> 00108 inline bool RCProxyShdPtr<T>::operator!=( const RCProxyShdPtr<T>& rhs ) const 00109 { 00110 return _data != rhs._data; 00111 } 00112 00113 #if 0 00114 //------------------------------------------------------------------------------ 00115 template <class T,class X> 00116 inline RCProxyShdPtr<T>::RCProxyShdPtr( const RCProxyShdPtr<X>& rhs ) 00117 { 00118 // verify that X* can be converted to T* (i.e. X* is const T*, or 00119 // T is a base class of X) 00120 X* x; 00121 T* t = x; 00122 00123 // FIXME: will this work? 00124 acquire( rhs._data ); 00125 } 00126 00127 //------------------------------------------------------------------------------ 00128 template <class T,class X> 00129 inline RCProxyShdPtr<T>& 00130 RCProxyShdPtr<T>::operator=( const RCProxyShdPtr<X>& rhs ) 00131 { 00132 DGFX_ASSERT( this != &rhs ); 00133 00134 // verify that X* can be converted to T* (i.e. X* is const T*, or 00135 // T is a base class of X) 00136 X* x; 00137 T* t = x; 00138 00139 if ( this != &rhs ) { 00140 release(); 00141 acquire( rhs._data ); 00142 } 00143 return *this; 00144 } 00145 #endif 00146 00147 //------------------------------------------------------------------------------ 00148 template <class T> 00149 inline bool RCProxyShdPtr<T>::isNull() const 00150 { 00151 return _data == 0; 00152 } 00153 00154 //------------------------------------------------------------------------------ 00155 template <class T> 00156 inline T& RCProxyShdPtr<T>::operator*() const 00157 { 00158 DGFX_ASSERT( ! isNull() ); 00159 DGFX_ASSERT( 0 != _data->_ptr ); 00160 return *static_cast<T*>( _data->_ptr ); 00161 } 00162 00163 //------------------------------------------------------------------------------ 00164 template <class T> 00165 inline T* RCProxyShdPtr<T>::operator->() const 00166 { 00167 DGFX_ASSERT( ! isNull() ); 00168 DGFX_ASSERT( 0 != _data->_ptr ); 00169 return static_cast<T*>( _data->_ptr ); 00170 } 00171 00172 //------------------------------------------------------------------------------ 00173 template <class T> 00174 inline T* RCProxyShdPtr<T>::get() const 00175 { 00176 return static_cast<T*>( 0 != _data ? _data->_ptr : 0 ); 00177 } 00178 00179 //------------------------------------------------------------------------------ 00180 template <class T> 00181 inline void RCProxyShdPtr<T>::acquire( Data* data ) 00182 { 00183 //DGFX_TRACE_ENTER( "RCProxyShdPtr<" << typeid(T).name() << ">::acquire" ); 00184 //DGFX_TRACE( "this = " << this ); 00185 //DGFX_TRACE( "ptr = " << static_cast<void *>( data ? data->_ptr : 0 ) ); 00186 //DGFX_TRACE( "count = " << ( data ? data->_count : 0 ) ); 00187 _data = data; 00188 if ( 0 != _data ) { 00189 ++_data->_count; 00190 } 00191 } 00192 00193 //------------------------------------------------------------------------------ 00194 template <class T> 00195 inline void RCProxyShdPtr<T>::release() 00196 { 00197 //DGFX_TRACE_ENTER( "RCProxyShdPtr<" << typeid(T).name() << ">::release" ); 00198 //DGFX_TRACE( "this = " << this ); 00199 //DGFX_TRACE( "ptr = " << static_cast<void *>( isNull() ? 0 : _data->_ptr) ); 00200 //DGFX_TRACE( "count = " << ( _data ? _data->_count : 0 ) ); 00201 if ( _data ) { 00202 --_data->_count; 00203 if ( _data->_count == 0 ) { 00204 delete static_cast<T*>( _data->_ptr ); 00205 delete _data; 00206 } 00207 _data = 0; 00208 } 00209 } 00210 00211 00212 00213 //////////////////////////////////////////////////////////////////////////////// 00214 // GLOBAL FUNCTIONS 00215 00216 //------------------------------------------------------------------------------ 00217 template <class T> 00218 inline std::ostream& operator<<( 00219 std::ostream& out, 00220 const RCProxyShdPtr<T>& ptr 00221 ) 00222 { 00223 if ( ptr.isNull() ) { 00224 out << "(null)"; 00225 } 00226 else { 00227 out << *ptr; 00228 } 00229 return out; 00230 } 00231 00232 FREECLOTH_NAMESPACE_END 00233 00234 #endif