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