Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 Google Inc. All Rights Reserved. | 1 // Copyright 2013 Google Inc. All Rights Reserved. |
| 2 // | 2 // |
| 3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
| 4 // modification, are permitted provided that the following conditions are | 4 // modification, are permitted provided that the following conditions are |
| 5 // met: | 5 // met: |
| 6 // | 6 // |
| 7 // * Redistributions of source code must retain the above copyright | 7 // * Redistributions of source code must retain the above copyright |
| 8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
| 9 // * Redistributions in binary form must reproduce the above | 9 // * Redistributions in binary form must reproduce the above |
| 10 // copyright notice, this list of conditions and the following disclaimer | 10 // copyright notice, this list of conditions and the following disclaimer |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 | 28 |
| 29 // This is a copy of breakpad's standalone scoped_ptr, which has been | 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 | 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 | 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. | 32 // closely match c++11, and an implicit conversion to bool has been added. |
| 33 | 33 |
| 34 // Scopers help you manage ownership of a pointer, helping you easily manage the | 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 | 35 // a pointer within a scope, and automatically destroying the pointer at the |
| 36 // end of a scope. | 36 // end of a scope. |
| 37 // | 37 // |
| 38 // A unique_ptr<T> is like a T*, except that the destructor of unique_ptr<T> | |
| 39 // automatically deletes the pointer it holds (if any). | |
| 40 // That is, unique_ptr<T> owns the T object that it points to. | |
| 41 // Like a T*, a unique_ptr<T> may hold either NULL or a pointer to a T object. | |
| 42 // Also like T*, unique_ptr<T> is thread-compatible, and once you | |
| 43 // dereference it, you get the threadsafety guarantees of T. | |
|
Lei Zhang
2015/05/06 23:59:35
nit: "thread safety"
Tom Sepez
2015/05/07 00:07:40
Done.
| |
| 44 // | |
| 38 // Example usage (unique_ptr): | 45 // Example usage (unique_ptr): |
| 39 // { | 46 // { |
| 40 // unique_ptr<Foo> foo(new Foo("wee")); | 47 // unique_ptr<Foo> foo(new Foo("wee")); |
| 41 // } // foo goes out of scope, releasing the pointer with it. | 48 // } // foo goes out of scope, releasing the pointer with it. |
| 42 // | 49 // |
| 43 // { | 50 // { |
| 44 // unique_ptr<Foo> foo; // No pointer managed. | 51 // unique_ptr<Foo> foo; // No pointer managed. |
| 45 // foo.reset(new Foo("wee")); // Now a pointer is managed. | 52 // foo.reset(new Foo("wee")); // Now a pointer is managed. |
| 46 // foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. | 53 // foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. |
| 47 // foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. | 54 // foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. |
| 48 // foo->Method(); // Foo::Method() called. | 55 // foo->Method(); // Foo::Method() called. |
| 49 // foo.get()->Method(); // Foo::Method() called. | 56 // foo.get()->Method(); // Foo::Method() called. |
| 50 // SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer | 57 // SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer |
| 51 // // manages a pointer. | 58 // // manages a pointer. |
| 52 // foo.reset(new Foo("wee4")); // foo manages a pointer again. | 59 // foo.reset(new Foo("wee4")); // foo manages a pointer again. |
| 53 // foo.reset(); // Foo("wee4") destroyed, foo no longer | 60 // foo.reset(); // Foo("wee4") destroyed, foo no longer |
| 54 // // manages a pointer. | 61 // // manages a pointer. |
| 55 // } // foo wasn't managing a pointer, so nothing was destroyed. | 62 // } // foo wasn't managing a pointer, so nothing was destroyed. |
| 63 // | |
| 64 // The size of a unique_ptr is small: sizeof(unique_ptr<C>) == sizeof(C*) | |
| 56 | 65 |
| 57 #ifndef NONSTD_UNIQUE_PTR_H_ | 66 #ifndef NONSTD_UNIQUE_PTR_H_ |
| 58 #define NONSTD_UNIQUE_PTR_H_ | 67 #define NONSTD_UNIQUE_PTR_H_ |
| 59 | 68 |
| 60 // This is an implementation designed to match the anticipated future TR2 | 69 // This is an implementation designed to match the anticipated future TR2 |
| 61 // implementation of the unique_ptr class. | 70 // implementation of the unique_ptr class. |
| 62 | 71 |
| 63 #include <assert.h> | 72 #include <assert.h> |
| 64 #include <stddef.h> | 73 #include <stddef.h> |
| 65 #include <stdlib.h> | 74 #include <stdlib.h> |
| 66 | 75 |
| 67 namespace nonstd { | 76 namespace nonstd { |
| 68 | 77 |
| 69 // A unique_ptr<T> is like a T*, except that the destructor of unique_ptr<T> | 78 // Common implementation for both pointers to elements and pointers to |
| 70 // automatically deletes the pointer it holds (if any). | 79 // arrays. These are diferenatiated below based on the need to invoke |
|
Lei Zhang
2015/05/06 23:59:35
typo
Tom Sepez
2015/05/07 00:07:40
Done.
| |
| 71 // That is, unique_ptr<T> owns the T object that it points to. | 80 // delete vs. delete[] as appropriate. |
| 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> | 81 template <class C> |
| 79 class unique_ptr { | 82 class unique_ptr_base { |
| 80 public: | 83 public: |
| 81 | 84 |
| 82 // The element type | 85 // The element type |
| 83 typedef C element_type; | 86 typedef C element_type; |
| 84 | 87 |
| 85 // Constructor. Defaults to initializing with NULL. | 88 explicit unique_ptr_base(C* p) : ptr_(p) { } |
| 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 | 89 |
| 109 // Accessors to get the owned object. | 90 // Accessors to get the owned object. |
| 110 // operator* and operator-> will assert() if there is no current object. | 91 // operator* and operator-> will assert() if there is no current object. |
| 111 C& operator*() const { | 92 C& operator*() const { |
| 112 assert(ptr_ != NULL); | 93 assert(ptr_ != NULL); |
| 113 return *ptr_; | 94 return *ptr_; |
| 114 } | 95 } |
| 115 C* operator->() const { | 96 C* operator->() const { |
| 116 assert(ptr_ != NULL); | 97 assert(ptr_ != NULL); |
| 117 return ptr_; | 98 return ptr_; |
| 118 } | 99 } |
| 119 C* get() const { return ptr_; } | 100 C* get() const { return ptr_; } |
| 120 | 101 |
| 121 // Comparison operators. | 102 // Comparison operators. |
| 122 // These return whether two unique_ptr refer to the same object, not just to | 103 // These return whether two unique_ptr refer to the same object, not just to |
| 123 // two different but equal objects. | 104 // two different but equal objects. |
| 124 bool operator==(C* p) const { return ptr_ == p; } | 105 bool operator==(C* p) const { return ptr_ == p; } |
| 125 bool operator!=(C* p) const { return ptr_ != p; } | 106 bool operator!=(C* p) const { return ptr_ != p; } |
| 126 | 107 |
| 127 // Swap two scoped pointers. | 108 // Swap two scoped pointers. |
| 128 void swap(unique_ptr& p2) { | 109 void swap(unique_ptr_base& p2) { |
| 129 C* tmp = ptr_; | 110 C* tmp = ptr_; |
| 130 ptr_ = p2.ptr_; | 111 ptr_ = p2.ptr_; |
| 131 p2.ptr_ = tmp; | 112 p2.ptr_ = tmp; |
| 132 } | 113 } |
| 133 | 114 |
| 134 // Release a pointer. | 115 // Release a pointer. |
| 135 // The return value is the current pointer held by this object. | 116 // The return value is the current pointer held by this object. |
| 136 // If this object holds a NULL pointer, the return value is NULL. | 117 // If this object holds a NULL pointer, the return value is NULL. |
| 137 // After this operation, this object will hold a NULL pointer, | 118 // After this operation, this object will hold a NULL pointer, |
| 138 // and will not own the object any more. | 119 // and will not own the object any more. |
| 139 C* release() { | 120 C* release() { |
| 140 C* retVal = ptr_; | 121 C* retVal = ptr_; |
| 141 ptr_ = NULL; | 122 ptr_ = NULL; |
| 142 return retVal; | 123 return retVal; |
| 143 } | 124 } |
| 144 | 125 |
| 145 // Allow promotion to bool for conditional statements. | 126 // Allow promotion to bool for conditional statements. |
| 146 operator bool() const { return ptr_ != NULL; } | 127 operator bool() const { return ptr_ != NULL; } |
| 147 | 128 |
| 148 private: | 129 protected: |
| 149 C* ptr_; | 130 C* ptr_; |
| 131 }; | |
| 150 | 132 |
| 133 // Implementation for ordinary pointers using delete. | |
| 134 template <class C> | |
| 135 class unique_ptr : public unique_ptr_base<C> { | |
| 136 public: | |
| 137 using unique_ptr_base<C>::ptr_; | |
| 138 explicit unique_ptr(C* p = NULL) : unique_ptr_base<C>(p) { } | |
| 139 | |
| 140 // Destructor. If there is a C object, delete it. | |
| 141 // We don't need to test ptr_ == NULL because C++ does that for us. | |
| 142 ~unique_ptr() { | |
| 143 enum { type_must_be_complete = sizeof(C) }; | |
| 144 delete ptr_; | |
| 145 } | |
| 146 | |
| 147 // Reset. Deletes the current owned object, if any. | |
| 148 // Then takes ownership of a new object, if given. | |
| 149 // this->reset(this->get()) works. | |
| 150 void reset(C* p = NULL) { | |
| 151 if (p != ptr_) { | |
| 152 enum { type_must_be_complete = sizeof(C) }; | |
| 153 C* old_ptr = ptr_; | |
| 154 ptr_ = p; | |
| 155 delete old_ptr; | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 private: | |
| 151 // Forbid comparison of unique_ptr types. If C2 != C, it totally doesn't | 160 // 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 | 161 // 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. | 162 // never have the same object owned by two different unique_ptrs. |
| 163 template <class C2> bool operator==(unique_ptr<C2> const& p2) const; | |
| 164 template <class C2> bool operator!=(unique_ptr<C2> const& p2) const; | |
| 165 | |
| 166 // Disallow evil constructors | |
| 167 unique_ptr(const unique_ptr&); | |
| 168 void operator=(const unique_ptr&); | |
| 169 }; | |
| 170 | |
| 171 // Specialization for arrays using delete[]. | |
| 172 template <class C> | |
| 173 class unique_ptr<C[]> : public unique_ptr_base<C> { | |
| 174 public: | |
| 175 using unique_ptr_base<C>::ptr_; | |
| 176 explicit unique_ptr(C* p = NULL) : unique_ptr_base<C>(p) { } | |
| 177 | |
| 178 // Destructor. If there is a C object, delete it. | |
| 179 // We don't need to test ptr_ == NULL because C++ does that for us. | |
| 180 ~unique_ptr() { | |
| 181 enum { type_must_be_complete = sizeof(C) }; | |
| 182 delete[] ptr_; | |
| 183 } | |
| 184 | |
| 185 // Reset. Deletes the current owned object, if any. | |
| 186 // Then takes ownership of a new object, if given. | |
| 187 // this->reset(this->get()) works. | |
| 188 void reset(C* p = NULL) { | |
| 189 if (p != ptr_) { | |
| 190 enum { type_must_be_complete = sizeof(C) }; | |
| 191 C* old_ptr = ptr_; | |
| 192 ptr_ = p; | |
| 193 delete[] old_ptr; | |
| 194 } | |
| 195 } | |
| 196 | |
| 197 // Support indexing since it is holding array. | |
| 198 C& operator[] (size_t i) { return ptr_[i]; } | |
| 199 | |
| 200 private: | |
| 201 // Forbid comparison of unique_ptr types. If C2 != C, it totally doesn't | |
| 202 // make sense, and if C2 == C, it still doesn't make sense because you should | |
| 203 // never have the same object owned by two different unique_ptrs. | |
| 154 template <class C2> bool operator==(unique_ptr<C2> const& p2) const; | 204 template <class C2> bool operator==(unique_ptr<C2> const& p2) const; |
| 155 template <class C2> bool operator!=(unique_ptr<C2> const& p2) const; | 205 template <class C2> bool operator!=(unique_ptr<C2> const& p2) const; |
| 156 | 206 |
| 157 // Disallow evil constructors | 207 // Disallow evil constructors |
| 158 unique_ptr(const unique_ptr&); | 208 unique_ptr(const unique_ptr&); |
| 159 void operator=(const unique_ptr&); | 209 void operator=(const unique_ptr&); |
| 160 }; | 210 }; |
| 161 | 211 |
| 162 // Free functions | 212 // Free functions |
| 163 template <class C> | 213 template <class C> |
| 164 void swap(unique_ptr<C>& p1, unique_ptr<C>& p2) { | 214 void swap(unique_ptr<C>& p1, unique_ptr<C>& p2) { |
| 165 p1.swap(p2); | 215 p1.swap(p2); |
| 166 } | 216 } |
| 167 | 217 |
| 168 template <class C> | 218 template <class C> |
| 169 bool operator==(C* p1, const unique_ptr<C>& p2) { | 219 bool operator==(C* p1, const unique_ptr<C>& p2) { |
| 170 return p1 == p2.get(); | 220 return p1 == p2.get(); |
| 171 } | 221 } |
| 172 | 222 |
| 173 template <class C> | 223 template <class C> |
| 174 bool operator!=(C* p1, const unique_ptr<C>& p2) { | 224 bool operator!=(C* p1, const unique_ptr<C>& p2) { |
| 175 return p1 != p2.get(); | 225 return p1 != p2.get(); |
| 176 } | 226 } |
| 177 | 227 |
| 178 } // namespace nonstd | 228 } // namespace nonstd |
| 179 | 229 |
| 180 #endif // NONSTD_UNIQUE_PTR_H_ | 230 #endif // NONSTD_UNIQUE_PTR_H_ |
| OLD | NEW |