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 |