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. 39 inline SmartPointerBase() : p_(NULL) {} 40 41 // Constructs a scoped pointer from a plain one. 42 explicit inline SmartPointerBase(T* ptr) : p_(ptr) {} 43 44 // Copy constructor removes the pointer from the original to avoid double 45 // freeing. 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. 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). 79 inline T* Detach() { 80 T* temp = p_; 81 p_ = NULL; 82 return temp; 83 } 84 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 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 { 113 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: 122 inline SmartArrayPointer() { } 123 explicit inline SmartArrayPointer(T* ptr) 124 : SmartPointerBase<ArrayDeallocator<T>, T>(ptr) { } 125 inline SmartArrayPointer(const SmartArrayPointer<T>& rhs) 126 : SmartPointerBase<ArrayDeallocator<T>, T>(rhs) { } 127 }; 128 129 130 template<typename T> 131 struct ObjectDeallocator { 132 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: 141 inline SmartPointer() { } 142 explicit inline SmartPointer(T* ptr) 143 : SmartPointerBase<ObjectDeallocator<T>, T>(ptr) { } 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