Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 a | 5 // Scopers help you manage ownership of a pointer, helping you easily manage a |
| 6 // pointer within a scope, and automatically destroying the pointer at the end | 6 // pointer within a scope, and automatically destroying the pointer at the end |
| 7 // of a scope. There are two main classes you will use, which correspond to the | 7 // of a scope. There are two main classes you will use, which correspond to the |
| 8 // operators new/delete and new[]/delete[]. | 8 // operators new/delete and new[]/delete[]. |
| 9 // | 9 // |
| 10 // Example usage (scoped_ptr<T>): | 10 // Example usage (scoped_ptr<T>): |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: | 182 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: |
| 183 value | 183 value |
| 184 }; | 184 }; |
| 185 }; | 185 }; |
| 186 | 186 |
| 187 // Minimal implementation of the core logic of scoped_ptr, suitable for | 187 // Minimal implementation of the core logic of scoped_ptr, suitable for |
| 188 // reuse in both scoped_ptr and its specializations. | 188 // reuse in both scoped_ptr and its specializations. |
| 189 template <class T, class D> | 189 template <class T, class D> |
| 190 class scoped_ptr_impl { | 190 class scoped_ptr_impl { |
| 191 public: | 191 public: |
| 192 explicit scoped_ptr_impl(T* p) : data_(p) { } | 192 explicit scoped_ptr_impl(T* p) : data_(p) {} |
| 193 | 193 |
| 194 // Initializer for deleters that have data parameters. | 194 // Initializer for deleters that have data parameters. |
| 195 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} | 195 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} |
| 196 | 196 |
| 197 // Templated constructor that destructively takes the value from another | 197 // Templated constructor that destructively takes the value from another |
| 198 // scoped_ptr_impl. | 198 // scoped_ptr_impl. |
| 199 template <typename U, typename V> | 199 template <typename U, typename V> |
| 200 scoped_ptr_impl(scoped_ptr_impl<U, V>* other) | 200 scoped_ptr_impl(scoped_ptr_impl<U, V>* other) |
| 201 : data_(other->release(), other->get_deleter()) { | 201 : data_(other->release(), other->get_deleter()) { |
| 202 // We do not support move-only deleters. We could modify our move | 202 // We do not support move-only deleters. We could modify our move |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 312 | 312 |
| 313 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, | 313 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, |
| 314 T_is_refcounted_type_and_needs_scoped_refptr); | 314 T_is_refcounted_type_and_needs_scoped_refptr); |
| 315 | 315 |
| 316 public: | 316 public: |
| 317 // The element and deleter types. | 317 // The element and deleter types. |
| 318 typedef T element_type; | 318 typedef T element_type; |
| 319 typedef D deleter_type; | 319 typedef D deleter_type; |
| 320 | 320 |
| 321 // Constructor. Defaults to initializing with NULL. | 321 // Constructor. Defaults to initializing with NULL. |
| 322 scoped_ptr() : impl_(NULL) { } | 322 scoped_ptr() : impl_(NULL) {} |
|
jamesr
2014/09/25 05:58:08
nit: impl_(nullptr) ?
| |
| 323 | 323 |
| 324 // Constructor. Takes ownership of p. | 324 // Constructor. Takes ownership of p. |
| 325 explicit scoped_ptr(element_type* p) : impl_(p) { } | 325 explicit scoped_ptr(element_type* p) : impl_(p) {} |
| 326 | 326 |
| 327 // Constructor. Allows initialization of a stateful deleter. | 327 // Constructor. Allows initialization of a stateful deleter. |
| 328 scoped_ptr(element_type* p, const D& d) : impl_(p, d) { } | 328 scoped_ptr(element_type* p, const D& d) : impl_(p, d) {} |
| 329 | |
| 330 // Constructor. Allows construction from a nullptr. | |
| 331 scoped_ptr(decltype(nullptr)) : impl_(NULL) {} | |
| 329 | 332 |
| 330 // Constructor. Allows construction from a scoped_ptr rvalue for a | 333 // Constructor. Allows construction from a scoped_ptr rvalue for a |
| 331 // convertible type and deleter. | 334 // convertible type and deleter. |
| 332 // | 335 // |
| 333 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct | 336 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct |
|
jamesr
2014/09/25 05:58:08
does this note still apply?
danakj
2014/09/25 14:47:52
I think so. unique_ptr has 2 constructors:
unique_
danakj
2014/09/25 14:50:19
Rather,
unique_ptr(unique_ptr&&)
template <U,E> u
| |
| 334 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor | 337 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor |
| 335 // has different post-conditions if D is a reference type. Since this | 338 // has different post-conditions if D is a reference type. Since this |
| 336 // implementation does not support deleters with reference type, | 339 // implementation does not support deleters with reference type, |
| 337 // we do not need a separate move constructor allowing us to avoid one | 340 // we do not need a separate move constructor allowing us to avoid one |
| 338 // use of SFINAE. You only need to care about this if you modify the | 341 // use of SFINAE. You only need to care about this if you modify the |
| 339 // implementation of scoped_ptr. | 342 // implementation of scoped_ptr. |
| 340 template <typename U, typename V> | 343 template <typename U, typename V> |
| 341 scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) { | 344 scoped_ptr(scoped_ptr<U, V>&& other) |
| 345 : impl_(&other.impl_) { | |
| 342 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); | 346 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); |
| 343 } | 347 } |
| 344 | 348 |
| 345 // Constructor. Move constructor for C++03 move emulation of this type. | 349 // Constructor. Move constructor for C++03 move emulation of this type. |
| 346 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } | 350 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) {} |
| 347 | 351 |
| 348 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible | 352 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible |
| 349 // type and deleter. | 353 // type and deleter. |
| 350 // | 354 // |
| 351 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from | 355 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from |
| 352 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated | 356 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated |
| 353 // form has different requirements on for move-only Deleters. Since this | 357 // form has different requirements on for move-only Deleters. Since this |
| 354 // implementation does not support move-only Deleters, we do not need a | 358 // implementation does not support move-only Deleters, we do not need a |
| 355 // separate move assignment operator allowing us to avoid one use of SFINAE. | 359 // separate move assignment operator allowing us to avoid one use of SFINAE. |
| 356 // You only need to care about this if you modify the implementation of | 360 // You only need to care about this if you modify the implementation of |
| 357 // scoped_ptr. | 361 // scoped_ptr. |
| 358 template <typename U, typename V> | 362 template <typename U, typename V> |
| 359 scoped_ptr& operator=(scoped_ptr<U, V> rhs) { | 363 scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) { |
| 360 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); | 364 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); |
| 361 impl_.TakeState(&rhs.impl_); | 365 impl_.TakeState(&rhs.impl_); |
| 362 return *this; | 366 return *this; |
| 363 } | 367 } |
| 364 | 368 |
| 369 // operator=. Allows assignment from a nullptr. Deletes the currently owned | |
| 370 // object, if any. | |
| 371 scoped_ptr& operator=(decltype(nullptr)) { | |
| 372 reset(); | |
| 373 return *this; | |
| 374 } | |
| 375 | |
| 365 // Reset. Deletes the currently owned object, if any. | 376 // Reset. Deletes the currently owned object, if any. |
| 366 // Then takes ownership of a new object, if given. | 377 // Then takes ownership of a new object, if given. |
| 367 void reset(element_type* p = NULL) { impl_.reset(p); } | 378 void reset(element_type* p = NULL) { impl_.reset(p); } |
| 368 | 379 |
| 369 // Accessors to get the owned object. | 380 // Accessors to get the owned object. |
| 370 // operator* and operator-> will assert() if there is no current object. | 381 // operator* and operator-> will assert() if there is no current object. |
| 371 element_type& operator*() const { | 382 element_type& operator*() const { |
| 372 assert(impl_.get() != NULL); | 383 assert(impl_.get() != NULL); |
| 373 return *impl_.get(); | 384 return *impl_.get(); |
| 374 } | 385 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 446 template <class T, class D> | 457 template <class T, class D> |
| 447 class scoped_ptr<T[], D> { | 458 class scoped_ptr<T[], D> { |
| 448 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) | 459 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) |
| 449 | 460 |
| 450 public: | 461 public: |
| 451 // The element and deleter types. | 462 // The element and deleter types. |
| 452 typedef T element_type; | 463 typedef T element_type; |
| 453 typedef D deleter_type; | 464 typedef D deleter_type; |
| 454 | 465 |
| 455 // Constructor. Defaults to initializing with NULL. | 466 // Constructor. Defaults to initializing with NULL. |
| 456 scoped_ptr() : impl_(NULL) { } | 467 scoped_ptr() : impl_(NULL) {} |
|
jamesr
2014/09/25 05:58:08
s/NULL/nullptr/, same for the rest of file
| |
| 457 | 468 |
| 458 // Constructor. Stores the given array. Note that the argument's type | 469 // Constructor. Stores the given array. Note that the argument's type |
| 459 // must exactly match T*. In particular: | 470 // must exactly match T*. In particular: |
| 460 // - it cannot be a pointer to a type derived from T, because it is | 471 // - it cannot be a pointer to a type derived from T, because it is |
| 461 // inherently unsafe in the general case to access an array through a | 472 // inherently unsafe in the general case to access an array through a |
| 462 // pointer whose dynamic type does not match its static type (eg., if | 473 // pointer whose dynamic type does not match its static type (eg., if |
| 463 // T and the derived types had different sizes access would be | 474 // T and the derived types had different sizes access would be |
| 464 // incorrectly calculated). Deletion is also always undefined | 475 // incorrectly calculated). Deletion is also always undefined |
| 465 // (C++98 [expr.delete]p3). If you're doing this, fix your code. | 476 // (C++98 [expr.delete]p3). If you're doing this, fix your code. |
| 466 // - it cannot be NULL, because NULL is an integral expression, not a | 477 // - it cannot be NULL, because NULL is an integral expression, not a |
|
jamesr
2014/09/25 05:58:08
update this part of the comment plz
| |
| 467 // pointer to T. Use the no-argument version instead of explicitly | 478 // pointer to T. Use the no-argument version instead of explicitly |
| 468 // passing NULL. | 479 // passing NULL. |
| 469 // - it cannot be const-qualified differently from T per unique_ptr spec | 480 // - it cannot be const-qualified differently from T per unique_ptr spec |
| 470 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting | 481 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting |
| 471 // to work around this may use implicit_cast<const T*>(). | 482 // to work around this may use implicit_cast<const T*>(). |
| 472 // However, because of the first bullet in this comment, users MUST | 483 // However, because of the first bullet in this comment, users MUST |
| 473 // NOT use implicit_cast<Base*>() to upcast the static type of the array. | 484 // NOT use implicit_cast<Base*>() to upcast the static type of the array. |
| 474 explicit scoped_ptr(element_type* array) : impl_(array) { } | 485 explicit scoped_ptr(element_type* array) : impl_(array) {} |
| 486 | |
| 487 // Constructor. Allows construction from a nullptr. | |
| 488 scoped_ptr(decltype(nullptr)) : impl_(NULL) {} | |
| 489 | |
| 490 // Constructor. Allows construction from a scoped_ptr rvalue. | |
| 491 scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} | |
| 475 | 492 |
| 476 // Constructor. Move constructor for C++03 move emulation of this type. | 493 // Constructor. Move constructor for C++03 move emulation of this type. |
| 477 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } | 494 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) {} |
| 495 | |
| 496 // operator=. Allows assignment from a scoped_ptr rvalue. | |
| 497 scoped_ptr& operator=(scoped_ptr&& rhs) { | |
| 498 impl_.TakeState(&rhs.impl_); | |
| 499 return *this; | |
| 500 } | |
| 478 | 501 |
| 479 // operator=. Move operator= for C++03 move emulation of this type. | 502 // operator=. Move operator= for C++03 move emulation of this type. |
| 480 scoped_ptr& operator=(RValue rhs) { | 503 scoped_ptr& operator=(RValue rhs) { |
| 481 impl_.TakeState(&rhs.object->impl_); | 504 impl_.TakeState(&rhs.object->impl_); |
| 482 return *this; | 505 return *this; |
| 483 } | 506 } |
| 484 | 507 |
| 508 // operator=. Allows assignment from a nullptr. Deletes the currently owned | |
| 509 // array, if any. | |
| 510 scoped_ptr& operator=(decltype(nullptr)) { | |
| 511 reset(); | |
| 512 return *this; | |
| 513 } | |
| 514 | |
| 485 // Reset. Deletes the currently owned array, if any. | 515 // Reset. Deletes the currently owned array, if any. |
| 486 // Then takes ownership of a new object, if given. | 516 // Then takes ownership of a new object, if given. |
| 487 void reset(element_type* array = NULL) { impl_.reset(array); } | 517 void reset(element_type* array = NULL) { impl_.reset(array); } |
| 488 | 518 |
| 489 // Accessors to get the owned array. | 519 // Accessors to get the owned array. |
| 490 element_type& operator[](size_t i) const { | 520 element_type& operator[](size_t i) const { |
| 491 assert(impl_.get() != NULL); | 521 assert(impl_.get() != NULL); |
| 492 return impl_.get()[i]; | 522 return impl_.get()[i]; |
| 493 } | 523 } |
| 494 element_type* get() const { return impl_.get(); } | 524 element_type* get() const { return impl_.get(); } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 | 602 |
| 573 // A function to convert T* into scoped_ptr<T> | 603 // A function to convert T* into scoped_ptr<T> |
| 574 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation | 604 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation |
| 575 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) | 605 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) |
| 576 template <typename T> | 606 template <typename T> |
| 577 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 607 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
| 578 return scoped_ptr<T>(ptr); | 608 return scoped_ptr<T>(ptr); |
| 579 } | 609 } |
| 580 | 610 |
| 581 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 611 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
| OLD | NEW |