Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 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 | 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 #ifndef V8_SMART_POINTERS_H_ | 5 #ifndef V8_BASE_SMART_POINTERS_H_ |
| 6 #define V8_SMART_POINTERS_H_ | 6 #define V8_BASE_SMART_POINTERS_H_ |
| 7 | 7 |
| 8 namespace v8 { | 8 namespace v8 { |
| 9 namespace base { | |
| 9 namespace internal { | 10 namespace internal { |
| 10 | 11 |
| 11 | 12 |
| 12 template<typename Deallocator, typename T> | 13 template <typename Deallocator, typename T> |
| 13 class SmartPointerBase { | 14 class SmartPointerBase { |
| 14 public: | 15 public: |
| 15 // Default constructor. Constructs an empty scoped pointer. | 16 // Default constructor. Constructs an empty scoped pointer. |
| 16 SmartPointerBase() : p_(NULL) {} | 17 SmartPointerBase() : p_(NULL) {} |
| 17 | 18 |
| 18 // Constructs a scoped pointer from a plain one. | 19 // Constructs a scoped pointer from a plain one. |
| 19 explicit SmartPointerBase(T* ptr) : p_(ptr) {} | 20 explicit SmartPointerBase(T* ptr) : p_(ptr) {} |
| 20 | 21 |
| 21 // Copy constructor removes the pointer from the original to avoid double | 22 // Copy constructor removes the pointer from the original to avoid double |
| 22 // freeing. | 23 // freeing. |
| 23 SmartPointerBase(const SmartPointerBase<Deallocator, T>& rhs) | 24 SmartPointerBase(const SmartPointerBase<Deallocator, T>& rhs) : p_(rhs.p_) { |
| 24 : p_(rhs.p_) { | |
| 25 const_cast<SmartPointerBase<Deallocator, T>&>(rhs).p_ = NULL; | 25 const_cast<SmartPointerBase<Deallocator, T>&>(rhs).p_ = NULL; |
| 26 } | 26 } |
| 27 | 27 |
| 28 T* operator->() const { return p_; } | 28 T* operator->() const { return p_; } |
| 29 | 29 |
| 30 T& operator*() const { return *p_; } | 30 T& operator*() const { return *p_; } |
| 31 | 31 |
| 32 T* get() const { return p_; } | 32 T* get() const { return p_; } |
| 33 | 33 |
| 34 // You can use [n] to index as if it was a plain pointer. | 34 // You can use [n] to index as if it was a plain pointer. |
| 35 T& operator[](size_t i) { | 35 T& operator[](size_t i) { return p_[i]; } |
| 36 return p_[i]; | |
| 37 } | |
| 38 | 36 |
| 39 // You can use [n] to index as if it was a plain pointer. | 37 // You can use [n] to index as if it was a plain pointer. |
| 40 const T& operator[](size_t i) const { | 38 const T& operator[](size_t i) const { return p_[i]; } |
| 41 return p_[i]; | |
| 42 } | |
| 43 | 39 |
| 44 // We don't have implicit conversion to a T* since that hinders migration: | 40 // We don't have implicit conversion to a T* since that hinders migration: |
| 45 // You would not be able to change a method from returning a T* to | 41 // You would not be able to change a method from returning a T* to |
| 46 // returning an SmartArrayPointer<T> and then get errors wherever it is used. | 42 // returning an SmartArrayPointer<T> and then get errors wherever it is used. |
| 47 | 43 |
| 48 | 44 |
| 49 // If you want to take out the plain pointer and don't want it automatically | 45 // If you want to take out the plain pointer and don't want it automatically |
| 50 // deleted then call Detach(). Afterwards, the smart pointer is empty | 46 // deleted then call Detach(). Afterwards, the smart pointer is empty |
| 51 // (NULL). | 47 // (NULL). |
| 52 T* Detach() { | 48 T* Detach() { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 72 p_ = tmp; | 68 p_ = tmp; |
| 73 return *this; | 69 return *this; |
| 74 } | 70 } |
| 75 | 71 |
| 76 bool is_empty() const { return p_ == NULL; } | 72 bool is_empty() const { return p_ == NULL; } |
| 77 | 73 |
| 78 protected: | 74 protected: |
| 79 // When the destructor of the scoped pointer is executed the plain pointer | 75 // When the destructor of the scoped pointer is executed the plain pointer |
| 80 // is deleted using DeleteArray. This implies that you must allocate with | 76 // is deleted using DeleteArray. This implies that you must allocate with |
| 81 // NewArray. | 77 // NewArray. |
| 82 ~SmartPointerBase() { if (p_) Deallocator::Delete(p_); } | 78 ~SmartPointerBase() { |
| 79 if (p_) Deallocator::Delete(p_); | |
| 80 } | |
| 83 | 81 |
| 84 private: | 82 private: |
| 85 T* p_; | 83 T* p_; |
| 86 }; | 84 }; |
| 87 | 85 |
| 86 | |
| 87 } // namepsace internal | |
| 88 } // namespace base | |
| 89 | |
| 90 namespace internal { | |
|
rmcilroy
2015/07/08 14:30:58
I kept this in namespace v8::internal to avoid ugl
jochen (gone - plz use gerrit)
2015/07/10 08:35:38
hum, i'd rather have it in base. scoped_ptr isn't
| |
| 91 | |
| 88 // A 'scoped array pointer' that calls DeleteArray on its pointer when the | 92 // A 'scoped array pointer' that calls DeleteArray on its pointer when the |
| 89 // destructor is called. | 93 // destructor is called. |
| 90 | 94 |
| 91 template<typename T> | 95 template <typename T> |
| 92 struct ArrayDeallocator { | 96 struct ArrayDeallocator { |
| 93 static void Delete(T* array) { | 97 static void Delete(T* array) { DeleteArray(array); } |
| 94 DeleteArray(array); | |
| 95 } | |
| 96 }; | 98 }; |
| 97 | 99 |
| 98 | 100 |
| 99 template<typename T> | 101 template <typename T> |
| 100 class SmartArrayPointer: public SmartPointerBase<ArrayDeallocator<T>, T> { | 102 class SmartArrayPointer |
| 103 : public base::internal::SmartPointerBase<ArrayDeallocator<T>, T> { | |
| 101 public: | 104 public: |
| 102 SmartArrayPointer() { } | 105 SmartArrayPointer() {} |
| 103 explicit SmartArrayPointer(T* ptr) | 106 explicit SmartArrayPointer(T* ptr) |
| 104 : SmartPointerBase<ArrayDeallocator<T>, T>(ptr) { } | 107 : base::internal::SmartPointerBase<ArrayDeallocator<T>, T>(ptr) {} |
| 105 SmartArrayPointer(const SmartArrayPointer<T>& rhs) | 108 SmartArrayPointer(const SmartArrayPointer<T>& rhs) |
| 106 : SmartPointerBase<ArrayDeallocator<T>, T>(rhs) { } | 109 : base::internal::SmartPointerBase<ArrayDeallocator<T>, T>(rhs) {} |
| 107 }; | 110 }; |
| 108 | 111 |
| 109 | 112 |
| 110 template<typename T> | 113 template <typename T> |
| 111 struct ObjectDeallocator { | 114 struct ObjectDeallocator { |
| 112 static void Delete(T* object) { | 115 static void Delete(T* object) { delete object; } |
| 113 delete object; | |
| 114 } | |
| 115 }; | 116 }; |
| 116 | 117 |
| 117 | 118 template <typename T> |
| 118 template<typename T> | 119 class SmartPointer |
| 119 class SmartPointer: public SmartPointerBase<ObjectDeallocator<T>, T> { | 120 : public base::internal::SmartPointerBase<ObjectDeallocator<T>, T> { |
| 120 public: | 121 public: |
| 121 SmartPointer() { } | 122 SmartPointer() {} |
| 122 explicit SmartPointer(T* ptr) | 123 explicit SmartPointer(T* ptr) |
| 123 : SmartPointerBase<ObjectDeallocator<T>, T>(ptr) { } | 124 : base::internal::SmartPointerBase<ObjectDeallocator<T>, T>(ptr) {} |
| 124 SmartPointer(const SmartPointer<T>& rhs) | 125 SmartPointer(const SmartPointer<T>& rhs) |
| 125 : SmartPointerBase<ObjectDeallocator<T>, T>(rhs) { } | 126 : base::internal::SmartPointerBase<ObjectDeallocator<T>, T>(rhs) {} |
| 126 }; | 127 }; |
| 127 | 128 |
| 128 } } // namespace v8::internal | 129 } // namespace internal |
| 130 } // namespace v8 | |
| 129 | 131 |
| 130 #endif // V8_SMART_POINTERS_H_ | 132 #endif // V8_SMART_POINTERS_H_ |
| OLD | NEW |