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