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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 #ifndef BASE_MEMORY_SCOPED_PTR_H_ | 77 #ifndef BASE_MEMORY_SCOPED_PTR_H_ |
78 #define BASE_MEMORY_SCOPED_PTR_H_ | 78 #define BASE_MEMORY_SCOPED_PTR_H_ |
79 | 79 |
80 // This is an implementation designed to match the anticipated future TR2 | 80 // This is an implementation designed to match the anticipated future TR2 |
81 // implementation of the scoped_ptr class. | 81 // implementation of the scoped_ptr class. |
82 | 82 |
83 #include <assert.h> | 83 #include <assert.h> |
84 #include <stddef.h> | 84 #include <stddef.h> |
85 #include <stdlib.h> | 85 #include <stdlib.h> |
86 | 86 |
87 #include <algorithm> // For std::swap(). | |
88 #include <iosfwd> | 87 #include <iosfwd> |
| 88 #include <memory> |
| 89 #include <utility> |
89 | 90 |
90 #include "base/basictypes.h" | 91 #include "base/basictypes.h" |
91 #include "base/compiler_specific.h" | 92 #include "base/compiler_specific.h" |
92 #include "base/move.h" | 93 #include "base/move.h" |
93 #include "base/template_util.h" | 94 #include "base/template_util.h" |
94 | 95 |
95 namespace base { | 96 namespace base { |
96 | 97 |
97 namespace subtle { | 98 namespace subtle { |
98 class RefCountedBase; | 99 class RefCountedBase; |
99 class RefCountedThreadSafeBase; | 100 class RefCountedThreadSafeBase; |
100 } // namespace subtle | 101 } // namespace subtle |
101 | 102 |
102 // Function object which deletes its parameter, which must be a pointer. | |
103 // If C is an array type, invokes 'delete[]' on the parameter; otherwise, | |
104 // invokes 'delete'. The default deleter for scoped_ptr<T>. | |
105 template <class T> | |
106 struct DefaultDeleter { | |
107 DefaultDeleter() {} | |
108 template <typename U> DefaultDeleter(const DefaultDeleter<U>& other) { | |
109 // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor | |
110 // if U* is implicitly convertible to T* and U is not an array type. | |
111 // | |
112 // Correct implementation should use SFINAE to disable this | |
113 // constructor. However, since there are no other 1-argument constructors, | |
114 // using a COMPILE_ASSERT() based on is_convertible<> and requiring | |
115 // complete types is simpler and will cause compile failures for equivalent | |
116 // misuses. | |
117 // | |
118 // Note, the is_convertible<U*, T*> check also ensures that U is not an | |
119 // array. T is guaranteed to be a non-array, so any U* where U is an array | |
120 // cannot convert to T*. | |
121 enum { T_must_be_complete = sizeof(T) }; | |
122 enum { U_must_be_complete = sizeof(U) }; | |
123 COMPILE_ASSERT((base::is_convertible<U*, T*>::value), | |
124 U_ptr_must_implicitly_convert_to_T_ptr); | |
125 } | |
126 inline void operator()(T* ptr) const { | |
127 enum { type_must_be_complete = sizeof(T) }; | |
128 delete ptr; | |
129 } | |
130 }; | |
131 | |
132 // Specialization of DefaultDeleter for array types. | |
133 template <class T> | |
134 struct DefaultDeleter<T[]> { | |
135 inline void operator()(T* ptr) const { | |
136 enum { type_must_be_complete = sizeof(T) }; | |
137 delete[] ptr; | |
138 } | |
139 | |
140 private: | |
141 // Disable this operator for any U != T because it is undefined to execute | |
142 // an array delete when the static type of the array mismatches the dynamic | |
143 // type. | |
144 // | |
145 // References: | |
146 // C++98 [expr.delete]p3 | |
147 // http://cplusplus.github.com/LWG/lwg-defects.html#938 | |
148 template <typename U> void operator()(U* array) const; | |
149 }; | |
150 | |
151 template <class T, int n> | |
152 struct DefaultDeleter<T[n]> { | |
153 // Never allow someone to declare something like scoped_ptr<int[10]>. | |
154 COMPILE_ASSERT(sizeof(T) == -1, do_not_use_array_with_size_as_type); | |
155 }; | |
156 | |
157 // Function object which invokes 'free' on its parameter, which must be | 103 // Function object which invokes 'free' on its parameter, which must be |
158 // a pointer. Can be used to store malloc-allocated pointers in scoped_ptr: | 104 // a pointer. Can be used to store malloc-allocated pointers in scoped_ptr: |
159 // | 105 // |
160 // scoped_ptr<int, base::FreeDeleter> foo_ptr( | 106 // scoped_ptr<int, base::FreeDeleter> foo_ptr( |
161 // static_cast<int*>(malloc(sizeof(int)))); | 107 // static_cast<int*>(malloc(sizeof(int)))); |
162 struct FreeDeleter { | 108 struct FreeDeleter { |
163 inline void operator()(void* ptr) const { | 109 inline void operator()(void* ptr) const { |
164 free(ptr); | 110 free(ptr); |
165 } | 111 } |
166 }; | 112 }; |
167 | 113 |
168 namespace internal { | 114 namespace internal { |
169 | 115 |
170 template <typename T> struct IsNotRefCounted { | 116 template <typename T> struct IsNotRefCounted { |
171 enum { | 117 enum { |
172 value = !base::is_convertible<T*, base::subtle::RefCountedBase*>::value && | 118 value = !base::is_convertible<T*, base::subtle::RefCountedBase*>::value && |
173 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: | 119 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: |
174 value | 120 value |
175 }; | 121 }; |
176 }; | 122 }; |
177 | 123 |
178 template <typename T> | |
179 struct ShouldAbortOnSelfReset { | |
180 template <typename U> | |
181 static NoType Test(const typename U::AllowSelfReset*); | |
182 | |
183 template <typename U> | |
184 static YesType Test(...); | |
185 | |
186 static const bool value = sizeof(Test<T>(0)) == sizeof(YesType); | |
187 }; | |
188 | |
189 // Minimal implementation of the core logic of scoped_ptr, suitable for | 124 // Minimal implementation of the core logic of scoped_ptr, suitable for |
190 // reuse in both scoped_ptr and its specializations. | 125 // reuse in both scoped_ptr and its specializations. |
191 template <class T, class D> | 126 template <class T, class D> |
192 class scoped_ptr_impl { | 127 class scoped_ptr_impl { |
193 public: | 128 public: |
194 explicit scoped_ptr_impl(T* p) : data_(p) {} | 129 explicit scoped_ptr_impl(T* p) : data_(p) {} |
195 | 130 |
196 // Initializer for deleters that have data parameters. | 131 // Initializer for deleters that have data parameters. |
197 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} | 132 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} |
198 | 133 |
(...skipping 24 matching lines...) Expand all Loading... |
223 // in a reference cycle (see ScopedPtrTest.ReferenceCycle). | 158 // in a reference cycle (see ScopedPtrTest.ReferenceCycle). |
224 // 3. If |this| is accessed in the future, in a use-after-free bug, attempts | 159 // 3. If |this| is accessed in the future, in a use-after-free bug, attempts |
225 // to dereference |this|'s pointer should cause either a failure or a | 160 // to dereference |this|'s pointer should cause either a failure or a |
226 // segfault closer to the problem. If |this| wasn't reset to nullptr, | 161 // segfault closer to the problem. If |this| wasn't reset to nullptr, |
227 // the access would cause the deleted memory to be read or written | 162 // the access would cause the deleted memory to be read or written |
228 // leading to other more subtle issues. | 163 // leading to other more subtle issues. |
229 reset(nullptr); | 164 reset(nullptr); |
230 } | 165 } |
231 | 166 |
232 void reset(T* p) { | 167 void reset(T* p) { |
233 // This is a self-reset, which is no longer allowed for default deleters: | |
234 // https://crbug.com/162971 | |
235 assert(!ShouldAbortOnSelfReset<D>::value || p == nullptr || p != data_.ptr); | |
236 | |
237 // Match C++11's definition of unique_ptr::reset(), which requires changing | 168 // Match C++11's definition of unique_ptr::reset(), which requires changing |
238 // the pointer before invoking the deleter on the old pointer. This prevents | 169 // the pointer before invoking the deleter on the old pointer. This prevents |
239 // |this| from being accessed after the deleter is run, which may destroy | 170 // |this| from being accessed after the deleter is run, which may destroy |
240 // |this|. | 171 // |this|. |
241 T* old = data_.ptr; | 172 T* old = data_.ptr; |
242 data_.ptr = p; | 173 data_.ptr = p; |
243 if (old != nullptr) | 174 if (old != nullptr) |
244 static_cast<D&>(data_)(old); | 175 static_cast<D&>(data_)(old); |
245 } | 176 } |
246 | 177 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 } // namespace base | 219 } // namespace base |
289 | 220 |
290 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> | 221 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> |
291 // automatically deletes the pointer it holds (if any). | 222 // automatically deletes the pointer it holds (if any). |
292 // That is, scoped_ptr<T> owns the T object that it points to. | 223 // That is, scoped_ptr<T> owns the T object that it points to. |
293 // Like a T*, a scoped_ptr<T> may hold either nullptr or a pointer to a T | 224 // Like a T*, a scoped_ptr<T> may hold either nullptr or a pointer to a T |
294 // object. Also like T*, scoped_ptr<T> is thread-compatible, and once you | 225 // object. Also like T*, scoped_ptr<T> is thread-compatible, and once you |
295 // dereference it, you get the thread safety guarantees of T. | 226 // dereference it, you get the thread safety guarantees of T. |
296 // | 227 // |
297 // The size of scoped_ptr is small. On most compilers, when using the | 228 // The size of scoped_ptr is small. On most compilers, when using the |
298 // DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will | 229 // std::default_delete, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters |
299 // increase the size proportional to whatever state they need to have. See | 230 // will increase the size proportional to whatever state they need to have. See |
300 // comments inside scoped_ptr_impl<> for details. | 231 // comments inside scoped_ptr_impl<> for details. |
301 // | 232 // |
302 // Current implementation targets having a strict subset of C++11's | 233 // Current implementation targets having a strict subset of C++11's |
303 // unique_ptr<> features. Known deficiencies include not supporting move-only | 234 // unique_ptr<> features. Known deficiencies include not supporting move-only |
304 // deleteres, function pointers as deleters, and deleters with reference | 235 // deleteres, function pointers as deleters, and deleters with reference |
305 // types. | 236 // types. |
306 template <class T, class D = base::DefaultDeleter<T> > | 237 template <class T, class D = std::default_delete<T>> |
307 class scoped_ptr { | 238 class scoped_ptr { |
308 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr) | 239 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr) |
309 | 240 |
310 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, | 241 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, |
311 T_is_refcounted_type_and_needs_scoped_refptr); | 242 T_is_refcounted_type_and_needs_scoped_refptr); |
312 | 243 |
313 public: | 244 public: |
314 // The element and deleter types. | 245 // The element and deleter types. |
315 typedef T element_type; | 246 typedef T element_type; |
316 typedef D deleter_type; | 247 typedef D deleter_type; |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 551 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
621 return scoped_ptr<T>(ptr); | 552 return scoped_ptr<T>(ptr); |
622 } | 553 } |
623 | 554 |
624 template <typename T> | 555 template <typename T> |
625 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { | 556 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { |
626 return out << p.get(); | 557 return out << p.get(); |
627 } | 558 } |
628 | 559 |
629 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 560 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
OLD | NEW |