| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reser
ved. | 2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reser
ved. |
| 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 |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 * Library General Public License for more details. | 12 * Library General Public License for more details. |
| 13 * | 13 * |
| 14 * You should have received a copy of the GNU Library General Public License | 14 * You should have received a copy of the GNU Library General Public License |
| 15 * along with this library; see the file COPYING.LIB. If not, write to | 15 * along with this library; see the file COPYING.LIB. If not, write to |
| 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 17 * Boston, MA 02110-1301, USA. | 17 * Boston, MA 02110-1301, USA. |
| 18 * | 18 * |
| 19 */ | 19 */ |
| 20 | 20 |
| 21 #ifndef WTF_PassRefPtr_h | 21 #ifndef WTF_PassRefPtr_h |
| 22 #define WTF_PassRefPtr_h | 22 #define WTF_PassRefPtr_h |
| 23 | 23 |
| 24 #include "wtf/Assertions.h" | 24 #include "wtf/Assertions.h" |
| 25 #include "wtf/RawPtr.h" | 25 #include "wtf/RawPtr.h" |
| 26 #include "wtf/TypeTraits.h" | 26 #include "wtf/TypeTraits.h" |
| 27 | 27 |
| 28 namespace WTF { | 28 namespace WTF { |
| 29 | 29 |
| 30 template <typename T> class RefPtr; | 30 template <typename T> |
| 31 template <typename T> class PassRefPtr; | 31 class RefPtr; |
| 32 template <typename T> PassRefPtr<T> adoptRef(T*); | 32 template <typename T> |
| 33 class PassRefPtr; |
| 34 template <typename T> |
| 35 PassRefPtr<T> adoptRef(T*); |
| 33 | 36 |
| 34 inline void adopted(const void*) {} | 37 inline void adopted(const void*) {} |
| 35 | 38 |
| 36 // requireAdoption() is not overloaded for WTF::RefCounted, which has a built-in | 39 // requireAdoption() is not overloaded for WTF::RefCounted, which has a built-in |
| 37 // assumption that adoption is required. requireAdoption() is for bootstrapping | 40 // assumption that adoption is required. requireAdoption() is for bootstrapping |
| 38 // alternate reference count classes that are compatible with ReftPtr/PassRefPtr | 41 // alternate reference count classes that are compatible with ReftPtr/PassRefPtr |
| 39 // but cannot have adoption checks enabled by default, such as skia's | 42 // but cannot have adoption checks enabled by default, such as skia's |
| 40 // SkRefCnt. The purpose of requireAdoption() is to enable adoption checks only | 43 // SkRefCnt. The purpose of requireAdoption() is to enable adoption checks only |
| 41 // once it is known that the object will be used with RefPtr/PassRefPtr. | 44 // once it is known that the object will be used with RefPtr/PassRefPtr. |
| 42 inline void requireAdoption(const void*) {} | 45 inline void requireAdoption(const void*) {} |
| 43 | 46 |
| 44 template <typename T> ALWAYS_INLINE void refIfNotNull(T* ptr) | 47 template <typename T> |
| 45 { | 48 ALWAYS_INLINE void refIfNotNull(T* ptr) { |
| 46 if (LIKELY(ptr != 0)) { | 49 if (LIKELY(ptr != 0)) { |
| 47 requireAdoption(ptr); | 50 requireAdoption(ptr); |
| 48 ptr->ref(); | 51 ptr->ref(); |
| 49 } | 52 } |
| 50 } | 53 } |
| 51 | 54 |
| 52 template <typename T> ALWAYS_INLINE void derefIfNotNull(T* ptr) | 55 template <typename T> |
| 53 { | 56 ALWAYS_INLINE void derefIfNotNull(T* ptr) { |
| 54 if (LIKELY(ptr != 0)) | 57 if (LIKELY(ptr != 0)) |
| 55 ptr->deref(); | 58 ptr->deref(); |
| 56 } | 59 } |
| 57 | 60 |
| 58 template <typename T> class PassRefPtr { | 61 template <typename T> |
| 59 public: | 62 class PassRefPtr { |
| 60 PassRefPtr() : m_ptr(nullptr) {} | 63 public: |
| 61 PassRefPtr(std::nullptr_t) : m_ptr(nullptr) {} | 64 PassRefPtr() |
| 62 PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } | 65 : m_ptr(nullptr) {} |
| 63 template <typename U> PassRefPtr(const RawPtr<U>& ptr, EnsurePtrConvertibleA
rgDecl(U, T)) : m_ptr(ptr.get()) { refIfNotNull(m_ptr); } | 66 PassRefPtr(std::nullptr_t) |
| 64 explicit PassRefPtr(T& ptr) : m_ptr(&ptr) { m_ptr->ref(); } | 67 : m_ptr(nullptr) {} |
| 65 // It somewhat breaks the type system to allow transfer of ownership out of | 68 PassRefPtr(T* ptr) |
| 66 // a const PassRefPtr. However, it makes it much easier to work with | 69 : m_ptr(ptr) { refIfNotNull(ptr); } |
| 67 // PassRefPtr temporaries, and we don't have a need to use real const | 70 template <typename U> |
| 68 // PassRefPtrs anyway. | 71 PassRefPtr(const RawPtr<U>& ptr, EnsurePtrConvertibleArgDecl(U, T)) |
| 69 PassRefPtr(const PassRefPtr& o) : m_ptr(o.leakRef()) {} | 72 : m_ptr(ptr.get()) { refIfNotNull(m_ptr); } |
| 70 template <typename U> PassRefPtr(const PassRefPtr<U>& o, EnsurePtrConvertibl
eArgDecl(U, T)) : m_ptr(o.leakRef()) {} | 73 explicit PassRefPtr(T& ptr) |
| 74 : m_ptr(&ptr) { m_ptr->ref(); } |
| 75 // It somewhat breaks the type system to allow transfer of ownership out of |
| 76 // a const PassRefPtr. However, it makes it much easier to work with |
| 77 // PassRefPtr temporaries, and we don't have a need to use real const |
| 78 // PassRefPtrs anyway. |
| 79 PassRefPtr(const PassRefPtr& o) |
| 80 : m_ptr(o.leakRef()) {} |
| 81 template <typename U> |
| 82 PassRefPtr(const PassRefPtr<U>& o, EnsurePtrConvertibleArgDecl(U, T)) |
| 83 : m_ptr(o.leakRef()) {} |
| 71 | 84 |
| 72 ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); } | 85 ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); } |
| 73 | 86 |
| 74 template <typename U> PassRefPtr(const RefPtr<U>&, EnsurePtrConvertibleArgDe
cl(U, T)); | 87 template <typename U> |
| 88 PassRefPtr(const RefPtr<U>&, EnsurePtrConvertibleArgDecl(U, T)); |
| 75 | 89 |
| 76 T* get() const { return m_ptr; } | 90 T* get() const { return m_ptr; } |
| 77 | 91 |
| 78 T* leakRef() const WARN_UNUSED_RETURN; | 92 T* leakRef() const WARN_UNUSED_RETURN; |
| 79 | 93 |
| 80 T& operator*() const { return *m_ptr; } | 94 T& operator*() const { return *m_ptr; } |
| 81 T* operator->() const { return m_ptr; } | 95 T* operator->() const { return m_ptr; } |
| 82 | 96 |
| 83 bool operator!() const { return !m_ptr; } | 97 bool operator!() const { return !m_ptr; } |
| 84 | 98 |
| 85 // This conversion operator allows implicit conversion to bool but not to | 99 // This conversion operator allows implicit conversion to bool but not to |
| 86 // other integer types. | 100 // other integer types. |
| 87 typedef T* (PassRefPtr::*UnspecifiedBoolType); | 101 typedef T*(PassRefPtr::*UnspecifiedBoolType); |
| 88 operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0
; } | 102 operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0;
} |
| 89 | 103 |
| 90 friend PassRefPtr adoptRef<T>(T*); | 104 friend PassRefPtr adoptRef<T>(T*); |
| 91 | 105 |
| 92 private: | 106 private: |
| 93 enum AdoptRefTag { AdoptRef }; | 107 enum AdoptRefTag { AdoptRef }; |
| 94 PassRefPtr(T* ptr, AdoptRefTag) : m_ptr(ptr) {} | 108 PassRefPtr(T* ptr, AdoptRefTag) |
| 109 : m_ptr(ptr) {} |
| 95 | 110 |
| 96 PassRefPtr& operator=(const PassRefPtr&) | 111 PassRefPtr& operator=(const PassRefPtr&) { |
| 97 { | 112 static_assert(!sizeof(T*), "PassRefPtr should never be assigned to"); |
| 98 static_assert(!sizeof(T*), "PassRefPtr should never be assigned to"); | 113 return *this; |
| 99 return *this; | 114 } |
| 100 } | |
| 101 | 115 |
| 102 mutable T* m_ptr; | 116 mutable T* m_ptr; |
| 103 }; | 117 }; |
| 104 | 118 |
| 105 template <typename T> | 119 template <typename T> |
| 106 template <typename U> inline PassRefPtr<T>::PassRefPtr(const RefPtr<U>& o, Ensur
ePtrConvertibleArgDefn(U, T)) | 120 template <typename U> |
| 107 : m_ptr(o.get()) | 121 inline PassRefPtr<T>::PassRefPtr(const RefPtr<U>& o, EnsurePtrConvertibleArgDefn
(U, T)) |
| 108 { | 122 : m_ptr(o.get()) { |
| 109 T* ptr = m_ptr; | 123 T* ptr = m_ptr; |
| 110 refIfNotNull(ptr); | 124 refIfNotNull(ptr); |
| 111 } | 125 } |
| 112 | 126 |
| 113 template <typename T> inline T* PassRefPtr<T>::leakRef() const | 127 template <typename T> |
| 114 { | 128 inline T* PassRefPtr<T>::leakRef() const { |
| 115 T* ptr = m_ptr; | 129 T* ptr = m_ptr; |
| 116 m_ptr = nullptr; | 130 m_ptr = nullptr; |
| 117 return ptr; | 131 return ptr; |
| 118 } | 132 } |
| 119 | 133 |
| 120 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a,
const PassRefPtr<U>& b) | 134 template <typename T, typename U> |
| 121 { | 135 inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<U>& b) { |
| 122 return a.get() == b.get(); | 136 return a.get() == b.get(); |
| 123 } | 137 } |
| 124 | 138 |
| 125 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a,
const RefPtr<U>& b) | 139 template <typename T, typename U> |
| 126 { | 140 inline bool operator==(const PassRefPtr<T>& a, const RefPtr<U>& b) { |
| 127 return a.get() == b.get(); | 141 return a.get() == b.get(); |
| 128 } | 142 } |
| 129 | 143 |
| 130 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, con
st PassRefPtr<U>& b) | 144 template <typename T, typename U> |
| 131 { | 145 inline bool operator==(const RefPtr<T>& a, const PassRefPtr<U>& b) { |
| 132 return a.get() == b.get(); | 146 return a.get() == b.get(); |
| 133 } | 147 } |
| 134 | 148 |
| 135 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a,
U* b) | 149 template <typename T, typename U> |
| 136 { | 150 inline bool operator==(const PassRefPtr<T>& a, U* b) { |
| 137 return a.get() == b; | 151 return a.get() == b; |
| 138 } | 152 } |
| 139 | 153 |
| 140 template <typename T, typename U> inline bool operator==(T* a, const PassRefPtr<
U>& b) | 154 template <typename T, typename U> |
| 141 { | 155 inline bool operator==(T* a, const PassRefPtr<U>& b) { |
| 142 return a == b.get(); | 156 return a == b.get(); |
| 143 } | 157 } |
| 144 | 158 |
| 145 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a,
const RawPtr<U>& b) | 159 template <typename T, typename U> |
| 146 { | 160 inline bool operator==(const PassRefPtr<T>& a, const RawPtr<U>& b) { |
| 147 return a.get() == b.get(); | 161 return a.get() == b.get(); |
| 148 } | 162 } |
| 149 | 163 |
| 150 template <typename T, typename U> inline bool operator==(const RawPtr<T>& a, con
st PassRefPtr<U>& b) | 164 template <typename T, typename U> |
| 151 { | 165 inline bool operator==(const RawPtr<T>& a, const PassRefPtr<U>& b) { |
| 152 return a.get() == b.get(); | 166 return a.get() == b.get(); |
| 153 } | 167 } |
| 154 | 168 |
| 155 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a,
const PassRefPtr<U>& b) | 169 template <typename T, typename U> |
| 156 { | 170 inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<U>& b) { |
| 157 return a.get() != b.get(); | 171 return a.get() != b.get(); |
| 158 } | 172 } |
| 159 | 173 |
| 160 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a,
const RefPtr<U>& b) | 174 template <typename T, typename U> |
| 161 { | 175 inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<U>& b) { |
| 162 return a.get() != b.get(); | 176 return a.get() != b.get(); |
| 163 } | 177 } |
| 164 | 178 |
| 165 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, con
st PassRefPtr<U>& b) | 179 template <typename T, typename U> |
| 166 { | 180 inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b) { |
| 167 return a.get() != b.get(); | 181 return a.get() != b.get(); |
| 168 } | 182 } |
| 169 | 183 |
| 170 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a,
U* b) | 184 template <typename T, typename U> |
| 171 { | 185 inline bool operator!=(const PassRefPtr<T>& a, U* b) { |
| 172 return a.get() != b; | 186 return a.get() != b; |
| 173 } | 187 } |
| 174 | 188 |
| 175 template <typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<
U>& b) | 189 template <typename T, typename U> |
| 176 { | 190 inline bool operator!=(T* a, const PassRefPtr<U>& b) { |
| 177 return a != b.get(); | 191 return a != b.get(); |
| 178 } | 192 } |
| 179 | 193 |
| 180 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a,
const RawPtr<U>& b) | 194 template <typename T, typename U> |
| 181 { | 195 inline bool operator!=(const PassRefPtr<T>& a, const RawPtr<U>& b) { |
| 182 return a.get() != b.get(); | 196 return a.get() != b.get(); |
| 183 } | 197 } |
| 184 | 198 |
| 185 template <typename T, typename U> inline bool operator!=(const RawPtr<T>& a, con
st PassRefPtr<U>& b) | 199 template <typename T, typename U> |
| 186 { | 200 inline bool operator!=(const RawPtr<T>& a, const PassRefPtr<U>& b) { |
| 187 return a.get() != b.get(); | 201 return a.get() != b.get(); |
| 188 } | 202 } |
| 189 | 203 |
| 190 template <typename T> PassRefPtr<T> adoptRef(T* p) | 204 template <typename T> |
| 191 { | 205 PassRefPtr<T> adoptRef(T* p) { |
| 192 adopted(p); | 206 adopted(p); |
| 193 return PassRefPtr<T>(p, PassRefPtr<T>::AdoptRef); | 207 return PassRefPtr<T>(p, PassRefPtr<T>::AdoptRef); |
| 194 } | 208 } |
| 195 | 209 |
| 196 template <typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const
PassRefPtr<U>& p) | 210 template <typename T, typename U> |
| 197 { | 211 inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p) { |
| 198 return adoptRef(static_cast<T*>(p.leakRef())); | 212 return adoptRef(static_cast<T*>(p.leakRef())); |
| 199 } | 213 } |
| 200 | 214 |
| 201 template <typename T> inline T* getPtr(const PassRefPtr<T>& p) | 215 template <typename T> |
| 202 { | 216 inline T* getPtr(const PassRefPtr<T>& p) { |
| 203 return p.get(); | 217 return p.get(); |
| 204 } | 218 } |
| 205 | 219 |
| 206 } // namespace WTF | 220 } // namespace WTF |
| 207 | 221 |
| 208 using WTF::PassRefPtr; | 222 using WTF::PassRefPtr; |
| 209 using WTF::adoptRef; | 223 using WTF::adoptRef; |
| 210 using WTF::static_pointer_cast; | 224 using WTF::static_pointer_cast; |
| 211 | 225 |
| 212 #endif // WTF_PassRefPtr_h | 226 #endif // WTF_PassRefPtr_h |
| OLD | NEW |