Planeshift
|
00001 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. 00002 // Copyright (c) 2001, 2002 Peter Dimov 00003 // 00004 // Permission to copy, use, modify, sell and distribute this software 00005 // is granted provided this copyright notice appears in all copies. 00006 // This software is provided "as is" without express or implied 00007 // warranty, and with no claim as to its suitability for any purpose. 00008 // 00009 // See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation. 00010 // 00011 00012 // scoped_ptr mimics a built-in pointer except that it guarantees deletion 00013 // of the object pointed to, either on destruction of the scoped_ptr or via 00014 // an explicit reset(). scoped_ptr is a simple solution for simple needs; 00015 // use shared_ptr or std::auto_ptr if your needs are more complex. 00016 00017 // *** NOTE *** 00018 // If your scoped_ptr is a class member of class FOO pointing to a 00019 // forward declared type BAR (as shown below), then you MUST use a non-inlined 00020 // version of the destructor. The destructor of a scoped_ptr (called from 00021 // FOO's destructor) must have a complete definition of BAR in order to 00022 // destroy it. Example: 00023 // 00024 // -- foo.h -- 00025 // class BAR; 00026 // 00027 // class FOO { 00028 // public: 00029 // FOO(); 00030 // ~FOO(); // Required for sources that instantiate class FOO to compile! 00031 // 00032 // private: 00033 // scoped_ptr<BAR> bar_; 00034 // }; 00035 // 00036 // -- foo.cc -- 00037 // #include "foo.h" 00038 // FOO::~FOO() {} // Empty, but must be non-inlined to FOO's class definition. 00039 00040 // scoped_ptr_malloc added by Google 00041 // When one of these goes out of scope, instead of doing a delete or 00042 // delete[], it calls free(). scoped_ptr_malloc<char> is likely to see 00043 // much more use than any other specializations. 00044 00045 // release() added by Google 00046 // Use this to conditionally transfer ownership of a heap-allocated object 00047 // to the caller, usually on method success. 00048 00049 #ifndef COMMON_SCOPED_PTR_H_ 00050 #define COMMON_SCOPED_PTR_H_ 00051 00052 #include <cstddef> // for std::ptrdiff_t 00053 #include <assert.h> // for assert 00054 #include <stdlib.h> // for free() decl 00055 00056 namespace google_breakpad { 00057 00058 template <typename T> 00059 class scoped_ptr { 00060 private: 00061 00062 T* ptr; 00063 00064 scoped_ptr(scoped_ptr const &); 00065 scoped_ptr & operator=(scoped_ptr const &); 00066 00067 public: 00068 00069 typedef T element_type; 00070 00071 explicit scoped_ptr(T* p = 0): ptr(p) {} 00072 00073 ~scoped_ptr() { 00074 typedef char type_must_be_complete[sizeof(T)]; 00075 delete ptr; 00076 } 00077 00078 void reset(T* p = 0) { 00079 typedef char type_must_be_complete[sizeof(T)]; 00080 00081 if (ptr != p) { 00082 delete ptr; 00083 ptr = p; 00084 } 00085 } 00086 00087 T& operator*() const { 00088 assert(ptr != 0); 00089 return *ptr; 00090 } 00091 00092 T* operator->() const { 00093 assert(ptr != 0); 00094 return ptr; 00095 } 00096 00097 bool operator==(T* p) const { 00098 return ptr == p; 00099 } 00100 00101 bool operator!=(T* p) const { 00102 return ptr != p; 00103 } 00104 00105 T* get() const { 00106 return ptr; 00107 } 00108 00109 void swap(scoped_ptr & b) { 00110 T* tmp = b.ptr; 00111 b.ptr = ptr; 00112 ptr = tmp; 00113 } 00114 00115 T* release() { 00116 T* tmp = ptr; 00117 ptr = 0; 00118 return tmp; 00119 } 00120 00121 private: 00122 00123 // no reason to use these: each scoped_ptr should have its own object 00124 template <typename U> bool operator==(scoped_ptr<U> const& p) const; 00125 template <typename U> bool operator!=(scoped_ptr<U> const& p) const; 00126 }; 00127 00128 template<typename T> inline 00129 void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) { 00130 a.swap(b); 00131 } 00132 00133 template<typename T> inline 00134 bool operator==(T* p, const scoped_ptr<T>& b) { 00135 return p == b.get(); 00136 } 00137 00138 template<typename T> inline 00139 bool operator!=(T* p, const scoped_ptr<T>& b) { 00140 return p != b.get(); 00141 } 00142 00143 // scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to 00144 // is guaranteed, either on destruction of the scoped_array or via an explicit 00145 // reset(). Use shared_array or std::vector if your needs are more complex. 00146 00147 template<typename T> 00148 class scoped_array { 00149 private: 00150 00151 T* ptr; 00152 00153 scoped_array(scoped_array const &); 00154 scoped_array & operator=(scoped_array const &); 00155 00156 public: 00157 00158 typedef T element_type; 00159 00160 explicit scoped_array(T* p = 0) : ptr(p) {} 00161 00162 ~scoped_array() { 00163 typedef char type_must_be_complete[sizeof(T)]; 00164 delete[] ptr; 00165 } 00166 00167 void reset(T* p = 0) { 00168 typedef char type_must_be_complete[sizeof(T)]; 00169 00170 if (ptr != p) { 00171 delete [] ptr; 00172 ptr = p; 00173 } 00174 } 00175 00176 T& operator[](std::ptrdiff_t i) const { 00177 assert(ptr != 0); 00178 assert(i >= 0); 00179 return ptr[i]; 00180 } 00181 00182 bool operator==(T* p) const { 00183 return ptr == p; 00184 } 00185 00186 bool operator!=(T* p) const { 00187 return ptr != p; 00188 } 00189 00190 T* get() const { 00191 return ptr; 00192 } 00193 00194 void swap(scoped_array & b) { 00195 T* tmp = b.ptr; 00196 b.ptr = ptr; 00197 ptr = tmp; 00198 } 00199 00200 T* release() { 00201 T* tmp = ptr; 00202 ptr = 0; 00203 return tmp; 00204 } 00205 00206 private: 00207 00208 // no reason to use these: each scoped_array should have its own object 00209 template <typename U> bool operator==(scoped_array<U> const& p) const; 00210 template <typename U> bool operator!=(scoped_array<U> const& p) const; 00211 }; 00212 00213 template<class T> inline 00214 void swap(scoped_array<T>& a, scoped_array<T>& b) { 00215 a.swap(b); 00216 } 00217 00218 template<typename T> inline 00219 bool operator==(T* p, const scoped_array<T>& b) { 00220 return p == b.get(); 00221 } 00222 00223 template<typename T> inline 00224 bool operator!=(T* p, const scoped_array<T>& b) { 00225 return p != b.get(); 00226 } 00227 00228 00229 // This class wraps the c library function free() in a class that can be 00230 // passed as a template argument to scoped_ptr_malloc below. 00231 class ScopedPtrMallocFree { 00232 public: 00233 inline void operator()(void* x) const { 00234 free(x); 00235 } 00236 }; 00237 00238 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a 00239 // second template argument, the functor used to free the object. 00240 00241 template<typename T, typename FreeProc = ScopedPtrMallocFree> 00242 class scoped_ptr_malloc { 00243 private: 00244 00245 T* ptr; 00246 00247 scoped_ptr_malloc(scoped_ptr_malloc const &); 00248 scoped_ptr_malloc & operator=(scoped_ptr_malloc const &); 00249 00250 public: 00251 00252 typedef T element_type; 00253 00254 explicit scoped_ptr_malloc(T* p = 0): ptr(p) {} 00255 00256 ~scoped_ptr_malloc() { 00257 typedef char type_must_be_complete[sizeof(T)]; 00258 free_((void*) ptr); 00259 } 00260 00261 void reset(T* p = 0) { 00262 typedef char type_must_be_complete[sizeof(T)]; 00263 00264 if (ptr != p) { 00265 free_((void*) ptr); 00266 ptr = p; 00267 } 00268 } 00269 00270 T& operator*() const { 00271 assert(ptr != 0); 00272 return *ptr; 00273 } 00274 00275 T* operator->() const { 00276 assert(ptr != 0); 00277 return ptr; 00278 } 00279 00280 bool operator==(T* p) const { 00281 return ptr == p; 00282 } 00283 00284 bool operator!=(T* p) const { 00285 return ptr != p; 00286 } 00287 00288 T* get() const { 00289 return ptr; 00290 } 00291 00292 void swap(scoped_ptr_malloc & b) { 00293 T* tmp = b.ptr; 00294 b.ptr = ptr; 00295 ptr = tmp; 00296 } 00297 00298 T* release() { 00299 T* tmp = ptr; 00300 ptr = 0; 00301 return tmp; 00302 } 00303 00304 private: 00305 00306 // no reason to use these: each scoped_ptr_malloc should have its own object 00307 template <typename U, typename GP> 00308 bool operator==(scoped_ptr_malloc<U, GP> const& p) const; 00309 template <typename U, typename GP> 00310 bool operator!=(scoped_ptr_malloc<U, GP> const& p) const; 00311 00312 static FreeProc const free_; 00313 }; 00314 00315 template<typename T, typename FP> 00316 FP const scoped_ptr_malloc<T,FP>::free_ = FP(); 00317 00318 template<typename T, typename FP> inline 00319 void swap(scoped_ptr_malloc<T,FP>& a, scoped_ptr_malloc<T,FP>& b) { 00320 a.swap(b); 00321 } 00322 00323 template<typename T, typename FP> inline 00324 bool operator==(T* p, const scoped_ptr_malloc<T,FP>& b) { 00325 return p == b.get(); 00326 } 00327 00328 template<typename T, typename FP> inline 00329 bool operator!=(T* p, const scoped_ptr_malloc<T,FP>& b) { 00330 return p != b.get(); 00331 } 00332 00333 } // namespace google_breakpad 00334 00335 #endif // COMMON_SCOPED_PTR_H_