00001 /* OOQP * 00002 * Authors: E. Michael Gertz, Stephen J. Wright * 00003 * (C) 2001 University of Chicago. See Copyright Notification in OOQP */ 00004 00005 #ifndef SMARTPOINTER 00006 #define SMARTPOINTER 00007 00015 #include "assert.h" 00016 00110 template <class T> 00111 class SmartPointer { 00112 public: 00114 SmartPointer() : obj(0) {}; 00116 00121 SmartPointer( const SmartPointer<T>& sp ) 00122 { 00123 this->obj = sp.ptr(); 00124 }; 00125 #ifdef HAVE_MEMBER_TEMPLATES 00126 template <class S> 00127 SmartPointer( const SmartPointer<S>& sp ) 00128 { 00129 this->obj = sp.ptr(); 00130 } 00131 #endif 00132 00133 00134 00135 T& operator*() { return *obj; }; 00136 const T& operator*() const { return *obj; }; 00138 00139 00143 SmartPointer<T>& operator=( const SmartPointer<T>& sp) 00144 { 00145 T * newobj = sp.ptr(); 00146 if( this->obj ) IotrRelease( &this->obj ); 00147 00148 this->obj = newobj; 00149 00150 return *this; 00151 }; 00152 #ifdef HAVE_MEMBER_TEMPLATES 00153 template <class S> 00154 SmartPointer<T>& operator=(const SmartPointer<S>& sp) 00155 { 00156 S * ptrin = sp.ptr(); 00157 if( this->obj ) IotrRelease( &this->obj ); 00158 00159 this->obj = ptrin; 00160 00161 return *this; 00162 } 00163 #endif 00164 00165 00168 ~SmartPointer() 00169 { 00170 if( obj ) IotrRelease( &obj ); 00171 } 00173 00176 T * operator->() { 00177 return obj; 00178 } 00179 const T * operator->() const { 00180 return obj; 00181 } 00183 00187 operator T*() 00188 { 00189 return obj; 00190 } 00193 static void bind( SmartPointer<T>& sp, T ** obj ) 00194 { 00195 sp.obj = *obj; 00196 *obj = 0; 00197 } 00200 static void referTo( SmartPointer<T>& sp, T * obj ) 00201 { 00202 if( obj ) IotrAddRef( &obj ); 00203 if( sp.obj ) IotrRelease( &sp.obj ); 00204 00205 sp.obj = obj; 00206 } 00209 T * ptr() const 00210 { 00211 if (obj) IotrAddRef( &obj ); 00212 00213 return obj; 00214 } 00215 00219 #ifdef HAVE_EXPLICIT 00220 explicit 00221 #endif 00222 SmartPointer( T * t ) { obj = t; } 00223 protected: 00225 T * obj; 00226 }; 00227 00231 template <class T> 00232 inline void SpNil( SmartPointer<T>& sp ) 00233 { 00234 T * t = 0; 00235 SmartPointer<T>::bind( sp, &t ); 00236 } 00237 00242 template <class T> 00243 inline void SpReferTo( SmartPointer<T>& sp, T * obj ) 00244 { 00245 SmartPointer<T>::referTo( sp, obj ); 00246 } 00247 00248 00256 template <class T> 00257 inline T * SpAsPointer( SmartPointer<T>& sp ) 00258 { 00259 return sp.ptr(); 00260 } 00261 00262 #endif