| 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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 // builds. | 221 // builds. |
| 222 static_cast<D&>(data_)(data_.ptr); | 222 static_cast<D&>(data_)(data_.ptr); |
| 223 } | 223 } |
| 224 } | 224 } |
| 225 | 225 |
| 226 void reset(T* p) { | 226 void reset(T* p) { |
| 227 // This is a self-reset, which is no longer allowed for default deleters: | 227 // This is a self-reset, which is no longer allowed for default deleters: |
| 228 // https://crbug.com/162971 | 228 // https://crbug.com/162971 |
| 229 assert(!ShouldAbortOnSelfReset<D>::value || p == nullptr || p != data_.ptr); | 229 assert(!ShouldAbortOnSelfReset<D>::value || p == nullptr || p != data_.ptr); |
| 230 | 230 |
| 231 // Note that running data_.ptr = p can lead to undefined behavior if | 231 // Match C++11's definition of unique_ptr::reset(), which requires changing |
| 232 // get_deleter()(get()) deletes this. In order to prevent this, reset() | 232 // the pointer before invoking the deleter on the old pointer. This prevents |
| 233 // should update the stored pointer before deleting its old value. | 233 // |this| from being accessed after the deleter is run, which may destroy |
| 234 // | 234 // |this|. |
| 235 // However, changing reset() to use that behavior may cause current code to | |
| 236 // break in unexpected ways. If the destruction of the owned object | |
| 237 // dereferences the scoped_ptr when it is destroyed by a call to reset(), | |
| 238 // then it will incorrectly dispatch calls to |p| rather than the original | |
| 239 // value of |data_.ptr|. | |
| 240 // | |
| 241 // During the transition period, set the stored pointer to nullptr while | |
| 242 // deleting the object. Eventually, this safety check will be removed to | |
| 243 // prevent the scenario initially described from occuring and | |
| 244 // http://crbug.com/176091 can be closed. | |
| 245 T* old = data_.ptr; | 235 T* old = data_.ptr; |
| 246 data_.ptr = nullptr; | 236 data_.ptr = p; |
| 247 if (old != nullptr) | 237 if (old != nullptr) |
| 248 static_cast<D&>(data_)(old); | 238 static_cast<D&>(data_)(old); |
| 249 data_.ptr = p; | |
| 250 } | 239 } |
| 251 | 240 |
| 252 T* get() const { return data_.ptr; } | 241 T* get() const { return data_.ptr; } |
| 253 | 242 |
| 254 D& get_deleter() { return data_; } | 243 D& get_deleter() { return data_; } |
| 255 const D& get_deleter() const { return data_; } | 244 const D& get_deleter() const { return data_; } |
| 256 | 245 |
| 257 void swap(scoped_ptr_impl& p2) { | 246 void swap(scoped_ptr_impl& p2) { |
| 258 // Standard swap idiom: 'using std::swap' ensures that std::swap is | 247 // Standard swap idiom: 'using std::swap' ensures that std::swap is |
| 259 // present in the overload set, but we call swap unqualified so that | 248 // present in the overload set, but we call swap unqualified so that |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 572 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
| 584 return scoped_ptr<T>(ptr); | 573 return scoped_ptr<T>(ptr); |
| 585 } | 574 } |
| 586 | 575 |
| 587 template <typename T> | 576 template <typename T> |
| 588 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { | 577 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { |
| 589 return out << p.get(); | 578 return out << p.get(); |
| 590 } | 579 } |
| 591 | 580 |
| 592 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 581 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
| OLD | NEW |