| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 namespace WTF { | 46 namespace WTF { |
| 47 | 47 |
| 48 // Unlike most most of our smart pointers, RetainPtr can take either the pointer | 48 // Unlike most most of our smart pointers, RetainPtr can take either the pointer |
| 49 // type or the pointed-to type, so both RetainPtr<NSDictionary> and | 49 // type or the pointed-to type, so both RetainPtr<NSDictionary> and |
| 50 // RetainPtr<CFDictionaryRef> will work. | 50 // RetainPtr<CFDictionaryRef> will work. |
| 51 | 51 |
| 52 enum AdoptCFTag { AdoptCF }; | 52 enum AdoptCFTag { AdoptCF }; |
| 53 enum AdoptNSTag { AdoptNS }; | 53 enum AdoptNSTag { AdoptNS }; |
| 54 | 54 |
| 55 #ifdef __OBJC__ | 55 #ifdef __OBJC__ |
| 56 inline void adoptNSReference(id ptr) | 56 inline void adoptNSReference(id ptr) { |
| 57 { | 57 if (ptr) { |
| 58 if (ptr) { | 58 CFRetain(ptr); |
| 59 CFRetain(ptr); | 59 [ptr release]; |
| 60 [ptr release]; | 60 } |
| 61 } | |
| 62 } | 61 } |
| 63 #endif | 62 #endif |
| 64 | 63 |
| 65 template <typename T> class RetainPtr { | 64 template <typename T> |
| 66 public: | 65 class RetainPtr { |
| 67 typedef typename RemovePointer<T>::Type ValueType; | 66 public: |
| 68 typedef ValueType* PtrType; | 67 typedef typename RemovePointer<T>::Type ValueType; |
| 69 | 68 typedef ValueType* PtrType; |
| 70 RetainPtr() : m_ptr(nullptr) {} | 69 |
| 71 RetainPtr(PtrType ptr) : m_ptr(ptr) | 70 RetainPtr() |
| 72 { | 71 : m_ptr(nullptr) {} |
| 73 if (ptr) | 72 RetainPtr(PtrType ptr) |
| 74 CFRetain(ptr); | 73 : m_ptr(ptr) { |
| 75 } | 74 if (ptr) |
| 76 | 75 CFRetain(ptr); |
| 77 RetainPtr(AdoptCFTag, PtrType ptr) : m_ptr(ptr) {} | 76 } |
| 78 RetainPtr(AdoptNSTag, PtrType ptr) : m_ptr(ptr) { adoptNSReference(ptr); } | 77 |
| 79 | 78 RetainPtr(AdoptCFTag, PtrType ptr) |
| 80 RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) | 79 : m_ptr(ptr) {} |
| 81 { | 80 RetainPtr(AdoptNSTag, PtrType ptr) |
| 82 if (PtrType ptr = m_ptr) | 81 : m_ptr(ptr) { adoptNSReference(ptr); } |
| 83 CFRetain(ptr); | 82 |
| 84 } | 83 RetainPtr(const RetainPtr& o) |
| 85 | 84 : m_ptr(o.m_ptr) { |
| 86 RetainPtr(RetainPtr&& o) : m_ptr(o.leakRef()) {} | 85 if (PtrType ptr = m_ptr) |
| 87 | 86 CFRetain(ptr); |
| 88 // Hash table deleted values, which are only constructed and never copied or | 87 } |
| 89 // destroyed. | 88 |
| 90 RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } | 89 RetainPtr(RetainPtr&& o) |
| 91 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue
(); } | 90 : m_ptr(o.leakRef()) {} |
| 92 | 91 |
| 93 ~RetainPtr() | 92 // Hash table deleted values, which are only constructed and never copied or |
| 94 { | 93 // destroyed. |
| 95 if (PtrType ptr = m_ptr) | 94 RetainPtr(HashTableDeletedValueType) |
| 96 CFRelease(ptr); | 95 : m_ptr(hashTableDeletedValue()) {} |
| 97 } | 96 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue()
; } |
| 98 | 97 |
| 99 template <typename U> RetainPtr(const RetainPtr<U>&); | 98 ~RetainPtr() { |
| 100 | 99 if (PtrType ptr = m_ptr) |
| 101 void clear(); | 100 CFRelease(ptr); |
| 102 PtrType leakRef() WARN_UNUSED_RETURN; | 101 } |
| 103 | 102 |
| 104 PtrType get() const { return m_ptr; } | 103 template <typename U> |
| 105 PtrType operator->() const { return m_ptr; } | 104 RetainPtr(const RetainPtr<U>&); |
| 105 |
| 106 void clear(); |
| 107 PtrType leakRef() WARN_UNUSED_RETURN; |
| 108 |
| 109 PtrType get() const { return m_ptr; } |
| 110 PtrType operator->() const { return m_ptr; } |
| 106 #if COMPILER_SUPPORTS(CXX_EXPLICIT_CONVERSIONS) | 111 #if COMPILER_SUPPORTS(CXX_EXPLICIT_CONVERSIONS) |
| 107 explicit operator PtrType() const { return m_ptr; } | 112 explicit operator PtrType() const { return m_ptr; } |
| 108 #endif | 113 #endif |
| 109 | 114 |
| 110 bool operator!() const { return !m_ptr; } | 115 bool operator!() const { return !m_ptr; } |
| 111 | 116 |
| 112 // This conversion operator allows implicit conversion to bool but not to | 117 // This conversion operator allows implicit conversion to bool but not to |
| 113 // other integer types. | 118 // other integer types. |
| 114 typedef PtrType RetainPtr::*UnspecifiedBoolType; | 119 typedef PtrType RetainPtr::*UnspecifiedBoolType; |
| 115 operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr : 0;
} | 120 operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr : 0; } |
| 116 | 121 |
| 117 RetainPtr& operator=(const RetainPtr&); | 122 RetainPtr& operator=(const RetainPtr&); |
| 118 template <typename U> RetainPtr& operator=(const RetainPtr<U>&); | 123 template <typename U> |
| 119 RetainPtr& operator=(PtrType); | 124 RetainPtr& operator=(const RetainPtr<U>&); |
| 120 template <typename U> RetainPtr& operator=(U*); | 125 RetainPtr& operator=(PtrType); |
| 121 | 126 template <typename U> |
| 122 RetainPtr& operator=(RetainPtr&&); | 127 RetainPtr& operator=(U*); |
| 123 template <typename U> RetainPtr& operator=(RetainPtr<U>&&); | 128 |
| 129 RetainPtr& operator=(RetainPtr&&); |
| 130 template <typename U> |
| 131 RetainPtr& operator=(RetainPtr<U>&&); |
| 124 | 132 |
| 125 #if !COMPILER_SUPPORTS(CXX_NULLPTR) | 133 #if !COMPILER_SUPPORTS(CXX_NULLPTR) |
| 126 RetainPtr& operator=(std::nullptr_t) | 134 RetainPtr& operator=(std::nullptr_t) { |
| 127 { | 135 clear(); |
| 128 clear(); | 136 return *this; |
| 129 return *this; | 137 } |
| 130 } | |
| 131 #endif | 138 #endif |
| 132 | 139 |
| 133 void adoptCF(PtrType); | 140 void adoptCF(PtrType); |
| 134 void adoptNS(PtrType); | 141 void adoptNS(PtrType); |
| 135 | 142 |
| 136 void swap(RetainPtr&); | 143 void swap(RetainPtr&); |
| 137 | 144 |
| 138 private: | 145 private: |
| 139 static PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType>(-1
); } | 146 static PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType>(-1);
} |
| 140 | 147 |
| 141 PtrType m_ptr; | 148 PtrType m_ptr; |
| 142 }; | 149 }; |
| 143 | 150 |
| 144 template <typename T> | 151 template <typename T> |
| 145 template <typename U> inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o) | 152 template <typename U> |
| 146 : m_ptr(o.get()) | 153 inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o) |
| 147 { | 154 : m_ptr(o.get()) { |
| 148 if (PtrType ptr = m_ptr) | 155 if (PtrType ptr = m_ptr) |
| 149 CFRetain(ptr); | 156 CFRetain(ptr); |
| 150 } | 157 } |
| 151 | 158 |
| 152 template <typename T> inline void RetainPtr<T>::clear() | 159 template <typename T> |
| 153 { | 160 inline void RetainPtr<T>::clear() { |
| 154 if (PtrType ptr = m_ptr) { | 161 if (PtrType ptr = m_ptr) { |
| 155 m_ptr = nullptr; | |
| 156 CFRelease(ptr); | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 template <typename T> inline typename RetainPtr<T>::PtrType RetainPtr<T>::leakRe
f() | |
| 161 { | |
| 162 PtrType ptr = m_ptr; | |
| 163 m_ptr = nullptr; | 162 m_ptr = nullptr; |
| 164 return ptr; | 163 CFRelease(ptr); |
| 165 } | 164 } |
| 166 | 165 } |
| 167 template <typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainP
tr<T>& o) | 166 |
| 168 { | 167 template <typename T> |
| 169 PtrType optr = o.get(); | 168 inline typename RetainPtr<T>::PtrType RetainPtr<T>::leakRef() { |
| 170 if (optr) | 169 PtrType ptr = m_ptr; |
| 171 CFRetain(optr); | 170 m_ptr = nullptr; |
| 172 PtrType ptr = m_ptr; | 171 return ptr; |
| 173 m_ptr = optr; | 172 } |
| 174 if (ptr) | 173 |
| 175 CFRelease(ptr); | 174 template <typename T> |
| 176 return *this; | 175 inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<T>& o) { |
| 177 } | 176 PtrType optr = o.get(); |
| 178 | 177 if (optr) |
| 179 template <typename T> | 178 CFRetain(optr); |
| 180 template <typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainP
tr<U>& o) | 179 PtrType ptr = m_ptr; |
| 181 { | 180 m_ptr = optr; |
| 182 PtrType optr = o.get(); | 181 if (ptr) |
| 183 if (optr) | 182 CFRelease(ptr); |
| 184 CFRetain(optr); | 183 return *this; |
| 185 PtrType ptr = m_ptr; | 184 } |
| 186 m_ptr = optr; | 185 |
| 187 if (ptr) | 186 template <typename T> |
| 188 CFRelease(ptr); | 187 template <typename U> |
| 189 return *this; | 188 inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<U>& o) { |
| 190 } | 189 PtrType optr = o.get(); |
| 191 | 190 if (optr) |
| 192 template <typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr) | 191 CFRetain(optr); |
| 193 { | 192 PtrType ptr = m_ptr; |
| 194 if (optr) | 193 m_ptr = optr; |
| 195 CFRetain(optr); | 194 if (ptr) |
| 196 PtrType ptr = m_ptr; | 195 CFRelease(ptr); |
| 197 m_ptr = optr; | 196 return *this; |
| 198 if (ptr) | 197 } |
| 199 CFRelease(ptr); | 198 |
| 200 return *this; | 199 template <typename T> |
| 201 } | 200 inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr) { |
| 202 | 201 if (optr) |
| 203 template <typename T> | 202 CFRetain(optr); |
| 204 template <typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr) | 203 PtrType ptr = m_ptr; |
| 205 { | 204 m_ptr = optr; |
| 206 if (optr) | 205 if (ptr) |
| 207 CFRetain(optr); | 206 CFRelease(ptr); |
| 208 PtrType ptr = m_ptr; | 207 return *this; |
| 209 m_ptr = optr; | 208 } |
| 210 if (ptr) | 209 |
| 211 CFRelease(ptr); | 210 template <typename T> |
| 212 return *this; | 211 template <typename U> |
| 213 } | 212 inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr) { |
| 214 | 213 if (optr) |
| 215 template <typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<T>&
& o) | 214 CFRetain(optr); |
| 216 { | 215 PtrType ptr = m_ptr; |
| 217 adoptCF(o.leakRef()); | 216 m_ptr = optr; |
| 218 return *this; | 217 if (ptr) |
| 219 } | 218 CFRelease(ptr); |
| 220 | 219 return *this; |
| 221 template <typename T> | 220 } |
| 222 template <typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<U>&
& o) | 221 |
| 223 { | 222 template <typename T> |
| 224 adoptCF(o.leakRef()); | 223 inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<T>&& o) { |
| 225 return *this; | 224 adoptCF(o.leakRef()); |
| 226 } | 225 return *this; |
| 227 | 226 } |
| 228 template <typename T> inline void RetainPtr<T>::adoptCF(PtrType optr) | 227 |
| 229 { | 228 template <typename T> |
| 230 PtrType ptr = m_ptr; | 229 template <typename U> |
| 231 m_ptr = optr; | 230 inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<U>&& o) { |
| 232 if (ptr) | 231 adoptCF(o.leakRef()); |
| 233 CFRelease(ptr); | 232 return *this; |
| 234 } | 233 } |
| 235 | 234 |
| 236 template <typename T> inline void RetainPtr<T>::adoptNS(PtrType optr) | 235 template <typename T> |
| 237 { | 236 inline void RetainPtr<T>::adoptCF(PtrType optr) { |
| 238 adoptNSReference(optr); | 237 PtrType ptr = m_ptr; |
| 239 | 238 m_ptr = optr; |
| 240 PtrType ptr = m_ptr; | 239 if (ptr) |
| 241 m_ptr = optr; | 240 CFRelease(ptr); |
| 242 if (ptr) | 241 } |
| 243 CFRelease(ptr); | 242 |
| 244 } | 243 template <typename T> |
| 245 | 244 inline void RetainPtr<T>::adoptNS(PtrType optr) { |
| 246 template <typename T> inline void RetainPtr<T>::swap(RetainPtr<T>& o) | 245 adoptNSReference(optr); |
| 247 { | 246 |
| 248 std::swap(m_ptr, o.m_ptr); | 247 PtrType ptr = m_ptr; |
| 249 } | 248 m_ptr = optr; |
| 250 | 249 if (ptr) |
| 251 template <typename T> inline void swap(RetainPtr<T>& a, RetainPtr<T>& b) | 250 CFRelease(ptr); |
| 252 { | 251 } |
| 253 a.swap(b); | 252 |
| 254 } | 253 template <typename T> |
| 255 | 254 inline void RetainPtr<T>::swap(RetainPtr<T>& o) { |
| 256 template <typename T, typename U> inline bool operator==(const RetainPtr<T>& a,
const RetainPtr<U>& b) | 255 std::swap(m_ptr, o.m_ptr); |
| 257 { | 256 } |
| 258 return a.get() == b.get(); | 257 |
| 259 } | 258 template <typename T> |
| 260 | 259 inline void swap(RetainPtr<T>& a, RetainPtr<T>& b) { |
| 261 template <typename T, typename U> inline bool operator==(const RetainPtr<T>& a,
U* b) | 260 a.swap(b); |
| 262 { | 261 } |
| 263 return a.get() == b; | 262 |
| 264 } | 263 template <typename T, typename U> |
| 265 | 264 inline bool operator==(const RetainPtr<T>& a, const RetainPtr<U>& b) { |
| 266 template <typename T, typename U> inline bool operator==(T* a, const RetainPtr<U
>& b) | 265 return a.get() == b.get(); |
| 267 { | 266 } |
| 268 return a == b.get(); | 267 |
| 269 } | 268 template <typename T, typename U> |
| 270 | 269 inline bool operator==(const RetainPtr<T>& a, U* b) { |
| 271 template <typename T, typename U> inline bool operator!=(const RetainPtr<T>& a,
const RetainPtr<U>& b) | 270 return a.get() == b; |
| 272 { | 271 } |
| 273 return a.get() != b.get(); | 272 |
| 274 } | 273 template <typename T, typename U> |
| 275 | 274 inline bool operator==(T* a, const RetainPtr<U>& b) { |
| 276 template <typename T, typename U> inline bool operator!=(const RetainPtr<T>& a,
U* b) | 275 return a == b.get(); |
| 277 { | 276 } |
| 278 return a.get() != b; | 277 |
| 279 } | 278 template <typename T, typename U> |
| 280 | 279 inline bool operator!=(const RetainPtr<T>& a, const RetainPtr<U>& b) { |
| 281 template <typename T, typename U> inline bool operator!=(T* a, const RetainPtr<U
>& b) | 280 return a.get() != b.get(); |
| 282 { | 281 } |
| 283 return a != b.get(); | 282 |
| 284 } | 283 template <typename T, typename U> |
| 285 | 284 inline bool operator!=(const RetainPtr<T>& a, U* b) { |
| 286 template <typename T> inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT) WARN_U
NUSED_RETURN; | 285 return a.get() != b; |
| 287 template <typename T> inline RetainPtr<T> adoptCF(T o) | 286 } |
| 288 { | 287 |
| 289 return RetainPtr<T>(AdoptCF, o); | 288 template <typename T, typename U> |
| 290 } | 289 inline bool operator!=(T* a, const RetainPtr<U>& b) { |
| 291 | 290 return a != b.get(); |
| 292 template <typename T> inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT) WARN_U
NUSED_RETURN; | 291 } |
| 293 template <typename T> inline RetainPtr<T> adoptNS(T o) | 292 |
| 294 { | 293 template <typename T> |
| 295 return RetainPtr<T>(AdoptNS, o); | 294 inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT) WARN_UNUSED_RETURN; |
| 295 template <typename T> |
| 296 inline RetainPtr<T> adoptCF(T o) { |
| 297 return RetainPtr<T>(AdoptCF, o); |
| 298 } |
| 299 |
| 300 template <typename T> |
| 301 inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT) WARN_UNUSED_RETURN; |
| 302 template <typename T> |
| 303 inline RetainPtr<T> adoptNS(T o) { |
| 304 return RetainPtr<T>(AdoptNS, o); |
| 296 } | 305 } |
| 297 | 306 |
| 298 // Helper function for creating a RetainPtr using template argument deduction. | 307 // Helper function for creating a RetainPtr using template argument deduction. |
| 299 template <typename T> inline RetainPtr<T> retainPtr(T) WARN_UNUSED_RETURN; | 308 template <typename T> |
| 300 template <typename T> inline RetainPtr<T> retainPtr(T o) | 309 inline RetainPtr<T> retainPtr(T) WARN_UNUSED_RETURN; |
| 301 { | 310 template <typename T> |
| 302 return RetainPtr<T>(o); | 311 inline RetainPtr<T> retainPtr(T o) { |
| 303 } | 312 return RetainPtr<T>(o); |
| 304 | 313 } |
| 305 template <typename P> struct HashTraits<RetainPtr<P>> : SimpleClassHashTraits<Re
tainPtr<P>> { }; | 314 |
| 306 | 315 template <typename P> |
| 307 template <typename P> struct PtrHash<RetainPtr<P>> : PtrHash<typename RetainPtr<
P>::PtrType> { | 316 struct HashTraits<RetainPtr<P>> : SimpleClassHashTraits<RetainPtr<P>> {}; |
| 308 using PtrHash<typename RetainPtr<P>::PtrType>::hash; | 317 |
| 309 static unsigned hash(const RetainPtr<P>& key) { return hash(key.get()); } | 318 template <typename P> |
| 310 using PtrHash<typename RetainPtr<P>::PtrType>::equal; | 319 struct PtrHash<RetainPtr<P>> : PtrHash<typename RetainPtr<P>::PtrType> { |
| 311 static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b) { return a =
= b; } | 320 using PtrHash<typename RetainPtr<P>::PtrType>::hash; |
| 312 static bool equal(typename RetainPtr<P>::PtrType a, const RetainPtr<P>& b) {
return a == b; } | 321 static unsigned hash(const RetainPtr<P>& key) { return hash(key.get()); } |
| 313 static bool equal(const RetainPtr<P>& a, typename RetainPtr<P>::PtrType b) {
return a == b; } | 322 using PtrHash<typename RetainPtr<P>::PtrType>::equal; |
| 323 static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b) { return a ==
b; } |
| 324 static bool equal(typename RetainPtr<P>::PtrType a, const RetainPtr<P>& b) { r
eturn a == b; } |
| 325 static bool equal(const RetainPtr<P>& a, typename RetainPtr<P>::PtrType b) { r
eturn a == b; } |
| 314 }; | 326 }; |
| 315 | 327 |
| 316 template <typename P> struct DefaultHash<RetainPtr<P>> { typedef PtrHash<RetainP
tr<P>> Hash; }; | 328 template <typename P> |
| 317 | 329 struct DefaultHash<RetainPtr<P>> { typedef PtrHash<RetainPtr<P>> Hash; }; |
| 318 } // namespace WTF | 330 |
| 331 } // namespace WTF |
| 319 | 332 |
| 320 using WTF::AdoptCF; | 333 using WTF::AdoptCF; |
| 321 using WTF::AdoptNS; | 334 using WTF::AdoptNS; |
| 322 using WTF::adoptCF; | 335 using WTF::adoptCF; |
| 323 using WTF::adoptNS; | 336 using WTF::adoptNS; |
| 324 using WTF::RetainPtr; | 337 using WTF::RetainPtr; |
| 325 using WTF::retainPtr; | 338 using WTF::retainPtr; |
| 326 | 339 |
| 327 #endif // WTF_RetainPtr_h | 340 #endif // WTF_RetainPtr_h |
| OLD | NEW |