Chromium Code Reviews| 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 NULL) 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 |
| 11 // object vanishing and e.g. tasks posted to it being silently dropped. | 11 // object vanishing and e.g. tasks posted to it being silently dropped. |
| 12 // Reference-counting such an object would complicate the ownership graph and | 12 // Reference-counting such an object would complicate the ownership graph and |
| 13 // make it harder to reason about the object's lifetime. | 13 // make it harder to reason about the object's lifetime. |
| 14 | 14 |
| 15 // EXAMPLE: | 15 // EXAMPLE: |
| 16 // | 16 // |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 // unbound from the SequencedTaskRunner/Thread. The WeakPtrFactory may then be | 63 // unbound from the SequencedTaskRunner/Thread. The WeakPtrFactory may then be |
| 64 // destroyed, or new WeakPtr objects may be used, from a different sequence. | 64 // destroyed, or new WeakPtr objects may be used, from a different sequence. |
| 65 // | 65 // |
| 66 // Thus, at least one WeakPtr object must exist and have been dereferenced on | 66 // Thus, at least one WeakPtr object must exist and have been dereferenced on |
| 67 // the correct thread to enforce that other WeakPtr objects will enforce they | 67 // the correct thread to enforce that other WeakPtr objects will enforce they |
| 68 // are used on the desired thread. | 68 // are used on the desired thread. |
| 69 | 69 |
| 70 #ifndef BASE_MEMORY_WEAK_PTR_H_ | 70 #ifndef BASE_MEMORY_WEAK_PTR_H_ |
| 71 #define BASE_MEMORY_WEAK_PTR_H_ | 71 #define BASE_MEMORY_WEAK_PTR_H_ |
| 72 | 72 |
| 73 #include <cstddef> | |
| 73 #include <type_traits> | 74 #include <type_traits> |
| 74 | 75 |
| 75 #include "base/base_export.h" | 76 #include "base/base_export.h" |
| 76 #include "base/logging.h" | 77 #include "base/logging.h" |
| 77 #include "base/macros.h" | 78 #include "base/macros.h" |
| 78 #include "base/memory/ref_counted.h" | 79 #include "base/memory/ref_counted.h" |
| 79 #include "base/sequence_checker.h" | 80 #include "base/sequence_checker.h" |
| 80 | 81 |
| 81 namespace base { | 82 namespace base { |
| 82 | 83 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 // EXAMPLE: | 193 // EXAMPLE: |
| 193 // | 194 // |
| 194 // class Foo { ... }; | 195 // class Foo { ... }; |
| 195 // WeakPtr<Foo> foo; | 196 // WeakPtr<Foo> foo; |
| 196 // if (foo) | 197 // if (foo) |
| 197 // foo->method(); | 198 // foo->method(); |
| 198 // | 199 // |
| 199 template <typename T> | 200 template <typename T> |
| 200 class WeakPtr : public internal::WeakPtrBase { | 201 class WeakPtr : public internal::WeakPtrBase { |
| 201 public: | 202 public: |
| 202 WeakPtr() : ptr_(NULL) { | 203 WeakPtr() : ptr_(nullptr) { |
| 203 } | 204 } |
| 204 | 205 |
| 206 WeakPtr(std::nullptr_t) : ptr_(nullptr) { } | |
|
sky
2016/04/05 17:10:21
nit: no {}. I would hope git cl format converts '{
dcheng
2016/04/05 17:16:33
I forgot to run git cl format =S
| |
| 207 | |
| 205 // Allow conversion from U to T provided U "is a" T. Note that this | 208 // Allow conversion from U to T provided U "is a" T. Note that this |
| 206 // is separate from the (implicit) copy constructor. | 209 // is separate from the (implicit) copy constructor. |
| 207 template <typename U> | 210 template <typename U> |
| 208 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.ptr_) { | 211 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.ptr_) { |
| 209 } | 212 } |
| 210 | 213 |
| 211 T* get() const { return ref_.is_valid() ? ptr_ : NULL; } | 214 T* get() const { return ref_.is_valid() ? ptr_ : nullptr; } |
| 212 | 215 |
| 213 T& operator*() const { | 216 T& operator*() const { |
| 214 DCHECK(get() != NULL); | 217 DCHECK(get() != nullptr); |
| 215 return *get(); | 218 return *get(); |
| 216 } | 219 } |
| 217 T* operator->() const { | 220 T* operator->() const { |
| 218 DCHECK(get() != NULL); | 221 DCHECK(get() != nullptr); |
| 219 return get(); | 222 return get(); |
| 220 } | 223 } |
| 221 | 224 |
| 222 void reset() { | 225 void reset() { |
| 223 ref_ = internal::WeakReference(); | 226 ref_ = internal::WeakReference(); |
| 224 ptr_ = NULL; | 227 ptr_ = nullptr; |
| 225 } | 228 } |
| 226 | 229 |
| 227 // Implement "Safe Bool Idiom" | 230 // Implement "Safe Bool Idiom" |
| 228 // https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool | 231 // https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool |
| 229 // | 232 // |
| 230 // Allow WeakPtr<element_type> to be used in boolean expressions such as | 233 // Allow WeakPtr<element_type> to be used in boolean expressions such as |
| 231 // if (weak_ptr_instance) | 234 // if (weak_ptr_instance) |
| 232 // But do not become convertible to a real bool (which is dangerous). | 235 // But do not become convertible to a real bool (which is dangerous). |
| 233 // Implementation requires: | 236 // Implementation requires: |
| 234 // typedef Testable | 237 // typedef Testable |
| 235 // operator Testable() const | 238 // operator Testable() const |
| 236 // operator== | 239 // operator== |
| 237 // operator!= | 240 // operator!= |
| 238 // | 241 // |
| 239 // == and != operators must be declared explicitly or dissallowed, as | 242 // == and != operators must be declared explicitly or dissallowed, as |
| 240 // otherwise "ptr1 == ptr2" will compile but do the wrong thing (i.e., convert | 243 // otherwise "ptr1 == ptr2" will compile but do the wrong thing (i.e., convert |
| 241 // to Testable and then do the comparison). | 244 // to Testable and then do the comparison). |
| 242 // | 245 // |
| 243 // C++11 provides for "explicit operator bool()", however it is currently | 246 // C++11 provides for "explicit operator bool()", however it is currently |
| 244 // banned due to MSVS2013. https://chromium-cpp.appspot.com/#core-blacklist | 247 // banned due to MSVS2013. https://chromium-cpp.appspot.com/#core-blacklist |
| 245 private: | 248 private: |
| 246 typedef T* WeakPtr::*Testable; | 249 typedef T* WeakPtr::*Testable; |
| 247 | 250 |
| 248 public: | 251 public: |
| 249 operator Testable() const { return get() ? &WeakPtr::ptr_ : NULL; } | 252 operator Testable() const { return get() ? &WeakPtr::ptr_ : nullptr; } |
| 250 | 253 |
| 251 private: | 254 private: |
| 252 // Explicitly declare comparison operators as required by the "Safe Bool | 255 // Explicitly declare comparison operators as required by the "Safe Bool |
| 253 // Idiom", but keep them private. | 256 // Idiom", but keep them private. |
| 254 template <class U> bool operator==(WeakPtr<U> const&) const; | 257 template <class U> bool operator==(WeakPtr<U> const&) const; |
| 255 template <class U> bool operator!=(WeakPtr<U> const&) const; | 258 template <class U> bool operator!=(WeakPtr<U> const&) const; |
| 256 | 259 |
| 257 friend class internal::SupportsWeakPtrBase; | 260 friend class internal::SupportsWeakPtrBase; |
| 258 template <typename U> friend class WeakPtr; | 261 template <typename U> friend class WeakPtr; |
| 259 friend class SupportsWeakPtr<T>; | 262 friend class SupportsWeakPtr<T>; |
| 260 friend class WeakPtrFactory<T>; | 263 friend class WeakPtrFactory<T>; |
| 261 | 264 |
| 262 WeakPtr(const internal::WeakReference& ref, T* ptr) | 265 WeakPtr(const internal::WeakReference& ref, T* ptr) |
| 263 : WeakPtrBase(ref), | 266 : WeakPtrBase(ref), |
| 264 ptr_(ptr) { | 267 ptr_(ptr) { |
| 265 } | 268 } |
| 266 | 269 |
| 267 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its | 270 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its |
| 268 // value is undefined (as opposed to NULL). | 271 // value is undefined (as opposed to nullptr). |
| 269 T* ptr_; | 272 T* ptr_; |
| 270 }; | 273 }; |
| 271 | 274 |
| 272 // A class may be composed of a WeakPtrFactory and thereby | 275 // A class may be composed of a WeakPtrFactory and thereby |
| 273 // control how it exposes weak pointers to itself. This is helpful if you only | 276 // control how it exposes weak pointers to itself. This is helpful if you only |
| 274 // need weak pointers within the implementation of a class. This class is also | 277 // need weak pointers within the implementation of a class. This class is also |
| 275 // useful when working with primitive types. For example, you could have a | 278 // useful when working with primitive types. For example, you could have a |
| 276 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. | 279 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. |
| 277 template <class T> | 280 template <class T> |
| 278 class WeakPtrFactory { | 281 class WeakPtrFactory { |
| 279 public: | 282 public: |
| 280 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { | 283 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { |
| 281 } | 284 } |
| 282 | 285 |
| 283 ~WeakPtrFactory() { | 286 ~WeakPtrFactory() { |
| 284 ptr_ = NULL; | 287 ptr_ = nullptr; |
| 285 } | 288 } |
| 286 | 289 |
| 287 WeakPtr<T> GetWeakPtr() { | 290 WeakPtr<T> GetWeakPtr() { |
| 288 DCHECK(ptr_); | 291 DCHECK(ptr_); |
| 289 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); | 292 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); |
| 290 } | 293 } |
| 291 | 294 |
| 292 // Call this method to invalidate all existing weak pointers. | 295 // Call this method to invalidate all existing weak pointers. |
| 293 void InvalidateWeakPtrs() { | 296 void InvalidateWeakPtrs() { |
| 294 DCHECK(ptr_); | 297 DCHECK(ptr_); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. | 351 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. |
| 349 | 352 |
| 350 template <typename Derived> | 353 template <typename Derived> |
| 351 WeakPtr<Derived> AsWeakPtr(Derived* t) { | 354 WeakPtr<Derived> AsWeakPtr(Derived* t) { |
| 352 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); | 355 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); |
| 353 } | 356 } |
| 354 | 357 |
| 355 } // namespace base | 358 } // namespace base |
| 356 | 359 |
| 357 #endif // BASE_MEMORY_WEAK_PTR_H_ | 360 #endif // BASE_MEMORY_WEAK_PTR_H_ |
| OLD | NEW |