OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // This defines a set of argument wrappers and related factory methods that | 5 // This defines a set of argument wrappers and related factory methods that |
6 // can be used specify the refcounting and reference semantics of arguments | 6 // can be used specify the refcounting and reference semantics of arguments |
7 // that are bound by the Bind() function in base/bind.h. | 7 // that are bound by the Bind() function in base/bind.h. |
8 // | 8 // |
9 // It also defines a set of simple functions and utilities that people want | 9 // It also defines a set of simple functions and utilities that people want |
10 // when using Callback<> and Bind(). | 10 // when using Callback<> and Bind(). |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 | 167 |
168 #include "base/callback.h" | 168 #include "base/callback.h" |
169 #include "base/memory/weak_ptr.h" | 169 #include "base/memory/weak_ptr.h" |
170 #include "build/build_config.h" | 170 #include "build/build_config.h" |
171 | 171 |
172 namespace base { | 172 namespace base { |
173 | 173 |
174 template <typename T> | 174 template <typename T> |
175 struct IsWeakReceiver; | 175 struct IsWeakReceiver; |
176 | 176 |
177 template <typename> | |
178 struct BindUnwrapTraits; | |
179 | |
177 namespace internal { | 180 namespace internal { |
178 | 181 |
179 template <typename T> | 182 template <typename T> |
180 class UnretainedWrapper { | 183 class UnretainedWrapper { |
181 public: | 184 public: |
182 explicit UnretainedWrapper(T* o) : ptr_(o) {} | 185 explicit UnretainedWrapper(T* o) : ptr_(o) {} |
183 T* get() const { return ptr_; } | 186 T* get() const { return ptr_; } |
184 private: | 187 private: |
185 T* ptr_; | 188 T* ptr_; |
186 }; | 189 }; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 CHECK(is_valid_); | 271 CHECK(is_valid_); |
269 is_valid_ = false; | 272 is_valid_ = false; |
270 return std::move(scoper_); | 273 return std::move(scoper_); |
271 } | 274 } |
272 | 275 |
273 private: | 276 private: |
274 mutable bool is_valid_; | 277 mutable bool is_valid_; |
275 mutable T scoper_; | 278 mutable T scoper_; |
276 }; | 279 }; |
277 | 280 |
278 // Unwrap the stored parameters for the wrappers above. | |
279 template <typename T> | 281 template <typename T> |
280 T&& Unwrap(T&& o) { | 282 using Unwrapper = BindUnwrapTraits<typename std::decay<T>::type>; |
281 return std::forward<T>(o); | |
282 } | |
283 | 283 |
284 template <typename T> | 284 template <typename T> |
285 T* Unwrap(const UnretainedWrapper<T>& unretained) { | 285 auto Unwrap(T&& o) -> decltype(Unwrapper<T>::Unwrap(std::forward<T>(o))) { |
286 return unretained.get(); | 286 return Unwrapper<T>::Unwrap(std::forward<T>(o)); |
dcheng
2016/08/23 05:25:38
Just curious, but can't we just invoke the templat
tzik
2016/08/23 07:01:09
It's possible, but it makes the caller a bit more
| |
287 } | |
288 | |
289 template <typename T> | |
290 const T& Unwrap(const ConstRefWrapper<T>& const_ref) { | |
291 return const_ref.get(); | |
292 } | |
293 | |
294 template <typename T> | |
295 T* Unwrap(const RetainedRefWrapper<T>& o) { | |
296 return o.get(); | |
297 } | |
298 | |
299 template <typename T> | |
300 T* Unwrap(const OwnedWrapper<T>& o) { | |
301 return o.get(); | |
302 } | |
303 | |
304 template <typename T> | |
305 T Unwrap(const PassedWrapper<T>& o) { | |
306 return o.Take(); | |
307 } | 287 } |
308 | 288 |
309 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a | 289 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a |
310 // method. It is used internally by Bind() to select the correct | 290 // method. It is used internally by Bind() to select the correct |
311 // InvokeHelper that will no-op itself in the event the WeakPtr<> for | 291 // InvokeHelper that will no-op itself in the event the WeakPtr<> for |
312 // the target object is invalidated. | 292 // the target object is invalidated. |
313 // | 293 // |
314 // The first argument should be the type of the object that will be received by | 294 // The first argument should be the type of the object that will be received by |
315 // the method. | 295 // the method. |
316 template <bool is_method, typename... Args> | 296 template <bool is_method, typename... Args> |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 // base::Bind(&Foo::bar, oo).Run(); | 470 // base::Bind(&Foo::bar, oo).Run(); |
491 template <typename T> | 471 template <typename T> |
492 struct IsWeakReceiver : std::false_type {}; | 472 struct IsWeakReceiver : std::false_type {}; |
493 | 473 |
494 template <typename T> | 474 template <typename T> |
495 struct IsWeakReceiver<internal::ConstRefWrapper<T>> : IsWeakReceiver<T> {}; | 475 struct IsWeakReceiver<internal::ConstRefWrapper<T>> : IsWeakReceiver<T> {}; |
496 | 476 |
497 template <typename T> | 477 template <typename T> |
498 struct IsWeakReceiver<WeakPtr<T>> : std::true_type {}; | 478 struct IsWeakReceiver<WeakPtr<T>> : std::true_type {}; |
499 | 479 |
480 // An injection point to control how bound objects passed to the target | |
481 // function. BindUnwrapTraits<>::Unwrap() is called for each bound objects right | |
482 // before the target function is invoked. | |
483 template <typename> | |
484 struct BindUnwrapTraits { | |
485 template <typename T> | |
486 static T&& Unwrap(T&& o) { return std::forward<T>(o); } | |
487 }; | |
488 | |
489 template <typename T> | |
490 struct BindUnwrapTraits<internal::UnretainedWrapper<T>> { | |
491 static T* Unwrap(const internal::UnretainedWrapper<T>& o) { | |
492 return o.get(); | |
493 } | |
494 }; | |
495 | |
496 template <typename T> | |
497 struct BindUnwrapTraits<internal::ConstRefWrapper<T>> { | |
498 static const T& Unwrap(const internal::ConstRefWrapper<T>& o) { | |
499 return o.get(); | |
500 } | |
501 }; | |
502 | |
503 template <typename T> | |
504 struct BindUnwrapTraits<internal::RetainedRefWrapper<T>> { | |
505 static T* Unwrap(const internal::RetainedRefWrapper<T>& o) { | |
506 return o.get(); | |
507 } | |
508 }; | |
509 | |
510 template <typename T> | |
511 struct BindUnwrapTraits<internal::OwnedWrapper<T>> { | |
512 static T* Unwrap(const internal::OwnedWrapper<T>& o) { | |
513 return o.get(); | |
514 } | |
515 }; | |
516 | |
517 template <typename T> | |
518 struct BindUnwrapTraits<internal::PassedWrapper<T>> { | |
519 static T Unwrap(const internal::PassedWrapper<T>& o) { | |
520 return o.Take(); | |
521 } | |
522 }; | |
523 | |
500 } // namespace base | 524 } // namespace base |
501 | 525 |
502 #endif // BASE_BIND_HELPERS_H_ | 526 #endif // BASE_BIND_HELPERS_H_ |
OLD | NEW |