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 |