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. scoped_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 172namespace base { 173 174template <typename T> 175struct IsWeakReceiver; 176 177namespace internal { 178 179template <typename T> 180class UnretainedWrapper { 181 public: 182 explicit UnretainedWrapper(T* o) : ptr_(o) {} 183 T* get() const { return ptr_; } 184 private: 185 T* ptr_; 186}; 187 188template <typename T> 189class ConstRefWrapper { 190 public: 191 explicit ConstRefWrapper(const T& o) : ptr_(&o) {} 192 const T& get() const { return *ptr_; } 193 private: 194 const T* ptr_; 195}; 196 197template <typename T> 198class RetainedRefWrapper { 199 public: 200 explicit RetainedRefWrapper(T* o) : ptr_(o) {} 201 explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {} 202 T* get() const { return ptr_.get(); } 203 private: 204 scoped_refptr<T> ptr_; 205}; 206 207template <typename T> 208struct IgnoreResultHelper { 209 explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {} 210 explicit operator bool() const { return !!functor_; } 211 212 T functor_; 213}; 214 215// An alternate implementation is to avoid the destructive copy, and instead 216// specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to 217// a class that is essentially a std::unique_ptr<>. 218// 219// The current implementation has the benefit though of leaving ParamTraits<> 220// fully in callback_internal.h as well as avoiding type conversions during 221// storage. 222template <typename T> 223class OwnedWrapper { 224 public: 225 explicit OwnedWrapper(T* o) : ptr_(o) {} 226 ~OwnedWrapper() { delete ptr_; } 227 T* get() const { return ptr_; } 228 OwnedWrapper(OwnedWrapper&& other) { 229 ptr_ = other.ptr_; 230 other.ptr_ = NULL; 231 } 232 233 private: 234 mutable T* ptr_; 235}; 236 237// PassedWrapper is a copyable adapter for a scoper that ignores const. 238// 239// It is needed to get around the fact that Bind() takes a const reference to 240// all its arguments. Because Bind() takes a const reference to avoid 241// unnecessary copies, it is incompatible with movable-but-not-copyable 242// types; doing a destructive "move" of the type into Bind() would violate 243// the const correctness. 244// 245// This conundrum cannot be solved without either C++11 rvalue references or 246// a O(2^n) blowup of Bind() templates to handle each combination of regular 247// types and movable-but-not-copyable types. Thus we introduce a wrapper type 248// that is copyable to transmit the correct type information down into 249// BindState<>. Ignoring const in this type makes sense because it is only 250// created when we are explicitly trying to do a destructive move. 251// 252// Two notes: 253// 1) PassedWrapper supports any type that has a move constructor, however 254// the type will need to be specifically whitelisted in order for it to be 255// bound to a Callback. We guard this explicitly at the call of Passed() 256// to make for clear errors. Things not given to Passed() will be forwarded 257// and stored by value which will not work for general move-only types. 258// 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" 259// scoper to a Callback and allow the Callback to execute once. 260template <typename T> 261class PassedWrapper { 262 public: 263 explicit PassedWrapper(T&& scoper) 264 : is_valid_(true), scoper_(std::move(scoper)) {} 265 PassedWrapper(PassedWrapper&& other) 266 : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {} 267 T Take() const { 268 CHECK(is_valid_); 269 is_valid_ = false; 270 return std::move(scoper_); 271 } 272 273 private: 274 mutable bool is_valid_; 275 mutable T scoper_; 276}; 277 278// Unwrap the stored parameters for the wrappers above. 279template <typename T> 280T&& Unwrap(T&& o) { 281 return std::forward<T>(o); 282} 283 284template <typename T> 285T* Unwrap(const UnretainedWrapper<T>& unretained) { 286 return unretained.get(); 287} 288 289template <typename T> 290const T& Unwrap(const ConstRefWrapper<T>& const_ref) { 291 return const_ref.get(); 292} 293 294template <typename T> 295T* Unwrap(const RetainedRefWrapper<T>& o) { 296 return o.get(); 297} 298 299template <typename T> 300T* Unwrap(const OwnedWrapper<T>& o) { 301 return o.get(); 302} 303 304template <typename T> 305T Unwrap(const PassedWrapper<T>& o) { 306 return o.Take(); 307} 308 309// 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 311// InvokeHelper that will no-op itself in the event the WeakPtr<> for 312// the target object is invalidated. 313// 314// The first argument should be the type of the object that will be received by 315// the method. 316template <bool is_method, typename... Args> 317struct IsWeakMethod : std::false_type {}; 318 319template <typename T, typename... Args> 320struct IsWeakMethod<true, T, Args...> : IsWeakReceiver<T> {}; 321 322// Packs a list of types to hold them in a single type. 323template <typename... Types> 324struct TypeList {}; 325 326// Used for DropTypeListItem implementation. 327template <size_t n, typename List> 328struct DropTypeListItemImpl; 329 330// Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. 331template <size_t n, typename T, typename... List> 332struct DropTypeListItemImpl<n, TypeList<T, List...>> 333 : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; 334 335template <typename T, typename... List> 336struct DropTypeListItemImpl<0, TypeList<T, List...>> { 337 using Type = TypeList<T, List...>; 338}; 339 340template <> 341struct DropTypeListItemImpl<0, TypeList<>> { 342 using Type = TypeList<>; 343}; 344 345// A type-level function that drops |n| list item from given TypeList. 346template <size_t n, typename List> 347using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; 348 349// Used for TakeTypeListItem implementation. 350template <size_t n, typename List, typename... Accum> 351struct TakeTypeListItemImpl; 352 353// Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. 354template <size_t n, typename T, typename... List, typename... Accum> 355struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...> 356 : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {}; 357 358template <typename T, typename... List, typename... Accum> 359struct TakeTypeListItemImpl<0, TypeList<T, List...>, Accum...> { 360 using Type = TypeList<Accum...>; 361}; 362 363template <typename... Accum> 364struct TakeTypeListItemImpl<0, TypeList<>, Accum...> { 365 using Type = TypeList<Accum...>; 366}; 367 368// A type-level function that takes first |n| list item from given TypeList. 369// E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to 370// TypeList<A, B, C>. 371template <size_t n, typename List> 372using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type; 373 374// Used for ConcatTypeLists implementation. 375template <typename List1, typename List2> 376struct ConcatTypeListsImpl; 377 378template <typename... Types1, typename... Types2> 379struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { 380 using Type = TypeList<Types1..., Types2...>; 381}; 382 383// A type-level function that concats two TypeLists. 384template <typename List1, typename List2> 385using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; 386 387// Used for MakeFunctionType implementation. 388template <typename R, typename ArgList> 389struct MakeFunctionTypeImpl; 390 391template <typename R, typename... Args> 392struct MakeFunctionTypeImpl<R, TypeList<Args...>> { 393 // MSVC 2013 doesn't support Type Alias of function types. 394 // Revisit this after we update it to newer version. 395 typedef R Type(Args...); 396}; 397 398// A type-level function that constructs a function type that has |R| as its 399// return type and has TypeLists items as its arguments. 400template <typename R, typename ArgList> 401using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; 402 403// Used for ExtractArgs and ExtractReturnType. 404template <typename Signature> 405struct ExtractArgsImpl; 406 407template <typename R, typename... Args> 408struct ExtractArgsImpl<R(Args...)> { 409 using ReturnType = R; 410 using ArgsList = TypeList<Args...>; 411}; 412 413// A type-level function that extracts function arguments into a TypeList. 414// E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>. 415template <typename Signature> 416using ExtractArgs = typename ExtractArgsImpl<Signature>::ArgsList; 417 418// A type-level function that extracts the return type of a function. 419// E.g. ExtractReturnType<R(A, B, C)> is evaluated to R. 420template <typename Signature> 421using ExtractReturnType = typename ExtractArgsImpl<Signature>::ReturnType; 422 423} // namespace internal 424 425template <typename T> 426static inline internal::UnretainedWrapper<T> Unretained(T* o) { 427 return internal::UnretainedWrapper<T>(o); 428} 429 430template <typename T> 431static inline internal::RetainedRefWrapper<T> RetainedRef(T* o) { 432 return internal::RetainedRefWrapper<T>(o); 433} 434 435template <typename T> 436static inline internal::RetainedRefWrapper<T> RetainedRef(scoped_refptr<T> o) { 437 return internal::RetainedRefWrapper<T>(std::move(o)); 438} 439 440template <typename T> 441static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { 442 return internal::ConstRefWrapper<T>(o); 443} 444 445template <typename T> 446static inline internal::OwnedWrapper<T> Owned(T* o) { 447 return internal::OwnedWrapper<T>(o); 448} 449 450// We offer 2 syntaxes for calling Passed(). The first takes an rvalue and 451// is best suited for use with the return value of a function or other temporary 452// rvalues. The second takes a pointer to the scoper and is just syntactic sugar 453// to avoid having to write Passed(std::move(scoper)). 454// 455// Both versions of Passed() prevent T from being an lvalue reference. The first 456// via use of enable_if, and the second takes a T* which will not bind to T&. 457template <typename T, 458 typename std::enable_if<!std::is_lvalue_reference<T>::value>::type* = 459 nullptr> 460static inline internal::PassedWrapper<T> Passed(T&& scoper) { 461 return internal::PassedWrapper<T>(std::move(scoper)); 462} 463template <typename T> 464static inline internal::PassedWrapper<T> Passed(T* scoper) { 465 return internal::PassedWrapper<T>(std::move(*scoper)); 466} 467 468template <typename T> 469static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { 470 return internal::IgnoreResultHelper<T>(std::move(data)); 471} 472 473BASE_EXPORT void DoNothing(); 474 475template<typename T> 476void DeletePointer(T* obj) { 477 delete obj; 478} 479 480// An injection point to control |this| pointer behavior on a method invocation. 481// If IsWeakReceiver<> is true_type for |T| and |T| is used for a receiver of a 482// method, base::Bind cancels the method invocation if the receiver is tested as 483// false. 484// E.g. Foo::bar() is not called: 485// struct Foo : base::SupportsWeakPtr<Foo> { 486// void bar() {} 487// }; 488// 489// WeakPtr<Foo> oo = nullptr; 490// base::Bind(&Foo::bar, oo).Run(); 491template <typename T> 492struct IsWeakReceiver : std::false_type {}; 493 494template <typename T> 495struct IsWeakReceiver<internal::ConstRefWrapper<T>> : IsWeakReceiver<T> {}; 496 497template <typename T> 498struct IsWeakReceiver<WeakPtr<T>> : std::true_type {}; 499 500} // namespace base 501 502#endif // BASE_BIND_HELPERS_H_ 503