1 /* 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2013 Intel Corporation. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22 #ifndef WTF_OwnPtr_h 23 #define WTF_OwnPtr_h 24 25 #include "wtf/Noncopyable.h" 26 #include "wtf/NullPtr.h" 27 #include "wtf/OwnPtrCommon.h" 28 #include <algorithm> 29 30 namespace WTF { 31 32 template<typename T> class PassOwnPtr; 33 34 template<typename T> class OwnPtr { 35 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 36 // If rvalue references are not supported, the copy constructor is 37 // public so OwnPtr cannot be marked noncopyable. See note below. 38 WTF_MAKE_NONCOPYABLE(OwnPtr); 39 #endif 40 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(OwnPtr); 41 public: 42 typedef typename RemoveExtent<T>::Type ValueType; 43 typedef ValueType* PtrType; 44 45 OwnPtr() : m_ptr(0) { } 46 OwnPtr(std::nullptr_t) : m_ptr(0) { } 47 48 // See comment in PassOwnPtr.h for why this takes a const reference. 49 OwnPtr(const PassOwnPtr<T>&); 50 template<typename U> OwnPtr(const PassOwnPtr<U>&, EnsurePtrConvertibleArgDecl(U, T)); 51 52 #if !COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 53 // This copy constructor is used implicitly by gcc when it generates 54 // transients for assigning a PassOwnPtr<T> object to a stack-allocated 55 // OwnPtr<T> object. It should never be called explicitly and gcc 56 // should optimize away the constructor when generating code. 57 OwnPtr(const OwnPtr&); 58 #endif 59 60 ~OwnPtr() 61 { 62 OwnedPtrDeleter<T>::deletePtr(m_ptr); 63 m_ptr = 0; 64 } 65 66 PtrType get() const { return m_ptr; } 67 68 void clear(); 69 PassOwnPtr<T> release(); 70 PtrType leakPtr() WARN_UNUSED_RETURN; 71 72 ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; } 73 PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } 74 75 ValueType& operator[](std::ptrdiff_t i) const; 76 77 bool operator!() const { return !m_ptr; } 78 79 // This conversion operator allows implicit conversion to bool but not to other integer types. 80 typedef PtrType OwnPtr::*UnspecifiedBoolType; 81 operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; } 82 83 OwnPtr& operator=(const PassOwnPtr<T>&); 84 OwnPtr& operator=(std::nullptr_t) { clear(); return *this; } 85 template<typename U> OwnPtr& operator=(const PassOwnPtr<U>&); 86 87 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 88 OwnPtr(OwnPtr&&); 89 template<typename U> OwnPtr(OwnPtr<U>&&); 90 91 OwnPtr& operator=(OwnPtr&&); 92 template<typename U> OwnPtr& operator=(OwnPtr<U>&&); 93 #endif 94 95 void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); } 96 97 private: 98 #if !COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 99 // If rvalue references are supported, noncopyable takes care of this. 100 OwnPtr& operator=(const OwnPtr&); 101 #endif 102 103 // We should never have two OwnPtrs for the same underlying object (otherwise we'll get 104 // double-destruction), so these equality operators should never be needed. 105 template<typename U> bool operator==(const OwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } 106 template<typename U> bool operator!=(const OwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } 107 template<typename U> bool operator==(const PassOwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } 108 template<typename U> bool operator!=(const PassOwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } 109 110 PtrType m_ptr; 111 }; 112 113 template<typename T> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<T>& o) 114 : m_ptr(o.leakPtr()) 115 { 116 } 117 118 template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<U>& o, EnsurePtrConvertibleArgDefn(U, T)) 119 : m_ptr(o.leakPtr()) 120 { 121 COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted); 122 } 123 124 template<typename T> inline void OwnPtr<T>::clear() 125 { 126 PtrType ptr = m_ptr; 127 m_ptr = 0; 128 OwnedPtrDeleter<T>::deletePtr(ptr); 129 } 130 131 template<typename T> inline PassOwnPtr<T> OwnPtr<T>::release() 132 { 133 PtrType ptr = m_ptr; 134 m_ptr = 0; 135 return PassOwnPtr<T>(ptr); 136 } 137 138 template<typename T> inline typename OwnPtr<T>::PtrType OwnPtr<T>::leakPtr() 139 { 140 PtrType ptr = m_ptr; 141 m_ptr = 0; 142 return ptr; 143 } 144 145 template<typename T> inline typename OwnPtr<T>::ValueType& OwnPtr<T>::operator[](std::ptrdiff_t i) const 146 { 147 COMPILE_ASSERT(IsArray<T>::value, Elements_access_is_possible_for_arrays_only); 148 ASSERT(m_ptr); 149 ASSERT(i >= 0); 150 return m_ptr[i]; 151 } 152 153 template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o) 154 { 155 PtrType ptr = m_ptr; 156 m_ptr = o.leakPtr(); 157 ASSERT(!ptr || m_ptr != ptr); 158 OwnedPtrDeleter<T>::deletePtr(ptr); 159 return *this; 160 } 161 162 template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<U>& o) 163 { 164 COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted); 165 PtrType ptr = m_ptr; 166 m_ptr = o.leakPtr(); 167 ASSERT(!ptr || m_ptr != ptr); 168 OwnedPtrDeleter<T>::deletePtr(ptr); 169 return *this; 170 } 171 172 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 173 template<typename T> inline OwnPtr<T>::OwnPtr(OwnPtr<T>&& o) 174 : m_ptr(o.leakPtr()) 175 { 176 } 177 178 template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(OwnPtr<U>&& o) 179 : m_ptr(o.leakPtr()) 180 { 181 COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted); 182 } 183 184 template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<T>&& o) 185 { 186 PtrType ptr = m_ptr; 187 m_ptr = o.leakPtr(); 188 ASSERT(!ptr || m_ptr != ptr); 189 OwnedPtrDeleter<T>::deletePtr(ptr); 190 191 return *this; 192 } 193 194 template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<U>&& o) 195 { 196 COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted); 197 PtrType ptr = m_ptr; 198 m_ptr = o.leakPtr(); 199 ASSERT(!ptr || m_ptr != ptr); 200 OwnedPtrDeleter<T>::deletePtr(ptr); 201 202 return *this; 203 } 204 #endif 205 206 template<typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b) 207 { 208 a.swap(b); 209 } 210 211 template<typename T, typename U> inline bool operator==(const OwnPtr<T>& a, U* b) 212 { 213 return a.get() == b; 214 } 215 216 template<typename T, typename U> inline bool operator==(T* a, const OwnPtr<U>& b) 217 { 218 return a == b.get(); 219 } 220 221 template<typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, U* b) 222 { 223 return a.get() != b; 224 } 225 226 template<typename T, typename U> inline bool operator!=(T* a, const OwnPtr<U>& b) 227 { 228 return a != b.get(); 229 } 230 231 template<typename T> inline typename OwnPtr<T>::PtrType getPtr(const OwnPtr<T>& p) 232 { 233 return p.get(); 234 } 235 236 } // namespace WTF 237 238 using WTF::OwnPtr; 239 240 #endif // WTF_OwnPtr_h 241