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. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef WKRetainPtr_h 27#define WKRetainPtr_h 28 29#include <WebKit/WKType.h> 30#include <algorithm> 31 32namespace WebKit { 33 34enum WKAdoptTag { AdoptWK }; 35 36template<typename T> class WKRetainPtr { 37public: 38 typedef T PtrType; 39 40 WKRetainPtr() 41 : m_ptr(0) 42 { 43 } 44 45 WKRetainPtr(PtrType ptr) 46 : m_ptr(ptr) 47 { 48 if (ptr) 49 WKRetain(ptr); 50 } 51 52 WKRetainPtr(WKAdoptTag, PtrType ptr) 53 : m_ptr(ptr) 54 { 55 } 56 57 template<typename U> WKRetainPtr(const WKRetainPtr<U>& o) 58 : m_ptr(o.get()) 59 { 60 if (PtrType ptr = m_ptr) 61 WKRetain(ptr); 62 } 63 64 WKRetainPtr(const WKRetainPtr& o) 65 : m_ptr(o.m_ptr) 66 { 67 if (PtrType ptr = m_ptr) 68 WKRetain(ptr); 69 } 70 71 template<typename U> WKRetainPtr(WKRetainPtr<U>&& o) 72 : m_ptr(o.leakRef()) 73 { 74 } 75 76 WKRetainPtr(WKRetainPtr&& o) 77 : m_ptr(o.leakRef()) 78 { 79 } 80 81 ~WKRetainPtr() 82 { 83 if (PtrType ptr = m_ptr) 84 WKRelease(ptr); 85 } 86 87 PtrType get() const { return m_ptr; } 88 89 void clear() 90 { 91 PtrType ptr = m_ptr; 92 m_ptr = 0; 93 if (ptr) 94 WKRelease(ptr); 95 } 96 97 PtrType leakRef() 98 { 99 PtrType ptr = m_ptr; 100 m_ptr = 0; 101 return ptr; 102 } 103 104 PtrType operator->() const { return m_ptr; } 105 bool operator!() const { return !m_ptr; } 106 107 // This conversion operator allows implicit conversion to bool but not to other integer types. 108 typedef PtrType WKRetainPtr::*UnspecifiedBoolType; 109 operator UnspecifiedBoolType() const { return m_ptr ? &WKRetainPtr::m_ptr : 0; } 110 111 WKRetainPtr& operator=(const WKRetainPtr&); 112 template<typename U> WKRetainPtr& operator=(const WKRetainPtr<U>&); 113 WKRetainPtr& operator=(PtrType); 114 template<typename U> WKRetainPtr& operator=(U*); 115 116 WKRetainPtr& operator=(WKRetainPtr&&); 117 template<typename U> WKRetainPtr& operator=(WKRetainPtr<U>&&); 118 119 void adopt(PtrType); 120 void swap(WKRetainPtr&); 121 122private: 123 PtrType m_ptr; 124}; 125 126template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(const WKRetainPtr<T>& o) 127{ 128 PtrType optr = o.get(); 129 if (optr) 130 WKRetain(optr); 131 PtrType ptr = m_ptr; 132 m_ptr = optr; 133 if (ptr) 134 WKRelease(ptr); 135 return *this; 136} 137 138template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(const WKRetainPtr<U>& o) 139{ 140 PtrType optr = o.get(); 141 if (optr) 142 WKRetain(optr); 143 PtrType ptr = m_ptr; 144 m_ptr = optr; 145 if (ptr) 146 WKRelease(ptr); 147 return *this; 148} 149 150template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(PtrType optr) 151{ 152 if (optr) 153 WKRetain(optr); 154 PtrType ptr = m_ptr; 155 m_ptr = optr; 156 if (ptr) 157 WKRelease(ptr); 158 return *this; 159} 160 161template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(U* optr) 162{ 163 if (optr) 164 WKRetain(optr); 165 PtrType ptr = m_ptr; 166 m_ptr = optr; 167 if (ptr) 168 WKRelease(ptr); 169 return *this; 170} 171 172template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(WKRetainPtr<T>&& o) 173{ 174 adopt(o.leakRef()); 175 return *this; 176} 177 178template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(WKRetainPtr<U>&& o) 179{ 180 adopt(o.leakRef()); 181 return *this; 182} 183 184template<typename T> inline void WKRetainPtr<T>::adopt(PtrType optr) 185{ 186 PtrType ptr = m_ptr; 187 m_ptr = optr; 188 if (ptr) 189 WKRelease(ptr); 190} 191 192template<typename T> inline void WKRetainPtr<T>::swap(WKRetainPtr<T>& o) 193{ 194 std::swap(m_ptr, o.m_ptr); 195} 196 197template<typename T> inline void swap(WKRetainPtr<T>& a, WKRetainPtr<T>& b) 198{ 199 a.swap(b); 200} 201 202template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b) 203{ 204 return a.get() == b.get(); 205} 206 207template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, U* b) 208{ 209 return a.get() == b; 210} 211 212template<typename T, typename U> inline bool operator==(T* a, const WKRetainPtr<U>& b) 213{ 214 return a == b.get(); 215} 216 217template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b) 218{ 219 return a.get() != b.get(); 220} 221 222template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, U* b) 223{ 224 return a.get() != b; 225} 226 227template<typename T, typename U> inline bool operator!=(T* a, const WKRetainPtr<U>& b) 228{ 229 return a != b.get(); 230} 231 232#if defined(__GNUC__) && !(defined(__CC_ARM) || defined(__ARMCC__)) 233#define WK_WARN_UNUSED_RETURN __attribute__((warn_unused_result)) 234#else 235#define WK_WARN_UNUSED_RETURN 236#endif 237 238template<typename T> inline WKRetainPtr<T> adoptWK(T) WK_WARN_UNUSED_RETURN; 239 240#undef WK_WARN_UNUSED_RETURN 241 242template<typename T> inline WKRetainPtr<T> adoptWK(T o) 243{ 244 return WKRetainPtr<T>(AdoptWK, o); 245} 246 247} // namespace WebKit 248 249using WebKit::WKRetainPtr; 250using WebKit::AdoptWK; 251using WebKit::adoptWK; 252 253#endif // WKRetainPtr_h 254