| OLD | NEW |
| (Empty) |
| 1 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. | |
| 2 // Copyright (c) 2001, 2002 Peter Dimov | |
| 3 // | |
| 4 // Permission to copy, use, modify, sell and distribute this software | |
| 5 // is granted provided this copyright notice appears in all copies. | |
| 6 // This software is provided "as is" without express or implied | |
| 7 // warranty, and with no claim as to its suitability for any purpose. | |
| 8 // | |
| 9 // See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation. | |
| 10 // | |
| 11 | |
| 12 // scoped_ptr mimics a built-in pointer except that it guarantees deletion | |
| 13 // of the object pointed to, either on destruction of the scoped_ptr or via | |
| 14 // an explicit reset(). scoped_ptr is a simple solution for simple needs; | |
| 15 // use shared_ptr or std::auto_ptr if your needs are more complex. | |
| 16 | |
| 17 // *** NOTE *** | |
| 18 // If your scoped_ptr is a class member of class FOO pointing to a | |
| 19 // forward declared type BAR (as shown below), then you MUST use a non-inlined | |
| 20 // version of the destructor. The destructor of a scoped_ptr (called from | |
| 21 // FOO's destructor) must have a complete definition of BAR in order to | |
| 22 // destroy it. Example: | |
| 23 // | |
| 24 // -- foo.h -- | |
| 25 // class BAR; | |
| 26 // | |
| 27 // class FOO { | |
| 28 // public: | |
| 29 // FOO(); | |
| 30 // ~FOO(); // Required for sources that instantiate class FOO to compile! | |
| 31 // | |
| 32 // private: | |
| 33 // scoped_ptr<BAR> bar_; | |
| 34 // }; | |
| 35 // | |
| 36 // -- foo.cc -- | |
| 37 // #include "foo.h" | |
| 38 // FOO::~FOO() {} // Empty, but must be non-inlined to FOO's class definition. | |
| 39 | |
| 40 // scoped_ptr_malloc added by Google | |
| 41 // When one of these goes out of scope, instead of doing a delete or | |
| 42 // delete[], it calls free(). scoped_ptr_malloc<char> is likely to see | |
| 43 // much more use than any other specializations. | |
| 44 | |
| 45 // release() added by Google | |
| 46 // Use this to conditionally transfer ownership of a heap-allocated object | |
| 47 // to the caller, usually on method success. | |
| 48 | |
| 49 #ifndef PROCESSOR_SCOPED_PTR_H__ | |
| 50 #define PROCESSOR_SCOPED_PTR_H__ | |
| 51 | |
| 52 #include <cstddef> // for std::ptrdiff_t | |
| 53 #include <assert.h> // for assert | |
| 54 #include <stdlib.h> // for free() decl | |
| 55 | |
| 56 namespace google_breakpad { | |
| 57 | |
| 58 template <typename T> | |
| 59 class scoped_ptr { | |
| 60 private: | |
| 61 | |
| 62 T* ptr; | |
| 63 | |
| 64 scoped_ptr(scoped_ptr const &); | |
| 65 scoped_ptr & operator=(scoped_ptr const &); | |
| 66 | |
| 67 public: | |
| 68 | |
| 69 typedef T element_type; | |
| 70 | |
| 71 explicit scoped_ptr(T* p = 0): ptr(p) {} | |
| 72 | |
| 73 ~scoped_ptr() { | |
| 74 typedef char type_must_be_complete[sizeof(T)]; | |
| 75 delete ptr; | |
| 76 } | |
| 77 | |
| 78 void reset(T* p = 0) { | |
| 79 typedef char type_must_be_complete[sizeof(T)]; | |
| 80 | |
| 81 if (ptr != p) { | |
| 82 delete ptr; | |
| 83 ptr = p; | |
| 84 } | |
| 85 } | |
| 86 | |
| 87 T& operator*() const { | |
| 88 assert(ptr != 0); | |
| 89 return *ptr; | |
| 90 } | |
| 91 | |
| 92 T* operator->() const { | |
| 93 assert(ptr != 0); | |
| 94 return ptr; | |
| 95 } | |
| 96 | |
| 97 bool operator==(T* p) const { | |
| 98 return ptr == p; | |
| 99 } | |
| 100 | |
| 101 bool operator!=(T* p) const { | |
| 102 return ptr != p; | |
| 103 } | |
| 104 | |
| 105 T* get() const { | |
| 106 return ptr; | |
| 107 } | |
| 108 | |
| 109 void swap(scoped_ptr & b) { | |
| 110 T* tmp = b.ptr; | |
| 111 b.ptr = ptr; | |
| 112 ptr = tmp; | |
| 113 } | |
| 114 | |
| 115 T* release() { | |
| 116 T* tmp = ptr; | |
| 117 ptr = 0; | |
| 118 return tmp; | |
| 119 } | |
| 120 | |
| 121 private: | |
| 122 | |
| 123 // no reason to use these: each scoped_ptr should have its own object | |
| 124 template <typename U> bool operator==(scoped_ptr<U> const& p) const; | |
| 125 template <typename U> bool operator!=(scoped_ptr<U> const& p) const; | |
| 126 }; | |
| 127 | |
| 128 template<typename T> inline | |
| 129 void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) { | |
| 130 a.swap(b); | |
| 131 } | |
| 132 | |
| 133 template<typename T> inline | |
| 134 bool operator==(T* p, const scoped_ptr<T>& b) { | |
| 135 return p == b.get(); | |
| 136 } | |
| 137 | |
| 138 template<typename T> inline | |
| 139 bool operator!=(T* p, const scoped_ptr<T>& b) { | |
| 140 return p != b.get(); | |
| 141 } | |
| 142 | |
| 143 // scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to | |
| 144 // is guaranteed, either on destruction of the scoped_array or via an explicit | |
| 145 // reset(). Use shared_array or std::vector if your needs are more complex. | |
| 146 | |
| 147 template<typename T> | |
| 148 class scoped_array { | |
| 149 private: | |
| 150 | |
| 151 T* ptr; | |
| 152 | |
| 153 scoped_array(scoped_array const &); | |
| 154 scoped_array & operator=(scoped_array const &); | |
| 155 | |
| 156 public: | |
| 157 | |
| 158 typedef T element_type; | |
| 159 | |
| 160 explicit scoped_array(T* p = 0) : ptr(p) {} | |
| 161 | |
| 162 ~scoped_array() { | |
| 163 typedef char type_must_be_complete[sizeof(T)]; | |
| 164 delete[] ptr; | |
| 165 } | |
| 166 | |
| 167 void reset(T* p = 0) { | |
| 168 typedef char type_must_be_complete[sizeof(T)]; | |
| 169 | |
| 170 if (ptr != p) { | |
| 171 delete [] ptr; | |
| 172 ptr = p; | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 T& operator[](std::ptrdiff_t i) const { | |
| 177 assert(ptr != 0); | |
| 178 assert(i >= 0); | |
| 179 return ptr[i]; | |
| 180 } | |
| 181 | |
| 182 bool operator==(T* p) const { | |
| 183 return ptr == p; | |
| 184 } | |
| 185 | |
| 186 bool operator!=(T* p) const { | |
| 187 return ptr != p; | |
| 188 } | |
| 189 | |
| 190 T* get() const { | |
| 191 return ptr; | |
| 192 } | |
| 193 | |
| 194 void swap(scoped_array & b) { | |
| 195 T* tmp = b.ptr; | |
| 196 b.ptr = ptr; | |
| 197 ptr = tmp; | |
| 198 } | |
| 199 | |
| 200 T* release() { | |
| 201 T* tmp = ptr; | |
| 202 ptr = 0; | |
| 203 return tmp; | |
| 204 } | |
| 205 | |
| 206 private: | |
| 207 | |
| 208 // no reason to use these: each scoped_array should have its own object | |
| 209 template <typename U> bool operator==(scoped_array<U> const& p) const; | |
| 210 template <typename U> bool operator!=(scoped_array<U> const& p) const; | |
| 211 }; | |
| 212 | |
| 213 template<class T> inline | |
| 214 void swap(scoped_array<T>& a, scoped_array<T>& b) { | |
| 215 a.swap(b); | |
| 216 } | |
| 217 | |
| 218 template<typename T> inline | |
| 219 bool operator==(T* p, const scoped_array<T>& b) { | |
| 220 return p == b.get(); | |
| 221 } | |
| 222 | |
| 223 template<typename T> inline | |
| 224 bool operator!=(T* p, const scoped_array<T>& b) { | |
| 225 return p != b.get(); | |
| 226 } | |
| 227 | |
| 228 | |
| 229 // This class wraps the c library function free() in a class that can be | |
| 230 // passed as a template argument to scoped_ptr_malloc below. | |
| 231 class ScopedPtrMallocFree { | |
| 232 public: | |
| 233 inline void operator()(void* x) const { | |
| 234 free(x); | |
| 235 } | |
| 236 }; | |
| 237 | |
| 238 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a | |
| 239 // second template argument, the functor used to free the object. | |
| 240 | |
| 241 template<typename T, typename FreeProc = ScopedPtrMallocFree> | |
| 242 class scoped_ptr_malloc { | |
| 243 private: | |
| 244 | |
| 245 T* ptr; | |
| 246 | |
| 247 scoped_ptr_malloc(scoped_ptr_malloc const &); | |
| 248 scoped_ptr_malloc & operator=(scoped_ptr_malloc const &); | |
| 249 | |
| 250 public: | |
| 251 | |
| 252 typedef T element_type; | |
| 253 | |
| 254 explicit scoped_ptr_malloc(T* p = 0): ptr(p) {} | |
| 255 | |
| 256 ~scoped_ptr_malloc() { | |
| 257 typedef char type_must_be_complete[sizeof(T)]; | |
| 258 free_((void*) ptr); | |
| 259 } | |
| 260 | |
| 261 void reset(T* p = 0) { | |
| 262 typedef char type_must_be_complete[sizeof(T)]; | |
| 263 | |
| 264 if (ptr != p) { | |
| 265 free_((void*) ptr); | |
| 266 ptr = p; | |
| 267 } | |
| 268 } | |
| 269 | |
| 270 T& operator*() const { | |
| 271 assert(ptr != 0); | |
| 272 return *ptr; | |
| 273 } | |
| 274 | |
| 275 T* operator->() const { | |
| 276 assert(ptr != 0); | |
| 277 return ptr; | |
| 278 } | |
| 279 | |
| 280 bool operator==(T* p) const { | |
| 281 return ptr == p; | |
| 282 } | |
| 283 | |
| 284 bool operator!=(T* p) const { | |
| 285 return ptr != p; | |
| 286 } | |
| 287 | |
| 288 T* get() const { | |
| 289 return ptr; | |
| 290 } | |
| 291 | |
| 292 void swap(scoped_ptr_malloc & b) { | |
| 293 T* tmp = b.ptr; | |
| 294 b.ptr = ptr; | |
| 295 ptr = tmp; | |
| 296 } | |
| 297 | |
| 298 T* release() { | |
| 299 T* tmp = ptr; | |
| 300 ptr = 0; | |
| 301 return tmp; | |
| 302 } | |
| 303 | |
| 304 private: | |
| 305 | |
| 306 // no reason to use these: each scoped_ptr_malloc should have its own object | |
| 307 template <typename U, typename GP> | |
| 308 bool operator==(scoped_ptr_malloc<U, GP> const& p) const; | |
| 309 template <typename U, typename GP> | |
| 310 bool operator!=(scoped_ptr_malloc<U, GP> const& p) const; | |
| 311 | |
| 312 static FreeProc const free_; | |
| 313 }; | |
| 314 | |
| 315 template<typename T, typename FP> | |
| 316 FP const scoped_ptr_malloc<T,FP>::free_ = FP(); | |
| 317 | |
| 318 template<typename T, typename FP> inline | |
| 319 void swap(scoped_ptr_malloc<T,FP>& a, scoped_ptr_malloc<T,FP>& b) { | |
| 320 a.swap(b); | |
| 321 } | |
| 322 | |
| 323 template<typename T, typename FP> inline | |
| 324 bool operator==(T* p, const scoped_ptr_malloc<T,FP>& b) { | |
| 325 return p == b.get(); | |
| 326 } | |
| 327 | |
| 328 template<typename T, typename FP> inline | |
| 329 bool operator!=(T* p, const scoped_ptr_malloc<T,FP>& b) { | |
| 330 return p != b.get(); | |
| 331 } | |
| 332 | |
| 333 } // namespace google_breakpad | |
| 334 | |
| 335 #endif // PROCESSOR_SCOPED_PTR_H__ | |
| OLD | NEW |