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 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 correspond | 7 // end of a scope. There are two main classes you will use, which correspond |
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<T>): | 10 // Example usage (scoped_ptr): |
11 // { | 11 // { |
12 // scoped_ptr<Foo> foo(new Foo("wee")); | 12 // scoped_ptr<Foo> foo(new Foo("wee")); |
13 // } // foo goes out of scope, releasing the pointer with it. | 13 // } // foo goes out of scope, releasing the pointer with it. |
14 // | 14 // |
15 // { | 15 // { |
16 // scoped_ptr<Foo> foo; // No pointer managed. | 16 // scoped_ptr<Foo> foo; // No pointer managed. |
17 // foo.reset(new Foo("wee")); // Now a pointer is managed. | 17 // foo.reset(new Foo("wee")); // Now a pointer is managed. |
18 // foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. | 18 // foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. |
19 // foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. | 19 // foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. |
20 // foo->Method(); // Foo::Method() called. | 20 // foo->Method(); // Foo::Method() called. |
21 // foo.get()->Method(); // Foo::Method() called. | 21 // foo.get()->Method(); // Foo::Method() called. |
22 // SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer | 22 // SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer |
23 // // manages a pointer. | 23 // // manages a pointer. |
24 // foo.reset(new Foo("wee4")); // foo manages a pointer again. | 24 // foo.reset(new Foo("wee4")); // foo manages a pointer again. |
25 // foo.reset(); // Foo("wee4") destroyed, foo no longer | 25 // foo.reset(); // Foo("wee4") destroyed, foo no longer |
26 // // manages a pointer. | 26 // // manages a pointer. |
27 // } // foo wasn't managing a pointer, so nothing was destroyed. | 27 // } // foo wasn't managing a pointer, so nothing was destroyed. |
28 // | 28 // |
29 // Example usage (scoped_ptr<T[]>): | 29 // Example usage (scoped_array): |
30 // { | 30 // { |
31 // scoped_ptr<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 // These scopers also implement part of the functionality of C++11 unique_ptr | 36 // These scopers also implement part of the functionality of C++11 unique_ptr |
37 // in that they are "movable but not copyable." You can use the scopers in | 37 // in that they are "movable but not copyable." You can use the scopers in |
38 // the parameter and return types of functions to signify ownership transfer | 38 // the parameter and return types of functions to signify ownership transfer |
39 // in to and out of a function. When calling a function that has a scoper | 39 // in to and out of a function. When calling a function that has a scoper |
40 // as the argument type, it must be called with the result of an analogous | 40 // as the argument type, it must be called with the result of an analogous |
41 // scoper's Pass() function or another function that generates a temporary; | 41 // scoper's Pass() function or another function that generates a temporary; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 // scoped_ptr<Foo> foo(new Foo()); | 74 // scoped_ptr<Foo> foo(new Foo()); |
75 // scoped_ptr<FooParent> parent = foo.Pass(); | 75 // scoped_ptr<FooParent> parent = foo.Pass(); |
76 // | 76 // |
77 // PassAs<>() should be used to upcast return value in return statement: | 77 // PassAs<>() should be used to upcast return value in return statement: |
78 // | 78 // |
79 // scoped_ptr<Foo> CreateFoo() { | 79 // scoped_ptr<Foo> CreateFoo() { |
80 // scoped_ptr<FooChild> result(new FooChild()); | 80 // scoped_ptr<FooChild> result(new FooChild()); |
81 // return result.PassAs<Foo>(); | 81 // return result.PassAs<Foo>(); |
82 // } | 82 // } |
83 // | 83 // |
84 // Note that PassAs<>() is implemented only for scoped_ptr<T>, but not for | 84 // Note that PassAs<>() is implemented only for scoped_ptr, but not for |
85 // scoped_ptr<T[]>. This is because casting array pointers may not be safe. | 85 // scoped_array. This is because casting array pointers may not be safe. |
86 | 86 |
87 #ifndef BASE_MEMORY_SCOPED_PTR_H_ | 87 #ifndef BASE_MEMORY_SCOPED_PTR_H_ |
88 #define BASE_MEMORY_SCOPED_PTR_H_ | 88 #define BASE_MEMORY_SCOPED_PTR_H_ |
89 | 89 |
90 // This is an implementation designed to match the anticipated future TR2 | 90 // This is an implementation designed to match the anticipated future TR2 |
91 // implementation of the scoped_ptr class and scoped_ptr_malloc (deprecated). | 91 // implementation of the scoped_ptr class, and its closely-related brethren, |
| 92 // scoped_array, scoped_ptr_malloc. |
92 | 93 |
93 #include <assert.h> | 94 #include <assert.h> |
94 #include <stddef.h> | 95 #include <stddef.h> |
95 #include <stdlib.h> | 96 #include <stdlib.h> |
96 | 97 |
97 #include <algorithm> // For std::swap(). | 98 #include <algorithm> // For std::swap(). |
98 | 99 |
99 #include "base/basictypes.h" | 100 #include "base/basictypes.h" |
100 #include "base/compiler_specific.h" | 101 #include "base/compiler_specific.h" |
101 #include "base/move.h" | 102 #include "base/move.h" |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 template <class T, class D> | 556 template <class T, class D> |
556 bool operator==(T* p1, const scoped_ptr<T, D>& p2) { | 557 bool operator==(T* p1, const scoped_ptr<T, D>& p2) { |
557 return p1 == p2.get(); | 558 return p1 == p2.get(); |
558 } | 559 } |
559 | 560 |
560 template <class T, class D> | 561 template <class T, class D> |
561 bool operator!=(T* p1, const scoped_ptr<T, D>& p2) { | 562 bool operator!=(T* p1, const scoped_ptr<T, D>& p2) { |
562 return p1 != p2.get(); | 563 return p1 != p2.get(); |
563 } | 564 } |
564 | 565 |
| 566 // DEPRECATED: Use scoped_ptr<C[]> instead. |
| 567 // |
| 568 // scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate |
| 569 // with new [] and the destructor deletes objects with delete []. |
| 570 // |
| 571 // As with scoped_ptr<C>, a scoped_array<C> either points to an object |
| 572 // or is NULL. A scoped_array<C> owns the object that it points to. |
| 573 // scoped_array<T> is thread-compatible, and once you index into it, |
| 574 // the returned objects have only the thread safety guarantees of T. |
| 575 // |
| 576 // Size: sizeof(scoped_array<C>) == sizeof(C*) |
| 577 template <class C> |
| 578 class scoped_array { |
| 579 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_array, RValue) |
| 580 |
| 581 public: |
| 582 |
| 583 // The element type |
| 584 typedef C element_type; |
| 585 |
| 586 // Constructor. Defaults to initializing with NULL. |
| 587 // There is no way to create an uninitialized scoped_array. |
| 588 // The input parameter must be allocated with new []. |
| 589 explicit scoped_array(C* p = NULL) : array_(p) { } |
| 590 |
| 591 // Constructor. Move constructor for C++03 move emulation of this type. |
| 592 scoped_array(RValue rvalue) |
| 593 : array_(rvalue.object->release()) { |
| 594 } |
| 595 |
| 596 // Destructor. If there is a C object, delete it. |
| 597 // We don't need to test ptr_ == NULL because C++ does that for us. |
| 598 ~scoped_array() { |
| 599 enum { type_must_be_complete = sizeof(C) }; |
| 600 delete[] array_; |
| 601 } |
| 602 |
| 603 // operator=. Move operator= for C++03 move emulation of this type. |
| 604 scoped_array& operator=(RValue rhs) { |
| 605 reset(rhs.object->release()); |
| 606 return *this; |
| 607 } |
| 608 |
| 609 // Reset. Deletes the current owned object, if any. |
| 610 void reset(C* p = NULL) { |
| 611 // This is a self-reset, which is no longer allowed: http://crbug.com/162971 |
| 612 if (p != NULL && p == array_) |
| 613 abort(); |
| 614 |
| 615 C* old = array_; |
| 616 array_ = NULL; |
| 617 if (old != NULL) |
| 618 delete[] old; |
| 619 array_ = p; |
| 620 } |
| 621 |
| 622 // Get one element of the current object. |
| 623 // Will assert() if there is no current object, or index i is negative. |
| 624 C& operator[](ptrdiff_t i) const { |
| 625 assert(i >= 0); |
| 626 assert(array_ != NULL); |
| 627 return array_[i]; |
| 628 } |
| 629 |
| 630 // Get a pointer to the zeroth element of the current object. |
| 631 // If there is no current object, return NULL. |
| 632 C* get() const { |
| 633 return array_; |
| 634 } |
| 635 |
| 636 // Allow scoped_array<C> to be used in boolean expressions, but not |
| 637 // implicitly convertible to a real bool (which is dangerous). |
| 638 typedef C* scoped_array::*Testable; |
| 639 operator Testable() const { return array_ ? &scoped_array::array_ : NULL; } |
| 640 |
| 641 // Comparison operators. |
| 642 // These return whether two scoped_array refer to the same object, not just to |
| 643 // two different but equal objects. |
| 644 bool operator==(C* p) const { return array_ == p; } |
| 645 bool operator!=(C* p) const { return array_ != p; } |
| 646 |
| 647 // Swap two scoped arrays. |
| 648 void swap(scoped_array& p2) { |
| 649 C* tmp = array_; |
| 650 array_ = p2.array_; |
| 651 p2.array_ = tmp; |
| 652 } |
| 653 |
| 654 // Release an array. |
| 655 // The return value is the current pointer held by this object. |
| 656 // If this object holds a NULL pointer, the return value is NULL. |
| 657 // After this operation, this object will hold a NULL pointer, |
| 658 // and will not own the object any more. |
| 659 C* release() WARN_UNUSED_RESULT { |
| 660 C* retVal = array_; |
| 661 array_ = NULL; |
| 662 return retVal; |
| 663 } |
| 664 |
| 665 private: |
| 666 C* array_; |
| 667 |
| 668 // Disable initialization from any type other than C*, by providing a |
| 669 // constructor that matches such an initialization, but is private and has no |
| 670 // definition. This is disabled because it is not safe to call delete[] on an |
| 671 // array whose static type does not match its dynamic type. |
| 672 template <typename C2> explicit scoped_array(C2* array); |
| 673 explicit scoped_array(int disallow_construction_from_null); |
| 674 |
| 675 // Disable reset() from any type other than C*, for the same reasons as the |
| 676 // constructor above. |
| 677 template <typename C2> void reset(C2* array); |
| 678 void reset(int disallow_reset_from_null); |
| 679 |
| 680 // Forbid comparison of different scoped_array types. |
| 681 template <class C2> bool operator==(scoped_array<C2> const& p2) const; |
| 682 template <class C2> bool operator!=(scoped_array<C2> const& p2) const; |
| 683 }; |
| 684 |
| 685 // Free functions |
| 686 template <class C> |
| 687 void swap(scoped_array<C>& p1, scoped_array<C>& p2) { |
| 688 p1.swap(p2); |
| 689 } |
| 690 |
| 691 template <class C> |
| 692 bool operator==(C* p1, const scoped_array<C>& p2) { |
| 693 return p1 == p2.get(); |
| 694 } |
| 695 |
| 696 template <class C> |
| 697 bool operator!=(C* p1, const scoped_array<C>& p2) { |
| 698 return p1 != p2.get(); |
| 699 } |
| 700 |
565 // DEPRECATED: Use scoped_ptr<C, base::FreeDeleter> instead. | 701 // DEPRECATED: Use scoped_ptr<C, base::FreeDeleter> instead. |
566 // | 702 // |
567 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a | 703 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a |
568 // second template argument, the functor used to free the object. | 704 // second template argument, the functor used to free the object. |
569 | 705 |
570 template<class C, class FreeProc = base::FreeDeleter> | 706 template<class C, class FreeProc = base::FreeDeleter> |
571 class scoped_ptr_malloc { | 707 class scoped_ptr_malloc { |
572 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr_malloc, RValue) | 708 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr_malloc, RValue) |
573 | 709 |
574 public: | 710 public: |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 | 828 |
693 // A function to convert T* into scoped_ptr<T> | 829 // A function to convert T* into scoped_ptr<T> |
694 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation | 830 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation |
695 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) | 831 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) |
696 template <typename T> | 832 template <typename T> |
697 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 833 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
698 return scoped_ptr<T>(ptr); | 834 return scoped_ptr<T>(ptr); |
699 } | 835 } |
700 | 836 |
701 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 837 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
OLD | NEW |