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 |