9fb019edd1cd178bc8b064285e4ec9045e138444
[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
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     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
122 private:
123     PtrType m_ptr;
124 };
125
126 template<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
138 template<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
150 template<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
161 template<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
172 template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(WKRetainPtr<T>&& o)
173 {
174     adopt(o.leakRef());
175     return *this;
176 }
177
178 template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(WKRetainPtr<U>&& o)
179 {
180     adopt(o.leakRef());
181     return *this;
182 }
183
184 template<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
192 template<typename T> inline void WKRetainPtr<T>::swap(WKRetainPtr<T>& o)
193 {
194     std::swap(m_ptr, o.m_ptr);
195 }
196
197 template<typename T> inline void swap(WKRetainPtr<T>& a, WKRetainPtr<T>& b)
198 {
199     a.swap(b);
200 }
201
202 template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b)
203
204     return a.get() == b.get(); 
205 }
206
207 template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, U* b)
208
209     return a.get() == b; 
210 }
211
212 template<typename T, typename U> inline bool operator==(T* a, const WKRetainPtr<U>& b) 
213 {
214     return a == b.get(); 
215 }
216
217 template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b)
218
219     return a.get() != b.get(); 
220 }
221
222 template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, U* b)
223 {
224     return a.get() != b; 
225 }
226
227 template<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
238 template<typename T> inline WKRetainPtr<T> adoptWK(T) WK_WARN_UNUSED_RETURN;
239
240 #undef WK_WARN_UNUSED_RETURN
241
242 template<typename T> inline WKRetainPtr<T> adoptWK(T o) 
243 {
244     return WKRetainPtr<T>(AdoptWK, o);
245 }
246
247 } // namespace WebKit
248
249 using WebKit::WKRetainPtr;
250 using WebKit::AdoptWK;
251 using WebKit::adoptWK;
252
253 #endif // WKRetainPtr_h