1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef WTF_PassOwnArrayPtr_h 27 #define WTF_PassOwnArrayPtr_h 28 29 #include "Assertions.h" 30 #include "NullPtr.h" 31 #include "TypeTraits.h" 32 33 namespace WTF { 34 35 template<typename T> class OwnArrayPtr; 36 template<typename T> class PassOwnArrayPtr; 37 template<typename T> PassOwnArrayPtr<T> adoptArrayPtr(T*); 38 template<typename T> void deleteOwnedArrayPtr(T* ptr); 39 40 template<typename T> class PassOwnArrayPtr { 41 public: 42 typedef T* PtrType; 43 44 PassOwnArrayPtr() : m_ptr(0) { } 45 46 #if !defined(LOOSE_PASS_OWN_PTR) || !HAVE(NULLPTR) 47 PassOwnArrayPtr(std::nullptr_t) : m_ptr(0) { } 48 #endif 49 50 // It somewhat breaks the type system to allow transfer of ownership out of 51 // a const PassOwnArrayPtr. However, it makes it much easier to work with PassOwnArrayPtr 52 // temporaries, and we don't have a need to use real const PassOwnArrayPtrs anyway. 53 PassOwnArrayPtr(const PassOwnArrayPtr& o) : m_ptr(o.leakPtr()) { } 54 template<typename U> PassOwnArrayPtr(const PassOwnArrayPtr<U>& o) : m_ptr(o.leakPtr()) { } 55 56 ~PassOwnArrayPtr() { deleteOwnedArrayPtr(m_ptr); } 57 58 PtrType get() const { return m_ptr; } 59 60 void clear(); 61 PtrType leakPtr() const WARN_UNUSED_RETURN; 62 63 T& operator*() const { ASSERT(m_ptr); return *m_ptr; } 64 PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } 65 66 bool operator!() const { return !m_ptr; } 67 68 // This conversion operator allows implicit conversion to bool but not to other integer types. 69 #if COMPILER(WINSCW) 70 operator bool() const { return m_ptr; } 71 #else 72 typedef PtrType PassOwnArrayPtr::*UnspecifiedBoolType; 73 operator UnspecifiedBoolType() const { return m_ptr ? &PassOwnArrayPtr::m_ptr : 0; } 74 #endif 75 76 PassOwnArrayPtr& operator=(const PassOwnArrayPtr<T>&); 77 #if !defined(LOOSE_PASS_OWN_ARRAY_PTR) || !HAVE(NULLPTR) 78 PassOwnArrayPtr& operator=(std::nullptr_t) { clear(); return *this; } 79 #endif 80 template<typename U> PassOwnArrayPtr& operator=(const PassOwnArrayPtr<U>&); 81 82 template<typename U> friend PassOwnArrayPtr<U> adoptArrayPtr(U*); 83 84 #ifdef LOOSE_PASS_OWN_ARRAY_PTR 85 PassOwnArrayPtr(PtrType ptr) : m_ptr(ptr) { } 86 PassOwnArrayPtr& operator=(PtrType); 87 #endif 88 89 private: 90 #ifndef LOOSE_PASS_OWN_ARRAY_PTR 91 explicit PassOwnArrayPtr(PtrType ptr) : m_ptr(ptr) { } 92 #endif 93 94 mutable PtrType m_ptr; 95 }; 96 97 template<typename T> inline void PassOwnArrayPtr<T>::clear() 98 { 99 PtrType ptr = m_ptr; 100 m_ptr = 0; 101 deleteOwnedArrayPtr(ptr); 102 } 103 104 template<typename T> inline typename PassOwnArrayPtr<T>::PtrType PassOwnArrayPtr<T>::leakPtr() const 105 { 106 PtrType ptr = m_ptr; 107 m_ptr = 0; 108 return ptr; 109 } 110 111 #ifdef LOOSE_PASS_OWN_ARRAY_PTR 112 template<typename T> inline PassOwnArrayPtr<T>& PassOwnArrayPtr<T>::operator=(PtrType optr) 113 { 114 PtrType ptr = m_ptr; 115 m_ptr = optr; 116 ASSERT(!ptr || m_ptr != ptr); 117 if (ptr) 118 deleteOwnedArrayPtr(ptr); 119 return *this; 120 } 121 #endif 122 123 template<typename T> inline PassOwnArrayPtr<T>& PassOwnArrayPtr<T>::operator=(const PassOwnArrayPtr<T>& optr) 124 { 125 PtrType ptr = m_ptr; 126 m_ptr = optr.leakPtr(); 127 ASSERT(!ptr || m_ptr != ptr); 128 if (ptr) 129 deleteOwnedArrayPtr(ptr); 130 return *this; 131 } 132 133 template<typename T> template<typename U> inline PassOwnArrayPtr<T>& PassOwnArrayPtr<T>::operator=(const PassOwnArrayPtr<U>& optr) 134 { 135 PtrType ptr = m_ptr; 136 m_ptr = optr.leakPtr(); 137 ASSERT(!ptr || m_ptr != ptr); 138 if (ptr) 139 deleteOwnedArrayPtr(ptr); 140 return *this; 141 } 142 143 template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) 144 { 145 return a.get() == b.get(); 146 } 147 148 template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, const OwnArrayPtr<U>& b) 149 { 150 return a.get() == b.get(); 151 } 152 153 template<typename T, typename U> inline bool operator==(const OwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) 154 { 155 return a.get() == b.get(); 156 } 157 158 template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, U* b) 159 { 160 return a.get() == b; 161 } 162 163 template<typename T, typename U> inline bool operator==(T* a, const PassOwnArrayPtr<U>& b) 164 { 165 return a == b.get(); 166 } 167 168 template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) 169 { 170 return a.get() != b.get(); 171 } 172 173 template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, const OwnArrayPtr<U>& b) 174 { 175 return a.get() != b.get(); 176 } 177 178 template<typename T, typename U> inline bool operator!=(const OwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) 179 { 180 return a.get() != b.get(); 181 } 182 183 template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, U* b) 184 { 185 return a.get() != b; 186 } 187 188 template<typename T, typename U> inline bool operator!=(T* a, const PassOwnArrayPtr<U>& b) 189 { 190 return a != b.get(); 191 } 192 193 template<typename T> inline PassOwnArrayPtr<T> adoptArrayPtr(T* ptr) 194 { 195 return PassOwnArrayPtr<T>(ptr); 196 } 197 198 template<typename T> inline void deleteOwnedArrayPtr(T* ptr) 199 { 200 typedef char known[sizeof(T) ? 1 : -1]; 201 if (sizeof(known)) 202 delete [] ptr; 203 } 204 205 template<typename T, typename U> inline PassOwnArrayPtr<T> static_pointer_cast(const PassOwnArrayPtr<U>& p) 206 { 207 return adoptArrayPtr(static_cast<T*>(p.leakPtr())); 208 } 209 210 template<typename T, typename U> inline PassOwnArrayPtr<T> const_pointer_cast(const PassOwnArrayPtr<U>& p) 211 { 212 return adoptArrayPtr(const_cast<T*>(p.leakPtr())); 213 } 214 215 template<typename T> inline T* getPtr(const PassOwnArrayPtr<T>& p) 216 { 217 return p.get(); 218 } 219 220 } // namespace WTF 221 222 using WTF::PassOwnArrayPtr; 223 using WTF::adoptArrayPtr; 224 using WTF::const_pointer_cast; 225 using WTF::static_pointer_cast; 226 227 #endif // WTF_PassOwnArrayPtr_h 228