| 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 |