 Chromium Code Reviews
 Chromium Code Reviews Issue 2250373002:
  Readd base::UnwrapTraits to support rvalue-reference wrappers  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@20_oneshot
    
  
    Issue 2250373002:
  Readd base::UnwrapTraits to support rvalue-reference wrappers  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@20_oneshot| 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 |