| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Scopers help you manage ownership of a pointer, helping you easily manage the | 5 // Scopers help you manage ownership of a pointer, helping you easily manage the |
| 6 // a pointer within a scope, and automatically destroying the pointer at the | 6 // a pointer within a scope, and automatically destroying the pointer at the |
| 7 // end of a scope. There are two main classes you will use, which coorespond | 7 // end of a scope. There are two main classes you will use, which coorespond |
| 8 // to the operators new/delete and new[]/delete[]. | 8 // to the operators new/delete and new[]/delete[]. |
| 9 // | 9 // |
| 10 // Example usage (scoped_ptr): | 10 // Example usage (scoped_ptr): |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 // Example usage (scoped_array): | 29 // Example usage (scoped_array): |
| 30 // { | 30 // { |
| 31 // scoped_array<Foo> foo(new Foo[100]); | 31 // scoped_array<Foo> foo(new Foo[100]); |
| 32 // foo.get()->Method(); // Foo::Method on the 0th element. | 32 // foo.get()->Method(); // Foo::Method on the 0th element. |
| 33 // foo[10].Method(); // Foo::Method on the 10th element. | 33 // foo[10].Method(); // Foo::Method on the 10th element. |
| 34 // } | 34 // } |
| 35 | 35 |
| 36 #ifndef BASE_SCOPED_PTR_H_ | 36 #ifndef BASE_SCOPED_PTR_H_ |
| 37 #define BASE_SCOPED_PTR_H_ | 37 #define BASE_SCOPED_PTR_H_ |
| 38 | 38 |
| 39 #include "base/thread_collision_warner.h" |
| 40 |
| 39 // This is an implementation designed to match the anticipated future TR2 | 41 // This is an implementation designed to match the anticipated future TR2 |
| 40 // implementation of the scoped_ptr class, and its closely-related brethren, | 42 // implementation of the scoped_ptr class, and its closely-related brethren, |
| 41 // scoped_array, scoped_ptr_malloc. | 43 // scoped_array, scoped_ptr_malloc. |
| 42 | 44 |
| 43 #include <assert.h> | 45 #include <assert.h> |
| 44 #include <stdlib.h> | 46 #include <stdlib.h> |
| 45 #include <cstddef> | 47 #include <cstddef> |
| 46 | 48 |
| 47 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> | 49 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> |
| 48 // automatically deletes the pointer it holds (if any). | 50 // automatically deletes the pointer it holds (if any). |
| (...skipping 20 matching lines...) Expand all Loading... |
| 69 // We don't need to test ptr_ == NULL because C++ does that for us. | 71 // We don't need to test ptr_ == NULL because C++ does that for us. |
| 70 ~scoped_ptr() { | 72 ~scoped_ptr() { |
| 71 enum { type_must_be_complete = sizeof(C) }; | 73 enum { type_must_be_complete = sizeof(C) }; |
| 72 delete ptr_; | 74 delete ptr_; |
| 73 } | 75 } |
| 74 | 76 |
| 75 // Reset. Deletes the current owned object, if any. | 77 // Reset. Deletes the current owned object, if any. |
| 76 // Then takes ownership of a new object, if given. | 78 // Then takes ownership of a new object, if given. |
| 77 // this->reset(this->get()) works. | 79 // this->reset(this->get()) works. |
| 78 void reset(C* p = NULL) { | 80 void reset(C* p = NULL) { |
| 81 D_BOOK_CRITICAL_SECTION(scoped_ptr_); |
| 79 if (p != ptr_) { | 82 if (p != ptr_) { |
| 80 enum { type_must_be_complete = sizeof(C) }; | 83 enum { type_must_be_complete = sizeof(C) }; |
| 81 delete ptr_; | 84 delete ptr_; |
| 82 ptr_ = p; | 85 ptr_ = p; |
| 83 } | 86 } |
| 84 } | 87 } |
| 85 | 88 |
| 86 // Accessors to get the owned object. | 89 // Accessors to get the owned object. |
| 87 // operator* and operator-> will assert() if there is no current object. | 90 // operator* and operator-> will assert() if there is no current object. |
| 88 C& operator*() const { | 91 C& operator*() const { |
| 92 D_BOOK_CRITICAL_SECTION(scoped_ptr_); |
| 89 assert(ptr_ != NULL); | 93 assert(ptr_ != NULL); |
| 90 return *ptr_; | 94 return *ptr_; |
| 91 } | 95 } |
| 92 C* operator->() const { | 96 C* operator->() const { |
| 97 D_BOOK_CRITICAL_SECTION(scoped_ptr_); |
| 93 assert(ptr_ != NULL); | 98 assert(ptr_ != NULL); |
| 94 return ptr_; | 99 return ptr_; |
| 95 } | 100 } |
| 96 C* get() const { return ptr_; } | 101 C* get() const { |
| 102 D_BOOK_CRITICAL_SECTION(scoped_ptr_); |
| 103 return ptr_; |
| 104 } |
| 97 | 105 |
| 98 // Comparison operators. | 106 // Comparison operators. |
| 99 // These return whether two scoped_ptr refer to the same object, not just to | 107 // These return whether two scoped_ptr refer to the same object, not just to |
| 100 // two different but equal objects. | 108 // two different but equal objects. |
| 101 bool operator==(C* p) const { return ptr_ == p; } | 109 bool operator==(C* p) const { |
| 102 bool operator!=(C* p) const { return ptr_ != p; } | 110 D_BOOK_CRITICAL_SECTION(scoped_ptr_); |
| 111 return ptr_ == p; |
| 112 } |
| 113 bool operator!=(C* p) const { |
| 114 D_BOOK_CRITICAL_SECTION(scoped_ptr_); |
| 115 return ptr_ != p; |
| 116 } |
| 103 | 117 |
| 104 // Swap two scoped pointers. | 118 // Swap two scoped pointers. |
| 105 void swap(scoped_ptr& p2) { | 119 void swap(scoped_ptr& p2) { |
| 120 D_BOOK_CRITICAL_SECTION(scoped_ptr_); |
| 121 |
| 106 C* tmp = ptr_; | 122 C* tmp = ptr_; |
| 107 ptr_ = p2.ptr_; | 123 ptr_ = p2.ptr_; |
| 108 p2.ptr_ = tmp; | 124 p2.ptr_ = tmp; |
| 109 } | 125 } |
| 110 | 126 |
| 111 // Release a pointer. | 127 // Release a pointer. |
| 112 // The return value is the current pointer held by this object. | 128 // The return value is the current pointer held by this object. |
| 113 // If this object holds a NULL pointer, the return value is NULL. | 129 // If this object holds a NULL pointer, the return value is NULL. |
| 114 // After this operation, this object will hold a NULL pointer, | 130 // After this operation, this object will hold a NULL pointer, |
| 115 // and will not own the object any more. | 131 // and will not own the object any more. |
| 116 C* release() { | 132 C* release() { |
| 133 D_BOOK_CRITICAL_SECTION(scoped_ptr_); |
| 134 |
| 117 C* retVal = ptr_; | 135 C* retVal = ptr_; |
| 118 ptr_ = NULL; | 136 ptr_ = NULL; |
| 119 return retVal; | 137 return retVal; |
| 120 } | 138 } |
| 121 | 139 |
| 122 private: | 140 private: |
| 123 C* ptr_; | 141 C* ptr_; |
| 124 | 142 |
| 125 // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't | 143 // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't |
| 126 // make sense, and if C2 == C, it still doesn't make sense because you should | 144 // make sense, and if C2 == C, it still doesn't make sense because you should |
| 127 // never have the same object owned by two different scoped_ptrs. | 145 // never have the same object owned by two different scoped_ptrs. |
| 128 template <class C2> bool operator==(scoped_ptr<C2> const& p2) const; | 146 template <class C2> bool operator==(scoped_ptr<C2> const& p2) const; |
| 129 template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const; | 147 template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const; |
| 130 | 148 |
| 131 // Disallow evil constructors | 149 // Disallow evil constructors |
| 132 scoped_ptr(const scoped_ptr&); | 150 scoped_ptr(const scoped_ptr&); |
| 133 void operator=(const scoped_ptr&); | 151 void operator=(const scoped_ptr&); |
| 152 |
| 153 D_DEFINE_CRITICAL_SECTION(scoped_ptr_); |
| 134 }; | 154 }; |
| 135 | 155 |
| 136 // Free functions | 156 // Free functions |
| 137 template <class C> | 157 template <class C> |
| 138 void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) { | 158 void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) { |
| 139 p1.swap(p2); | 159 p1.swap(p2); |
| 140 } | 160 } |
| 141 | 161 |
| 142 template <class C> | 162 template <class C> |
| 143 bool operator==(C* p1, const scoped_ptr<C>& p2) { | 163 bool operator==(C* p1, const scoped_ptr<C>& p2) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 174 // We don't need to test ptr_ == NULL because C++ does that for us. | 194 // We don't need to test ptr_ == NULL because C++ does that for us. |
| 175 ~scoped_array() { | 195 ~scoped_array() { |
| 176 enum { type_must_be_complete = sizeof(C) }; | 196 enum { type_must_be_complete = sizeof(C) }; |
| 177 delete[] array_; | 197 delete[] array_; |
| 178 } | 198 } |
| 179 | 199 |
| 180 // Reset. Deletes the current owned object, if any. | 200 // Reset. Deletes the current owned object, if any. |
| 181 // Then takes ownership of a new object, if given. | 201 // Then takes ownership of a new object, if given. |
| 182 // this->reset(this->get()) works. | 202 // this->reset(this->get()) works. |
| 183 void reset(C* p = NULL) { | 203 void reset(C* p = NULL) { |
| 204 D_BOOK_CRITICAL_SECTION(scoped_array_); |
| 184 if (p != array_) { | 205 if (p != array_) { |
| 185 enum { type_must_be_complete = sizeof(C) }; | 206 enum { type_must_be_complete = sizeof(C) }; |
| 186 delete[] array_; | 207 delete[] array_; |
| 187 array_ = p; | 208 array_ = p; |
| 188 } | 209 } |
| 189 } | 210 } |
| 190 | 211 |
| 191 // Get one element of the current object. | 212 // Get one element of the current object. |
| 192 // Will assert() if there is no current object, or index i is negative. | 213 // Will assert() if there is no current object, or index i is negative. |
| 193 C& operator[](std::ptrdiff_t i) const { | 214 C& operator[](std::ptrdiff_t i) const { |
| 215 D_BOOK_CRITICAL_SECTION(scoped_array_); |
| 194 assert(i >= 0); | 216 assert(i >= 0); |
| 195 assert(array_ != NULL); | 217 assert(array_ != NULL); |
| 196 return array_[i]; | 218 return array_[i]; |
| 197 } | 219 } |
| 198 | 220 |
| 199 // Get a pointer to the zeroth element of the current object. | 221 // Get a pointer to the zeroth element of the current object. |
| 200 // If there is no current object, return NULL. | 222 // If there is no current object, return NULL. |
| 201 C* get() const { | 223 C* get() const { |
| 224 D_BOOK_CRITICAL_SECTION(scoped_array_); |
| 202 return array_; | 225 return array_; |
| 203 } | 226 } |
| 204 | 227 |
| 205 // Comparison operators. | 228 // Comparison operators. |
| 206 // These return whether two scoped_array refer to the same object, not just to | 229 // These return whether two scoped_array refer to the same object, not just to |
| 207 // two different but equal objects. | 230 // two different but equal objects. |
| 208 bool operator==(C* p) const { return array_ == p; } | 231 bool operator==(C* p) const { |
| 209 bool operator!=(C* p) const { return array_ != p; } | 232 D_BOOK_CRITICAL_SECTION(scoped_array_); |
| 233 return array_ == p; |
| 234 } |
| 235 bool operator!=(C* p) const { |
| 236 D_BOOK_CRITICAL_SECTION(scoped_array_); |
| 237 return array_ != p; |
| 238 } |
| 210 | 239 |
| 211 // Swap two scoped arrays. | 240 // Swap two scoped arrays. |
| 212 void swap(scoped_array& p2) { | 241 void swap(scoped_array& p2) { |
| 242 D_BOOK_CRITICAL_SECTION(scoped_array_); |
| 213 C* tmp = array_; | 243 C* tmp = array_; |
| 214 array_ = p2.array_; | 244 array_ = p2.array_; |
| 215 p2.array_ = tmp; | 245 p2.array_ = tmp; |
| 216 } | 246 } |
| 217 | 247 |
| 218 // Release an array. | 248 // Release an array. |
| 219 // The return value is the current pointer held by this object. | 249 // The return value is the current pointer held by this object. |
| 220 // If this object holds a NULL pointer, the return value is NULL. | 250 // If this object holds a NULL pointer, the return value is NULL. |
| 221 // After this operation, this object will hold a NULL pointer, | 251 // After this operation, this object will hold a NULL pointer, |
| 222 // and will not own the object any more. | 252 // and will not own the object any more. |
| 223 C* release() { | 253 C* release() { |
| 254 D_BOOK_CRITICAL_SECTION(scoped_array_); |
| 224 C* retVal = array_; | 255 C* retVal = array_; |
| 225 array_ = NULL; | 256 array_ = NULL; |
| 226 return retVal; | 257 return retVal; |
| 227 } | 258 } |
| 228 | 259 |
| 229 private: | 260 private: |
| 230 C* array_; | 261 C* array_; |
| 231 | 262 |
| 232 // Forbid comparison of different scoped_array types. | 263 // Forbid comparison of different scoped_array types. |
| 233 template <class C2> bool operator==(scoped_array<C2> const& p2) const; | 264 template <class C2> bool operator==(scoped_array<C2> const& p2) const; |
| 234 template <class C2> bool operator!=(scoped_array<C2> const& p2) const; | 265 template <class C2> bool operator!=(scoped_array<C2> const& p2) const; |
| 235 | 266 |
| 236 // Disallow evil constructors | 267 // Disallow evil constructors |
| 237 scoped_array(const scoped_array&); | 268 scoped_array(const scoped_array&); |
| 238 void operator=(const scoped_array&); | 269 void operator=(const scoped_array&); |
| 270 |
| 271 D_DEFINE_CRITICAL_SECTION(scoped_array_); |
| 239 }; | 272 }; |
| 240 | 273 |
| 241 // Free functions | 274 // Free functions |
| 242 template <class C> | 275 template <class C> |
| 243 void swap(scoped_array<C>& p1, scoped_array<C>& p2) { | 276 void swap(scoped_array<C>& p1, scoped_array<C>& p2) { |
| 244 p1.swap(p2); | 277 p1.swap(p2); |
| 245 } | 278 } |
| 246 | 279 |
| 247 template <class C> | 280 template <class C> |
| 248 bool operator==(C* p1, const scoped_array<C>& p2) { | 281 bool operator==(C* p1, const scoped_array<C>& p2) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 | 315 |
| 283 // Destructor. If there is a C object, call the Free functor. | 316 // Destructor. If there is a C object, call the Free functor. |
| 284 ~scoped_ptr_malloc() { | 317 ~scoped_ptr_malloc() { |
| 285 free_(ptr_); | 318 free_(ptr_); |
| 286 } | 319 } |
| 287 | 320 |
| 288 // Reset. Calls the Free functor on the current owned object, if any. | 321 // Reset. Calls the Free functor on the current owned object, if any. |
| 289 // Then takes ownership of a new object, if given. | 322 // Then takes ownership of a new object, if given. |
| 290 // this->reset(this->get()) works. | 323 // this->reset(this->get()) works. |
| 291 void reset(C* p = NULL) { | 324 void reset(C* p = NULL) { |
| 325 D_BOOK_CRITICAL_SECTION(scoped_ptr_malloc_); |
| 292 if (ptr_ != p) { | 326 if (ptr_ != p) { |
| 293 free_(ptr_); | 327 free_(ptr_); |
| 294 ptr_ = p; | 328 ptr_ = p; |
| 295 } | 329 } |
| 296 } | 330 } |
| 297 | 331 |
| 298 // Get the current object. | 332 // Get the current object. |
| 299 // operator* and operator-> will cause an assert() failure if there is | 333 // operator* and operator-> will cause an assert() failure if there is |
| 300 // no current object. | 334 // no current object. |
| 301 C& operator*() const { | 335 C& operator*() const { |
| 336 D_BOOK_CRITICAL_SECTION(scoped_ptr_malloc_); |
| 302 assert(ptr_ != NULL); | 337 assert(ptr_ != NULL); |
| 303 return *ptr_; | 338 return *ptr_; |
| 304 } | 339 } |
| 305 | 340 |
| 306 C* operator->() const { | 341 C* operator->() const { |
| 342 D_BOOK_CRITICAL_SECTION(scoped_ptr_malloc_); |
| 307 assert(ptr_ != NULL); | 343 assert(ptr_ != NULL); |
| 308 return ptr_; | 344 return ptr_; |
| 309 } | 345 } |
| 310 | 346 |
| 311 C* get() const { | 347 C* get() const { |
| 348 D_BOOK_CRITICAL_SECTION(scoped_ptr_malloc_); |
| 312 return ptr_; | 349 return ptr_; |
| 313 } | 350 } |
| 314 | 351 |
| 315 // Comparison operators. | 352 // Comparison operators. |
| 316 // These return whether a scoped_ptr_malloc and a plain pointer refer | 353 // These return whether a scoped_ptr_malloc and a plain pointer refer |
| 317 // to the same object, not just to two different but equal objects. | 354 // to the same object, not just to two different but equal objects. |
| 318 // For compatibility wwith the boost-derived implementation, these | 355 // For compatibility wwith the boost-derived implementation, these |
| 319 // take non-const arguments. | 356 // take non-const arguments. |
| 320 bool operator==(C* p) const { | 357 bool operator==(C* p) const { |
| 358 D_BOOK_CRITICAL_SECTION(scoped_ptr_malloc_); |
| 321 return ptr_ == p; | 359 return ptr_ == p; |
| 322 } | 360 } |
| 323 | 361 |
| 324 bool operator!=(C* p) const { | 362 bool operator!=(C* p) const { |
| 363 D_BOOK_CRITICAL_SECTION(scoped_ptr_malloc_); |
| 325 return ptr_ != p; | 364 return ptr_ != p; |
| 326 } | 365 } |
| 327 | 366 |
| 328 // Swap two scoped pointers. | 367 // Swap two scoped pointers. |
| 329 void swap(scoped_ptr_malloc & b) { | 368 void swap(scoped_ptr_malloc & b) { |
| 369 D_BOOK_CRITICAL_SECTION(scoped_ptr_malloc_); |
| 330 C* tmp = b.ptr_; | 370 C* tmp = b.ptr_; |
| 331 b.ptr_ = ptr_; | 371 b.ptr_ = ptr_; |
| 332 ptr_ = tmp; | 372 ptr_ = tmp; |
| 333 } | 373 } |
| 334 | 374 |
| 335 // Release a pointer. | 375 // Release a pointer. |
| 336 // The return value is the current pointer held by this object. | 376 // The return value is the current pointer held by this object. |
| 337 // If this object holds a NULL pointer, the return value is NULL. | 377 // If this object holds a NULL pointer, the return value is NULL. |
| 338 // After this operation, this object will hold a NULL pointer, | 378 // After this operation, this object will hold a NULL pointer, |
| 339 // and will not own the object any more. | 379 // and will not own the object any more. |
| 340 C* release() { | 380 C* release() { |
| 381 D_BOOK_CRITICAL_SECTION(scoped_ptr_malloc_); |
| 341 C* tmp = ptr_; | 382 C* tmp = ptr_; |
| 342 ptr_ = NULL; | 383 ptr_ = NULL; |
| 343 return tmp; | 384 return tmp; |
| 344 } | 385 } |
| 345 | 386 |
| 346 private: | 387 private: |
| 347 C* ptr_; | 388 C* ptr_; |
| 348 | 389 |
| 349 // no reason to use these: each scoped_ptr_malloc should have its own object | 390 // no reason to use these: each scoped_ptr_malloc should have its own object |
| 350 template <class C2, class GP> | 391 template <class C2, class GP> |
| 351 bool operator==(scoped_ptr_malloc<C2, GP> const& p) const; | 392 bool operator==(scoped_ptr_malloc<C2, GP> const& p) const; |
| 352 template <class C2, class GP> | 393 template <class C2, class GP> |
| 353 bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const; | 394 bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const; |
| 354 | 395 |
| 355 static FreeProc const free_; | 396 static FreeProc const free_; |
| 356 | 397 |
| 357 // Disallow evil constructors | 398 // Disallow evil constructors |
| 358 scoped_ptr_malloc(const scoped_ptr_malloc&); | 399 scoped_ptr_malloc(const scoped_ptr_malloc&); |
| 359 void operator=(const scoped_ptr_malloc&); | 400 void operator=(const scoped_ptr_malloc&); |
| 401 |
| 402 D_DEFINE_CRITICAL_SECTION(scoped_ptr_malloc_); |
| 360 }; | 403 }; |
| 361 | 404 |
| 362 template<class C, class FP> | 405 template<class C, class FP> |
| 363 FP const scoped_ptr_malloc<C, FP>::free_ = FP(); | 406 FP const scoped_ptr_malloc<C, FP>::free_ = FP(); |
| 364 | 407 |
| 365 template<class C, class FP> inline | 408 template<class C, class FP> inline |
| 366 void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) { | 409 void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) { |
| 367 a.swap(b); | 410 a.swap(b); |
| 368 } | 411 } |
| 369 | 412 |
| 370 template<class C, class FP> inline | 413 template<class C, class FP> inline |
| 371 bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) { | 414 bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) { |
| 372 return p == b.get(); | 415 return p == b.get(); |
| 373 } | 416 } |
| 374 | 417 |
| 375 template<class C, class FP> inline | 418 template<class C, class FP> inline |
| 376 bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) { | 419 bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) { |
| 377 return p != b.get(); | 420 return p != b.get(); |
| 378 } | 421 } |
| 379 | 422 |
| 380 #endif // BASE_SCOPED_PTR_H_ | 423 #endif // BASE_SCOPED_PTR_H_ |
| OLD | NEW |