| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 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 13 matching lines...) Expand all Loading... |
| 24 #define WTF_RefPtr_h | 24 #define WTF_RefPtr_h |
| 25 | 25 |
| 26 #include "wtf/HashTableDeletedValueType.h" | 26 #include "wtf/HashTableDeletedValueType.h" |
| 27 #include "wtf/PassRefPtr.h" | 27 #include "wtf/PassRefPtr.h" |
| 28 #include "wtf/RawPtr.h" | 28 #include "wtf/RawPtr.h" |
| 29 #include <algorithm> | 29 #include <algorithm> |
| 30 #include <utility> | 30 #include <utility> |
| 31 | 31 |
| 32 namespace WTF { | 32 namespace WTF { |
| 33 | 33 |
| 34 template <typename T> class PassRefPtr; | 34 template <typename T> |
| 35 | 35 class PassRefPtr; |
| 36 template <typename T> class RefPtr { | 36 |
| 37 public: | 37 template <typename T> |
| 38 ALWAYS_INLINE RefPtr() : m_ptr(nullptr) {} | 38 class RefPtr { |
| 39 ALWAYS_INLINE RefPtr(std::nullptr_t) : m_ptr(nullptr) {} | 39 public: |
| 40 ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } | 40 ALWAYS_INLINE RefPtr() |
| 41 template <typename U> RefPtr(const RawPtr<U>& ptr, EnsurePtrConvertibleArgDe
cl(U, T)) : m_ptr(ptr.get()) { refIfNotNull(m_ptr); } | 41 : m_ptr(nullptr) {} |
| 42 ALWAYS_INLINE explicit RefPtr(T& ref) : m_ptr(&ref) { m_ptr->ref(); } | 42 ALWAYS_INLINE RefPtr(std::nullptr_t) |
| 43 ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr)
; } | 43 : m_ptr(nullptr) {} |
| 44 template <typename U> RefPtr(const RefPtr<U>& o, EnsurePtrConvertibleArgDecl
(U, T)) : m_ptr(o.get()) { refIfNotNull(m_ptr); } | 44 ALWAYS_INLINE RefPtr(T* ptr) |
| 45 | 45 : m_ptr(ptr) { refIfNotNull(ptr); } |
| 46 RefPtr(RefPtr&& o) : m_ptr(o.m_ptr) { o.m_ptr = nullptr; } | 46 template <typename U> |
| 47 RefPtr& operator=(RefPtr&&); | 47 RefPtr(const RawPtr<U>& ptr, EnsurePtrConvertibleArgDecl(U, T)) |
| 48 | 48 : m_ptr(ptr.get()) { refIfNotNull(m_ptr); } |
| 49 // See comments in PassRefPtr.h for an explanation of why this takes a const | 49 ALWAYS_INLINE explicit RefPtr(T& ref) |
| 50 // reference. | 50 : m_ptr(&ref) { m_ptr->ref(); } |
| 51 template <typename U> RefPtr(const PassRefPtr<U>&, EnsurePtrConvertibleArgDe
cl(U, T)); | 51 ALWAYS_INLINE RefPtr(const RefPtr& o) |
| 52 | 52 : m_ptr(o.m_ptr) { refIfNotNull(m_ptr); } |
| 53 // Hash table deleted values, which are only constructed and never copied or | 53 template <typename U> |
| 54 // destroyed. | 54 RefPtr(const RefPtr<U>& o, EnsurePtrConvertibleArgDecl(U, T)) |
| 55 RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) {} | 55 : m_ptr(o.get()) { refIfNotNull(m_ptr); } |
| 56 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue
(); } | 56 |
| 57 | 57 RefPtr(RefPtr&& o) |
| 58 ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); } | 58 : m_ptr(o.m_ptr) { o.m_ptr = nullptr; } |
| 59 | 59 RefPtr& operator=(RefPtr&&); |
| 60 ALWAYS_INLINE T* get() const { return m_ptr; } | 60 |
| 61 | 61 // See comments in PassRefPtr.h for an explanation of why this takes a const |
| 62 void clear(); | 62 // reference. |
| 63 PassRefPtr<T> release() | 63 template <typename U> |
| 64 { | 64 RefPtr(const PassRefPtr<U>&, EnsurePtrConvertibleArgDecl(U, T)); |
| 65 PassRefPtr<T> tmp = adoptRef(m_ptr); | 65 |
| 66 m_ptr = nullptr; | 66 // Hash table deleted values, which are only constructed and never copied or |
| 67 return tmp; | 67 // destroyed. |
| 68 } | 68 RefPtr(HashTableDeletedValueType) |
| 69 | 69 : m_ptr(hashTableDeletedValue()) {} |
| 70 T& operator*() const { return *m_ptr; } | 70 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue()
; } |
| 71 ALWAYS_INLINE T* operator->() const { return m_ptr; } | 71 |
| 72 | 72 ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); } |
| 73 bool operator!() const { return !m_ptr; } | 73 |
| 74 | 74 ALWAYS_INLINE T* get() const { return m_ptr; } |
| 75 // This conversion operator allows implicit conversion to bool but not to | 75 |
| 76 // other integer types. | 76 void clear(); |
| 77 typedef T* (RefPtr::*UnspecifiedBoolType); | 77 PassRefPtr<T> release() { |
| 78 operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; } | 78 PassRefPtr<T> tmp = adoptRef(m_ptr); |
| 79 | 79 m_ptr = nullptr; |
| 80 RefPtr& operator=(const RefPtr&); | 80 return tmp; |
| 81 RefPtr& operator=(T*); | 81 } |
| 82 RefPtr& operator=(const PassRefPtr<T>&); | 82 |
| 83 RefPtr& operator=(std::nullptr_t) { clear(); return *this; } | 83 T& operator*() const { return *m_ptr; } |
| 84 | 84 ALWAYS_INLINE T* operator->() const { return m_ptr; } |
| 85 template <typename U> RefPtr<T>& operator=(const RefPtr<U>&); | 85 |
| 86 template <typename U> RefPtr<T>& operator=(const PassRefPtr<U>&); | 86 bool operator!() const { return !m_ptr; } |
| 87 template <typename U> RefPtr<T>& operator=(const RawPtr<U>&); | 87 |
| 88 | 88 // This conversion operator allows implicit conversion to bool but not to |
| 89 void swap(RefPtr&); | 89 // other integer types. |
| 90 | 90 typedef T*(RefPtr::*UnspecifiedBoolType); |
| 91 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } | 91 operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; } |
| 92 | 92 |
| 93 private: | 93 RefPtr& operator=(const RefPtr&); |
| 94 T* m_ptr; | 94 RefPtr& operator=(T*); |
| 95 RefPtr& operator=(const PassRefPtr<T>&); |
| 96 RefPtr& operator=(std::nullptr_t) { |
| 97 clear(); |
| 98 return *this; |
| 99 } |
| 100 |
| 101 template <typename U> |
| 102 RefPtr<T>& operator=(const RefPtr<U>&); |
| 103 template <typename U> |
| 104 RefPtr<T>& operator=(const PassRefPtr<U>&); |
| 105 template <typename U> |
| 106 RefPtr<T>& operator=(const RawPtr<U>&); |
| 107 |
| 108 void swap(RefPtr&); |
| 109 |
| 110 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } |
| 111 |
| 112 private: |
| 113 T* m_ptr; |
| 95 }; | 114 }; |
| 96 | 115 |
| 97 template <typename T> | 116 template <typename T> |
| 98 template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o, EnsurePtr
ConvertibleArgDefn(U, T)) | 117 template <typename U> |
| 99 : m_ptr(o.leakRef()) | 118 inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o, EnsurePtrConvertibleArgDefn(U,
T)) |
| 100 { | 119 : m_ptr(o.leakRef()) { |
| 101 } | 120 } |
| 102 | 121 |
| 103 template <typename T> inline void RefPtr<T>::clear() | 122 template <typename T> |
| 104 { | 123 inline void RefPtr<T>::clear() { |
| 105 T* ptr = m_ptr; | 124 T* ptr = m_ptr; |
| 106 m_ptr = nullptr; | 125 m_ptr = nullptr; |
| 107 derefIfNotNull(ptr); | 126 derefIfNotNull(ptr); |
| 108 } | 127 } |
| 109 | 128 |
| 110 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr& o) | 129 template <typename T> |
| 111 { | 130 inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr& o) { |
| 112 RefPtr ptr = o; | 131 RefPtr ptr = o; |
| 113 swap(ptr); | 132 swap(ptr); |
| 114 return *this; | 133 return *this; |
| 115 } | 134 } |
| 116 | 135 |
| 117 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(RefPtr&& o) | 136 template <typename T> |
| 118 { | 137 inline RefPtr<T>& RefPtr<T>::operator=(RefPtr&& o) { |
| 119 // FIXME: Instead of explicitly casting to RefPtr&& here, we should use | 138 // FIXME: Instead of explicitly casting to RefPtr&& here, we should use |
| 120 // std::move, but that requires us to have a standard library that supports | 139 // std::move, but that requires us to have a standard library that supports |
| 121 // move semantics. | 140 // move semantics. |
| 122 RefPtr ptr = static_cast<RefPtr&&>(o); | 141 RefPtr ptr = static_cast<RefPtr&&>(o); |
| 123 swap(ptr); | 142 swap(ptr); |
| 124 return *this; | 143 return *this; |
| 125 } | 144 } |
| 126 | 145 |
| 127 template <typename T> | 146 template <typename T> |
| 128 template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o) | 147 template <typename U> |
| 129 { | 148 inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o) { |
| 130 RefPtr ptr = o; | 149 RefPtr ptr = o; |
| 131 swap(ptr); | 150 swap(ptr); |
| 132 return *this; | 151 return *this; |
| 133 } | 152 } |
| 134 | 153 |
| 135 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr) | 154 template <typename T> |
| 136 { | 155 inline RefPtr<T>& RefPtr<T>::operator=(T* optr) { |
| 137 RefPtr ptr = optr; | 156 RefPtr ptr = optr; |
| 138 swap(ptr); | 157 swap(ptr); |
| 139 return *this; | 158 return *this; |
| 140 } | 159 } |
| 141 | 160 |
| 142 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>
& o) | 161 template <typename T> |
| 143 { | 162 inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o) { |
| 144 RefPtr ptr = o; | 163 RefPtr ptr = o; |
| 145 swap(ptr); | 164 swap(ptr); |
| 146 return *this; | 165 return *this; |
| 147 } | 166 } |
| 148 | 167 |
| 149 template <typename T> | 168 template <typename T> |
| 150 template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>
& o) | 169 template <typename U> |
| 151 { | 170 inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o) { |
| 152 RefPtr ptr = o; | 171 RefPtr ptr = o; |
| 153 swap(ptr); | 172 swap(ptr); |
| 154 return *this; | 173 return *this; |
| 155 } | 174 } |
| 156 | 175 |
| 157 template <typename T> | 176 template <typename T> |
| 158 template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RawPtr<U>& o) | 177 template <typename U> |
| 159 { | 178 inline RefPtr<T>& RefPtr<T>::operator=(const RawPtr<U>& o) { |
| 160 RefPtr ptr = o.get(); | 179 RefPtr ptr = o.get(); |
| 161 swap(ptr); | 180 swap(ptr); |
| 162 return *this; | 181 return *this; |
| 163 } | 182 } |
| 164 | 183 |
| 165 template <class T> inline void RefPtr<T>::swap(RefPtr& o) | 184 template <class T> |
| 166 { | 185 inline void RefPtr<T>::swap(RefPtr& o) { |
| 167 std::swap(m_ptr, o.m_ptr); | 186 std::swap(m_ptr, o.m_ptr); |
| 168 } | 187 } |
| 169 | 188 |
| 170 template <class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b) | 189 template <class T> |
| 171 { | 190 inline void swap(RefPtr<T>& a, RefPtr<T>& b) { |
| 172 a.swap(b); | 191 a.swap(b); |
| 173 } | 192 } |
| 174 | 193 |
| 175 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, con
st RefPtr<U>& b) | 194 template <typename T, typename U> |
| 176 { | 195 inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) { |
| 177 return a.get() == b.get(); | 196 return a.get() == b.get(); |
| 178 } | 197 } |
| 179 | 198 |
| 180 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, U*
b) | 199 template <typename T, typename U> |
| 181 { | 200 inline bool operator==(const RefPtr<T>& a, U* b) { |
| 182 return a.get() == b; | 201 return a.get() == b; |
| 183 } | 202 } |
| 184 | 203 |
| 185 template <typename T, typename U> inline bool operator==(T* a, const RefPtr<U>&
b) | 204 template <typename T, typename U> |
| 186 { | 205 inline bool operator==(T* a, const RefPtr<U>& b) { |
| 187 return a == b.get(); | 206 return a == b.get(); |
| 188 } | 207 } |
| 189 | 208 |
| 190 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, con
st RefPtr<U>& b) | 209 template <typename T, typename U> |
| 191 { | 210 inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) { |
| 192 return a.get() != b.get(); | 211 return a.get() != b.get(); |
| 193 } | 212 } |
| 194 | 213 |
| 195 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U*
b) | 214 template <typename T, typename U> |
| 196 { | 215 inline bool operator!=(const RefPtr<T>& a, U* b) { |
| 197 return a.get() != b; | 216 return a.get() != b; |
| 198 } | 217 } |
| 199 | 218 |
| 200 template <typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>&
b) | 219 template <typename T, typename U> |
| 201 { | 220 inline bool operator!=(T* a, const RefPtr<U>& b) { |
| 202 return a != b.get(); | 221 return a != b.get(); |
| 203 } | 222 } |
| 204 | 223 |
| 205 template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const Ref
Ptr<U>& p) | 224 template <typename T, typename U> |
| 206 { | 225 inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p) { |
| 207 return RefPtr<T>(static_cast<T*>(p.get())); | 226 return RefPtr<T>(static_cast<T*>(p.get())); |
| 208 } | 227 } |
| 209 | 228 |
| 210 template <typename T> inline T* getPtr(const RefPtr<T>& p) | 229 template <typename T> |
| 211 { | 230 inline T* getPtr(const RefPtr<T>& p) { |
| 212 return p.get(); | 231 return p.get(); |
| 213 } | 232 } |
| 214 | 233 |
| 215 template <typename T> class RefPtrValuePeeker { | 234 template <typename T> |
| 216 public: | 235 class RefPtrValuePeeker { |
| 217 ALWAYS_INLINE RefPtrValuePeeker(T* p): m_ptr(p) {} | 236 public: |
| 218 ALWAYS_INLINE RefPtrValuePeeker(std::nullptr_t): m_ptr(nullptr) {} | 237 ALWAYS_INLINE RefPtrValuePeeker(T* p) |
| 219 template <typename U> RefPtrValuePeeker(const RefPtr<U>& p): m_ptr(p.get())
{} | 238 : m_ptr(p) {} |
| 220 template <typename U> RefPtrValuePeeker(const PassRefPtr<U>& p): m_ptr(p.get
()) {} | 239 ALWAYS_INLINE RefPtrValuePeeker(std::nullptr_t) |
| 221 | 240 : m_ptr(nullptr) {} |
| 222 ALWAYS_INLINE operator T*() const { return m_ptr; } | 241 template <typename U> |
| 223 private: | 242 RefPtrValuePeeker(const RefPtr<U>& p) |
| 224 T* m_ptr; | 243 : m_ptr(p.get()) {} |
| 244 template <typename U> |
| 245 RefPtrValuePeeker(const PassRefPtr<U>& p) |
| 246 : m_ptr(p.get()) {} |
| 247 |
| 248 ALWAYS_INLINE operator T*() const { return m_ptr; } |
| 249 |
| 250 private: |
| 251 T* m_ptr; |
| 225 }; | 252 }; |
| 226 | 253 |
| 227 } // namespace WTF | 254 } // namespace WTF |
| 228 | 255 |
| 229 using WTF::RefPtr; | 256 using WTF::RefPtr; |
| 230 using WTF::static_pointer_cast; | 257 using WTF::static_pointer_cast; |
| 231 | 258 |
| 232 #endif // WTF_RefPtr_h | 259 #endif // WTF_RefPtr_h |
| OLD | NEW |