00001 // Copyright 2008 the V8 project authors. All rights reserved. 00002 // Redistribution and use in source and binary forms, with or without 00003 // modification, are permitted provided that the following conditions are 00004 // met: 00005 // 00006 // * Redistributions of source code must retain the above copyright 00007 // notice, this list of conditions and the following disclaimer. 00008 // * Redistributions in binary form must reproduce the above 00009 // copyright notice, this list of conditions and the following 00010 // disclaimer in the documentation and/or other materials provided 00011 // with the distribution. 00012 // * Neither the name of Google Inc. nor the names of its 00013 // contributors may be used to endorse or promote products derived 00014 // from this software without specific prior written permission. 00015 // 00016 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00017 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00018 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00019 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00020 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00021 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00026 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 00028 #ifndef V8_SMART_POINTER_H_ 00029 #define V8_SMART_POINTER_H_ 00030 00031 namespace v8 { namespace internal { 00032 00033 00034 // A 'scoped array pointer' that calls DeleteArray on its pointer when the 00035 // destructor is called. 00036 template<typename T> 00037 class SmartPointer { 00038 public: 00039 00040 // Default constructor. Construct an empty scoped pointer. 00041 inline SmartPointer() : p(NULL) {} 00042 00043 00044 // Construct a scoped pointer from a plain one. 00045 explicit inline SmartPointer(T* pointer) : p(pointer) {} 00046 00047 00048 // Copy constructor removes the pointer from the original to avoid double 00049 // freeing. 00050 inline SmartPointer(const SmartPointer<T>& rhs) : p(rhs.p) { 00051 const_cast<SmartPointer<T>&>(rhs).p = NULL; 00052 } 00053 00054 00055 // When the destructor of the scoped pointer is executed the plain pointer 00056 // is deleted using DeleteArray. This implies that you must allocate with 00057 // NewArray. 00058 inline ~SmartPointer() { if (p) DeleteArray(p); } 00059 00060 00061 // You can get the underlying pointer out with the * operator. 00062 inline T* operator*() { return p; } 00063 00064 00065 // You can use [n] to index as if it was a plain pointer 00066 inline T& operator[](size_t i) { 00067 return p[i]; 00068 } 00069 00070 // We don't have implicit conversion to a T* since that hinders migration: 00071 // You would not be able to change a method from returning a T* to 00072 // returning an SmartPointer<T> and then get errors wherever it is used. 00073 00074 00075 // If you want to take out the plain pointer and don't want it automatically 00076 // deleted then call Detach(). Afterwards, the smart pointer is empty 00077 // (NULL). 00078 inline T* Detach() { 00079 T* temp = p; 00080 p = NULL; 00081 return temp; 00082 } 00083 00084 00085 // Assignment requires an empty (NULL) SmartPointer as the receiver. Like 00086 // the copy constructor it removes the pointer in the original to avoid 00087 // double freeing. 00088 inline SmartPointer& operator=(const SmartPointer<T>& rhs) { 00089 ASSERT(is_empty()); 00090 T* tmp = rhs.p; // swap to handle self-assignment 00091 const_cast<SmartPointer<T>&>(rhs).p = NULL; 00092 p = tmp; 00093 return *this; 00094 } 00095 00096 00097 inline bool is_empty() { 00098 return p == NULL; 00099 } 00100 00101 00102 private: 00103 T* p; 00104 }; 00105 00106 } } // namespace v8::internal 00107 00108 #endif // V8_SMART_POINTER_H_