• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_SMART_POINTERS_H_
29 #define V8_SMART_POINTERS_H_
30 
31 namespace v8 {
32 namespace internal {
33 
34 
35 template<typename Deallocator, typename T>
36 class SmartPointerBase {
37  public:
38   // Default constructor. Constructs an empty scoped pointer.
SmartPointerBase()39   inline SmartPointerBase() : p_(NULL) {}
40 
41   // Constructs a scoped pointer from a plain one.
SmartPointerBase(T * ptr)42   explicit inline SmartPointerBase(T* ptr) : p_(ptr) {}
43 
44   // Copy constructor removes the pointer from the original to avoid double
45   // freeing.
SmartPointerBase(const SmartPointerBase<Deallocator,T> & rhs)46   inline SmartPointerBase(const SmartPointerBase<Deallocator, T>& rhs)
47       : p_(rhs.p_) {
48     const_cast<SmartPointerBase<Deallocator, T>&>(rhs).p_ = NULL;
49   }
50 
51   // When the destructor of the scoped pointer is executed the plain pointer
52   // is deleted using DeleteArray.  This implies that you must allocate with
53   // NewArray.
~SmartPointerBase()54   inline ~SmartPointerBase() { if (p_) Deallocator::Delete(p_); }
55 
56   inline T* operator->() const { return p_; }
57 
58   // You can get the underlying pointer out with the * operator.
59   inline T* operator*() { return p_; }
60 
61   // You can use [n] to index as if it was a plain pointer.
62   inline T& operator[](size_t i) {
63     return p_[i];
64   }
65 
66   // You can use [n] to index as if it was a plain pointer.
67   const inline T& operator[](size_t i) const {
68     return p_[i];
69   }
70 
71   // We don't have implicit conversion to a T* since that hinders migration:
72   // You would not be able to change a method from returning a T* to
73   // returning an SmartArrayPointer<T> and then get errors wherever it is used.
74 
75 
76   // If you want to take out the plain pointer and don't want it automatically
77   // deleted then call Detach().  Afterwards, the smart pointer is empty
78   // (NULL).
Detach()79   inline T* Detach() {
80     T* temp = p_;
81     p_ = NULL;
82     return temp;
83   }
84 
Reset(T * new_value)85   inline void Reset(T* new_value) {
86     if (p_) Deallocator::Delete(p_);
87     p_ = new_value;
88   }
89 
90   // Assignment requires an empty (NULL) SmartArrayPointer as the receiver. Like
91   // the copy constructor it removes the pointer in the original to avoid
92   // double freeing.
93   inline SmartPointerBase<Deallocator, T>& operator=(
94       const SmartPointerBase<Deallocator, T>& rhs) {
95     ASSERT(is_empty());
96     T* tmp = rhs.p_;  // swap to handle self-assignment
97     const_cast<SmartPointerBase<Deallocator, T>&>(rhs).p_ = NULL;
98     p_ = tmp;
99     return *this;
100   }
101 
is_empty()102   inline bool is_empty() { return p_ == NULL; }
103 
104  private:
105   T* p_;
106 };
107 
108 // A 'scoped array pointer' that calls DeleteArray on its pointer when the
109 // destructor is called.
110 
111 template<typename T>
112 struct ArrayDeallocator {
DeleteArrayDeallocator113   static void Delete(T* array) {
114     DeleteArray(array);
115   }
116 };
117 
118 
119 template<typename T>
120 class SmartArrayPointer: public SmartPointerBase<ArrayDeallocator<T>, T> {
121  public:
SmartArrayPointer()122   inline SmartArrayPointer() { }
SmartArrayPointer(T * ptr)123   explicit inline SmartArrayPointer(T* ptr)
124       : SmartPointerBase<ArrayDeallocator<T>, T>(ptr) { }
SmartArrayPointer(const SmartArrayPointer<T> & rhs)125   inline SmartArrayPointer(const SmartArrayPointer<T>& rhs)
126       : SmartPointerBase<ArrayDeallocator<T>, T>(rhs) { }
127 };
128 
129 
130 template<typename T>
131 struct ObjectDeallocator {
DeleteObjectDeallocator132   static void Delete(T* object) {
133     delete object;
134   }
135 };
136 
137 
138 template<typename T>
139 class SmartPointer: public SmartPointerBase<ObjectDeallocator<T>, T> {
140  public:
SmartPointer()141   inline SmartPointer() { }
SmartPointer(T * ptr)142   explicit inline SmartPointer(T* ptr)
143       : SmartPointerBase<ObjectDeallocator<T>, T>(ptr) { }
SmartPointer(const SmartPointer<T> & rhs)144   inline SmartPointer(const SmartPointer<T>& rhs)
145       : SmartPointerBase<ObjectDeallocator<T>, T>(rhs) { }
146 };
147 
148 } }  // namespace v8::internal
149 
150 #endif  // V8_SMART_POINTERS_H_
151