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