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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 <iosfwd> | 87 #include <iosfwd> |
88 #include <memory> | 88 #include <memory> |
| 89 #include <type_traits> |
89 #include <utility> | 90 #include <utility> |
90 | 91 |
91 #include "base/basictypes.h" | 92 #include "base/basictypes.h" |
92 #include "base/compiler_specific.h" | 93 #include "base/compiler_specific.h" |
93 #include "base/move.h" | 94 #include "base/move.h" |
94 #include "base/template_util.h" | 95 #include "base/template_util.h" |
95 | 96 |
96 namespace base { | 97 namespace base { |
97 | 98 |
98 namespace subtle { | 99 namespace subtle { |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 // types. | 237 // types. |
237 template <class T, class D = std::default_delete<T>> | 238 template <class T, class D = std::default_delete<T>> |
238 class scoped_ptr { | 239 class scoped_ptr { |
239 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr) | 240 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr) |
240 | 241 |
241 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, | 242 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, |
242 T_is_refcounted_type_and_needs_scoped_refptr); | 243 T_is_refcounted_type_and_needs_scoped_refptr); |
243 | 244 |
244 public: | 245 public: |
245 // The element and deleter types. | 246 // The element and deleter types. |
246 typedef T element_type; | 247 using element_type = T; |
247 typedef D deleter_type; | 248 using deleter_type = D; |
248 | 249 |
249 // Constructor. Defaults to initializing with nullptr. | 250 // Constructor. Defaults to initializing with nullptr. |
250 scoped_ptr() : impl_(nullptr) {} | 251 scoped_ptr() : impl_(nullptr) {} |
251 | 252 |
252 // Constructor. Takes ownership of p. | 253 // Constructor. Takes ownership of p. |
253 explicit scoped_ptr(element_type* p) : impl_(p) {} | 254 explicit scoped_ptr(element_type* p) : impl_(p) {} |
254 | 255 |
255 // Constructor. Allows initialization of a stateful deleter. | 256 // Constructor. Allows initialization of a stateful deleter. |
256 scoped_ptr(element_type* p, const D& d) : impl_(p, d) {} | 257 scoped_ptr(element_type* p, const D& d) : impl_(p, d) {} |
257 | 258 |
258 // Constructor. Allows construction from a nullptr. | 259 // Constructor. Allows construction from a nullptr. |
259 scoped_ptr(std::nullptr_t) : impl_(nullptr) {} | 260 scoped_ptr(std::nullptr_t) : impl_(nullptr) {} |
260 | 261 |
261 // Constructor. Allows construction from a scoped_ptr rvalue for a | 262 // Move constructor. |
| 263 // |
| 264 // IMPLEMENTATION NOTE: Clang requires a move constructor to be defined (and |
| 265 // not just the conversion constructor) in order to warn on pessimizing moves. |
| 266 // The requirements for the move constructor are specified in C++11 |
| 267 // 20.7.1.2.1.15-17, which has some subtleties around reference deleters. As |
| 268 // we don't support reference (or move-only) deleters, the post conditions are |
| 269 // trivially true: we always copy construct the deleter from other's deleter. |
| 270 scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} |
| 271 |
| 272 // Conversion constructor. Allows construction from a scoped_ptr rvalue for a |
262 // convertible type and deleter. | 273 // convertible type and deleter. |
263 // | 274 // |
264 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct | 275 // IMPLEMENTATION NOTE: C++ 20.7.1.2.1.19 requires this constructor to only |
265 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor | 276 // participate in overload resolution if all the following are true: |
266 // has different post-conditions if D is a reference type. Since this | 277 // - U is implicitly convertible to T: this is important for 2 reasons: |
267 // implementation does not support deleters with reference type, | 278 // 1. So type traits don't incorrectly return true, e.g. |
268 // we do not need a separate move constructor allowing us to avoid one | 279 // std::is_convertible<scoped_ptr<Base>, scoped_ptr<Derived>>::value |
269 // use of SFINAE. You only need to care about this if you modify the | 280 // should be false. |
270 // implementation of scoped_ptr. | 281 // 2. To make sure code like this compiles: |
271 template <typename U, typename V> | 282 // void F(scoped_ptr<int>); |
272 scoped_ptr(scoped_ptr<U, V>&& other) | 283 // void F(scoped_ptr<Base>); |
273 : impl_(&other.impl_) { | 284 // // Ambiguous since both conversion constructors match. |
274 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); | 285 // F(scoped_ptr<Derived>()); |
| 286 // - U is not an array type: to prevent conversions from scoped_ptr<T[]> to |
| 287 // scoped_ptr<T>. |
| 288 // - D is a reference type and E is the same type, or D is not a reference |
| 289 // type and E is implicitly convertible to D: again, we don't support |
| 290 // reference deleters, so we only worry about the latter requirement. |
| 291 template <typename U, |
| 292 typename E, |
| 293 typename std::enable_if<!std::is_array<U>::value && |
| 294 std::is_convertible<U*, T*>::value && |
| 295 std::is_convertible<E, D>::value>::type* = |
| 296 nullptr> |
| 297 scoped_ptr(scoped_ptr<U, E>&& other) |
| 298 : impl_(&other.impl_) {} |
| 299 |
| 300 // operator=. |
| 301 // |
| 302 // IMPLEMENTATION NOTE: Unlike the move constructor, Clang does not appear to |
| 303 // require a move assignment operator to trigger the pessimizing move warning: |
| 304 // in this case, the warning triggers when moving a temporary. For consistency |
| 305 // with the move constructor, we define it anyway. C++11 20.7.1.2.3.1-3 |
| 306 // defines several requirements around this: like the move constructor, the |
| 307 // requirements are simplified by the fact that we don't support move-only or |
| 308 // reference deleters. |
| 309 scoped_ptr& operator=(scoped_ptr&& rhs) { |
| 310 impl_.TakeState(&rhs.impl_); |
| 311 return *this; |
275 } | 312 } |
276 | 313 |
277 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible | 314 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible |
278 // type and deleter. | 315 // type and deleter. |
279 // | 316 // |
280 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from | 317 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from |
281 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated | 318 // the normal move assignment operator. C++11 20.7.1.2.3.4-7 contains the |
282 // form has different requirements on for move-only Deleters. Since this | 319 // requirement for this operator, but like the conversion constructor, the |
283 // implementation does not support move-only Deleters, we do not need a | 320 // requirements are greatly simplified by not supporting move-only or |
284 // separate move assignment operator allowing us to avoid one use of SFINAE. | 321 // reference deleters. |
285 // You only need to care about this if you modify the implementation of | 322 template <typename U, |
286 // scoped_ptr. | 323 typename E, |
287 template <typename U, typename V> | 324 typename std::enable_if<!std::is_array<U>::value && |
288 scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) { | 325 std::is_convertible<U*, T*>::value && |
289 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); | 326 // Note that this really should be |
| 327 // std::is_assignable, but <type_traits> |
| 328 // appears to be missing this on some |
| 329 // platforms. This is close enough (though |
| 330 // it's not the same). |
| 331 std::is_convertible<D, E>::value>::type* = |
| 332 nullptr> |
| 333 scoped_ptr& operator=(scoped_ptr<U, E>&& rhs) { |
290 impl_.TakeState(&rhs.impl_); | 334 impl_.TakeState(&rhs.impl_); |
291 return *this; | 335 return *this; |
292 } | 336 } |
293 | 337 |
294 // operator=. Allows assignment from a nullptr. Deletes the currently owned | 338 // operator=. Allows assignment from a nullptr. Deletes the currently owned |
295 // object, if any. | 339 // object, if any. |
296 scoped_ptr& operator=(std::nullptr_t) { | 340 scoped_ptr& operator=(std::nullptr_t) { |
297 reset(); | 341 reset(); |
298 return *this; | 342 return *this; |
299 } | 343 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 // Forbidden for API compatibility with std::unique_ptr. | 399 // Forbidden for API compatibility with std::unique_ptr. |
356 explicit scoped_ptr(int disallow_construction_from_null); | 400 explicit scoped_ptr(int disallow_construction_from_null); |
357 }; | 401 }; |
358 | 402 |
359 template <class T, class D> | 403 template <class T, class D> |
360 class scoped_ptr<T[], D> { | 404 class scoped_ptr<T[], D> { |
361 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr) | 405 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr) |
362 | 406 |
363 public: | 407 public: |
364 // The element and deleter types. | 408 // The element and deleter types. |
365 typedef T element_type; | 409 using element_type = T; |
366 typedef D deleter_type; | 410 using deleter_type = D; |
367 | 411 |
368 // Constructor. Defaults to initializing with nullptr. | 412 // Constructor. Defaults to initializing with nullptr. |
369 scoped_ptr() : impl_(nullptr) {} | 413 scoped_ptr() : impl_(nullptr) {} |
370 | 414 |
371 // Constructor. Stores the given array. Note that the argument's type | 415 // Constructor. Stores the given array. Note that the argument's type |
372 // must exactly match T*. In particular: | 416 // must exactly match T*. In particular: |
373 // - it cannot be a pointer to a type derived from T, because it is | 417 // - it cannot be a pointer to a type derived from T, because it is |
374 // inherently unsafe in the general case to access an array through a | 418 // inherently unsafe in the general case to access an array through a |
375 // pointer whose dynamic type does not match its static type (eg., if | 419 // pointer whose dynamic type does not match its static type (eg., if |
376 // T and the derived types had different sizes access would be | 420 // T and the derived types had different sizes access would be |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 595 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
552 return scoped_ptr<T>(ptr); | 596 return scoped_ptr<T>(ptr); |
553 } | 597 } |
554 | 598 |
555 template <typename T> | 599 template <typename T> |
556 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { | 600 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { |
557 return out << p.get(); | 601 return out << p.get(); |
558 } | 602 } |
559 | 603 |
560 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 604 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
OLD | NEW |