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): | 10 // Example usage (scoped_ptr<T>): |
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_array): | 29 // Example usage (scoped_ptr<T[]>): |
30 // { | 30 // { |
31 // scoped_array<Foo> foo(new Foo[100]); | 31 // scoped_ptr<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, but not for | 84 // Note that PassAs<>() is implemented only for scoped_ptr<T>, but not for |
85 // scoped_array. This is because casting array pointers may not be safe. | 85 // scoped_ptr<T[]>. 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 its closely-related brethren, | 91 // implementation of the scoped_ptr class and scoped_ptr_malloc (deprecated). |
92 // scoped_array, scoped_ptr_malloc. | |
93 | 92 |
94 #include <assert.h> | 93 #include <assert.h> |
95 #include <stddef.h> | 94 #include <stddef.h> |
96 #include <stdlib.h> | 95 #include <stdlib.h> |
97 | 96 |
98 #include <algorithm> // For std::swap(). | 97 #include <algorithm> // For std::swap(). |
99 | 98 |
100 #include "base/basictypes.h" | 99 #include "base/basictypes.h" |
101 #include "base/compiler_specific.h" | 100 #include "base/compiler_specific.h" |
102 #include "base/move.h" | 101 #include "base/move.h" |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 template <class T, class D> | 555 template <class T, class D> |
557 bool operator==(T* p1, const scoped_ptr<T, D>& p2) { | 556 bool operator==(T* p1, const scoped_ptr<T, D>& p2) { |
558 return p1 == p2.get(); | 557 return p1 == p2.get(); |
559 } | 558 } |
560 | 559 |
561 template <class T, class D> | 560 template <class T, class D> |
562 bool operator!=(T* p1, const scoped_ptr<T, D>& p2) { | 561 bool operator!=(T* p1, const scoped_ptr<T, D>& p2) { |
563 return p1 != p2.get(); | 562 return p1 != p2.get(); |
564 } | 563 } |
565 | 564 |
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 | |
701 // DEPRECATED: Use scoped_ptr<C, base::FreeDeleter> instead. | 565 // DEPRECATED: Use scoped_ptr<C, base::FreeDeleter> instead. |
702 // | 566 // |
703 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a | 567 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a |
704 // second template argument, the functor used to free the object. | 568 // second template argument, the functor used to free the object. |
705 | 569 |
706 template<class C, class FreeProc = base::FreeDeleter> | 570 template<class C, class FreeProc = base::FreeDeleter> |
707 class scoped_ptr_malloc { | 571 class scoped_ptr_malloc { |
708 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr_malloc, RValue) | 572 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr_malloc, RValue) |
709 | 573 |
710 public: | 574 public: |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 | 692 |
829 // A function to convert T* into scoped_ptr<T> | 693 // A function to convert T* into scoped_ptr<T> |
830 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation | 694 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation |
831 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) | 695 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) |
832 template <typename T> | 696 template <typename T> |
833 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 697 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
834 return scoped_ptr<T>(ptr); | 698 return scoped_ptr<T>(ptr); |
835 } | 699 } |
836 | 700 |
837 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 701 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
OLD | NEW |