| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 // implementation of the scoped_ptr class. | 91 // implementation of the scoped_ptr class. |
| 92 | 92 |
| 93 #include <assert.h> | 93 #include <assert.h> |
| 94 #include <stddef.h> | 94 #include <stddef.h> |
| 95 #include <stdlib.h> | 95 #include <stdlib.h> |
| 96 | 96 |
| 97 #include <algorithm> // For std::swap(). | 97 #include <algorithm> // For std::swap(). |
| 98 | 98 |
| 99 #include "base/basictypes.h" | 99 #include "base/basictypes.h" |
| 100 #include "base/compiler_specific.h" | 100 #include "base/compiler_specific.h" |
| 101 #include "base/debug/debugger.h" |
| 101 #include "base/move.h" | 102 #include "base/move.h" |
| 102 #include "base/template_util.h" | 103 #include "base/template_util.h" |
| 103 | 104 |
| 104 namespace base { | 105 namespace base { |
| 105 | 106 |
| 106 namespace subtle { | 107 namespace subtle { |
| 107 class RefCountedBase; | 108 class RefCountedBase; |
| 108 class RefCountedThreadSafeBase; | 109 class RefCountedThreadSafeBase; |
| 109 } // namespace subtle | 110 } // namespace subtle |
| 110 | 111 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 namespace internal { | 178 namespace internal { |
| 178 | 179 |
| 179 template <typename T> struct IsNotRefCounted { | 180 template <typename T> struct IsNotRefCounted { |
| 180 enum { | 181 enum { |
| 181 value = !base::is_convertible<T*, base::subtle::RefCountedBase*>::value && | 182 value = !base::is_convertible<T*, base::subtle::RefCountedBase*>::value && |
| 182 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: | 183 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: |
| 183 value | 184 value |
| 184 }; | 185 }; |
| 185 }; | 186 }; |
| 186 | 187 |
| 188 template <typename T> |
| 189 struct ShouldAbortOnSelfReset { |
| 190 template <typename U> |
| 191 static NoType Test(const typename U::AllowSelfReset*); |
| 192 |
| 193 template <typename U> |
| 194 static YesType Test(...); |
| 195 |
| 196 static const bool value = sizeof(Test<T>(0)) == sizeof(YesType); |
| 197 }; |
| 198 |
| 187 // Minimal implementation of the core logic of scoped_ptr, suitable for | 199 // Minimal implementation of the core logic of scoped_ptr, suitable for |
| 188 // reuse in both scoped_ptr and its specializations. | 200 // reuse in both scoped_ptr and its specializations. |
| 189 template <class T, class D> | 201 template <class T, class D> |
| 190 class scoped_ptr_impl { | 202 class scoped_ptr_impl { |
| 191 public: | 203 public: |
| 192 explicit scoped_ptr_impl(T* p) : data_(p) {} | 204 explicit scoped_ptr_impl(T* p) : data_(p) {} |
| 193 | 205 |
| 194 // Initializer for deleters that have data parameters. | 206 // Initializer for deleters that have data parameters. |
| 195 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} | 207 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} |
| 196 | 208 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 215 | 227 |
| 216 ~scoped_ptr_impl() { | 228 ~scoped_ptr_impl() { |
| 217 if (data_.ptr != nullptr) { | 229 if (data_.ptr != nullptr) { |
| 218 // Not using get_deleter() saves one function call in non-optimized | 230 // Not using get_deleter() saves one function call in non-optimized |
| 219 // builds. | 231 // builds. |
| 220 static_cast<D&>(data_)(data_.ptr); | 232 static_cast<D&>(data_)(data_.ptr); |
| 221 } | 233 } |
| 222 } | 234 } |
| 223 | 235 |
| 224 void reset(T* p) { | 236 void reset(T* p) { |
| 225 // This is a self-reset, which is no longer allowed: http://crbug.com/162971 | 237 // This is a self-reset, which is no longer allowed for default deleters: |
| 226 if (p != nullptr && p == data_.ptr) | 238 // https://crbug.com/162971 |
| 227 abort(); | 239 if (ShouldAbortOnSelfReset<D>::value && p != nullptr && p == data_.ptr) { |
| 240 // TODO(dcheng): This is essentially what CHECK() does under the covers. |
| 241 // However, that requires including base/logging.h. Since this file is |
| 242 // included in some Blink code, and the Chromium logging defines conflict |
| 243 // with Blink's, call base::debug::BreakDebugger() directly for now. |
| 244 base::debug::BreakDebugger(); |
| 245 } |
| 228 | 246 |
| 229 // Note that running data_.ptr = p can lead to undefined behavior if | 247 // Note that running data_.ptr = p can lead to undefined behavior if |
| 230 // get_deleter()(get()) deletes this. In order to prevent this, reset() | 248 // get_deleter()(get()) deletes this. In order to prevent this, reset() |
| 231 // should update the stored pointer before deleting its old value. | 249 // should update the stored pointer before deleting its old value. |
| 232 // | 250 // |
| 233 // However, changing reset() to use that behavior may cause current code to | 251 // However, changing reset() to use that behavior may cause current code to |
| 234 // break in unexpected ways. If the destruction of the owned object | 252 // break in unexpected ways. If the destruction of the owned object |
| 235 // dereferences the scoped_ptr when it is destroyed by a call to reset(), | 253 // dereferences the scoped_ptr when it is destroyed by a call to reset(), |
| 236 // then it will incorrectly dispatch calls to |p| rather than the original | 254 // then it will incorrectly dispatch calls to |p| rather than the original |
| 237 // value of |data_.ptr|. | 255 // value of |data_.ptr|. |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 | 607 |
| 590 // A function to convert T* into scoped_ptr<T> | 608 // A function to convert T* into scoped_ptr<T> |
| 591 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation | 609 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation |
| 592 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) | 610 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) |
| 593 template <typename T> | 611 template <typename T> |
| 594 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 612 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
| 595 return scoped_ptr<T>(ptr); | 613 return scoped_ptr<T>(ptr); |
| 596 } | 614 } |
| 597 | 615 |
| 598 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 616 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
| OLD | NEW |