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_SMART_POINTERS_H_ | |
6 #define V8_SMART_POINTERS_H_ | |
7 | |
8 namespace v8 { | |
9 namespace internal { | |
10 | |
11 | |
12 template<typename Deallocator, typename T> | |
13 class SmartPointerBase { | |
14 public: | |
15 // Default constructor. Constructs an empty scoped pointer. | |
16 SmartPointerBase() : p_(NULL) {} | |
17 | |
18 // Constructs a scoped pointer from a plain one. | |
19 explicit SmartPointerBase(T* ptr) : p_(ptr) {} | |
20 | |
21 // Copy constructor removes the pointer from the original to avoid double | |
22 // freeing. | |
23 SmartPointerBase(const SmartPointerBase<Deallocator, T>& rhs) | |
24 : 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) { | |
36 return p_[i]; | |
37 } | |
38 | |
39 // You can use [n] to index as if it was a plain pointer. | |
40 const T& operator[](size_t i) const { | |
41 return p_[i]; | |
42 } | |
43 | |
44 // 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 | |
46 // returning an SmartArrayPointer<T> and then get errors wherever it is used. | |
47 | |
48 | |
49 // 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 | |
51 // (NULL). | |
52 T* Detach() { | |
53 T* temp = p_; | |
54 p_ = NULL; | |
55 return temp; | |
56 } | |
57 | |
58 void Reset(T* new_value) { | |
59 DCHECK(p_ == NULL || p_ != new_value); | |
60 if (p_) Deallocator::Delete(p_); | |
61 p_ = new_value; | |
62 } | |
63 | |
64 // Assignment requires an empty (NULL) SmartArrayPointer as the receiver. Like | |
65 // the copy constructor it removes the pointer in the original to avoid | |
66 // double freeing. | |
67 SmartPointerBase<Deallocator, T>& operator=( | |
68 const SmartPointerBase<Deallocator, T>& rhs) { | |
69 DCHECK(is_empty()); | |
70 T* tmp = rhs.p_; // swap to handle self-assignment | |
71 const_cast<SmartPointerBase<Deallocator, T>&>(rhs).p_ = NULL; | |
72 p_ = tmp; | |
73 return *this; | |
74 } | |
75 | |
76 bool is_empty() const { return p_ == NULL; } | |
77 | |
78 protected: | |
79 // When the destructor of the scoped pointer is executed the plain pointer | |
80 // is deleted using DeleteArray. This implies that you must allocate with | |
81 // NewArray. | |
82 ~SmartPointerBase() { if (p_) Deallocator::Delete(p_); } | |
83 | |
84 private: | |
85 T* p_; | |
86 }; | |
87 | |
88 // A 'scoped array pointer' that calls DeleteArray on its pointer when the | |
89 // destructor is called. | |
90 | |
91 template<typename T> | |
92 struct ArrayDeallocator { | |
93 static void Delete(T* array) { | |
94 DeleteArray(array); | |
95 } | |
96 }; | |
97 | |
98 | |
99 template<typename T> | |
100 class SmartArrayPointer: public SmartPointerBase<ArrayDeallocator<T>, T> { | |
101 public: | |
102 SmartArrayPointer() { } | |
103 explicit SmartArrayPointer(T* ptr) | |
104 : SmartPointerBase<ArrayDeallocator<T>, T>(ptr) { } | |
105 SmartArrayPointer(const SmartArrayPointer<T>& rhs) | |
106 : SmartPointerBase<ArrayDeallocator<T>, T>(rhs) { } | |
107 }; | |
108 | |
109 | |
110 template<typename T> | |
111 struct ObjectDeallocator { | |
112 static void Delete(T* object) { | |
113 delete object; | |
114 } | |
115 }; | |
116 | |
117 | |
118 template<typename T> | |
119 class SmartPointer: public SmartPointerBase<ObjectDeallocator<T>, T> { | |
120 public: | |
121 SmartPointer() { } | |
122 explicit SmartPointer(T* ptr) | |
123 : SmartPointerBase<ObjectDeallocator<T>, T>(ptr) { } | |
124 SmartPointer(const SmartPointer<T>& rhs) | |
125 : SmartPointerBase<ObjectDeallocator<T>, T>(rhs) { } | |
126 }; | |
127 | |
128 } } // namespace v8::internal | |
129 | |
130 #endif // V8_SMART_POINTERS_H_ | |
OLD | NEW |