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> | |
dcheng
2015/11/16 18:22:59
In line with bratell@'s proposal to #include <util
| |
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]>. | |
danakj
2015/11/16 22:19:02
Is this check provided by libc++ somewhere? Should
dcheng
2015/11/17 17:08:42
It's not explicitly provided by libc++. For exampl
| |
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> | 124 template <typename T> |
179 struct ShouldAbortOnSelfReset { | 125 struct ShouldAbortOnSelfReset { |
danakj
2015/11/16 22:19:02
Does this go away then?
dcheng
2015/11/17 17:08:42
Yes, it should.
| |
180 template <typename U> | 126 template <typename U> |
181 static NoType Test(const typename U::AllowSelfReset*); | 127 static NoType Test(const typename U::AllowSelfReset*); |
danakj
2015/11/16 22:19:02
And any instances of AllowSelfReset in the codebas
dcheng
2015/11/17 17:08:42
Good catch, I forgot that there's some code in //n
| |
182 | 128 |
183 template <typename U> | 129 template <typename U> |
184 static YesType Test(...); | 130 static YesType Test(...); |
185 | 131 |
186 static const bool value = sizeof(Test<T>(0)) == sizeof(YesType); | 132 static const bool value = sizeof(Test<T>(0)) == sizeof(YesType); |
187 }; | 133 }; |
188 | 134 |
189 // Minimal implementation of the core logic of scoped_ptr, suitable for | 135 // Minimal implementation of the core logic of scoped_ptr, suitable for |
190 // reuse in both scoped_ptr and its specializations. | 136 // reuse in both scoped_ptr and its specializations. |
191 template <class T, class D> | 137 template <class T, class D> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 // in a reference cycle (see ScopedPtrTest.ReferenceCycle). | 169 // in a reference cycle (see ScopedPtrTest.ReferenceCycle). |
224 // 3. If |this| is accessed in the future, in a use-after-free bug, attempts | 170 // 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 | 171 // 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, | 172 // 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 | 173 // the access would cause the deleted memory to be read or written |
228 // leading to other more subtle issues. | 174 // leading to other more subtle issues. |
229 reset(nullptr); | 175 reset(nullptr); |
230 } | 176 } |
231 | 177 |
232 void reset(T* p) { | 178 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); | |
danakj
2015/11/16 22:19:02
I'm not sure why this went away in this CL TBH. I
dcheng
2015/11/17 17:08:42
This is just making the interface match std::uniqu
danakj
2015/11/17 19:09:27
Yah, I kinda figured this would make a reasonable
| |
236 | |
237 // Match C++11's definition of unique_ptr::reset(), which requires changing | 179 // 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 | 180 // 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 | 181 // |this| from being accessed after the deleter is run, which may destroy |
240 // |this|. | 182 // |this|. |
241 T* old = data_.ptr; | 183 T* old = data_.ptr; |
242 data_.ptr = p; | 184 data_.ptr = p; |
243 if (old != nullptr) | 185 if (old != nullptr) |
244 static_cast<D&>(data_)(old); | 186 static_cast<D&>(data_)(old); |
245 } | 187 } |
246 | 188 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
288 } // namespace base | 230 } // namespace base |
289 | 231 |
290 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> | 232 // 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). | 233 // automatically deletes the pointer it holds (if any). |
292 // That is, scoped_ptr<T> owns the T object that it points to. | 234 // 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 | 235 // 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 | 236 // object. Also like T*, scoped_ptr<T> is thread-compatible, and once you |
295 // dereference it, you get the thread safety guarantees of T. | 237 // dereference it, you get the thread safety guarantees of T. |
296 // | 238 // |
297 // The size of scoped_ptr is small. On most compilers, when using the | 239 // The size of scoped_ptr is small. On most compilers, when using the |
298 // DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will | 240 // std::default_delete, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters |
299 // increase the size proportional to whatever state they need to have. See | 241 // will increase the size proportional to whatever state they need to have. See |
300 // comments inside scoped_ptr_impl<> for details. | 242 // comments inside scoped_ptr_impl<> for details. |
301 // | 243 // |
302 // Current implementation targets having a strict subset of C++11's | 244 // Current implementation targets having a strict subset of C++11's |
303 // unique_ptr<> features. Known deficiencies include not supporting move-only | 245 // unique_ptr<> features. Known deficiencies include not supporting move-only |
304 // deleteres, function pointers as deleters, and deleters with reference | 246 // deleteres, function pointers as deleters, and deleters with reference |
305 // types. | 247 // types. |
306 template <class T, class D = base::DefaultDeleter<T> > | 248 template <class T, class D = std::default_delete<T>> |
307 class scoped_ptr { | 249 class scoped_ptr { |
308 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr) | 250 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr) |
309 | 251 |
310 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, | 252 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, |
311 T_is_refcounted_type_and_needs_scoped_refptr); | 253 T_is_refcounted_type_and_needs_scoped_refptr); |
312 | 254 |
313 public: | 255 public: |
314 // The element and deleter types. | 256 // The element and deleter types. |
315 typedef T element_type; | 257 typedef T element_type; |
316 typedef D deleter_type; | 258 typedef D deleter_type; |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
578 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 520 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
579 return scoped_ptr<T>(ptr); | 521 return scoped_ptr<T>(ptr); |
580 } | 522 } |
581 | 523 |
582 template <typename T> | 524 template <typename T> |
583 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { | 525 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { |
584 return out << p.get(); | 526 return out << p.get(); |
585 } | 527 } |
586 | 528 |
587 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 529 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
OLD | NEW |