OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 #define NS_RELEASES_ARGUMENT | 43 #define NS_RELEASES_ARGUMENT |
44 #endif | 44 #endif |
45 | 45 |
46 namespace WTF { | 46 namespace WTF { |
47 | 47 |
48 // Unlike most most of our smart pointers, RetainPtr can take either the poi
nter type or the pointed-to type, | 48 // Unlike most most of our smart pointers, RetainPtr can take either the poi
nter type or the pointed-to type, |
49 // so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work. | 49 // so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work. |
50 | 50 |
51 enum AdoptCFTag { AdoptCF }; | 51 enum AdoptCFTag { AdoptCF }; |
52 enum AdoptNSTag { AdoptNS }; | 52 enum AdoptNSTag { AdoptNS }; |
53 | 53 |
54 #ifdef __OBJC__ | 54 #ifdef __OBJC__ |
55 inline void adoptNSReference(id ptr) | 55 inline void adoptNSReference(id ptr) |
56 { | 56 { |
57 if (ptr) { | 57 if (ptr) { |
58 CFRetain(ptr); | 58 CFRetain(ptr); |
59 [ptr release]; | 59 [ptr release]; |
60 } | 60 } |
61 } | 61 } |
62 #endif | 62 #endif |
63 | 63 |
64 template<typename T> class RetainPtr { | 64 template<typename T> class RetainPtr { |
65 public: | 65 public: |
66 typedef typename RemovePointer<T>::Type ValueType; | 66 typedef typename RemovePointer<T>::Type ValueType; |
67 typedef ValueType* PtrType; | 67 typedef ValueType* PtrType; |
68 | 68 |
69 RetainPtr() : m_ptr(0) {} | 69 RetainPtr() : m_ptr(0) {} |
70 RetainPtr(PtrType ptr) : m_ptr(ptr) { if (ptr) CFRetain(ptr); } | 70 RetainPtr(PtrType ptr) : m_ptr(ptr) { if (ptr) CFRetain(ptr); } |
71 | 71 |
72 RetainPtr(AdoptCFTag, PtrType ptr) : m_ptr(ptr) { } | 72 RetainPtr(AdoptCFTag, PtrType ptr) : m_ptr(ptr) { } |
73 RetainPtr(AdoptNSTag, PtrType ptr) : m_ptr(ptr) { adoptNSReference(ptr);
} | 73 RetainPtr(AdoptNSTag, PtrType ptr) : m_ptr(ptr) { adoptNSReference(ptr);
} |
74 | 74 |
75 RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (PtrType ptr = m_ptr
) CFRetain(ptr); } | 75 RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (PtrType ptr = m_ptr
) CFRetain(ptr); } |
76 | 76 |
77 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | 77 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) |
78 RetainPtr(RetainPtr&& o) : m_ptr(o.leakRef()) { } | 78 RetainPtr(RetainPtr&& o) : m_ptr(o.leakRef()) { } |
79 #endif | 79 #endif |
80 | 80 |
81 // Hash table deleted values, which are only constructed and never copie
d or destroyed. | 81 // Hash table deleted values, which are only constructed and never copie
d or destroyed. |
82 RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) {
} | 82 RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) {
} |
83 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedV
alue(); } | 83 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedV
alue(); } |
84 | 84 |
85 ~RetainPtr() { if (PtrType ptr = m_ptr) CFRelease(ptr); } | 85 ~RetainPtr() { if (PtrType ptr = m_ptr) CFRelease(ptr); } |
86 | 86 |
87 template<typename U> RetainPtr(const RetainPtr<U>&); | 87 template<typename U> RetainPtr(const RetainPtr<U>&); |
88 | 88 |
89 void clear(); | 89 void clear(); |
90 PtrType leakRef() WARN_UNUSED_RETURN; | 90 PtrType leakRef() WARN_UNUSED_RETURN; |
91 | 91 |
92 PtrType get() const { return m_ptr; } | 92 PtrType get() const { return m_ptr; } |
93 PtrType operator->() const { return m_ptr; } | 93 PtrType operator->() const { return m_ptr; } |
94 #if COMPILER_SUPPORTS(CXX_EXPLICIT_CONVERSIONS) | 94 #if COMPILER_SUPPORTS(CXX_EXPLICIT_CONVERSIONS) |
95 explicit operator PtrType() const { return m_ptr; } | 95 explicit operator PtrType() const { return m_ptr; } |
96 #endif | 96 #endif |
97 | 97 |
98 bool operator!() const { return !m_ptr; } | 98 bool operator!() const { return !m_ptr; } |
99 | 99 |
100 // This conversion operator allows implicit conversion to bool but not t
o other integer types. | 100 // This conversion operator allows implicit conversion to bool but not t
o other integer types. |
101 typedef PtrType RetainPtr::*UnspecifiedBoolType; | 101 typedef PtrType RetainPtr::*UnspecifiedBoolType; |
102 operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr
: 0; } | 102 operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr
: 0; } |
103 | 103 |
104 RetainPtr& operator=(const RetainPtr&); | 104 RetainPtr& operator=(const RetainPtr&); |
105 template<typename U> RetainPtr& operator=(const RetainPtr<U>&); | 105 template<typename U> RetainPtr& operator=(const RetainPtr<U>&); |
106 RetainPtr& operator=(PtrType); | 106 RetainPtr& operator=(PtrType); |
107 template<typename U> RetainPtr& operator=(U*); | 107 template<typename U> RetainPtr& operator=(U*); |
108 | 108 |
109 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | 109 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) |
110 RetainPtr& operator=(RetainPtr&&); | 110 RetainPtr& operator=(RetainPtr&&); |
111 template<typename U> RetainPtr& operator=(RetainPtr<U>&&); | 111 template<typename U> RetainPtr& operator=(RetainPtr<U>&&); |
112 #endif | 112 #endif |
113 | 113 |
114 #if !COMPILER_SUPPORTS(CXX_NULLPTR) | 114 #if !COMPILER_SUPPORTS(CXX_NULLPTR) |
115 RetainPtr& operator=(std::nullptr_t) { clear(); return *this; } | 115 RetainPtr& operator=(std::nullptr_t) { clear(); return *this; } |
116 #endif | 116 #endif |
117 | 117 |
118 void adoptCF(PtrType); | 118 void adoptCF(PtrType); |
119 void adoptNS(PtrType); | 119 void adoptNS(PtrType); |
120 | 120 |
121 void swap(RetainPtr&); | 121 void swap(RetainPtr&); |
122 | 122 |
123 private: | 123 private: |
124 static PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType
>(-1); } | 124 static PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType
>(-1); } |
125 | 125 |
126 PtrType m_ptr; | 126 PtrType m_ptr; |
127 }; | 127 }; |
128 | 128 |
129 template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(con
st RetainPtr<U>& o) | 129 template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(con
st RetainPtr<U>& o) |
130 : m_ptr(o.get()) | 130 : m_ptr(o.get()) |
131 { | 131 { |
132 if (PtrType ptr = m_ptr) | 132 if (PtrType ptr = m_ptr) |
133 CFRetain(ptr); | 133 CFRetain(ptr); |
134 } | 134 } |
135 | 135 |
136 template<typename T> inline void RetainPtr<T>::clear() | 136 template<typename T> inline void RetainPtr<T>::clear() |
137 { | 137 { |
138 if (PtrType ptr = m_ptr) { | 138 if (PtrType ptr = m_ptr) { |
(...skipping 13 matching lines...) Expand all Loading... |
152 { | 152 { |
153 PtrType optr = o.get(); | 153 PtrType optr = o.get(); |
154 if (optr) | 154 if (optr) |
155 CFRetain(optr); | 155 CFRetain(optr); |
156 PtrType ptr = m_ptr; | 156 PtrType ptr = m_ptr; |
157 m_ptr = optr; | 157 m_ptr = optr; |
158 if (ptr) | 158 if (ptr) |
159 CFRelease(ptr); | 159 CFRelease(ptr); |
160 return *this; | 160 return *this; |
161 } | 161 } |
162 | 162 |
163 template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>:
:operator=(const RetainPtr<U>& o) | 163 template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>:
:operator=(const RetainPtr<U>& o) |
164 { | 164 { |
165 PtrType optr = o.get(); | 165 PtrType optr = o.get(); |
166 if (optr) | 166 if (optr) |
167 CFRetain(optr); | 167 CFRetain(optr); |
168 PtrType ptr = m_ptr; | 168 PtrType ptr = m_ptr; |
169 m_ptr = optr; | 169 m_ptr = optr; |
170 if (ptr) | 170 if (ptr) |
171 CFRelease(ptr); | 171 CFRelease(ptr); |
172 return *this; | 172 return *this; |
(...skipping 20 matching lines...) Expand all Loading... |
193 CFRelease(ptr); | 193 CFRelease(ptr); |
194 return *this; | 194 return *this; |
195 } | 195 } |
196 | 196 |
197 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | 197 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) |
198 template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<
T>&& o) | 198 template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<
T>&& o) |
199 { | 199 { |
200 adoptCF(o.leakRef()); | 200 adoptCF(o.leakRef()); |
201 return *this; | 201 return *this; |
202 } | 202 } |
203 | 203 |
204 template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>:
:operator=(RetainPtr<U>&& o) | 204 template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>:
:operator=(RetainPtr<U>&& o) |
205 { | 205 { |
206 adoptCF(o.leakRef()); | 206 adoptCF(o.leakRef()); |
207 return *this; | 207 return *this; |
208 } | 208 } |
209 #endif | 209 #endif |
210 | 210 |
211 template<typename T> inline void RetainPtr<T>::adoptCF(PtrType optr) | 211 template<typename T> inline void RetainPtr<T>::adoptCF(PtrType optr) |
212 { | 212 { |
213 PtrType ptr = m_ptr; | 213 PtrType ptr = m_ptr; |
214 m_ptr = optr; | 214 m_ptr = optr; |
215 if (ptr) | 215 if (ptr) |
216 CFRelease(ptr); | 216 CFRelease(ptr); |
217 } | 217 } |
218 | 218 |
219 template<typename T> inline void RetainPtr<T>::adoptNS(PtrType optr) | 219 template<typename T> inline void RetainPtr<T>::adoptNS(PtrType optr) |
220 { | 220 { |
221 adoptNSReference(optr); | 221 adoptNSReference(optr); |
222 | 222 |
223 PtrType ptr = m_ptr; | 223 PtrType ptr = m_ptr; |
224 m_ptr = optr; | 224 m_ptr = optr; |
225 if (ptr) | 225 if (ptr) |
226 CFRelease(ptr); | 226 CFRelease(ptr); |
227 } | 227 } |
228 | 228 |
229 template<typename T> inline void RetainPtr<T>::swap(RetainPtr<T>& o) | 229 template<typename T> inline void RetainPtr<T>::swap(RetainPtr<T>& o) |
230 { | 230 { |
231 std::swap(m_ptr, o.m_ptr); | 231 std::swap(m_ptr, o.m_ptr); |
232 } | 232 } |
233 | 233 |
234 template<typename T> inline void swap(RetainPtr<T>& a, RetainPtr<T>& b) | 234 template<typename T> inline void swap(RetainPtr<T>& a, RetainPtr<T>& b) |
235 { | 235 { |
236 a.swap(b); | 236 a.swap(b); |
237 } | 237 } |
238 | 238 |
239 template<typename T, typename U> inline bool operator==(const RetainPtr<T>&
a, const RetainPtr<U>& b) | 239 template<typename T, typename U> inline bool operator==(const RetainPtr<T>&
a, const RetainPtr<U>& b) |
240 { | 240 { |
241 return a.get() == b.get(); | 241 return a.get() == b.get(); |
242 } | 242 } |
243 | 243 |
244 template<typename T, typename U> inline bool operator==(const RetainPtr<T>&
a, U* b) | 244 template<typename T, typename U> inline bool operator==(const RetainPtr<T>&
a, U* b) |
245 { | 245 { |
246 return a.get() == b; | 246 return a.get() == b; |
247 } | 247 } |
248 | 248 |
249 template<typename T, typename U> inline bool operator==(T* a, const RetainPt
r<U>& b) | 249 template<typename T, typename U> inline bool operator==(T* a, const RetainPt
r<U>& b) |
250 { | 250 { |
251 return a == b.get(); | 251 return a == b.get(); |
252 } | 252 } |
253 | 253 |
254 template<typename T, typename U> inline bool operator!=(const RetainPtr<T>&
a, const RetainPtr<U>& b) | 254 template<typename T, typename U> inline bool operator!=(const RetainPtr<T>&
a, const RetainPtr<U>& b) |
255 { | 255 { |
256 return a.get() != b.get(); | 256 return a.get() != b.get(); |
257 } | 257 } |
258 | 258 |
259 template<typename T, typename U> inline bool operator!=(const RetainPtr<T>&
a, U* b) | 259 template<typename T, typename U> inline bool operator!=(const RetainPtr<T>&
a, U* b) |
260 { | 260 { |
261 return a.get() != b; | 261 return a.get() != b; |
262 } | 262 } |
263 | 263 |
264 template<typename T, typename U> inline bool operator!=(T* a, const RetainPt
r<U>& b) | 264 template<typename T, typename U> inline bool operator!=(T* a, const RetainPt
r<U>& b) |
265 { | 265 { |
266 return a != b.get(); | 266 return a != b.get(); |
267 } | 267 } |
268 | 268 |
269 template<typename T> inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT) WAR
N_UNUSED_RETURN; | 269 template<typename T> inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT) WAR
N_UNUSED_RETURN; |
270 template<typename T> inline RetainPtr<T> adoptCF(T o) | 270 template<typename T> inline RetainPtr<T> adoptCF(T o) |
271 { | 271 { |
272 return RetainPtr<T>(AdoptCF, o); | 272 return RetainPtr<T>(AdoptCF, o); |
273 } | 273 } |
274 | 274 |
275 template<typename T> inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT) WAR
N_UNUSED_RETURN; | 275 template<typename T> inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT) WAR
N_UNUSED_RETURN; |
276 template<typename T> inline RetainPtr<T> adoptNS(T o) | 276 template<typename T> inline RetainPtr<T> adoptNS(T o) |
277 { | 277 { |
278 return RetainPtr<T>(AdoptNS, o); | 278 return RetainPtr<T>(AdoptNS, o); |
279 } | 279 } |
280 | 280 |
281 // Helper function for creating a RetainPtr using template argument deductio
n. | 281 // Helper function for creating a RetainPtr using template argument deductio
n. |
282 template<typename T> inline RetainPtr<T> retainPtr(T) WARN_UNUSED_RETURN; | 282 template<typename T> inline RetainPtr<T> retainPtr(T) WARN_UNUSED_RETURN; |
283 template<typename T> inline RetainPtr<T> retainPtr(T o) | 283 template<typename T> inline RetainPtr<T> retainPtr(T o) |
284 { | 284 { |
285 return RetainPtr<T>(o); | 285 return RetainPtr<T>(o); |
286 } | 286 } |
287 | 287 |
288 template<typename P> struct HashTraits<RetainPtr<P> > : SimpleClassHashTrait
s<RetainPtr<P> > { }; | 288 template<typename P> struct HashTraits<RetainPtr<P> > : SimpleClassHashTrait
s<RetainPtr<P> > { }; |
289 | 289 |
290 template<typename P> struct PtrHash<RetainPtr<P> > : PtrHash<typename Retain
Ptr<P>::PtrType> { | 290 template<typename P> struct PtrHash<RetainPtr<P> > : PtrHash<typename Retain
Ptr<P>::PtrType> { |
291 using PtrHash<typename RetainPtr<P>::PtrType>::hash; | 291 using PtrHash<typename RetainPtr<P>::PtrType>::hash; |
292 static unsigned hash(const RetainPtr<P>& key) { return hash(key.get());
} | 292 static unsigned hash(const RetainPtr<P>& key) { return hash(key.get());
} |
293 using PtrHash<typename RetainPtr<P>::PtrType>::equal; | 293 using PtrHash<typename RetainPtr<P>::PtrType>::equal; |
294 static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b) { return
a == b; } | 294 static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b) { return
a == b; } |
295 static bool equal(typename RetainPtr<P>::PtrType a, const RetainPtr<P>&
b) { return a == b; } | 295 static bool equal(typename RetainPtr<P>::PtrType a, const RetainPtr<P>&
b) { return a == b; } |
296 static bool equal(const RetainPtr<P>& a, typename RetainPtr<P>::PtrType
b) { return a == b; } | 296 static bool equal(const RetainPtr<P>& a, typename RetainPtr<P>::PtrType
b) { return a == b; } |
297 }; | 297 }; |
298 | 298 |
299 template<typename P> struct DefaultHash<RetainPtr<P> > { typedef PtrHash<Ret
ainPtr<P> > Hash; }; | 299 template<typename P> struct DefaultHash<RetainPtr<P> > { typedef PtrHash<Ret
ainPtr<P> > Hash; }; |
300 } // namespace WTF | 300 } // namespace WTF |
301 | 301 |
302 using WTF::AdoptCF; | 302 using WTF::AdoptCF; |
303 using WTF::AdoptNS; | 303 using WTF::AdoptNS; |
304 using WTF::adoptCF; | 304 using WTF::adoptCF; |
305 using WTF::adoptNS; | 305 using WTF::adoptNS; |
306 using WTF::RetainPtr; | 306 using WTF::RetainPtr; |
307 using WTF::retainPtr; | 307 using WTF::retainPtr; |
308 | 308 |
309 #endif // WTF_RetainPtr_h | 309 #endif // WTF_RetainPtr_h |
OLD | NEW |