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

Side by Side Diff: base/bind_helpers.h

Issue 1698223002: Remove UnwrapTraits (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « no previous file | base/bind_internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 }; 349 };
350 350
351 // PassedWrapper is a copyable adapter for a scoper that ignores const. 351 // PassedWrapper is a copyable adapter for a scoper that ignores const.
352 // 352 //
353 // It is needed to get around the fact that Bind() takes a const reference to 353 // It is needed to get around the fact that Bind() takes a const reference to
354 // all its arguments. Because Bind() takes a const reference to avoid 354 // all its arguments. Because Bind() takes a const reference to avoid
355 // unnecessary copies, it is incompatible with movable-but-not-copyable 355 // unnecessary copies, it is incompatible with movable-but-not-copyable
356 // types; doing a destructive "move" of the type into Bind() would violate 356 // types; doing a destructive "move" of the type into Bind() would violate
357 // the const correctness. 357 // the const correctness.
358 // 358 //
359 // This conundrum cannot be solved without either C++11 rvalue references or 359 // This conundrum cannot be solved without either C++11 rvalue references or
Nico 2016/02/16 14:57:10 do we still need this type?
tzik 2016/02/16 15:22:17 Yes, we still need this for a while for Run() impl
Nico 2016/02/16 15:24:22 Maybe the comment could use updating then :-)
360 // a O(2^n) blowup of Bind() templates to handle each combination of regular 360 // a O(2^n) blowup of Bind() templates to handle each combination of regular
361 // types and movable-but-not-copyable types. Thus we introduce a wrapper type 361 // types and movable-but-not-copyable types. Thus we introduce a wrapper type
362 // that is copyable to transmit the correct type information down into 362 // that is copyable to transmit the correct type information down into
363 // BindState<>. Ignoring const in this type makes sense because it is only 363 // BindState<>. Ignoring const in this type makes sense because it is only
364 // created when we are explicitly trying to do a destructive move. 364 // created when we are explicitly trying to do a destructive move.
365 // 365 //
366 // Two notes: 366 // Two notes:
367 // 1) PassedWrapper supports any type that has a move constructor, however 367 // 1) PassedWrapper supports any type that has a move constructor, however
368 // the type will need to be specifically whitelisted in order for it to be 368 // the type will need to be specifically whitelisted in order for it to be
369 // bound to a Callback. We guard this explicitly at the call of Passed() 369 // bound to a Callback. We guard this explicitly at the call of Passed()
370 // to make for clear errors. Things not given to Passed() will be forwarded 370 // to make for clear errors. Things not given to Passed() will be forwarded
371 // and stored by value which will not work for general move-only types. 371 // and stored by value which will not work for general move-only types.
372 // 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" 372 // 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL"
373 // scoper to a Callback and allow the Callback to execute once. 373 // scoper to a Callback and allow the Callback to execute once.
374 template <typename T> 374 template <typename T>
375 class PassedWrapper { 375 class PassedWrapper {
376 public: 376 public:
377 explicit PassedWrapper(T&& scoper) 377 explicit PassedWrapper(T&& scoper)
378 : is_valid_(true), scoper_(std::move(scoper)) {} 378 : is_valid_(true), scoper_(std::move(scoper)) {}
379 PassedWrapper(const PassedWrapper& other) 379 PassedWrapper(const PassedWrapper& other)
380 : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {} 380 : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {}
381 T Pass() const { 381 T Take() const {
382 CHECK(is_valid_); 382 CHECK(is_valid_);
383 is_valid_ = false; 383 is_valid_ = false;
384 return std::move(scoper_); 384 return std::move(scoper_);
385 } 385 }
386 386
387 private: 387 private:
388 mutable bool is_valid_; 388 mutable bool is_valid_;
389 mutable T scoper_; 389 mutable T scoper_;
390 }; 390 };
391 391
392 // Unwrap the stored parameters for the wrappers above. 392 // Unwrap the stored parameters for the wrappers above.
393 template <typename T> 393 template <typename T>
394 struct UnwrapTraits { 394 const T& Unwrap(const T& o) {
395 using ForwardType = const T&; 395 return o;
396 static ForwardType Unwrap(const T& o) { return o; } 396 }
397 };
398 397
399 template <typename T> 398 template <typename T>
400 struct UnwrapTraits<UnretainedWrapper<T> > { 399 T* Unwrap(UnretainedWrapper<T> unretained) {
401 using ForwardType = T*; 400 return unretained.get();
402 static ForwardType Unwrap(UnretainedWrapper<T> unretained) { 401 }
403 return unretained.get();
404 }
405 };
406 402
407 template <typename T> 403 template <typename T>
408 struct UnwrapTraits<ConstRefWrapper<T> > { 404 const T& Unwrap(ConstRefWrapper<T> const_ref) {
409 using ForwardType = const T&; 405 return const_ref.get();
410 static ForwardType Unwrap(ConstRefWrapper<T> const_ref) { 406 }
411 return const_ref.get();
412 }
413 };
414 407
415 template <typename T> 408 template <typename T>
416 struct UnwrapTraits<scoped_refptr<T> > { 409 T* Unwrap(const scoped_refptr<T>& o) {
417 using ForwardType = T*; 410 return o.get();
418 static ForwardType Unwrap(const scoped_refptr<T>& o) { return o.get(); } 411 }
419 };
420 412
421 template <typename T> 413 template <typename T>
422 struct UnwrapTraits<WeakPtr<T> > { 414 const WeakPtr<T>& Unwrap(const WeakPtr<T>& o) {
423 using ForwardType = const WeakPtr<T>&; 415 return o;
424 static ForwardType Unwrap(const WeakPtr<T>& o) { return o; } 416 }
425 };
426 417
427 template <typename T> 418 template <typename T>
428 struct UnwrapTraits<OwnedWrapper<T> > { 419 T* Unwrap(const OwnedWrapper<T>& o) {
429 using ForwardType = T*; 420 return o.get();
430 static ForwardType Unwrap(const OwnedWrapper<T>& o) { 421 }
431 return o.get();
432 }
433 };
434 422
435 template <typename T> 423 template <typename T>
436 struct UnwrapTraits<PassedWrapper<T> > { 424 T Unwrap(PassedWrapper<T>& o) {
437 using ForwardType = T; 425 return o.Take();
438 static T Unwrap(PassedWrapper<T>& o) { 426 }
439 return o.Pass();
440 }
441 };
442 427
443 // Utility for handling different refcounting semantics in the Bind() 428 // Utility for handling different refcounting semantics in the Bind()
444 // function. 429 // function.
445 template <bool is_method, typename... T> 430 template <bool is_method, typename... T>
446 struct MaybeScopedRefPtr; 431 struct MaybeScopedRefPtr;
447 432
448 template <bool is_method> 433 template <bool is_method>
449 struct MaybeScopedRefPtr<is_method> { 434 struct MaybeScopedRefPtr<is_method> {
450 MaybeScopedRefPtr() {} 435 MaybeScopedRefPtr() {}
451 }; 436 };
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 BASE_EXPORT void DoNothing(); 634 BASE_EXPORT void DoNothing();
650 635
651 template<typename T> 636 template<typename T>
652 void DeletePointer(T* obj) { 637 void DeletePointer(T* obj) {
653 delete obj; 638 delete obj;
654 } 639 }
655 640
656 } // namespace base 641 } // namespace base
657 642
658 #endif // BASE_BIND_HELPERS_H_ 643 #endif // BASE_BIND_HELPERS_H_
OLDNEW
« no previous file with comments | « no previous file | base/bind_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698