OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 Google Inc. All Rights Reserved. |
| 2 // |
| 3 // Redistribution and use in source and binary forms, with or without |
| 4 // modification, are permitted provided that the following conditions are |
| 5 // met: |
| 6 // |
| 7 // * Redistributions of source code must retain the above copyright |
| 8 // notice, this list of conditions and the following disclaimer. |
| 9 // * Redistributions in binary form must reproduce the above |
| 10 // copyright notice, this list of conditions and the following disclaimer |
| 11 // in the documentation and/or other materials provided with the |
| 12 // distribution. |
| 13 // * Neither the name of Google Inc. nor the names of its |
| 14 // contributors may be used to endorse or promote products derived from |
| 15 // this software without specific prior written permission. |
| 16 // |
| 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 |
| 29 // This is a copy of breakpad's standalone scoped_ptr, which has been |
| 30 // renamed to nonstd::unique_ptr, and from which more complicated classes |
| 31 // have been removed. The reset() method has also been tweaked to more |
| 32 // closely match c++11, and an implicit conversion to bool has been added. |
| 33 |
| 34 // Scopers help you manage ownership of a pointer, helping you easily manage the |
| 35 // a pointer within a scope, and automatically destroying the pointer at the |
| 36 // end of a scope. |
| 37 // |
| 38 // Example usage (unique_ptr): |
| 39 // { |
| 40 // unique_ptr<Foo> foo(new Foo("wee")); |
| 41 // } // foo goes out of scope, releasing the pointer with it. |
| 42 // |
| 43 // { |
| 44 // unique_ptr<Foo> foo; // No pointer managed. |
| 45 // foo.reset(new Foo("wee")); // Now a pointer is managed. |
| 46 // foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. |
| 47 // foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. |
| 48 // foo->Method(); // Foo::Method() called. |
| 49 // foo.get()->Method(); // Foo::Method() called. |
| 50 // SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer |
| 51 // // manages a pointer. |
| 52 // foo.reset(new Foo("wee4")); // foo manages a pointer again. |
| 53 // foo.reset(); // Foo("wee4") destroyed, foo no longer |
| 54 // // manages a pointer. |
| 55 // } // foo wasn't managing a pointer, so nothing was destroyed. |
| 56 |
| 57 #ifndef NONSTD_UNIQUE_PTR_H_ |
| 58 #define NONSTD_UNIQUE_PTR_H_ |
| 59 |
| 60 // This is an implementation designed to match the anticipated future TR2 |
| 61 // implementation of the unique_ptr class. |
| 62 |
| 63 #include <assert.h> |
| 64 #include <stddef.h> |
| 65 #include <stdlib.h> |
| 66 |
| 67 namespace nonstd { |
| 68 |
| 69 // A unique_ptr<T> is like a T*, except that the destructor of unique_ptr<T> |
| 70 // automatically deletes the pointer it holds (if any). |
| 71 // That is, unique_ptr<T> owns the T object that it points to. |
| 72 // Like a T*, a unique_ptr<T> may hold either NULL or a pointer to a T object. |
| 73 // Also like T*, unique_ptr<T> is thread-compatible, and once you |
| 74 // dereference it, you get the threadsafety guarantees of T. |
| 75 // |
| 76 // The size of a unique_ptr is small: |
| 77 // sizeof(unique_ptr<C>) == sizeof(C*) |
| 78 template <class C> |
| 79 class unique_ptr { |
| 80 public: |
| 81 |
| 82 // The element type |
| 83 typedef C element_type; |
| 84 |
| 85 // Constructor. Defaults to initializing with NULL. |
| 86 // There is no way to create an uninitialized unique_ptr. |
| 87 // The input parameter must be allocated with new. |
| 88 explicit unique_ptr(C* p = NULL) : ptr_(p) { } |
| 89 |
| 90 // Destructor. If there is a C object, delete it. |
| 91 // We don't need to test ptr_ == NULL because C++ does that for us. |
| 92 ~unique_ptr() { |
| 93 enum { type_must_be_complete = sizeof(C) }; |
| 94 delete ptr_; |
| 95 } |
| 96 |
| 97 // Reset. Deletes the current owned object, if any. |
| 98 // Then takes ownership of a new object, if given. |
| 99 // this->reset(this->get()) works. |
| 100 void reset(C* p = NULL) { |
| 101 if (p != ptr_) { |
| 102 enum { type_must_be_complete = sizeof(C) }; |
| 103 C* old_ptr = ptr_; |
| 104 ptr_ = p; |
| 105 delete old_ptr; |
| 106 } |
| 107 } |
| 108 |
| 109 // Accessors to get the owned object. |
| 110 // operator* and operator-> will assert() if there is no current object. |
| 111 C& operator*() const { |
| 112 assert(ptr_ != NULL); |
| 113 return *ptr_; |
| 114 } |
| 115 C* operator->() const { |
| 116 assert(ptr_ != NULL); |
| 117 return ptr_; |
| 118 } |
| 119 C* get() const { return ptr_; } |
| 120 |
| 121 // Comparison operators. |
| 122 // These return whether two unique_ptr refer to the same object, not just to |
| 123 // two different but equal objects. |
| 124 bool operator==(C* p) const { return ptr_ == p; } |
| 125 bool operator!=(C* p) const { return ptr_ != p; } |
| 126 |
| 127 // Swap two scoped pointers. |
| 128 void swap(unique_ptr& p2) { |
| 129 C* tmp = ptr_; |
| 130 ptr_ = p2.ptr_; |
| 131 p2.ptr_ = tmp; |
| 132 } |
| 133 |
| 134 // Release a pointer. |
| 135 // The return value is the current pointer held by this object. |
| 136 // If this object holds a NULL pointer, the return value is NULL. |
| 137 // After this operation, this object will hold a NULL pointer, |
| 138 // and will not own the object any more. |
| 139 C* release() { |
| 140 C* retVal = ptr_; |
| 141 ptr_ = NULL; |
| 142 return retVal; |
| 143 } |
| 144 |
| 145 // Allow promotion to bool for conditional statements. |
| 146 operator bool() const { return ptr_ != NULL; } |
| 147 |
| 148 private: |
| 149 C* ptr_; |
| 150 |
| 151 // Forbid comparison of unique_ptr types. If C2 != C, it totally doesn't |
| 152 // make sense, and if C2 == C, it still doesn't make sense because you should |
| 153 // never have the same object owned by two different unique_ptrs. |
| 154 template <class C2> bool operator==(unique_ptr<C2> const& p2) const; |
| 155 template <class C2> bool operator!=(unique_ptr<C2> const& p2) const; |
| 156 |
| 157 // Disallow evil constructors |
| 158 unique_ptr(const unique_ptr&); |
| 159 void operator=(const unique_ptr&); |
| 160 }; |
| 161 |
| 162 // Free functions |
| 163 template <class C> |
| 164 void swap(unique_ptr<C>& p1, unique_ptr<C>& p2) { |
| 165 p1.swap(p2); |
| 166 } |
| 167 |
| 168 template <class C> |
| 169 bool operator==(C* p1, const unique_ptr<C>& p2) { |
| 170 return p1 == p2.get(); |
| 171 } |
| 172 |
| 173 template <class C> |
| 174 bool operator!=(C* p1, const unique_ptr<C>& p2) { |
| 175 return p1 != p2.get(); |
| 176 } |
| 177 |
| 178 } // namespace nonstd |
| 179 |
| 180 #endif // NONSTD_UNIQUE_PTR_H_ |
OLD | NEW |