OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Weak pointers are pointers to an object that do not affect its lifetime, | 5 // Weak pointers are pointers to an object that do not affect its lifetime, |
6 // and which may be invalidated (i.e. reset to nullptr) by the object, or its | 6 // and which may be invalidated (i.e. reset to nullptr) by the object, or its |
7 // owner, at any time, most commonly when the object is about to be deleted. | 7 // owner, at any time, most commonly when the object is about to be deleted. |
8 | 8 |
9 // Weak pointers are useful when an object needs to be accessed safely by one | 9 // Weak pointers are useful when an object needs to be accessed safely by one |
10 // or more objects other than its owner, and those callers can cope with the | 10 // or more objects other than its owner, and those callers can cope with the |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 public: | 193 public: |
194 WeakPtrBase(); | 194 WeakPtrBase(); |
195 ~WeakPtrBase(); | 195 ~WeakPtrBase(); |
196 | 196 |
197 WeakPtrBase(const WeakPtrBase& other) = default; | 197 WeakPtrBase(const WeakPtrBase& other) = default; |
198 WeakPtrBase(WeakPtrBase&& other) = default; | 198 WeakPtrBase(WeakPtrBase&& other) = default; |
199 WeakPtrBase& operator=(const WeakPtrBase& other) = default; | 199 WeakPtrBase& operator=(const WeakPtrBase& other) = default; |
200 WeakPtrBase& operator=(WeakPtrBase&& other) = default; | 200 WeakPtrBase& operator=(WeakPtrBase&& other) = default; |
201 | 201 |
202 protected: | 202 protected: |
203 explicit WeakPtrBase(const WeakReference& ref); | 203 WeakPtrBase(const WeakReference& ref, uintptr_t ptr); |
204 | 204 |
205 WeakReference ref_; | 205 WeakReference ref_; |
| 206 |
| 207 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its |
| 208 // value is undefined (as opposed to nullptr). |
| 209 uintptr_t ptr_; |
206 }; | 210 }; |
207 | 211 |
208 // This class provides a common implementation of common functions that would | 212 // This class provides a common implementation of common functions that would |
209 // otherwise get instantiated separately for each distinct instantiation of | 213 // otherwise get instantiated separately for each distinct instantiation of |
210 // SupportsWeakPtr<>. | 214 // SupportsWeakPtr<>. |
211 class SupportsWeakPtrBase { | 215 class SupportsWeakPtrBase { |
212 public: | 216 public: |
213 // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This | 217 // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This |
214 // conversion will only compile if there is exists a Base which inherits | 218 // conversion will only compile if there is exists a Base which inherits |
215 // from SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper | 219 // from SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper |
216 // function that makes calling this easier. | 220 // function that makes calling this easier. |
217 template<typename Derived> | 221 template<typename Derived> |
218 static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) { | 222 static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) { |
219 static_assert( | 223 static_assert( |
220 std::is_base_of<internal::SupportsWeakPtrBase, Derived>::value, | 224 std::is_base_of<internal::SupportsWeakPtrBase, Derived>::value, |
221 "AsWeakPtr argument must inherit from SupportsWeakPtr"); | 225 "AsWeakPtr argument must inherit from SupportsWeakPtr"); |
222 return AsWeakPtrImpl<Derived>(t, *t); | 226 return AsWeakPtrImpl<Derived>(t, *t); |
223 } | 227 } |
224 | 228 |
225 private: | 229 private: |
226 // This template function uses type inference to find a Base of Derived | 230 // This template function uses type inference to find a Base of Derived |
227 // which is an instance of SupportsWeakPtr<Base>. We can then safely | 231 // which is an instance of SupportsWeakPtr<Base>. We can then safely |
228 // static_cast the Base* to a Derived*. | 232 // static_cast the Base* to a Derived*. |
229 template <typename Derived, typename Base> | 233 template <typename Derived, typename Base> |
230 static WeakPtr<Derived> AsWeakPtrImpl( | 234 static WeakPtr<Derived> AsWeakPtrImpl( |
231 Derived* t, const SupportsWeakPtr<Base>&) { | 235 Derived* t, const SupportsWeakPtr<Base>&) { |
232 WeakPtr<Base> ptr = t->Base::AsWeakPtr(); | 236 WeakPtr<Base> ptr = t->Base::AsWeakPtr(); |
233 return WeakPtr<Derived>(ptr.ref_, static_cast<Derived*>(ptr.ptr_)); | 237 return WeakPtr<Derived>( |
| 238 ptr.ref_, static_cast<Derived*>(reinterpret_cast<Base*>(ptr.ptr_))); |
234 } | 239 } |
235 }; | 240 }; |
236 | 241 |
237 } // namespace internal | 242 } // namespace internal |
238 | 243 |
239 template <typename T> class WeakPtrFactory; | 244 template <typename T> class WeakPtrFactory; |
240 | 245 |
241 // The WeakPtr class holds a weak reference to |T*|. | 246 // The WeakPtr class holds a weak reference to |T*|. |
242 // | 247 // |
243 // This class is designed to be used like a normal pointer. You should always | 248 // This class is designed to be used like a normal pointer. You should always |
244 // null-test an object of this class before using it or invoking a method that | 249 // null-test an object of this class before using it or invoking a method that |
245 // may result in the underlying object being destroyed. | 250 // may result in the underlying object being destroyed. |
246 // | 251 // |
247 // EXAMPLE: | 252 // EXAMPLE: |
248 // | 253 // |
249 // class Foo { ... }; | 254 // class Foo { ... }; |
250 // WeakPtr<Foo> foo; | 255 // WeakPtr<Foo> foo; |
251 // if (foo) | 256 // if (foo) |
252 // foo->method(); | 257 // foo->method(); |
253 // | 258 // |
254 template <typename T> | 259 template <typename T> |
255 class WeakPtr : public internal::WeakPtrBase { | 260 class WeakPtr : public internal::WeakPtrBase { |
256 public: | 261 public: |
257 WeakPtr() : ptr_(nullptr) {} | 262 WeakPtr() {} |
258 | 263 |
259 WeakPtr(std::nullptr_t) : ptr_(nullptr) {} | 264 WeakPtr(std::nullptr_t) {} |
260 | 265 |
261 // Allow conversion from U to T provided U "is a" T. Note that this | 266 // Allow conversion from U to T provided U "is a" T. Note that this |
262 // is separate from the (implicit) copy and move constructors. | 267 // is separate from the (implicit) copy and move constructors. |
263 template <typename U> | 268 template <typename U> |
264 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.ptr_) { | 269 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other) { |
| 270 // Need to cast from U* to T* to do pointer adjustment in case of multiple |
| 271 // inheritance. This also enforces the "U is a T" rule. |
| 272 T* t = reinterpret_cast<U*>(other.ptr_); |
| 273 ptr_ = reinterpret_cast<uintptr_t>(t); |
265 } | 274 } |
266 template <typename U> | 275 template <typename U> |
267 WeakPtr(WeakPtr<U>&& other) | 276 WeakPtr(WeakPtr<U>&& other) : WeakPtrBase(std::move(other)) { |
268 : WeakPtrBase(std::move(other)), ptr_(other.ptr_) {} | 277 // Need to cast from U* to T* to do pointer adjustment in case of multiple |
| 278 // inheritance. This also enforces the "U is a T" rule. |
| 279 T* t = reinterpret_cast<U*>(other.ptr_); |
| 280 ptr_ = reinterpret_cast<uintptr_t>(t); |
| 281 } |
269 | 282 |
270 T* get() const { | 283 T* get() const { |
271 // Intentionally bitwise and; see command on Flag::IsValid(). This provides | 284 // Intentionally bitwise and; see command on Flag::IsValid(). This provides |
272 // a fast way of conditionally retrieving the pointer, and conveniently sets | 285 // a fast way of conditionally retrieving the pointer, and conveniently sets |
273 // EFLAGS for any null-check performed by the caller. | 286 // EFLAGS for any null-check performed by the caller. |
274 return reinterpret_cast<T*>(ref_.is_valid() & | 287 return reinterpret_cast<T*>(ref_.is_valid() & ptr_); |
275 reinterpret_cast<uintptr_t>(ptr_)); | |
276 } | 288 } |
277 | 289 |
278 T& operator*() const { | 290 T& operator*() const { |
279 DCHECK(get() != nullptr); | 291 DCHECK(get() != nullptr); |
280 return *get(); | 292 return *get(); |
281 } | 293 } |
282 T* operator->() const { | 294 T* operator->() const { |
283 DCHECK(get() != nullptr); | 295 DCHECK(get() != nullptr); |
284 return get(); | 296 return get(); |
285 } | 297 } |
286 | 298 |
287 void reset() { | 299 void reset() { |
288 ref_ = internal::WeakReference(); | 300 ref_ = internal::WeakReference(); |
289 ptr_ = nullptr; | 301 ptr_ = 0; |
290 } | 302 } |
291 | 303 |
292 // Allow conditionals to test validity, e.g. if (weak_ptr) {...}; | 304 // Allow conditionals to test validity, e.g. if (weak_ptr) {...}; |
293 explicit operator bool() const { return get() != nullptr; } | 305 explicit operator bool() const { return get() != nullptr; } |
294 | 306 |
295 private: | 307 private: |
296 friend class internal::SupportsWeakPtrBase; | 308 friend class internal::SupportsWeakPtrBase; |
297 template <typename U> friend class WeakPtr; | 309 template <typename U> friend class WeakPtr; |
298 friend class SupportsWeakPtr<T>; | 310 friend class SupportsWeakPtr<T>; |
299 friend class WeakPtrFactory<T>; | 311 friend class WeakPtrFactory<T>; |
300 | 312 |
301 WeakPtr(const internal::WeakReference& ref, T* ptr) | 313 WeakPtr(const internal::WeakReference& ref, T* ptr) |
302 : WeakPtrBase(ref), | 314 : WeakPtrBase(ref, reinterpret_cast<uintptr_t>(ptr)) {} |
303 ptr_(ptr) { | |
304 } | |
305 | |
306 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its | |
307 // value is undefined (as opposed to nullptr). | |
308 T* ptr_; | |
309 }; | 315 }; |
310 | 316 |
311 // Allow callers to compare WeakPtrs against nullptr to test validity. | 317 // Allow callers to compare WeakPtrs against nullptr to test validity. |
312 template <class T> | 318 template <class T> |
313 bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) { | 319 bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) { |
314 return !(weak_ptr == nullptr); | 320 return !(weak_ptr == nullptr); |
315 } | 321 } |
316 template <class T> | 322 template <class T> |
317 bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) { | 323 bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) { |
318 return weak_ptr != nullptr; | 324 return weak_ptr != nullptr; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. | 418 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. |
413 | 419 |
414 template <typename Derived> | 420 template <typename Derived> |
415 WeakPtr<Derived> AsWeakPtr(Derived* t) { | 421 WeakPtr<Derived> AsWeakPtr(Derived* t) { |
416 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); | 422 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); |
417 } | 423 } |
418 | 424 |
419 } // namespace base | 425 } // namespace base |
420 | 426 |
421 #endif // BASE_MEMORY_WEAK_PTR_H_ | 427 #endif // BASE_MEMORY_WEAK_PTR_H_ |
OLD | NEW |