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 <WebKit2/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#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 72 template<typename U> WKRetainPtr(WKRetainPtr<U>&& o) 73 : m_ptr(o.leakRef()) 74 { 75 } 76 77 WKRetainPtr(WKRetainPtr&& o) 78 : m_ptr(o.leakRef()) 79 { 80 } 81#endif 82 83 ~WKRetainPtr() 84 { 85 if (PtrType ptr = m_ptr) 86 WKRelease(ptr); 87 } 88 89 PtrType get() const { return m_ptr; } 90 91 void clear() 92 { 93 PtrType ptr = m_ptr; 94 m_ptr = 0; 95 if (ptr) 96 WKRelease(ptr); 97 } 98 99 PtrType leakRef() 100 { 101 PtrType ptr = m_ptr; 102 m_ptr = 0; 103 return ptr; 104 } 105 106 PtrType operator->() const { return m_ptr; } 107 bool operator!() const { return !m_ptr; } 108 109 // This conversion operator allows implicit conversion to bool but not to other integer types. 110 typedef PtrType WKRetainPtr::*UnspecifiedBoolType; 111 operator UnspecifiedBoolType() const { return m_ptr ? &WKRetainPtr::m_ptr : 0; } 112 113 WKRetainPtr& operator=(const WKRetainPtr&); 114 template<typename U> WKRetainPtr& operator=(const WKRetainPtr<U>&); 115 WKRetainPtr& operator=(PtrType); 116 template<typename U> WKRetainPtr& operator=(U*); 117 118#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 119 WKRetainPtr& operator=(WKRetainPtr&&); 120 template<typename U> WKRetainPtr& operator=(WKRetainPtr<U>&&); 121#endif 122 123 void adopt(PtrType); 124 void swap(WKRetainPtr&); 125 126private: 127 PtrType m_ptr; 128}; 129 130template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(const WKRetainPtr<T>& o) 131{ 132 PtrType optr = o.get(); 133 if (optr) 134 WKRetain(optr); 135 PtrType ptr = m_ptr; 136 m_ptr = optr; 137 if (ptr) 138 WKRelease(ptr); 139 return *this; 140} 141 142template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(const WKRetainPtr<U>& o) 143{ 144 PtrType optr = o.get(); 145 if (optr) 146 WKRetain(optr); 147 PtrType ptr = m_ptr; 148 m_ptr = optr; 149 if (ptr) 150 WKRelease(ptr); 151 return *this; 152} 153 154template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(PtrType optr) 155{ 156 if (optr) 157 WKRetain(optr); 158 PtrType ptr = m_ptr; 159 m_ptr = optr; 160 if (ptr) 161 WKRelease(ptr); 162 return *this; 163} 164 165template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(U* optr) 166{ 167 if (optr) 168 WKRetain(optr); 169 PtrType ptr = m_ptr; 170 m_ptr = optr; 171 if (ptr) 172 WKRelease(ptr); 173 return *this; 174} 175 176#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 177template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(WKRetainPtr<T>&& o) 178{ 179 adopt(o.leakRef()); 180 return *this; 181} 182 183template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(WKRetainPtr<U>&& o) 184{ 185 adopt(o.leakRef()); 186 return *this; 187} 188#endif 189 190template<typename T> inline void WKRetainPtr<T>::adopt(PtrType optr) 191{ 192 PtrType ptr = m_ptr; 193 m_ptr = optr; 194 if (ptr) 195 WKRelease(ptr); 196} 197 198template<typename T> inline void WKRetainPtr<T>::swap(WKRetainPtr<T>& o) 199{ 200 std::swap(m_ptr, o.m_ptr); 201} 202 203template<typename T> inline void swap(WKRetainPtr<T>& a, WKRetainPtr<T>& b) 204{ 205 a.swap(b); 206} 207 208template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b) 209{ 210 return a.get() == b.get(); 211} 212 213template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, U* b) 214{ 215 return a.get() == b; 216} 217 218template<typename T, typename U> inline bool operator==(T* a, const WKRetainPtr<U>& b) 219{ 220 return a == b.get(); 221} 222 223template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b) 224{ 225 return a.get() != b.get(); 226} 227 228template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, U* b) 229{ 230 return a.get() != b; 231} 232 233template<typename T, typename U> inline bool operator!=(T* a, const WKRetainPtr<U>& b) 234{ 235 return a != b.get(); 236} 237 238template<typename T> inline WKRetainPtr<T> adoptWK(T) WARN_UNUSED_RETURN; 239 240template<typename T> inline WKRetainPtr<T> adoptWK(T o) 241{ 242 return WKRetainPtr<T>(AdoptWK, o); 243} 244 245} // namespace WebKit 246 247using WebKit::WKRetainPtr; 248using WebKit::AdoptWK; 249using WebKit::adoptWK; 250 251#endif // WKRetainPtr_h 252