| OLD | NEW |
| (Empty) |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef V8_BASE_SMART_POINTERS_H_ | |
| 6 #define V8_BASE_SMART_POINTERS_H_ | |
| 7 | |
| 8 #include "src/base/logging.h" | |
| 9 | |
| 10 namespace v8 { | |
| 11 namespace base { | |
| 12 | |
| 13 template <typename Deallocator, typename T> | |
| 14 class SmartPointerBase { | |
| 15 public: | |
| 16 // Default constructor. Constructs an empty scoped pointer. | |
| 17 SmartPointerBase() : p_(NULL) {} | |
| 18 | |
| 19 // Constructs a scoped pointer from a plain one. | |
| 20 explicit SmartPointerBase(T* ptr) : p_(ptr) {} | |
| 21 | |
| 22 // Copy constructor removes the pointer from the original to avoid double | |
| 23 // freeing. | |
| 24 SmartPointerBase(const SmartPointerBase<Deallocator, T>& rhs) : p_(rhs.p_) { | |
| 25 const_cast<SmartPointerBase<Deallocator, T>&>(rhs).p_ = NULL; | |
| 26 } | |
| 27 | |
| 28 T* operator->() const { return p_; } | |
| 29 | |
| 30 T& operator*() const { return *p_; } | |
| 31 | |
| 32 T* get() const { return p_; } | |
| 33 | |
| 34 // You can use [n] to index as if it was a plain pointer. | |
| 35 T& operator[](size_t i) { return p_[i]; } | |
| 36 | |
| 37 // You can use [n] to index as if it was a plain pointer. | |
| 38 const T& operator[](size_t i) const { return p_[i]; } | |
| 39 | |
| 40 // We don't have implicit conversion to a T* since that hinders migration: | |
| 41 // You would not be able to change a method from returning a T* to | |
| 42 // returning an SmartArrayPointer<T> and then get errors wherever it is used. | |
| 43 | |
| 44 | |
| 45 // If you want to take out the plain pointer and don't want it automatically | |
| 46 // deleted then call Detach(). Afterwards, the smart pointer is empty | |
| 47 // (NULL). | |
| 48 T* Detach() { | |
| 49 T* temp = p_; | |
| 50 p_ = NULL; | |
| 51 return temp; | |
| 52 } | |
| 53 | |
| 54 void Reset(T* new_value) { | |
| 55 DCHECK(p_ == NULL || p_ != new_value); | |
| 56 if (p_) Deallocator::Delete(p_); | |
| 57 p_ = new_value; | |
| 58 } | |
| 59 | |
| 60 // Assignment requires an empty (NULL) SmartArrayPointer as the receiver. Like | |
| 61 // the copy constructor it removes the pointer in the original to avoid | |
| 62 // double freeing. | |
| 63 SmartPointerBase<Deallocator, T>& operator=( | |
| 64 const SmartPointerBase<Deallocator, T>& rhs) { | |
| 65 DCHECK(is_empty()); | |
| 66 T* tmp = rhs.p_; // swap to handle self-assignment | |
| 67 const_cast<SmartPointerBase<Deallocator, T>&>(rhs).p_ = NULL; | |
| 68 p_ = tmp; | |
| 69 return *this; | |
| 70 } | |
| 71 | |
| 72 bool is_empty() const { return p_ == NULL; } | |
| 73 | |
| 74 protected: | |
| 75 // When the destructor of the scoped pointer is executed the plain pointer | |
| 76 // is deleted using DeleteArray. This implies that you must allocate with | |
| 77 // NewArray. | |
| 78 ~SmartPointerBase() { | |
| 79 if (p_) Deallocator::Delete(p_); | |
| 80 } | |
| 81 | |
| 82 private: | |
| 83 T* p_; | |
| 84 }; | |
| 85 | |
| 86 template <typename T> | |
| 87 struct ObjectDeallocator { | |
| 88 static void Delete(T* object) { delete object; } | |
| 89 }; | |
| 90 | |
| 91 template <typename T> | |
| 92 class SmartPointer : public SmartPointerBase<ObjectDeallocator<T>, T> { | |
| 93 public: | |
| 94 SmartPointer() {} | |
| 95 explicit SmartPointer(T* ptr) | |
| 96 : SmartPointerBase<ObjectDeallocator<T>, T>(ptr) {} | |
| 97 SmartPointer(const SmartPointer<T>& rhs) | |
| 98 : SmartPointerBase<ObjectDeallocator<T>, T>(rhs) {} | |
| 99 }; | |
| 100 | |
| 101 } // namespace base | |
| 102 } // namespace v8 | |
| 103 | |
| 104 #endif // V8_SMART_POINTERS_H_ | |
| OLD | NEW |