| 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 14 matching lines...) Expand all Loading... |
| 25 | 25 |
| 26 #include "wtf/Allocator.h" | 26 #include "wtf/Allocator.h" |
| 27 #include "wtf/HashTableDeletedValueType.h" | 27 #include "wtf/HashTableDeletedValueType.h" |
| 28 #include "wtf/PassRefPtr.h" | 28 #include "wtf/PassRefPtr.h" |
| 29 #include "wtf/RawPtr.h" | 29 #include "wtf/RawPtr.h" |
| 30 #include <algorithm> | 30 #include <algorithm> |
| 31 #include <utility> | 31 #include <utility> |
| 32 | 32 |
| 33 namespace WTF { | 33 namespace WTF { |
| 34 | 34 |
| 35 template <typename T> class PassRefPtr; | 35 template <typename T> |
| 36 template <typename T> class RefPtrValuePeeker; | 36 class PassRefPtr; |
| 37 template <typename T> |
| 38 class RefPtrValuePeeker; |
| 37 | 39 |
| 38 template <typename T> class RefPtr { | 40 template <typename T> |
| 39 USING_FAST_MALLOC(RefPtr); | 41 class RefPtr { |
| 40 public: | 42 USING_FAST_MALLOC(RefPtr); |
| 41 ALWAYS_INLINE RefPtr() : m_ptr(nullptr) {} | |
| 42 ALWAYS_INLINE RefPtr(std::nullptr_t) : m_ptr(nullptr) {} | |
| 43 ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } | |
| 44 template <typename U> RefPtr(const RawPtr<U>& ptr, EnsurePtrConvertibleArgDe
cl(U, T)) : m_ptr(ptr.get()) { refIfNotNull(m_ptr); } | |
| 45 ALWAYS_INLINE explicit RefPtr(T& ref) : m_ptr(&ref) { m_ptr->ref(); } | |
| 46 ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr)
; } | |
| 47 template <typename U> RefPtr(const RefPtr<U>& o, EnsurePtrConvertibleArgDecl
(U, T)) : m_ptr(o.get()) { refIfNotNull(m_ptr); } | |
| 48 RefPtr(RefPtr&& o) : m_ptr(o.m_ptr) { o.m_ptr = nullptr; } | |
| 49 | 43 |
| 50 // See comments in PassRefPtr.h for an explanation of why this takes a const | 44 public: |
| 51 // reference. | 45 ALWAYS_INLINE RefPtr() : m_ptr(nullptr) {} |
| 52 template <typename U> RefPtr(const PassRefPtr<U>&, EnsurePtrConvertibleArgDe
cl(U, T)); | 46 ALWAYS_INLINE RefPtr(std::nullptr_t) : m_ptr(nullptr) {} |
| 47 ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } |
| 48 template <typename U> |
| 49 RefPtr(const RawPtr<U>& ptr, EnsurePtrConvertibleArgDecl(U, T)) |
| 50 : m_ptr(ptr.get()) { |
| 51 refIfNotNull(m_ptr); |
| 52 } |
| 53 ALWAYS_INLINE explicit RefPtr(T& ref) : m_ptr(&ref) { m_ptr->ref(); } |
| 54 ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { |
| 55 refIfNotNull(m_ptr); |
| 56 } |
| 57 template <typename U> |
| 58 RefPtr(const RefPtr<U>& o, EnsurePtrConvertibleArgDecl(U, T)) |
| 59 : m_ptr(o.get()) { |
| 60 refIfNotNull(m_ptr); |
| 61 } |
| 62 RefPtr(RefPtr&& o) : m_ptr(o.m_ptr) { o.m_ptr = nullptr; } |
| 53 | 63 |
| 54 // Hash table deleted values, which are only constructed and never copied or | 64 // See comments in PassRefPtr.h for an explanation of why this takes a const |
| 55 // destroyed. | 65 // reference. |
| 56 RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) {} | 66 template <typename U> |
| 57 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue
(); } | 67 RefPtr(const PassRefPtr<U>&, EnsurePtrConvertibleArgDecl(U, T)); |
| 58 | 68 |
| 59 ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); } | 69 // Hash table deleted values, which are only constructed and never copied or |
| 70 // destroyed. |
| 71 RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) {} |
| 72 bool isHashTableDeletedValue() const { |
| 73 return m_ptr == hashTableDeletedValue(); |
| 74 } |
| 60 | 75 |
| 61 ALWAYS_INLINE T* get() const { return m_ptr; } | 76 ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); } |
| 62 | 77 |
| 63 void clear(); | 78 ALWAYS_INLINE T* get() const { return m_ptr; } |
| 64 PassRefPtr<T> release() | |
| 65 { | |
| 66 PassRefPtr<T> tmp = adoptRef(m_ptr); | |
| 67 m_ptr = nullptr; | |
| 68 return tmp; | |
| 69 } | |
| 70 | 79 |
| 71 T& operator*() const { return *m_ptr; } | 80 void clear(); |
| 72 ALWAYS_INLINE T* operator->() const { return m_ptr; } | 81 PassRefPtr<T> release() { |
| 82 PassRefPtr<T> tmp = adoptRef(m_ptr); |
| 83 m_ptr = nullptr; |
| 84 return tmp; |
| 85 } |
| 73 | 86 |
| 74 bool operator!() const { return !m_ptr; } | 87 T& operator*() const { return *m_ptr; } |
| 88 ALWAYS_INLINE T* operator->() const { return m_ptr; } |
| 75 | 89 |
| 76 // This conversion operator allows implicit conversion to bool but not to | 90 bool operator!() const { return !m_ptr; } |
| 77 // other integer types. | |
| 78 typedef T* (RefPtr::*UnspecifiedBoolType); | |
| 79 operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; } | |
| 80 | 91 |
| 81 RefPtr& operator=(RefPtr o) { swap(o); return *this; } | 92 // This conversion operator allows implicit conversion to bool but not to |
| 82 RefPtr& operator=(std::nullptr_t) { clear(); return *this; } | 93 // other integer types. |
| 83 // This is required by HashMap<RefPtr>>. | 94 typedef T*(RefPtr::*UnspecifiedBoolType); |
| 84 template <typename U> RefPtr& operator=(RefPtrValuePeeker<U>); | 95 operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; } |
| 85 | 96 |
| 86 void swap(RefPtr&); | 97 RefPtr& operator=(RefPtr o) { |
| 98 swap(o); |
| 99 return *this; |
| 100 } |
| 101 RefPtr& operator=(std::nullptr_t) { |
| 102 clear(); |
| 103 return *this; |
| 104 } |
| 105 // This is required by HashMap<RefPtr>>. |
| 106 template <typename U> |
| 107 RefPtr& operator=(RefPtrValuePeeker<U>); |
| 87 | 108 |
| 88 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } | 109 void swap(RefPtr&); |
| 89 | 110 |
| 90 private: | 111 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } |
| 91 T* m_ptr; | 112 |
| 113 private: |
| 114 T* m_ptr; |
| 92 }; | 115 }; |
| 93 | 116 |
| 94 template <typename T> | 117 template <typename T> |
| 95 template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o, EnsurePtr
ConvertibleArgDefn(U, T)) | 118 template <typename U> |
| 96 : m_ptr(o.leakRef()) | 119 inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o, |
| 97 { | 120 EnsurePtrConvertibleArgDefn(U, T)) |
| 98 } | 121 : m_ptr(o.leakRef()) {} |
| 99 | 122 |
| 100 template <typename T> inline void RefPtr<T>::clear() | 123 template <typename T> |
| 101 { | 124 inline void RefPtr<T>::clear() { |
| 102 T* ptr = m_ptr; | 125 T* ptr = m_ptr; |
| 103 m_ptr = nullptr; | 126 m_ptr = nullptr; |
| 104 derefIfNotNull(ptr); | 127 derefIfNotNull(ptr); |
| 105 } | 128 } |
| 106 | 129 |
| 107 template <typename T> | 130 template <typename T> |
| 108 template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(RefPtrValuePeeker<U
> optr) | 131 template <typename U> |
| 109 { | 132 inline RefPtr<T>& RefPtr<T>::operator=(RefPtrValuePeeker<U> optr) { |
| 110 RefPtr ptr = static_cast<U*>(optr); | 133 RefPtr ptr = static_cast<U*>(optr); |
| 111 swap(ptr); | 134 swap(ptr); |
| 112 return *this; | 135 return *this; |
| 113 } | 136 } |
| 114 | 137 |
| 115 template <class T> inline void RefPtr<T>::swap(RefPtr& o) | 138 template <class T> |
| 116 { | 139 inline void RefPtr<T>::swap(RefPtr& o) { |
| 117 std::swap(m_ptr, o.m_ptr); | 140 std::swap(m_ptr, o.m_ptr); |
| 118 } | 141 } |
| 119 | 142 |
| 120 template <class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b) | 143 template <class T> |
| 121 { | 144 inline void swap(RefPtr<T>& a, RefPtr<T>& b) { |
| 122 a.swap(b); | 145 a.swap(b); |
| 123 } | 146 } |
| 124 | 147 |
| 125 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, con
st RefPtr<U>& b) | 148 template <typename T, typename U> |
| 126 { | 149 inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) { |
| 127 return a.get() == b.get(); | 150 return a.get() == b.get(); |
| 128 } | 151 } |
| 129 | 152 |
| 130 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, U*
b) | 153 template <typename T, typename U> |
| 131 { | 154 inline bool operator==(const RefPtr<T>& a, U* b) { |
| 132 return a.get() == b; | 155 return a.get() == b; |
| 133 } | 156 } |
| 134 | 157 |
| 135 template <typename T, typename U> inline bool operator==(T* a, const RefPtr<U>&
b) | 158 template <typename T, typename U> |
| 136 { | 159 inline bool operator==(T* a, const RefPtr<U>& b) { |
| 137 return a == b.get(); | 160 return a == b.get(); |
| 138 } | 161 } |
| 139 | 162 |
| 140 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, con
st RefPtr<U>& b) | 163 template <typename T, typename U> |
| 141 { | 164 inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) { |
| 142 return a.get() != b.get(); | 165 return a.get() != b.get(); |
| 143 } | 166 } |
| 144 | 167 |
| 145 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U*
b) | 168 template <typename T, typename U> |
| 146 { | 169 inline bool operator!=(const RefPtr<T>& a, U* b) { |
| 147 return a.get() != b; | 170 return a.get() != b; |
| 148 } | 171 } |
| 149 | 172 |
| 150 template <typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>&
b) | 173 template <typename T, typename U> |
| 151 { | 174 inline bool operator!=(T* a, const RefPtr<U>& b) { |
| 152 return a != b.get(); | 175 return a != b.get(); |
| 153 } | 176 } |
| 154 | 177 |
| 155 template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const Ref
Ptr<U>& p) | 178 template <typename T, typename U> |
| 156 { | 179 inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p) { |
| 157 return RefPtr<T>(static_cast<T*>(p.get())); | 180 return RefPtr<T>(static_cast<T*>(p.get())); |
| 158 } | 181 } |
| 159 | 182 |
| 160 template <typename T> inline T* getPtr(const RefPtr<T>& p) | 183 template <typename T> |
| 161 { | 184 inline T* getPtr(const RefPtr<T>& p) { |
| 162 return p.get(); | 185 return p.get(); |
| 163 } | 186 } |
| 164 | 187 |
| 165 template <typename T> class RefPtrValuePeeker { | 188 template <typename T> |
| 166 DISALLOW_NEW(); | 189 class RefPtrValuePeeker { |
| 167 public: | 190 DISALLOW_NEW(); |
| 168 ALWAYS_INLINE RefPtrValuePeeker(T* p): m_ptr(p) {} | |
| 169 ALWAYS_INLINE RefPtrValuePeeker(std::nullptr_t): m_ptr(nullptr) {} | |
| 170 template <typename U> RefPtrValuePeeker(const RefPtr<U>& p): m_ptr(p.get())
{} | |
| 171 template <typename U> RefPtrValuePeeker(const PassRefPtr<U>& p): m_ptr(p.get
()) {} | |
| 172 | 191 |
| 173 ALWAYS_INLINE operator T*() const { return m_ptr; } | 192 public: |
| 174 private: | 193 ALWAYS_INLINE RefPtrValuePeeker(T* p) : m_ptr(p) {} |
| 175 T* m_ptr; | 194 ALWAYS_INLINE RefPtrValuePeeker(std::nullptr_t) : m_ptr(nullptr) {} |
| 195 template <typename U> |
| 196 RefPtrValuePeeker(const RefPtr<U>& p) : m_ptr(p.get()) {} |
| 197 template <typename U> |
| 198 RefPtrValuePeeker(const PassRefPtr<U>& p) : m_ptr(p.get()) {} |
| 199 |
| 200 ALWAYS_INLINE operator T*() const { return m_ptr; } |
| 201 |
| 202 private: |
| 203 T* m_ptr; |
| 176 }; | 204 }; |
| 177 | 205 |
| 178 } // namespace WTF | 206 } // namespace WTF |
| 179 | 207 |
| 180 using WTF::RefPtr; | 208 using WTF::RefPtr; |
| 181 using WTF::static_pointer_cast; | 209 using WTF::static_pointer_cast; |
| 182 | 210 |
| 183 #endif // WTF_RefPtr_h | 211 #endif // WTF_RefPtr_h |
| OLD | NEW |