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 | #include <wtf/GetPtr.h> |
32 | #include <wtf/HashFunctions.h> |
33 | #include <wtf/HashTraits.h> |
34 | #include <wtf/RefPtr.h> |
35 | |
36 | namespace WebKit { |
37 | |
38 | template<typename T> class WKRetainPtr { |
39 | public: |
40 | typedef T PtrType; |
41 | |
42 | WKRetainPtr() |
43 | : m_ptr(0) |
44 | { |
45 | } |
46 | |
47 | WKRetainPtr(PtrType ptr) |
48 | : m_ptr(ptr) |
49 | { |
50 | if (ptr) |
51 | WKRetain(ptr); |
52 | } |
53 | |
54 | template<typename U> WKRetainPtr(const WKRetainPtr<U>& o) |
55 | : m_ptr(o.get()) |
56 | { |
57 | if (PtrType ptr = m_ptr) |
58 | WKRetain(ptr); |
59 | } |
60 | |
61 | WKRetainPtr(const WKRetainPtr& o) |
62 | : m_ptr(o.m_ptr) |
63 | { |
64 | if (PtrType ptr = m_ptr) |
65 | WKRetain(ptr); |
66 | } |
67 | |
68 | template<typename U> WKRetainPtr(WKRetainPtr<U>&& o) |
69 | : m_ptr(o.leakRef()) |
70 | { |
71 | } |
72 | |
73 | WKRetainPtr(WKRetainPtr&& o) |
74 | : m_ptr(o.leakRef()) |
75 | { |
76 | } |
77 | |
78 | ~WKRetainPtr() |
79 | { |
80 | if (PtrType ptr = m_ptr) |
81 | WKRelease(ptr); |
82 | } |
83 | |
84 | // Hash table deleted values, which are only constructed and never copied or destroyed. |
85 | WKRetainPtr(WTF::HashTableDeletedValueType) |
86 | : m_ptr(hashTableDeletedValue()) |
87 | { |
88 | } |
89 | |
90 | bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } |
91 | constexpr static T hashTableDeletedValue() { return reinterpret_cast<T>(-1); } |
92 | |
93 | PtrType get() const { return m_ptr; } |
94 | |
95 | void clear() |
96 | { |
97 | PtrType ptr = m_ptr; |
98 | m_ptr = 0; |
99 | if (ptr) |
100 | WKRelease(ptr); |
101 | } |
102 | |
103 | PtrType leakRef() |
104 | { |
105 | PtrType ptr = m_ptr; |
106 | m_ptr = 0; |
107 | return ptr; |
108 | } |
109 | |
110 | PtrType operator->() const { return m_ptr; } |
111 | bool operator!() const { return !m_ptr; } |
112 | |
113 | // This conversion operator allows implicit conversion to bool but not to other integer types. |
114 | typedef PtrType WKRetainPtr::*UnspecifiedBoolType; |
115 | operator UnspecifiedBoolType() const { return m_ptr ? &WKRetainPtr::m_ptr : 0; } |
116 | |
117 | WKRetainPtr& operator=(const WKRetainPtr&); |
118 | template<typename U> WKRetainPtr& operator=(const WKRetainPtr<U>&); |
119 | WKRetainPtr& operator=(PtrType); |
120 | template<typename U> WKRetainPtr& operator=(U*); |
121 | |
122 | WKRetainPtr& operator=(WKRetainPtr&&); |
123 | template<typename U> WKRetainPtr& operator=(WKRetainPtr<U>&&); |
124 | |
125 | void adopt(PtrType); |
126 | void swap(WKRetainPtr&); |
127 | |
128 | private: |
129 | template<typename U> friend WKRetainPtr<U> adoptWK(U); |
130 | enum WKAdoptTag { AdoptWK }; |
131 | WKRetainPtr(WKAdoptTag, PtrType ptr) |
132 | : m_ptr(ptr) { } |
133 | |
134 | PtrType m_ptr; |
135 | }; |
136 | |
137 | template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(const WKRetainPtr<T>& o) |
138 | { |
139 | PtrType optr = o.get(); |
140 | if (optr) |
141 | WKRetain(optr); |
142 | PtrType ptr = m_ptr; |
143 | m_ptr = optr; |
144 | if (ptr) |
145 | WKRelease(ptr); |
146 | return *this; |
147 | } |
148 | |
149 | template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(const WKRetainPtr<U>& o) |
150 | { |
151 | PtrType optr = o.get(); |
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 | |
161 | template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(PtrType 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 | |
172 | template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(U* optr) |
173 | { |
174 | if (optr) |
175 | WKRetain(optr); |
176 | PtrType ptr = m_ptr; |
177 | m_ptr = optr; |
178 | if (ptr) |
179 | WKRelease(ptr); |
180 | return *this; |
181 | } |
182 | |
183 | template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(WKRetainPtr<T>&& o) |
184 | { |
185 | adopt(o.leakRef()); |
186 | return *this; |
187 | } |
188 | |
189 | template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(WKRetainPtr<U>&& o) |
190 | { |
191 | adopt(o.leakRef()); |
192 | return *this; |
193 | } |
194 | |
195 | template<typename T> inline void WKRetainPtr<T>::adopt(PtrType optr) |
196 | { |
197 | PtrType ptr = m_ptr; |
198 | m_ptr = optr; |
199 | if (ptr) |
200 | WKRelease(ptr); |
201 | } |
202 | |
203 | template<typename T> inline void WKRetainPtr<T>::swap(WKRetainPtr<T>& o) |
204 | { |
205 | std::swap(m_ptr, o.m_ptr); |
206 | } |
207 | |
208 | template<typename T> inline void swap(WKRetainPtr<T>& a, WKRetainPtr<T>& b) |
209 | { |
210 | a.swap(b); |
211 | } |
212 | |
213 | template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b) |
214 | { |
215 | return a.get() == b.get(); |
216 | } |
217 | |
218 | template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, U* b) |
219 | { |
220 | return a.get() == b; |
221 | } |
222 | |
223 | template<typename T, typename U> inline bool operator==(T* a, const WKRetainPtr<U>& b) |
224 | { |
225 | return a == b.get(); |
226 | } |
227 | |
228 | template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b) |
229 | { |
230 | return a.get() != b.get(); |
231 | } |
232 | |
233 | template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, U* b) |
234 | { |
235 | return a.get() != b; |
236 | } |
237 | |
238 | template<typename T, typename U> inline bool operator!=(T* a, const WKRetainPtr<U>& b) |
239 | { |
240 | return a != b.get(); |
241 | } |
242 | |
243 | #if (defined(WIN32) || defined(_WIN32)) && !((_MSC_VER > 1900) && __clang__) |
244 | template<typename T> inline WKRetainPtr<T> adoptWK(T) _Check_return_; |
245 | #else |
246 | template<typename T> inline WKRetainPtr<T> adoptWK(T) __attribute__((warn_unused_result)); |
247 | #endif |
248 | template<typename T> inline WKRetainPtr<T> adoptWK(T o) |
249 | { |
250 | return WKRetainPtr<T>(WKRetainPtr<T>::AdoptWK, o); |
251 | } |
252 | |
253 | template<typename T> inline WKRetainPtr<T> retainWK(T ptr) |
254 | { |
255 | return ptr; |
256 | } |
257 | |
258 | } // namespace WebKit |
259 | |
260 | using WebKit::WKRetainPtr; |
261 | using WebKit::adoptWK; |
262 | using WebKit::retainWK; |
263 | |
264 | namespace WTF { |
265 | |
266 | template <typename T> struct IsSmartPtr<WKRetainPtr<T>> { |
267 | WTF_INTERNAL static const bool value = true; |
268 | }; |
269 | |
270 | template<typename P> struct DefaultHash<WKRetainPtr<P>> { |
271 | typedef PtrHash<WKRetainPtr<P>> Hash; |
272 | }; |
273 | |
274 | template<typename P> struct HashTraits<WKRetainPtr<P>> : SimpleClassHashTraits<WKRetainPtr<P>> { |
275 | static P emptyValue() { return nullptr; } |
276 | |
277 | typedef P PeekType; |
278 | static PeekType peek(const WKRetainPtr<P>& value) { return value.get(); } |
279 | static PeekType peek(P value) { return value; } |
280 | }; |
281 | |
282 | } // namespace WTF |
283 | |
284 | #endif // WKRetainPtr_h |
285 | |