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
1.2.14 written by Dimitri van Heesch,
© 1997-2002