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