| 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 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 T* operator->() const { | 219 T* operator->() const { |
| 220 DCHECK(get() != nullptr); | 220 DCHECK(get() != nullptr); |
| 221 return get(); | 221 return get(); |
| 222 } | 222 } |
| 223 | 223 |
| 224 void reset() { | 224 void reset() { |
| 225 ref_ = internal::WeakReference(); | 225 ref_ = internal::WeakReference(); |
| 226 ptr_ = nullptr; | 226 ptr_ = nullptr; |
| 227 } | 227 } |
| 228 | 228 |
| 229 // Implement "Safe Bool Idiom" | 229 // Allow conditionals to test validity, e.g. if (weak_ptr) {...}; |
| 230 // https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool | 230 explicit operator bool() const { return get() != nullptr; } |
| 231 // | |
| 232 // Allow WeakPtr<element_type> to be used in boolean expressions such as | |
| 233 // if (weak_ptr_instance) | |
| 234 // But do not become convertible to a real bool (which is dangerous). | |
| 235 // Implementation requires: | |
| 236 // typedef Testable | |
| 237 // operator Testable() const | |
| 238 // operator== | |
| 239 // operator!= | |
| 240 // | |
| 241 // == and != operators must be declared explicitly or dissallowed, as | |
| 242 // otherwise "ptr1 == ptr2" will compile but do the wrong thing (i.e., convert | |
| 243 // to Testable and then do the comparison). | |
| 244 // | |
| 245 // C++11 provides for "explicit operator bool()", however it is currently | |
| 246 // banned due to MSVS2013. https://chromium-cpp.appspot.com/#core-blacklist | |
| 247 private: | |
| 248 typedef T* WeakPtr::*Testable; | |
| 249 | |
| 250 public: | |
| 251 operator Testable() const { return get() ? &WeakPtr::ptr_ : nullptr; } | |
| 252 | 231 |
| 253 private: | 232 private: |
| 254 // Explicitly declare comparison operators as required by the "Safe Bool | |
| 255 // Idiom", but keep them private. | |
| 256 template <class U> bool operator==(WeakPtr<U> const&) const; | |
| 257 template <class U> bool operator!=(WeakPtr<U> const&) const; | |
| 258 | |
| 259 friend class internal::SupportsWeakPtrBase; | 233 friend class internal::SupportsWeakPtrBase; |
| 260 template <typename U> friend class WeakPtr; | 234 template <typename U> friend class WeakPtr; |
| 261 friend class SupportsWeakPtr<T>; | 235 friend class SupportsWeakPtr<T>; |
| 262 friend class WeakPtrFactory<T>; | 236 friend class WeakPtrFactory<T>; |
| 263 | 237 |
| 264 WeakPtr(const internal::WeakReference& ref, T* ptr) | 238 WeakPtr(const internal::WeakReference& ref, T* ptr) |
| 265 : WeakPtrBase(ref), | 239 : WeakPtrBase(ref), |
| 266 ptr_(ptr) { | 240 ptr_(ptr) { |
| 267 } | 241 } |
| 268 | 242 |
| 269 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its | 243 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its |
| 270 // value is undefined (as opposed to nullptr). | 244 // value is undefined (as opposed to nullptr). |
| 271 T* ptr_; | 245 T* ptr_; |
| 272 }; | 246 }; |
| 273 | 247 |
| 248 // Allow callers to compare WeakPtrs against nullptr to test validity. |
| 249 template <class T> |
| 250 bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) { |
| 251 return !(weak_ptr == nullptr); |
| 252 } |
| 253 template <class T> |
| 254 bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) { |
| 255 return weak_ptr != nullptr; |
| 256 } |
| 257 template <class T> |
| 258 bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) { |
| 259 return weak_ptr.get() == nullptr; |
| 260 } |
| 261 template <class T> |
| 262 bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) { |
| 263 return weak_ptr == nullptr; |
| 264 } |
| 265 |
| 274 // A class may be composed of a WeakPtrFactory and thereby | 266 // A class may be composed of a WeakPtrFactory and thereby |
| 275 // control how it exposes weak pointers to itself. This is helpful if you only | 267 // control how it exposes weak pointers to itself. This is helpful if you only |
| 276 // need weak pointers within the implementation of a class. This class is also | 268 // need weak pointers within the implementation of a class. This class is also |
| 277 // useful when working with primitive types. For example, you could have a | 269 // useful when working with primitive types. For example, you could have a |
| 278 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. | 270 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. |
| 279 template <class T> | 271 template <class T> |
| 280 class WeakPtrFactory { | 272 class WeakPtrFactory { |
| 281 public: | 273 public: |
| 282 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { | 274 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { |
| 283 } | 275 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. | 340 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. |
| 349 | 341 |
| 350 template <typename Derived> | 342 template <typename Derived> |
| 351 WeakPtr<Derived> AsWeakPtr(Derived* t) { | 343 WeakPtr<Derived> AsWeakPtr(Derived* t) { |
| 352 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); | 344 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); |
| 353 } | 345 } |
| 354 | 346 |
| 355 } // namespace base | 347 } // namespace base |
| 356 | 348 |
| 357 #endif // BASE_MEMORY_WEAK_PTR_H_ | 349 #endif // BASE_MEMORY_WEAK_PTR_H_ |
| OLD | NEW |