1 /* 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 * 19 */ 20 21 #ifndef WTF_OwnPtr_h 22 #define WTF_OwnPtr_h 23 24 #include "Assertions.h" 25 #include "NullPtr.h" 26 #include "OwnPtrCommon.h" 27 #include "TypeTraits.h" 28 #include <algorithm> 29 #include <memory> 30 31 // Remove this once we make all WebKit code compatible with stricter rules about OwnPtr. 32 #define LOOSE_OWN_PTR 33 34 namespace WTF { 35 36 // Unlike most of our smart pointers, OwnPtr can take either the pointer type or the pointed-to type. 37 38 template<typename T> class PassOwnPtr; 39 template<typename T> PassOwnPtr<T> adoptPtr(T*); 40 41 template<typename T> class OwnPtr { 42 public: 43 typedef typename RemovePointer<T>::Type ValueType; 44 typedef ValueType* PtrType; 45 OwnPtr()46 OwnPtr() : m_ptr(0) { } 47 48 // See comment in PassOwnPtr.h for why this takes a const reference. 49 template<typename U> OwnPtr(const PassOwnPtr<U>& o); 50 51 // This copy constructor is used implicitly by gcc when it generates 52 // transients for assigning a PassOwnPtr<T> object to a stack-allocated 53 // OwnPtr<T> object. It should never be called explicitly and gcc 54 // should optimize away the constructor when generating code. 55 OwnPtr(const OwnPtr<ValueType>&); 56 ~OwnPtr()57 ~OwnPtr() { deleteOwnedPtr(m_ptr); } 58 get()59 PtrType get() const { return m_ptr; } 60 61 void clear(); 62 PassOwnPtr<T> release(); 63 PtrType leakPtr() WARN_UNUSED_RETURN; 64 65 ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; } 66 PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } 67 68 bool operator!() const { return !m_ptr; } 69 70 // This conversion operator allows implicit conversion to bool but not to other integer types. 71 typedef PtrType OwnPtr::*UnspecifiedBoolType; UnspecifiedBoolType()72 operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; } 73 74 OwnPtr& operator=(const PassOwnPtr<T>&); 75 OwnPtr& operator=(std::nullptr_t) { clear(); return *this; } 76 template<typename U> OwnPtr& operator=(const PassOwnPtr<U>&); 77 swap(OwnPtr & o)78 void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); } 79 80 #ifdef LOOSE_OWN_PTR OwnPtr(PtrType ptr)81 explicit OwnPtr(PtrType ptr) : m_ptr(ptr) { } 82 void set(PtrType); 83 #endif 84 85 private: 86 PtrType m_ptr; 87 }; 88 OwnPtr(const PassOwnPtr<U> & o)89 template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<U>& o) 90 : m_ptr(o.leakPtr()) 91 { 92 } 93 clear()94 template<typename T> inline void OwnPtr<T>::clear() 95 { 96 PtrType ptr = m_ptr; 97 m_ptr = 0; 98 deleteOwnedPtr(ptr); 99 } 100 release()101 template<typename T> inline PassOwnPtr<T> OwnPtr<T>::release() 102 { 103 PtrType ptr = m_ptr; 104 m_ptr = 0; 105 return adoptPtr(ptr); 106 } 107 leakPtr()108 template<typename T> inline typename OwnPtr<T>::PtrType OwnPtr<T>::leakPtr() 109 { 110 PtrType ptr = m_ptr; 111 m_ptr = 0; 112 return ptr; 113 } 114 115 #ifdef LOOSE_OWN_PTR set(PtrType ptr)116 template<typename T> inline void OwnPtr<T>::set(PtrType ptr) 117 { 118 ASSERT(!ptr || m_ptr != ptr); 119 PtrType oldPtr = m_ptr; 120 m_ptr = ptr; 121 deleteOwnedPtr(oldPtr); 122 } 123 #endif 124 125 template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o) 126 { 127 PtrType ptr = m_ptr; 128 m_ptr = o.leakPtr(); 129 ASSERT(!ptr || m_ptr != ptr); 130 deleteOwnedPtr(ptr); 131 return *this; 132 } 133 134 template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<U>& o) 135 { 136 PtrType ptr = m_ptr; 137 m_ptr = o.leakPtr(); 138 ASSERT(!ptr || m_ptr != ptr); 139 deleteOwnedPtr(ptr); 140 return *this; 141 } 142 swap(OwnPtr<T> & a,OwnPtr<T> & b)143 template<typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b) 144 { 145 a.swap(b); 146 } 147 148 template<typename T, typename U> inline bool operator==(const OwnPtr<T>& a, U* b) 149 { 150 return a.get() == b; 151 } 152 153 template<typename T, typename U> inline bool operator==(T* a, const OwnPtr<U>& b) 154 { 155 return a == b.get(); 156 } 157 158 template<typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, U* b) 159 { 160 return a.get() != b; 161 } 162 163 template<typename T, typename U> inline bool operator!=(T* a, const OwnPtr<U>& b) 164 { 165 return a != b.get(); 166 } 167 getPtr(const OwnPtr<T> & p)168 template<typename T> inline typename OwnPtr<T>::PtrType getPtr(const OwnPtr<T>& p) 169 { 170 return p.get(); 171 } 172 173 } // namespace WTF 174 175 using WTF::OwnPtr; 176 177 #endif // WTF_OwnPtr_h 178