| 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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 509 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
| 579 return scoped_ptr<T>(ptr); | 510 return scoped_ptr<T>(ptr); |
| 580 } | 511 } |
| 581 | 512 |
| 582 template <typename T> | 513 template <typename T> |
| 583 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { | 514 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { |
| 584 return out << p.get(); | 515 return out << p.get(); |
| 585 } | 516 } |
| 586 | 517 |
| 587 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 518 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
| OLD | NEW |