Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(916)

Side by Side Diff: base/bind_helpers.h

Issue 2250373002: Readd base::UnwrapTraits to support rvalue-reference wrappers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@20_oneshot
Patch Set: remove unused "using" Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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_
OLDNEW
« no previous file with comments | « base/base.gyp ('k') | base/bind_helpers_unittest.cc » ('j') | base/bind_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698