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 3 // found in the LICENSE file. 4 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 7 // that are bound by the Bind() function in base/bind.h. 8 // 9 // It also defines a set of simple functions and utilities that people want 10 // when using Callback<> and Bind(). 11 // 12 // 13 // ARGUMENT BINDING WRAPPERS 14 // 15 // The wrapper functions are base::Unretained(), base::Owned(), base::Passed(), 16 // base::ConstRef(), and base::IgnoreResult(). 17 // 18 // Unretained() allows Bind() to bind a non-refcounted class, and to disable 19 // refcounting on arguments that are refcounted objects. 20 // 21 // Owned() transfers ownership of an object to the Callback resulting from 22 // bind; the object will be deleted when the Callback is deleted. 23 // 24 // Passed() is for transferring movable-but-not-copyable types (eg. unique_ptr) 25 // through a Callback. Logically, this signifies a destructive transfer of 26 // the state of the argument into the target function. Invoking 27 // Callback::Run() twice on a Callback that was created with a Passed() 28 // argument will CHECK() because the first invocation would have already 29 // transferred ownership to the target function. 30 // 31 // RetainedRef() accepts a ref counted object and retains a reference to it. 32 // When the callback is called, the object is passed as a raw pointer. 33 // 34 // ConstRef() allows binding a constant reference to an argument rather 35 // than a copy. 36 // 37 // IgnoreResult() is used to adapt a function or Callback with a return type to 38 // one with a void return. This is most useful if you have a function with, 39 // say, a pesky ignorable bool return that you want to use with PostTask or 40 // something else that expect a Callback with a void return. 41 // 42 // EXAMPLE OF Unretained(): 43 // 44 // class Foo { 45 // public: 46 // void func() { cout << "Foo:f" << endl; } 47 // }; 48 // 49 // // In some function somewhere. 50 // Foo foo; 51 // Closure foo_callback = 52 // Bind(&Foo::func, Unretained(&foo)); 53 // foo_callback.Run(); // Prints "Foo:f". 54 // 55 // Without the Unretained() wrapper on |&foo|, the above call would fail 56 // to compile because Foo does not support the AddRef() and Release() methods. 57 // 58 // 59 // EXAMPLE OF Owned(): 60 // 61 // void foo(int* arg) { cout << *arg << endl } 62 // 63 // int* pn = new int(1); 64 // Closure foo_callback = Bind(&foo, Owned(pn)); 65 // 66 // foo_callback.Run(); // Prints "1" 67 // foo_callback.Run(); // Prints "1" 68 // *n = 2; 69 // foo_callback.Run(); // Prints "2" 70 // 71 // foo_callback.Reset(); // |pn| is deleted. Also will happen when 72 // // |foo_callback| goes out of scope. 73 // 74 // Without Owned(), someone would have to know to delete |pn| when the last 75 // reference to the Callback is deleted. 76 // 77 // EXAMPLE OF RetainedRef(): 78 // 79 // void foo(RefCountedBytes* bytes) {} 80 // 81 // scoped_refptr<RefCountedBytes> bytes = ...; 82 // Closure callback = Bind(&foo, base::RetainedRef(bytes)); 83 // callback.Run(); 84 // 85 // Without RetainedRef, the scoped_refptr would try to implicitly convert to 86 // a raw pointer and fail compilation: 87 // 88 // Closure callback = Bind(&foo, bytes); // ERROR! 89 // 90 // 91 // EXAMPLE OF ConstRef(): 92 // 93 // void foo(int arg) { cout << arg << endl } 94 // 95 // int n = 1; 96 // Closure no_ref = Bind(&foo, n); 97 // Closure has_ref = Bind(&foo, ConstRef(n)); 98 // 99 // no_ref.Run(); // Prints "1" 100 // has_ref.Run(); // Prints "1" 101 // 102 // n = 2; 103 // no_ref.Run(); // Prints "1" 104 // has_ref.Run(); // Prints "2" 105 // 106 // Note that because ConstRef() takes a reference on |n|, |n| must outlive all 107 // its bound callbacks. 108 // 109 // 110 // EXAMPLE OF IgnoreResult(): 111 // 112 // int DoSomething(int arg) { cout << arg << endl; } 113 // 114 // // Assign to a Callback with a void return type. 115 // Callback<void(int)> cb = Bind(IgnoreResult(&DoSomething)); 116 // cb->Run(1); // Prints "1". 117 // 118 // // Prints "1" on |ml|. 119 // ml->PostTask(FROM_HERE, Bind(IgnoreResult(&DoSomething), 1); 120 // 121 // 122 // EXAMPLE OF Passed(): 123 // 124 // void TakesOwnership(std::unique_ptr<Foo> arg) { } 125 // std::unique_ptr<Foo> CreateFoo() { return std::unique_ptr<Foo>(new Foo()); 126 // } 127 // 128 // std::unique_ptr<Foo> f(new Foo()); 129 // 130 // // |cb| is given ownership of Foo(). |f| is now NULL. 131 // // You can use std::move(f) in place of &f, but it's more verbose. 132 // Closure cb = Bind(&TakesOwnership, Passed(&f)); 133 // 134 // // Run was never called so |cb| still owns Foo() and deletes 135 // // it on Reset(). 136 // cb.Reset(); 137 // 138 // // |cb| is given a new Foo created by CreateFoo(). 139 // cb = Bind(&TakesOwnership, Passed(CreateFoo())); 140 // 141 // // |arg| in TakesOwnership() is given ownership of Foo(). |cb| 142 // // no longer owns Foo() and, if reset, would not delete Foo(). 143 // cb.Run(); // Foo() is now transferred to |arg| and deleted. 144 // cb.Run(); // This CHECK()s since Foo() already been used once. 145 // 146 // Passed() is particularly useful with PostTask() when you are transferring 147 // ownership of an argument into a task, but don't necessarily know if the 148 // task will always be executed. This can happen if the task is cancellable 149 // or if it is posted to a TaskRunner. 150 // 151 // 152 // SIMPLE FUNCTIONS AND UTILITIES. 153 // 154 // DoNothing() - Useful for creating a Closure that does nothing when called. 155 // DeletePointer<T>() - Useful for creating a Closure that will delete a 156 // pointer when invoked. Only use this when necessary. 157 // In most cases MessageLoop::DeleteSoon() is a better 158 // fit. 159 160 #ifndef BASE_BIND_HELPERS_H_ 161 #define BASE_BIND_HELPERS_H_ 162 163 #include <stddef.h> 164 165 #include <type_traits> 166 #include <utility> 167 168 #include "base/callback.h" 169 #include "base/memory/weak_ptr.h" 170 #include "build/build_config.h" 171 172 namespace base { 173 174 template <typename T> 175 struct IsWeakReceiver; 176 177 template <typename> 178 struct BindUnwrapTraits; 179 180 namespace internal { 181 182 template <typename Functor, typename SFINAE = void> 183 struct FunctorTraits; 184 185 template <typename T> 186 class UnretainedWrapper { 187 public: 188 explicit UnretainedWrapper(T* o) : ptr_(o) {} 189 T* get() const { return ptr_; } 190 private: 191 T* ptr_; 192 }; 193 194 template <typename T> 195 class ConstRefWrapper { 196 public: 197 explicit ConstRefWrapper(const T& o) : ptr_(&o) {} 198 const T& get() const { return *ptr_; } 199 private: 200 const T* ptr_; 201 }; 202 203 template <typename T> 204 class RetainedRefWrapper { 205 public: 206 explicit RetainedRefWrapper(T* o) : ptr_(o) {} 207 explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {} 208 T* get() const { return ptr_.get(); } 209 private: 210 scoped_refptr<T> ptr_; 211 }; 212 213 template <typename T> 214 struct IgnoreResultHelper { 215 explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {} 216 explicit operator bool() const { return !!functor_; } 217 218 T functor_; 219 }; 220 221 // An alternate implementation is to avoid the destructive copy, and instead 222 // specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to 223 // a class that is essentially a std::unique_ptr<>. 224 // 225 // The current implementation has the benefit though of leaving ParamTraits<> 226 // fully in callback_internal.h as well as avoiding type conversions during 227 // storage. 228 template <typename T> 229 class OwnedWrapper { 230 public: 231 explicit OwnedWrapper(T* o) : ptr_(o) {} 232 ~OwnedWrapper() { delete ptr_; } 233 T* get() const { return ptr_; } 234 OwnedWrapper(OwnedWrapper&& other) { 235 ptr_ = other.ptr_; 236 other.ptr_ = NULL; 237 } 238 239 private: 240 mutable T* ptr_; 241 }; 242 243 // PassedWrapper is a copyable adapter for a scoper that ignores const. 244 // 245 // It is needed to get around the fact that Bind() takes a const reference to 246 // all its arguments. Because Bind() takes a const reference to avoid 247 // unnecessary copies, it is incompatible with movable-but-not-copyable 248 // types; doing a destructive "move" of the type into Bind() would violate 249 // the const correctness. 250 // 251 // This conundrum cannot be solved without either C++11 rvalue references or 252 // a O(2^n) blowup of Bind() templates to handle each combination of regular 253 // types and movable-but-not-copyable types. Thus we introduce a wrapper type 254 // that is copyable to transmit the correct type information down into 255 // BindState<>. Ignoring const in this type makes sense because it is only 256 // created when we are explicitly trying to do a destructive move. 257 // 258 // Two notes: 259 // 1) PassedWrapper supports any type that has a move constructor, however 260 // the type will need to be specifically whitelisted in order for it to be 261 // bound to a Callback. We guard this explicitly at the call of Passed() 262 // to make for clear errors. Things not given to Passed() will be forwarded 263 // and stored by value which will not work for general move-only types. 264 // 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" 265 // scoper to a Callback and allow the Callback to execute once. 266 template <typename T> 267 class PassedWrapper { 268 public: 269 explicit PassedWrapper(T&& scoper) 270 : is_valid_(true), scoper_(std::move(scoper)) {} 271 PassedWrapper(PassedWrapper&& other) 272 : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {} 273 T Take() const { 274 CHECK(is_valid_); 275 is_valid_ = false; 276 return std::move(scoper_); 277 } 278 279 private: 280 mutable bool is_valid_; 281 mutable T scoper_; 282 }; 283 284 template <typename T> 285 using Unwrapper = BindUnwrapTraits<typename std::decay<T>::type>; 286 287 template <typename T> 288 auto Unwrap(T&& o) -> decltype(Unwrapper<T>::Unwrap(std::forward<T>(o))) { 289 return Unwrapper<T>::Unwrap(std::forward<T>(o)); 290 } 291 292 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a 293 // method. It is used internally by Bind() to select the correct 294 // InvokeHelper that will no-op itself in the event the WeakPtr<> for 295 // the target object is invalidated. 296 // 297 // The first argument should be the type of the object that will be received by 298 // the method. 299 template <bool is_method, typename... Args> 300 struct IsWeakMethod : std::false_type {}; 301 302 template <typename T, typename... Args> 303 struct IsWeakMethod<true, T, Args...> : IsWeakReceiver<T> {}; 304 305 // Packs a list of types to hold them in a single type. 306 template <typename... Types> 307 struct TypeList {}; 308 309 // Used for DropTypeListItem implementation. 310 template <size_t n, typename List> 311 struct DropTypeListItemImpl; 312 313 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. 314 template <size_t n, typename T, typename... List> 315 struct DropTypeListItemImpl<n, TypeList<T, List...>> 316 : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; 317 318 template <typename T, typename... List> 319 struct DropTypeListItemImpl<0, TypeList<T, List...>> { 320 using Type = TypeList<T, List...>; 321 }; 322 323 template <> 324 struct DropTypeListItemImpl<0, TypeList<>> { 325 using Type = TypeList<>; 326 }; 327 328 // A type-level function that drops |n| list item from given TypeList. 329 template <size_t n, typename List> 330 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; 331 332 // Used for TakeTypeListItem implementation. 333 template <size_t n, typename List, typename... Accum> 334 struct TakeTypeListItemImpl; 335 336 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. 337 template <size_t n, typename T, typename... List, typename... Accum> 338 struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...> 339 : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {}; 340 341 template <typename T, typename... List, typename... Accum> 342 struct TakeTypeListItemImpl<0, TypeList<T, List...>, Accum...> { 343 using Type = TypeList<Accum...>; 344 }; 345 346 template <typename... Accum> 347 struct TakeTypeListItemImpl<0, TypeList<>, Accum...> { 348 using Type = TypeList<Accum...>; 349 }; 350 351 // A type-level function that takes first |n| list item from given TypeList. 352 // E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to 353 // TypeList<A, B, C>. 354 template <size_t n, typename List> 355 using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type; 356 357 // Used for ConcatTypeLists implementation. 358 template <typename List1, typename List2> 359 struct ConcatTypeListsImpl; 360 361 template <typename... Types1, typename... Types2> 362 struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { 363 using Type = TypeList<Types1..., Types2...>; 364 }; 365 366 // A type-level function that concats two TypeLists. 367 template <typename List1, typename List2> 368 using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; 369 370 // Used for MakeFunctionType implementation. 371 template <typename R, typename ArgList> 372 struct MakeFunctionTypeImpl; 373 374 template <typename R, typename... Args> 375 struct MakeFunctionTypeImpl<R, TypeList<Args...>> { 376 // MSVC 2013 doesn't support Type Alias of function types. 377 // Revisit this after we update it to newer version. 378 typedef R Type(Args...); 379 }; 380 381 // A type-level function that constructs a function type that has |R| as its 382 // return type and has TypeLists items as its arguments. 383 template <typename R, typename ArgList> 384 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; 385 386 // Used for ExtractArgs and ExtractReturnType. 387 template <typename Signature> 388 struct ExtractArgsImpl; 389 390 template <typename R, typename... Args> 391 struct ExtractArgsImpl<R(Args...)> { 392 using ReturnType = R; 393 using ArgsList = TypeList<Args...>; 394 }; 395 396 // A type-level function that extracts function arguments into a TypeList. 397 // E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>. 398 template <typename Signature> 399 using ExtractArgs = typename ExtractArgsImpl<Signature>::ArgsList; 400 401 // A type-level function that extracts the return type of a function. 402 // E.g. ExtractReturnType<R(A, B, C)> is evaluated to R. 403 template <typename Signature> 404 using ExtractReturnType = typename ExtractArgsImpl<Signature>::ReturnType; 405 406 } // namespace internal 407 408 template <typename T> 409 static inline internal::UnretainedWrapper<T> Unretained(T* o) { 410 return internal::UnretainedWrapper<T>(o); 411 } 412 413 template <typename T> 414 static inline internal::RetainedRefWrapper<T> RetainedRef(T* o) { 415 return internal::RetainedRefWrapper<T>(o); 416 } 417 418 template <typename T> 419 static inline internal::RetainedRefWrapper<T> RetainedRef(scoped_refptr<T> o) { 420 return internal::RetainedRefWrapper<T>(std::move(o)); 421 } 422 423 template <typename T> 424 static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { 425 return internal::ConstRefWrapper<T>(o); 426 } 427 428 template <typename T> 429 static inline internal::OwnedWrapper<T> Owned(T* o) { 430 return internal::OwnedWrapper<T>(o); 431 } 432 433 // We offer 2 syntaxes for calling Passed(). The first takes an rvalue and 434 // is best suited for use with the return value of a function or other temporary 435 // rvalues. The second takes a pointer to the scoper and is just syntactic sugar 436 // to avoid having to write Passed(std::move(scoper)). 437 // 438 // Both versions of Passed() prevent T from being an lvalue reference. The first 439 // via use of enable_if, and the second takes a T* which will not bind to T&. 440 template <typename T, 441 typename std::enable_if<!std::is_lvalue_reference<T>::value>::type* = 442 nullptr> 443 static inline internal::PassedWrapper<T> Passed(T&& scoper) { 444 return internal::PassedWrapper<T>(std::move(scoper)); 445 } 446 template <typename T> 447 static inline internal::PassedWrapper<T> Passed(T* scoper) { 448 return internal::PassedWrapper<T>(std::move(*scoper)); 449 } 450 451 template <typename T> 452 static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { 453 return internal::IgnoreResultHelper<T>(std::move(data)); 454 } 455 456 BASE_EXPORT void DoNothing(); 457 458 template<typename T> 459 void DeletePointer(T* obj) { 460 delete obj; 461 } 462 463 // An injection point to control |this| pointer behavior on a method invocation. 464 // If IsWeakReceiver<> is true_type for |T| and |T| is used for a receiver of a 465 // method, base::Bind cancels the method invocation if the receiver is tested as 466 // false. 467 // E.g. Foo::bar() is not called: 468 // struct Foo : base::SupportsWeakPtr<Foo> { 469 // void bar() {} 470 // }; 471 // 472 // WeakPtr<Foo> oo = nullptr; 473 // base::Bind(&Foo::bar, oo).Run(); 474 template <typename T> 475 struct IsWeakReceiver : std::false_type {}; 476 477 template <typename T> 478 struct IsWeakReceiver<internal::ConstRefWrapper<T>> : IsWeakReceiver<T> {}; 479 480 template <typename T> 481 struct IsWeakReceiver<WeakPtr<T>> : std::true_type {}; 482 483 // An injection point to control how bound objects passed to the target 484 // function. BindUnwrapTraits<>::Unwrap() is called for each bound objects right 485 // before the target function is invoked. 486 template <typename> 487 struct BindUnwrapTraits { 488 template <typename T> 489 static T&& Unwrap(T&& o) { return std::forward<T>(o); } 490 }; 491 492 template <typename T> 493 struct BindUnwrapTraits<internal::UnretainedWrapper<T>> { 494 static T* Unwrap(const internal::UnretainedWrapper<T>& o) { 495 return o.get(); 496 } 497 }; 498 499 template <typename T> 500 struct BindUnwrapTraits<internal::ConstRefWrapper<T>> { 501 static const T& Unwrap(const internal::ConstRefWrapper<T>& o) { 502 return o.get(); 503 } 504 }; 505 506 template <typename T> 507 struct BindUnwrapTraits<internal::RetainedRefWrapper<T>> { 508 static T* Unwrap(const internal::RetainedRefWrapper<T>& o) { 509 return o.get(); 510 } 511 }; 512 513 template <typename T> 514 struct BindUnwrapTraits<internal::OwnedWrapper<T>> { 515 static T* Unwrap(const internal::OwnedWrapper<T>& o) { 516 return o.get(); 517 } 518 }; 519 520 template <typename T> 521 struct BindUnwrapTraits<internal::PassedWrapper<T>> { 522 static T Unwrap(const internal::PassedWrapper<T>& o) { 523 return o.Take(); 524 } 525 }; 526 527 // CallbackCancellationTraits allows customization of Callback's cancellation 528 // semantics. By default, callbacks are not cancellable. A specialization should 529 // set is_cancellable = true and implement an IsCancelled() that returns if the 530 // callback should be cancelled. 531 template <typename Functor, typename BoundArgsTuple, typename SFINAE = void> 532 struct CallbackCancellationTraits { 533 static constexpr bool is_cancellable = false; 534 }; 535 536 // Specialization for method bound to weak pointer receiver. 537 template <typename Functor, typename... BoundArgs> 538 struct CallbackCancellationTraits< 539 Functor, 540 std::tuple<BoundArgs...>, 541 typename std::enable_if< 542 internal::IsWeakMethod<internal::FunctorTraits<Functor>::is_method, 543 BoundArgs...>::value>::type> { 544 static constexpr bool is_cancellable = true; 545 546 template <typename Receiver, typename... Args> 547 static bool IsCancelled(const Functor&, 548 const Receiver& receiver, 549 const Args&...) { 550 return !receiver; 551 } 552 }; 553 554 // Specialization for a nested bind. 555 template <typename Signature, 556 typename... BoundArgs, 557 internal::CopyMode copy_mode, 558 internal::RepeatMode repeat_mode> 559 struct CallbackCancellationTraits<Callback<Signature, copy_mode, repeat_mode>, 560 std::tuple<BoundArgs...>> { 561 static constexpr bool is_cancellable = true; 562 563 template <typename Functor> 564 static bool IsCancelled(const Functor& functor, const BoundArgs&...) { 565 return functor.IsCancelled(); 566 } 567 }; 568 569 } // namespace base 570 571 #endif // BASE_BIND_HELPERS_H_ 572