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 33namespace WTF { 34 35template<typename T> class OwnArrayPtr; 36template<typename T> class PassOwnArrayPtr; 37template<typename T> PassOwnArrayPtr<T> adoptArrayPtr(T*); 38template<typename T> void deleteOwnedArrayPtr(T* ptr); 39 40template<typename T> class PassOwnArrayPtr { 41public: 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 89private: 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 97template<typename T> inline void PassOwnArrayPtr<T>::clear() 98{ 99 PtrType ptr = m_ptr; 100 m_ptr = 0; 101 deleteOwnedArrayPtr(ptr); 102} 103 104template<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 112template<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 123template<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 133template<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 143template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) 144{ 145 return a.get() == b.get(); 146} 147 148template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, const OwnArrayPtr<U>& b) 149{ 150 return a.get() == b.get(); 151} 152 153template<typename T, typename U> inline bool operator==(const OwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) 154{ 155 return a.get() == b.get(); 156} 157 158template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, U* b) 159{ 160 return a.get() == b; 161} 162 163template<typename T, typename U> inline bool operator==(T* a, const PassOwnArrayPtr<U>& b) 164{ 165 return a == b.get(); 166} 167 168template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) 169{ 170 return a.get() != b.get(); 171} 172 173template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, const OwnArrayPtr<U>& b) 174{ 175 return a.get() != b.get(); 176} 177 178template<typename T, typename U> inline bool operator!=(const OwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) 179{ 180 return a.get() != b.get(); 181} 182 183template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, U* b) 184{ 185 return a.get() != b; 186} 187 188template<typename T, typename U> inline bool operator!=(T* a, const PassOwnArrayPtr<U>& b) 189{ 190 return a != b.get(); 191} 192 193template<typename T> inline PassOwnArrayPtr<T> adoptArrayPtr(T* ptr) 194{ 195 return PassOwnArrayPtr<T>(ptr); 196} 197 198template<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 205template<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 210template<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 215template<typename T> inline T* getPtr(const PassOwnArrayPtr<T>& p) 216{ 217 return p.get(); 218} 219 220} // namespace WTF 221 222using WTF::PassOwnArrayPtr; 223using WTF::adoptArrayPtr; 224using WTF::const_pointer_cast; 225using WTF::static_pointer_cast; 226 227#endif // WTF_PassOwnArrayPtr_h 228