OLD | NEW |
1 /* | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 * Copyright (C) 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
3 * | 3 // found in the LICENSE file. |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public License | |
15 * along with this library; see the file COPYING.LIB. If not, write to | |
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
17 * Boston, MA 02110-1301, USA. | |
18 * | |
19 */ | |
20 | 4 |
21 #ifndef RetainPtr_h | 5 #include "platform/wtf/RetainPtr.h" |
22 #define RetainPtr_h | |
23 | 6 |
24 #include "wtf/Compiler.h" | 7 // The contents of this header was moved to platform/wtf as part of |
25 #include "wtf/HashTableDeletedValueType.h" | 8 // WTF migration project. See the following post for details: |
26 #include "wtf/HashTraits.h" | 9 // https://groups.google.com/a/chromium.org/d/msg/blink-dev/tLdAZCTlcAA/bYXVT8gY
CAAJ |
27 #include "wtf/TypeTraits.h" | |
28 #include <algorithm> | |
29 #include <type_traits> | |
30 #include <utility> | |
31 | |
32 #if USE(CF) | |
33 #include <CoreFoundation/CoreFoundation.h> | |
34 #endif | |
35 | |
36 #ifdef __OBJC__ | |
37 #import <Foundation/Foundation.h> | |
38 #endif | |
39 | |
40 #ifndef CF_RELEASES_ARGUMENT | |
41 #define CF_RELEASES_ARGUMENT | |
42 #endif | |
43 | |
44 #ifndef NS_RELEASES_ARGUMENT | |
45 #define NS_RELEASES_ARGUMENT | |
46 #endif | |
47 | |
48 namespace WTF { | |
49 | |
50 // Unlike most most of our smart pointers, RetainPtr can take either the pointer | |
51 // type or the pointed-to type, so both RetainPtr<NSDictionary> and | |
52 // RetainPtr<CFDictionaryRef> will work. | |
53 | |
54 enum AdoptCFTag { AdoptCF }; | |
55 enum AdoptNSTag { AdoptNS }; | |
56 | |
57 #ifdef __OBJC__ | |
58 inline void adoptNSReference(id ptr) { | |
59 if (ptr) { | |
60 CFRetain(ptr); | |
61 [ptr release]; | |
62 } | |
63 } | |
64 #endif | |
65 | |
66 template <typename T> | |
67 class RetainPtr { | |
68 public: | |
69 typedef typename std::remove_pointer<T>::type ValueType; | |
70 typedef ValueType* PtrType; | |
71 | |
72 RetainPtr() : m_ptr(nullptr) {} | |
73 RetainPtr(PtrType ptr) : m_ptr(ptr) { | |
74 if (ptr) | |
75 CFRetain(ptr); | |
76 } | |
77 | |
78 RetainPtr(AdoptCFTag, PtrType ptr) : m_ptr(ptr) {} | |
79 RetainPtr(AdoptNSTag, PtrType ptr) : m_ptr(ptr) { adoptNSReference(ptr); } | |
80 | |
81 RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { | |
82 if (PtrType ptr = m_ptr) | |
83 CFRetain(ptr); | |
84 } | |
85 | |
86 RetainPtr(RetainPtr&& o) : m_ptr(o.leakRef()) {} | |
87 | |
88 // Hash table deleted values, which are only constructed and never copied or | |
89 // destroyed. | |
90 RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) {} | |
91 bool isHashTableDeletedValue() const { | |
92 return m_ptr == hashTableDeletedValue(); | |
93 } | |
94 | |
95 ~RetainPtr() { | |
96 if (PtrType ptr = m_ptr) | |
97 CFRelease(ptr); | |
98 } | |
99 | |
100 template <typename U> | |
101 RetainPtr(const RetainPtr<U>&); | |
102 | |
103 void clear(); | |
104 WARN_UNUSED_RESULT PtrType leakRef(); | |
105 | |
106 PtrType get() const { return m_ptr; } | |
107 PtrType operator->() const { return m_ptr; } | |
108 | |
109 bool operator!() const { return !m_ptr; } | |
110 explicit operator bool() const { return m_ptr; } | |
111 | |
112 RetainPtr& operator=(const RetainPtr&); | |
113 template <typename U> | |
114 RetainPtr& operator=(const RetainPtr<U>&); | |
115 RetainPtr& operator=(PtrType); | |
116 template <typename U> | |
117 RetainPtr& operator=(U*); | |
118 | |
119 RetainPtr& operator=(RetainPtr&&); | |
120 template <typename U> | |
121 RetainPtr& operator=(RetainPtr<U>&&); | |
122 | |
123 RetainPtr& operator=(std::nullptr_t) { | |
124 clear(); | |
125 return *this; | |
126 } | |
127 | |
128 void adoptCF(PtrType); | |
129 void adoptNS(PtrType); | |
130 | |
131 void swap(RetainPtr&); | |
132 | |
133 private: | |
134 static PtrType hashTableDeletedValue() { | |
135 return reinterpret_cast<PtrType>(-1); | |
136 } | |
137 | |
138 PtrType m_ptr; | |
139 }; | |
140 | |
141 template <typename T> | |
142 template <typename U> | |
143 inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o) : m_ptr(o.get()) { | |
144 if (PtrType ptr = m_ptr) | |
145 CFRetain(ptr); | |
146 } | |
147 | |
148 template <typename T> | |
149 inline void RetainPtr<T>::clear() { | |
150 if (PtrType ptr = m_ptr) { | |
151 m_ptr = nullptr; | |
152 CFRelease(ptr); | |
153 } | |
154 } | |
155 | |
156 template <typename T> | |
157 inline typename RetainPtr<T>::PtrType RetainPtr<T>::leakRef() { | |
158 PtrType ptr = m_ptr; | |
159 m_ptr = nullptr; | |
160 return ptr; | |
161 } | |
162 | |
163 template <typename T> | |
164 inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<T>& o) { | |
165 PtrType optr = o.get(); | |
166 if (optr) | |
167 CFRetain(optr); | |
168 PtrType ptr = m_ptr; | |
169 m_ptr = optr; | |
170 if (ptr) | |
171 CFRelease(ptr); | |
172 return *this; | |
173 } | |
174 | |
175 template <typename T> | |
176 template <typename U> | |
177 inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<U>& o) { | |
178 PtrType optr = o.get(); | |
179 if (optr) | |
180 CFRetain(optr); | |
181 PtrType ptr = m_ptr; | |
182 m_ptr = optr; | |
183 if (ptr) | |
184 CFRelease(ptr); | |
185 return *this; | |
186 } | |
187 | |
188 template <typename T> | |
189 inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr) { | |
190 if (optr) | |
191 CFRetain(optr); | |
192 PtrType ptr = m_ptr; | |
193 m_ptr = optr; | |
194 if (ptr) | |
195 CFRelease(ptr); | |
196 return *this; | |
197 } | |
198 | |
199 template <typename T> | |
200 template <typename U> | |
201 inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr) { | |
202 if (optr) | |
203 CFRetain(optr); | |
204 PtrType ptr = m_ptr; | |
205 m_ptr = optr; | |
206 if (ptr) | |
207 CFRelease(ptr); | |
208 return *this; | |
209 } | |
210 | |
211 template <typename T> | |
212 inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<T>&& o) { | |
213 adoptCF(o.leakRef()); | |
214 return *this; | |
215 } | |
216 | |
217 template <typename T> | |
218 template <typename U> | |
219 inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<U>&& o) { | |
220 adoptCF(o.leakRef()); | |
221 return *this; | |
222 } | |
223 | |
224 template <typename T> | |
225 inline void RetainPtr<T>::adoptCF(PtrType optr) { | |
226 PtrType ptr = m_ptr; | |
227 m_ptr = optr; | |
228 if (ptr) | |
229 CFRelease(ptr); | |
230 } | |
231 | |
232 template <typename T> | |
233 inline void RetainPtr<T>::adoptNS(PtrType optr) { | |
234 adoptNSReference(optr); | |
235 | |
236 PtrType ptr = m_ptr; | |
237 m_ptr = optr; | |
238 if (ptr) | |
239 CFRelease(ptr); | |
240 } | |
241 | |
242 template <typename T> | |
243 inline void RetainPtr<T>::swap(RetainPtr<T>& o) { | |
244 std::swap(m_ptr, o.m_ptr); | |
245 } | |
246 | |
247 template <typename T> | |
248 inline void swap(RetainPtr<T>& a, RetainPtr<T>& b) { | |
249 a.swap(b); | |
250 } | |
251 | |
252 template <typename T, typename U> | |
253 inline bool operator==(const RetainPtr<T>& a, const RetainPtr<U>& b) { | |
254 return a.get() == b.get(); | |
255 } | |
256 | |
257 template <typename T, typename U> | |
258 inline bool operator==(const RetainPtr<T>& a, U* b) { | |
259 return a.get() == b; | |
260 } | |
261 | |
262 template <typename T, typename U> | |
263 inline bool operator==(T* a, const RetainPtr<U>& b) { | |
264 return a == b.get(); | |
265 } | |
266 | |
267 template <typename T, typename U> | |
268 inline bool operator!=(const RetainPtr<T>& a, const RetainPtr<U>& b) { | |
269 return a.get() != b.get(); | |
270 } | |
271 | |
272 template <typename T, typename U> | |
273 inline bool operator!=(const RetainPtr<T>& a, U* b) { | |
274 return a.get() != b; | |
275 } | |
276 | |
277 template <typename T, typename U> | |
278 inline bool operator!=(T* a, const RetainPtr<U>& b) { | |
279 return a != b.get(); | |
280 } | |
281 | |
282 template <typename T> | |
283 WARN_UNUSED_RESULT inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT); | |
284 template <typename T> | |
285 inline RetainPtr<T> adoptCF(T o) { | |
286 return RetainPtr<T>(AdoptCF, o); | |
287 } | |
288 | |
289 template <typename T> | |
290 WARN_UNUSED_RESULT inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT); | |
291 template <typename T> | |
292 inline RetainPtr<T> adoptNS(T o) { | |
293 return RetainPtr<T>(AdoptNS, o); | |
294 } | |
295 | |
296 // Helper function for creating a RetainPtr using template argument deduction. | |
297 template <typename T> | |
298 WARN_UNUSED_RESULT inline RetainPtr<T> retainPtr(T); | |
299 template <typename T> | |
300 inline RetainPtr<T> retainPtr(T o) { | |
301 return RetainPtr<T>(o); | |
302 } | |
303 | |
304 template <typename T> | |
305 struct HashTraits<RetainPtr<T>> : SimpleClassHashTraits<RetainPtr<T>> {}; | |
306 | |
307 template <typename T> | |
308 struct RetainPtrHash | |
309 : PtrHash< | |
310 typename std::remove_pointer<typename RetainPtr<T>::PtrType>::type> { | |
311 using Base = PtrHash< | |
312 typename std::remove_pointer<typename RetainPtr<T>::PtrType>::type>; | |
313 using Base::hash; | |
314 static unsigned hash(const RetainPtr<T>& key) { return hash(key.get()); } | |
315 using Base::equal; | |
316 static bool equal(const RetainPtr<T>& a, const RetainPtr<T>& b) { | |
317 return a == b; | |
318 } | |
319 static bool equal(typename RetainPtr<T>::PtrType a, const RetainPtr<T>& b) { | |
320 return a == b; | |
321 } | |
322 static bool equal(const RetainPtr<T>& a, typename RetainPtr<T>::PtrType b) { | |
323 return a == b; | |
324 } | |
325 }; | |
326 | |
327 template <typename T> | |
328 struct DefaultHash<RetainPtr<T>> { | |
329 using Hash = RetainPtrHash<T>; | |
330 }; | |
331 | |
332 } // namespace WTF | |
333 | |
334 using WTF::AdoptCF; | |
335 using WTF::AdoptNS; | |
336 using WTF::adoptCF; | |
337 using WTF::adoptNS; | |
338 using WTF::RetainPtr; | |
339 using WTF::retainPtr; | |
340 | |
341 #endif // WTF_RetainPtr_h | |
OLD | NEW |