Remove Bind and Callback. Uses std::function instead. Had to work around being unable to bind unique_ptr once in setup.cc, but otherwise this was straightforward. Change-Id: I0a5380412b5eba602d4e26ffc2cc1e5f1c2e525c Reviewed-on: https://gn-review.googlesource.com/c/gn/+/6100 Reviewed-by: Scott Graham <scottmg@chromium.org> Commit-Queue: Brett Wilson <brettw@chromium.org>
diff --git a/base/bind.h b/base/bind.h deleted file mode 100644 index 71df0fe..0000000 --- a/base/bind.h +++ /dev/null
@@ -1,457 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_BIND_H_ -#define BASE_BIND_H_ - -#include <utility> - -#include "base/bind_internal.h" - -// ----------------------------------------------------------------------------- -// Usage documentation -// ----------------------------------------------------------------------------- -// -// Overview: -// base::BindOnce() and base::BindRepeating() are helpers for creating -// base::OnceCallback and base::RepeatingCallback objects respectively. -// -// For a runnable object of n-arity, the base::Bind*() family allows partial -// application of the first m arguments. The remaining n - m arguments must be -// passed when invoking the callback with Run(). -// -// // The first argument is bound at callback creation; the remaining -// // two must be passed when calling Run() on the callback object. -// base::OnceCallback<void(int, long)> cb = base::BindOnce( -// [](short x, int y, long z) { return x * y * z; }, 42); -// -// When binding to a method, the receiver object must also be specified at -// callback creation time. When Run() is invoked, the method will be invoked on -// the specified receiver object. -// -// class C : public base::RefCounted<C> { void F(); }; -// auto instance = base::MakeRefCounted<C>(); -// auto cb = base::BindOnce(&C::F, instance); -// cb.Run(); // Identical to instance->F() -// -// base::Bind is currently a type alias for base::BindRepeating(). In the -// future, we expect to flip this to default to base::BindOnce(). -// -// See //docs/callback.md for the full documentation. -// -// ----------------------------------------------------------------------------- -// Implementation notes -// ----------------------------------------------------------------------------- -// -// If you're reading the implementation, before proceeding further, you should -// read the top comment of base/bind_internal.h for a definition of common -// terms and concepts. - -namespace base { - -namespace internal { - -// IsOnceCallback<T> is a std::true_type if |T| is a OnceCallback. -template <typename T> -struct IsOnceCallback : std::false_type {}; - -template <typename Signature> -struct IsOnceCallback<OnceCallback<Signature>> : std::true_type {}; - -// Helper to assert that parameter |i| of type |Arg| can be bound, which means: -// - |Arg| can be retained internally as |Storage|. -// - |Arg| can be forwarded as |Unwrapped| to |Param|. -template <size_t i, - typename Arg, - typename Storage, - typename Unwrapped, - typename Param> -struct AssertConstructible { - private: - static constexpr bool param_is_forwardable = - std::is_constructible<Param, Unwrapped>::value; - // Unlike the check for binding into storage below, the check for - // forwardability drops the const qualifier for repeating callbacks. This is - // to try to catch instances where std::move()--which forwards as a const - // reference with repeating callbacks--is used instead of base::Passed(). - static_assert( - param_is_forwardable || - !std::is_constructible<Param, std::decay_t<Unwrapped>&&>::value, - "Bound argument |i| is move-only but will be forwarded by copy. " - "Ensure |Arg| is bound using base::Passed(), not std::move()."); - static_assert( - param_is_forwardable, - "Bound argument |i| of type |Arg| cannot be forwarded as " - "|Unwrapped| to the bound functor, which declares it as |Param|."); - - static constexpr bool arg_is_storable = - std::is_constructible<Storage, Arg>::value; - static_assert(arg_is_storable || - !std::is_constructible<Storage, std::decay_t<Arg>&&>::value, - "Bound argument |i| is move-only but will be bound by copy. " - "Ensure |Arg| is mutable and bound using std::move()."); - static_assert(arg_is_storable, - "Bound argument |i| of type |Arg| cannot be converted and " - "bound as |Storage|."); -}; - -// Takes three same-length TypeLists, and applies AssertConstructible for each -// triples. -template <typename Index, - typename Args, - typename UnwrappedTypeList, - typename ParamsList> -struct AssertBindArgsValidity; - -template <size_t... Ns, - typename... Args, - typename... Unwrapped, - typename... Params> -struct AssertBindArgsValidity<std::index_sequence<Ns...>, - TypeList<Args...>, - TypeList<Unwrapped...>, - TypeList<Params...>> - : AssertConstructible<Ns, Args, std::decay_t<Args>, Unwrapped, Params>... { - static constexpr bool ok = true; -}; - -// The implementation of TransformToUnwrappedType below. -template <bool is_once, typename T> -struct TransformToUnwrappedTypeImpl; - -template <typename T> -struct TransformToUnwrappedTypeImpl<true, T> { - using StoredType = std::decay_t<T>; - using ForwardType = StoredType&&; - using Unwrapped = decltype(Unwrap(std::declval<ForwardType>())); -}; - -template <typename T> -struct TransformToUnwrappedTypeImpl<false, T> { - using StoredType = std::decay_t<T>; - using ForwardType = const StoredType&; - using Unwrapped = decltype(Unwrap(std::declval<ForwardType>())); -}; - -// Transform |T| into `Unwrapped` type, which is passed to the target function. -// Example: -// In is_once == true case, -// `int&&` -> `int&&`, -// `const int&` -> `int&&`, -// `OwnedWrapper<int>&` -> `int*&&`. -// In is_once == false case, -// `int&&` -> `const int&`, -// `const int&` -> `const int&`, -// `OwnedWrapper<int>&` -> `int* const &`. -template <bool is_once, typename T> -using TransformToUnwrappedType = - typename TransformToUnwrappedTypeImpl<is_once, T>::Unwrapped; - -// Transforms |Args| into `Unwrapped` types, and packs them into a TypeList. -// If |is_method| is true, tries to dereference the first argument to support -// smart pointers. -template <bool is_once, bool is_method, typename... Args> -struct MakeUnwrappedTypeListImpl { - using Type = TypeList<TransformToUnwrappedType<is_once, Args>...>; -}; - -// Performs special handling for this pointers. -// Example: -// int* -> int*, -// std::unique_ptr<int> -> int*. -template <bool is_once, typename Receiver, typename... Args> -struct MakeUnwrappedTypeListImpl<is_once, true, Receiver, Args...> { - using UnwrappedReceiver = TransformToUnwrappedType<is_once, Receiver>; - using Type = TypeList<decltype(&*std::declval<UnwrappedReceiver>()), - TransformToUnwrappedType<is_once, Args>...>; -}; - -template <bool is_once, bool is_method, typename... Args> -using MakeUnwrappedTypeList = - typename MakeUnwrappedTypeListImpl<is_once, is_method, Args...>::Type; - -} // namespace internal - -// Bind as OnceCallback. -template <typename Functor, typename... Args> -inline OnceCallback<MakeUnboundRunType<Functor, Args...>> BindOnce( - Functor&& functor, - Args&&... args) { - static_assert(!internal::IsOnceCallback<std::decay_t<Functor>>() || - (std::is_rvalue_reference<Functor&&>() && - !std::is_const<std::remove_reference_t<Functor>>()), - "BindOnce requires non-const rvalue for OnceCallback binding." - " I.e.: base::BindOnce(std::move(callback))."); - - // This block checks if each |args| matches to the corresponding params of the - // target function. This check does not affect the behavior of Bind, but its - // error message should be more readable. - using Helper = internal::BindTypeHelper<Functor, Args...>; - using FunctorTraits = typename Helper::FunctorTraits; - using BoundArgsList = typename Helper::BoundArgsList; - using UnwrappedArgsList = - internal::MakeUnwrappedTypeList<true, FunctorTraits::is_method, - Args&&...>; - using BoundParamsList = typename Helper::BoundParamsList; - static_assert(internal::AssertBindArgsValidity< - std::make_index_sequence<Helper::num_bounds>, BoundArgsList, - UnwrappedArgsList, BoundParamsList>::ok, - "The bound args need to be convertible to the target params."); - - using BindState = internal::MakeBindStateType<Functor, Args...>; - using UnboundRunType = MakeUnboundRunType<Functor, Args...>; - using Invoker = internal::Invoker<BindState, UnboundRunType>; - using CallbackType = OnceCallback<UnboundRunType>; - - // Store the invoke func into PolymorphicInvoke before casting it to - // InvokeFuncStorage, so that we can ensure its type matches to - // PolymorphicInvoke, to which CallbackType will cast back. - using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke; - PolymorphicInvoke invoke_func = &Invoker::RunOnce; - - using InvokeFuncStorage = internal::BindStateBase::InvokeFuncStorage; - return CallbackType(new BindState( - reinterpret_cast<InvokeFuncStorage>(invoke_func), - std::forward<Functor>(functor), std::forward<Args>(args)...)); -} - -// Bind as RepeatingCallback. -template <typename Functor, typename... Args> -inline RepeatingCallback<MakeUnboundRunType<Functor, Args...>> BindRepeating( - Functor&& functor, - Args&&... args) { - static_assert( - !internal::IsOnceCallback<std::decay_t<Functor>>(), - "BindRepeating cannot bind OnceCallback. Use BindOnce with std::move()."); - - // This block checks if each |args| matches to the corresponding params of the - // target function. This check does not affect the behavior of Bind, but its - // error message should be more readable. - using Helper = internal::BindTypeHelper<Functor, Args...>; - using FunctorTraits = typename Helper::FunctorTraits; - using BoundArgsList = typename Helper::BoundArgsList; - using UnwrappedArgsList = - internal::MakeUnwrappedTypeList<false, FunctorTraits::is_method, - Args&&...>; - using BoundParamsList = typename Helper::BoundParamsList; - static_assert(internal::AssertBindArgsValidity< - std::make_index_sequence<Helper::num_bounds>, BoundArgsList, - UnwrappedArgsList, BoundParamsList>::ok, - "The bound args need to be convertible to the target params."); - - using BindState = internal::MakeBindStateType<Functor, Args...>; - using UnboundRunType = MakeUnboundRunType<Functor, Args...>; - using Invoker = internal::Invoker<BindState, UnboundRunType>; - using CallbackType = RepeatingCallback<UnboundRunType>; - - // Store the invoke func into PolymorphicInvoke before casting it to - // InvokeFuncStorage, so that we can ensure its type matches to - // PolymorphicInvoke, to which CallbackType will cast back. - using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke; - PolymorphicInvoke invoke_func = &Invoker::Run; - - using InvokeFuncStorage = internal::BindStateBase::InvokeFuncStorage; - return CallbackType(new BindState( - reinterpret_cast<InvokeFuncStorage>(invoke_func), - std::forward<Functor>(functor), std::forward<Args>(args)...)); -} - -// Unannotated Bind. -// TODO(tzik): Deprecate this and migrate to OnceCallback and -// RepeatingCallback, once they get ready. -template <typename Functor, typename... Args> -inline Callback<MakeUnboundRunType<Functor, Args...>> Bind(Functor&& functor, - Args&&... args) { - return base::BindRepeating(std::forward<Functor>(functor), - std::forward<Args>(args)...); -} - -// Special cases for binding to a base::Callback without extra bound arguments. -template <typename Signature> -OnceCallback<Signature> BindOnce(OnceCallback<Signature> closure) { - return closure; -} - -template <typename Signature> -RepeatingCallback<Signature> BindRepeating( - RepeatingCallback<Signature> closure) { - return closure; -} - -template <typename Signature> -Callback<Signature> Bind(Callback<Signature> closure) { - return closure; -} - -// Unretained() allows Bind() to bind a non-refcounted class, and to disable -// refcounting on arguments that are refcounted objects. -// -// EXAMPLE OF Unretained(): -// -// class Foo { -// public: -// void func() { cout << "Foo:f" << endl; } -// }; -// -// // In some function somewhere. -// Foo foo; -// Closure foo_callback = -// Bind(&Foo::func, Unretained(&foo)); -// foo_callback.Run(); // Prints "Foo:f". -// -// Without the Unretained() wrapper on |&foo|, the above call would fail -// to compile because Foo does not support the AddRef() and Release() methods. -template <typename T> -static inline internal::UnretainedWrapper<T> Unretained(T* o) { - return internal::UnretainedWrapper<T>(o); -} - -// RetainedRef() accepts a ref counted object and retains a reference to it. -// When the callback is called, the object is passed as a raw pointer. -// -// EXAMPLE OF RetainedRef(): -// -// void foo(RefCountedBytes* bytes) {} -// -// scoped_refptr<RefCountedBytes> bytes = ...; -// Closure callback = Bind(&foo, base::RetainedRef(bytes)); -// callback.Run(); -// -// Without RetainedRef, the scoped_refptr would try to implicitly convert to -// a raw pointer and fail compilation: -// -// Closure callback = Bind(&foo, bytes); // ERROR! -template <typename T> -static inline internal::RetainedRefWrapper<T> RetainedRef(T* o) { - return internal::RetainedRefWrapper<T>(o); -} -template <typename T> -static inline internal::RetainedRefWrapper<T> RetainedRef(scoped_refptr<T> o) { - return internal::RetainedRefWrapper<T>(std::move(o)); -} - -// ConstRef() allows binding a constant reference to an argument rather -// than a copy. -// -// EXAMPLE OF ConstRef(): -// -// void foo(int arg) { cout << arg << endl } -// -// int n = 1; -// Closure no_ref = Bind(&foo, n); -// Closure has_ref = Bind(&foo, ConstRef(n)); -// -// no_ref.Run(); // Prints "1" -// has_ref.Run(); // Prints "1" -// -// n = 2; -// no_ref.Run(); // Prints "1" -// has_ref.Run(); // Prints "2" -// -// Note that because ConstRef() takes a reference on |n|, |n| must outlive all -// its bound callbacks. -template <typename T> -static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { - return internal::ConstRefWrapper<T>(o); -} - -// Owned() transfers ownership of an object to the Callback resulting from -// bind; the object will be deleted when the Callback is deleted. -// -// EXAMPLE OF Owned(): -// -// void foo(int* arg) { cout << *arg << endl } -// -// int* pn = new int(1); -// Closure foo_callback = Bind(&foo, Owned(pn)); -// -// foo_callback.Run(); // Prints "1" -// foo_callback.Run(); // Prints "1" -// *n = 2; -// foo_callback.Run(); // Prints "2" -// -// foo_callback.Reset(); // |pn| is deleted. Also will happen when -// // |foo_callback| goes out of scope. -// -// Without Owned(), someone would have to know to delete |pn| when the last -// reference to the Callback is deleted. -template <typename T> -static inline internal::OwnedWrapper<T> Owned(T* o) { - return internal::OwnedWrapper<T>(o); -} - -// Passed() is for transferring movable-but-not-copyable types (eg. unique_ptr) -// through a Callback. Logically, this signifies a destructive transfer of -// the state of the argument into the target function. Invoking -// Callback::Run() twice on a Callback that was created with a Passed() -// argument will CHECK() because the first invocation would have already -// transferred ownership to the target function. -// -// Note that Passed() is not necessary with BindOnce(), as std::move() does the -// same thing. Avoid Passed() in favor of std::move() with BindOnce(). -// -// EXAMPLE OF Passed(): -// -// void TakesOwnership(std::unique_ptr<Foo> arg) { } -// std::unique_ptr<Foo> CreateFoo() { return std::make_unique<Foo>(); -// } -// -// auto f = std::make_unique<Foo>(); -// -// // |cb| is given ownership of Foo(). |f| is now NULL. -// // You can use std::move(f) in place of &f, but it's more verbose. -// Closure cb = Bind(&TakesOwnership, Passed(&f)); -// -// // Run was never called so |cb| still owns Foo() and deletes -// // it on Reset(). -// cb.Reset(); -// -// // |cb| is given a new Foo created by CreateFoo(). -// cb = Bind(&TakesOwnership, Passed(CreateFoo())); -// -// // |arg| in TakesOwnership() is given ownership of Foo(). |cb| -// // no longer owns Foo() and, if reset, would not delete Foo(). -// cb.Run(); // Foo() is now transferred to |arg| and deleted. -// cb.Run(); // This CHECK()s since Foo() already been used once. -// -// We offer 2 syntaxes for calling Passed(). The first takes an rvalue and -// is best suited for use with the return value of a function or other temporary -// rvalues. The second takes a pointer to the scoper and is just syntactic sugar -// to avoid having to write Passed(std::move(scoper)). -// -// Both versions of Passed() prevent T from being an lvalue reference. The first -// via use of enable_if, and the second takes a T* which will not bind to T&. -template <typename T, - std::enable_if_t<!std::is_lvalue_reference<T>::value>* = nullptr> -static inline internal::PassedWrapper<T> Passed(T&& scoper) { - return internal::PassedWrapper<T>(std::move(scoper)); -} -template <typename T> -static inline internal::PassedWrapper<T> Passed(T* scoper) { - return internal::PassedWrapper<T>(std::move(*scoper)); -} - -// IgnoreResult() is used to adapt a function or Callback with a return type to -// one with a void return. This is most useful if you have a function with, -// say, a pesky ignorable bool return that you want to use with PostTask or -// something else that expect a Callback with a void return. -// -// EXAMPLE OF IgnoreResult(): -// -// int DoSomething(int arg) { cout << arg << endl; } -// -// // Assign to a Callback with a void return type. -// Callback<void(int)> cb = Bind(IgnoreResult(&DoSomething)); -// cb->Run(1); // Prints "1". -// -// // Prints "1" on |ml|. -// ml->PostTask(FROM_HERE, Bind(IgnoreResult(&DoSomething), 1); -template <typename T> -static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { - return internal::IgnoreResultHelper<T>(std::move(data)); -} - -} // namespace base - -#endif // BASE_BIND_H_
diff --git a/base/bind_internal.h b/base/bind_internal.h deleted file mode 100644 index 89c1600..0000000 --- a/base/bind_internal.h +++ /dev/null
@@ -1,913 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_BIND_INTERNAL_H_ -#define BASE_BIND_INTERNAL_H_ - -#include <stddef.h> - -#include <tuple> -#include <type_traits> -#include <utility> - -#include "base/callback_internal.h" -#include "base/memory/raw_scoped_refptr_mismatch_checker.h" -#include "base/memory/weak_ptr.h" -#include "base/template_util.h" -#include "util/build_config.h" - -// See base/callback.h for user documentation. -// -// -// CONCEPTS: -// Functor -- A movable type representing something that should be called. -// All function pointers and Callback<> are functors even if the -// invocation syntax differs. -// RunType -- A function type (as opposed to function _pointer_ type) for -// a Callback<>::Run(). Usually just a convenience typedef. -// (Bound)Args -- A set of types that stores the arguments. -// -// Types: -// ForceVoidReturn<> -- Helper class for translating function signatures to -// equivalent forms with a "void" return type. -// FunctorTraits<> -- Type traits used to determine the correct RunType and -// invocation manner for a Functor. This is where function -// signature adapters are applied. -// InvokeHelper<> -- Take a Functor + arguments and actully invokes it. -// Handle the differing syntaxes needed for WeakPtr<> -// support. This is separate from Invoker to avoid creating -// multiple version of Invoker<>. -// Invoker<> -- Unwraps the curried parameters and executes the Functor. -// BindState<> -- Stores the curried parameters, and is the main entry point -// into the Bind() system. - -namespace base { - -template <typename T> -struct IsWeakReceiver; - -template <typename> -struct BindUnwrapTraits; - -template <typename Functor, typename BoundArgsTuple, typename SFINAE = void> -struct CallbackCancellationTraits; - -namespace internal { - -template <typename Functor, typename SFINAE = void> -struct FunctorTraits; - -template <typename T> -class UnretainedWrapper { - public: - explicit UnretainedWrapper(T* o) : ptr_(o) {} - T* get() const { return ptr_; } - - private: - T* ptr_; -}; - -template <typename T> -class ConstRefWrapper { - public: - explicit ConstRefWrapper(const T& o) : ptr_(&o) {} - const T& get() const { return *ptr_; } - - private: - const T* ptr_; -}; - -template <typename T> -class RetainedRefWrapper { - public: - explicit RetainedRefWrapper(T* o) : ptr_(o) {} - explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {} - T* get() const { return ptr_.get(); } - - private: - scoped_refptr<T> ptr_; -}; - -template <typename T> -struct IgnoreResultHelper { - explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {} - explicit operator bool() const { return !!functor_; } - - T functor_; -}; - -// An alternate implementation is to avoid the destructive copy, and instead -// specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to -// a class that is essentially a std::unique_ptr<>. -// -// The current implementation has the benefit though of leaving ParamTraits<> -// fully in callback_internal.h as well as avoiding type conversions during -// storage. -template <typename T> -class OwnedWrapper { - public: - explicit OwnedWrapper(T* o) : ptr_(o) {} - ~OwnedWrapper() { delete ptr_; } - T* get() const { return ptr_; } - OwnedWrapper(OwnedWrapper&& other) { - ptr_ = other.ptr_; - other.ptr_ = NULL; - } - - private: - mutable T* ptr_; -}; - -// PassedWrapper is a copyable adapter for a scoper that ignores const. -// -// It is needed to get around the fact that Bind() takes a const reference to -// all its arguments. Because Bind() takes a const reference to avoid -// unnecessary copies, it is incompatible with movable-but-not-copyable -// types; doing a destructive "move" of the type into Bind() would violate -// the const correctness. -// -// This conundrum cannot be solved without either C++11 rvalue references or -// a O(2^n) blowup of Bind() templates to handle each combination of regular -// types and movable-but-not-copyable types. Thus we introduce a wrapper type -// that is copyable to transmit the correct type information down into -// BindState<>. Ignoring const in this type makes sense because it is only -// created when we are explicitly trying to do a destructive move. -// -// Two notes: -// 1) PassedWrapper supports any type that has a move constructor, however -// the type will need to be specifically whitelisted in order for it to be -// bound to a Callback. We guard this explicitly at the call of Passed() -// to make for clear errors. Things not given to Passed() will be forwarded -// and stored by value which will not work for general move-only types. -// 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" -// scoper to a Callback and allow the Callback to execute once. -template <typename T> -class PassedWrapper { - public: - explicit PassedWrapper(T&& scoper) - : is_valid_(true), scoper_(std::move(scoper)) {} - PassedWrapper(PassedWrapper&& other) - : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {} - T Take() const { - CHECK(is_valid_); - is_valid_ = false; - return std::move(scoper_); - } - - private: - mutable bool is_valid_; - mutable T scoper_; -}; - -template <typename T> -using Unwrapper = BindUnwrapTraits<std::decay_t<T>>; - -template <typename T> -decltype(auto) Unwrap(T&& o) { - return Unwrapper<T>::Unwrap(std::forward<T>(o)); -} - -// IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a -// method. It is used internally by Bind() to select the correct -// InvokeHelper that will no-op itself in the event the WeakPtr<> for -// the target object is invalidated. -// -// The first argument should be the type of the object that will be received by -// the method. -template <bool is_method, typename... Args> -struct IsWeakMethod : std::false_type {}; - -template <typename T, typename... Args> -struct IsWeakMethod<true, T, Args...> : IsWeakReceiver<T> {}; - -// Packs a list of types to hold them in a single type. -template <typename... Types> -struct TypeList {}; - -// Used for DropTypeListItem implementation. -template <size_t n, typename List> -struct DropTypeListItemImpl; - -// Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. -template <size_t n, typename T, typename... List> -struct DropTypeListItemImpl<n, TypeList<T, List...>> - : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; - -template <typename T, typename... List> -struct DropTypeListItemImpl<0, TypeList<T, List...>> { - using Type = TypeList<T, List...>; -}; - -template <> -struct DropTypeListItemImpl<0, TypeList<>> { - using Type = TypeList<>; -}; - -// A type-level function that drops |n| list item from given TypeList. -template <size_t n, typename List> -using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; - -// Used for TakeTypeListItem implementation. -template <size_t n, typename List, typename... Accum> -struct TakeTypeListItemImpl; - -// Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. -template <size_t n, typename T, typename... List, typename... Accum> -struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...> - : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {}; - -template <typename T, typename... List, typename... Accum> -struct TakeTypeListItemImpl<0, TypeList<T, List...>, Accum...> { - using Type = TypeList<Accum...>; -}; - -template <typename... Accum> -struct TakeTypeListItemImpl<0, TypeList<>, Accum...> { - using Type = TypeList<Accum...>; -}; - -// A type-level function that takes first |n| list item from given TypeList. -// E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to -// TypeList<A, B, C>. -template <size_t n, typename List> -using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type; - -// Used for ConcatTypeLists implementation. -template <typename List1, typename List2> -struct ConcatTypeListsImpl; - -template <typename... Types1, typename... Types2> -struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { - using Type = TypeList<Types1..., Types2...>; -}; - -// A type-level function that concats two TypeLists. -template <typename List1, typename List2> -using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; - -// Used for MakeFunctionType implementation. -template <typename R, typename ArgList> -struct MakeFunctionTypeImpl; - -template <typename R, typename... Args> -struct MakeFunctionTypeImpl<R, TypeList<Args...>> { - // MSVC 2013 doesn't support Type Alias of function types. - // Revisit this after we update it to newer version. - typedef R Type(Args...); -}; - -// A type-level function that constructs a function type that has |R| as its -// return type and has TypeLists items as its arguments. -template <typename R, typename ArgList> -using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; - -// Used for ExtractArgs and ExtractReturnType. -template <typename Signature> -struct ExtractArgsImpl; - -template <typename R, typename... Args> -struct ExtractArgsImpl<R(Args...)> { - using ReturnType = R; - using ArgsList = TypeList<Args...>; -}; - -// A type-level function that extracts function arguments into a TypeList. -// E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>. -template <typename Signature> -using ExtractArgs = typename ExtractArgsImpl<Signature>::ArgsList; - -// A type-level function that extracts the return type of a function. -// E.g. ExtractReturnType<R(A, B, C)> is evaluated to R. -template <typename Signature> -using ExtractReturnType = typename ExtractArgsImpl<Signature>::ReturnType; - -template <typename Callable, - typename Signature = decltype(&Callable::operator())> -struct ExtractCallableRunTypeImpl; - -template <typename Callable, typename R, typename... Args> -struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...)> { - using Type = R(Args...); -}; - -template <typename Callable, typename R, typename... Args> -struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...) const> { - using Type = R(Args...); -}; - -// Evaluated to RunType of the given callable type. -// Example: -// auto f = [](int, char*) { return 0.1; }; -// ExtractCallableRunType<decltype(f)> -// is evaluated to -// double(int, char*); -template <typename Callable> -using ExtractCallableRunType = - typename ExtractCallableRunTypeImpl<Callable>::Type; - -// IsCallableObject<Functor> is std::true_type if |Functor| has operator(). -// Otherwise, it's std::false_type. -// Example: -// IsCallableObject<void(*)()>::value is false. -// -// struct Foo {}; -// IsCallableObject<void(Foo::*)()>::value is false. -// -// int i = 0; -// auto f = [i]() {}; -// IsCallableObject<decltype(f)>::value is false. -template <typename Functor, typename SFINAE = void> -struct IsCallableObject : std::false_type {}; - -template <typename Callable> -struct IsCallableObject<Callable, std::void_t<decltype(&Callable::operator())>> - : std::true_type {}; - -// HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw -// pointer to a RefCounted type. -// Implementation note: This non-specialized case handles zero-arity case only. -// Non-zero-arity cases should be handled by the specialization below. -template <typename... Args> -struct HasRefCountedTypeAsRawPtr : std::false_type {}; - -// Implementation note: Select true_type if the first parameter is a raw pointer -// to a RefCounted type. Otherwise, skip the first parameter and check rest of -// parameters recursively. -template <typename T, typename... Args> -struct HasRefCountedTypeAsRawPtr<T, Args...> - : std::conditional_t<NeedsScopedRefptrButGetsRawPtr<T>::value, - std::true_type, - HasRefCountedTypeAsRawPtr<Args...>> {}; - -// ForceVoidReturn<> -// -// Set of templates that support forcing the function return type to void. -template <typename Sig> -struct ForceVoidReturn; - -template <typename R, typename... Args> -struct ForceVoidReturn<R(Args...)> { - using RunType = void(Args...); -}; - -// FunctorTraits<> -// -// See description at top of file. -template <typename Functor, typename SFINAE> -struct FunctorTraits; - -// For empty callable types. -// This specialization is intended to allow binding captureless lambdas by -// base::Bind(), based on the fact that captureless lambdas are empty while -// capturing lambdas are not. This also allows any functors as far as it's an -// empty class. -// Example: -// -// // Captureless lambdas are allowed. -// []() {return 42;}; -// -// // Capturing lambdas are *not* allowed. -// int x; -// [x]() {return x;}; -// -// // Any empty class with operator() is allowed. -// struct Foo { -// void operator()() const {} -// // No non-static member variable and no virtual functions. -// }; -template <typename Functor> -struct FunctorTraits<Functor, - std::enable_if_t<IsCallableObject<Functor>::value && - std::is_empty<Functor>::value>> { - using RunType = ExtractCallableRunType<Functor>; - static constexpr bool is_method = false; - static constexpr bool is_nullable = false; - - template <typename RunFunctor, typename... RunArgs> - static ExtractReturnType<RunType> Invoke(RunFunctor&& functor, - RunArgs&&... args) { - return std::forward<RunFunctor>(functor)(std::forward<RunArgs>(args)...); - } -}; - -// For functions. -template <typename R, typename... Args> -struct FunctorTraits<R (*)(Args...)> { - using RunType = R(Args...); - static constexpr bool is_method = false; - static constexpr bool is_nullable = true; - - template <typename Function, typename... RunArgs> - static R Invoke(Function&& function, RunArgs&&... args) { - return std::forward<Function>(function)(std::forward<RunArgs>(args)...); - } -}; - -#if defined(OS_WIN) && !defined(ARCH_CPU_X86_64) - -// For functions. -template <typename R, typename... Args> -struct FunctorTraits<R(__stdcall*)(Args...)> { - using RunType = R(Args...); - static constexpr bool is_method = false; - static constexpr bool is_nullable = true; - - template <typename... RunArgs> - static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) { - return function(std::forward<RunArgs>(args)...); - } -}; - -// For functions. -template <typename R, typename... Args> -struct FunctorTraits<R(__fastcall*)(Args...)> { - using RunType = R(Args...); - static constexpr bool is_method = false; - static constexpr bool is_nullable = true; - - template <typename... RunArgs> - static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) { - return function(std::forward<RunArgs>(args)...); - } -}; - -#endif // defined(OS_WIN) && !defined(ARCH_CPU_X86_64) - -// For methods. -template <typename R, typename Receiver, typename... Args> -struct FunctorTraits<R (Receiver::*)(Args...)> { - using RunType = R(Receiver*, Args...); - static constexpr bool is_method = true; - static constexpr bool is_nullable = true; - - template <typename Method, typename ReceiverPtr, typename... RunArgs> - static R Invoke(Method method, - ReceiverPtr&& receiver_ptr, - RunArgs&&... args) { - return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); - } -}; - -// For const methods. -template <typename R, typename Receiver, typename... Args> -struct FunctorTraits<R (Receiver::*)(Args...) const> { - using RunType = R(const Receiver*, Args...); - static constexpr bool is_method = true; - static constexpr bool is_nullable = true; - - template <typename Method, typename ReceiverPtr, typename... RunArgs> - static R Invoke(Method method, - ReceiverPtr&& receiver_ptr, - RunArgs&&... args) { - return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); - } -}; - -#ifdef __cpp_noexcept_function_type -// noexcept makes a distinct function type in C++17. -// I.e. `void(*)()` and `void(*)() noexcept` are same in pre-C++17, and -// different in C++17. -template <typename R, typename... Args> -struct FunctorTraits<R (*)(Args...) noexcept> : FunctorTraits<R (*)(Args...)> { -}; - -template <typename R, typename Receiver, typename... Args> -struct FunctorTraits<R (Receiver::*)(Args...) noexcept> - : FunctorTraits<R (Receiver::*)(Args...)> {}; - -template <typename R, typename Receiver, typename... Args> -struct FunctorTraits<R (Receiver::*)(Args...) const noexcept> - : FunctorTraits<R (Receiver::*)(Args...) const> {}; -#endif - -// For IgnoreResults. -template <typename T> -struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> { - using RunType = - typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType; - - template <typename IgnoreResultType, typename... RunArgs> - static void Invoke(IgnoreResultType&& ignore_result_helper, - RunArgs&&... args) { - FunctorTraits<T>::Invoke( - std::forward<IgnoreResultType>(ignore_result_helper).functor_, - std::forward<RunArgs>(args)...); - } -}; - -// For OnceCallbacks. -template <typename R, typename... Args> -struct FunctorTraits<OnceCallback<R(Args...)>> { - using RunType = R(Args...); - static constexpr bool is_method = false; - static constexpr bool is_nullable = true; - - template <typename CallbackType, typename... RunArgs> - static R Invoke(CallbackType&& callback, RunArgs&&... args) { - DCHECK(!callback.is_null()); - return std::forward<CallbackType>(callback).Run( - std::forward<RunArgs>(args)...); - } -}; - -// For RepeatingCallbacks. -template <typename R, typename... Args> -struct FunctorTraits<RepeatingCallback<R(Args...)>> { - using RunType = R(Args...); - static constexpr bool is_method = false; - static constexpr bool is_nullable = true; - - template <typename CallbackType, typename... RunArgs> - static R Invoke(CallbackType&& callback, RunArgs&&... args) { - DCHECK(!callback.is_null()); - return std::forward<CallbackType>(callback).Run( - std::forward<RunArgs>(args)...); - } -}; - -template <typename Functor> -using MakeFunctorTraits = FunctorTraits<std::decay_t<Functor>>; - -// InvokeHelper<> -// -// There are 2 logical InvokeHelper<> specializations: normal, WeakCalls. -// -// The normal type just calls the underlying runnable. -// -// WeakCalls need special syntax that is applied to the first argument to check -// if they should no-op themselves. -template <bool is_weak_call, typename ReturnType> -struct InvokeHelper; - -template <typename ReturnType> -struct InvokeHelper<false, ReturnType> { - template <typename Functor, typename... RunArgs> - static inline ReturnType MakeItSo(Functor&& functor, RunArgs&&... args) { - using Traits = MakeFunctorTraits<Functor>; - return Traits::Invoke(std::forward<Functor>(functor), - std::forward<RunArgs>(args)...); - } -}; - -template <typename ReturnType> -struct InvokeHelper<true, ReturnType> { - // WeakCalls are only supported for functions with a void return type. - // Otherwise, the function result would be undefined if the the WeakPtr<> - // is invalidated. - static_assert(std::is_void<ReturnType>::value, - "weak_ptrs can only bind to methods without return values"); - - template <typename Functor, typename BoundWeakPtr, typename... RunArgs> - static inline void MakeItSo(Functor&& functor, - BoundWeakPtr&& weak_ptr, - RunArgs&&... args) { - if (!weak_ptr) - return; - using Traits = MakeFunctorTraits<Functor>; - Traits::Invoke(std::forward<Functor>(functor), - std::forward<BoundWeakPtr>(weak_ptr), - std::forward<RunArgs>(args)...); - } -}; - -// Invoker<> -// -// See description at the top of the file. -template <typename StorageType, typename UnboundRunType> -struct Invoker; - -template <typename StorageType, typename R, typename... UnboundArgs> -struct Invoker<StorageType, R(UnboundArgs...)> { - static R RunOnce(BindStateBase* base, - PassingTraitsType<UnboundArgs>... unbound_args) { - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - StorageType* storage = static_cast<StorageType*>(base); - static constexpr size_t num_bound_args = - std::tuple_size<decltype(storage->bound_args_)>::value; - return RunImpl(std::move(storage->functor_), - std::move(storage->bound_args_), - std::make_index_sequence<num_bound_args>(), - std::forward<UnboundArgs>(unbound_args)...); - } - - static R Run(BindStateBase* base, - PassingTraitsType<UnboundArgs>... unbound_args) { - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - const StorageType* storage = static_cast<StorageType*>(base); - static constexpr size_t num_bound_args = - std::tuple_size<decltype(storage->bound_args_)>::value; - return RunImpl(storage->functor_, storage->bound_args_, - std::make_index_sequence<num_bound_args>(), - std::forward<UnboundArgs>(unbound_args)...); - } - - private: - template <typename Functor, typename BoundArgsTuple, size_t... indices> - static inline R RunImpl(Functor&& functor, - BoundArgsTuple&& bound, - std::index_sequence<indices...>, - UnboundArgs&&... unbound_args) { - static constexpr bool is_method = MakeFunctorTraits<Functor>::is_method; - - using DecayedArgsTuple = std::decay_t<BoundArgsTuple>; - static constexpr bool is_weak_call = - IsWeakMethod<is_method, - std::tuple_element_t<indices, DecayedArgsTuple>...>(); - - return InvokeHelper<is_weak_call, R>::MakeItSo( - std::forward<Functor>(functor), - Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))..., - std::forward<UnboundArgs>(unbound_args)...); - } -}; - -// Extracts necessary type info from Functor and BoundArgs. -// Used to implement MakeUnboundRunType, BindOnce and BindRepeating. -template <typename Functor, typename... BoundArgs> -struct BindTypeHelper { - static constexpr size_t num_bounds = sizeof...(BoundArgs); - using FunctorTraits = MakeFunctorTraits<Functor>; - - // Example: - // When Functor is `double (Foo::*)(int, const std::string&)`, and BoundArgs - // is a template pack of `Foo*` and `int16_t`: - // - RunType is `double(Foo*, int, const std::string&)`, - // - ReturnType is `double`, - // - RunParamsList is `TypeList<Foo*, int, const std::string&>`, - // - BoundParamsList is `TypeList<Foo*, int>`, - // - UnboundParamsList is `TypeList<const std::string&>`, - // - BoundArgsList is `TypeList<Foo*, int16_t>`, - // - UnboundRunType is `double(const std::string&)`. - using RunType = typename FunctorTraits::RunType; - using ReturnType = ExtractReturnType<RunType>; - - using RunParamsList = ExtractArgs<RunType>; - using BoundParamsList = TakeTypeListItem<num_bounds, RunParamsList>; - using UnboundParamsList = DropTypeListItem<num_bounds, RunParamsList>; - - using BoundArgsList = TypeList<BoundArgs...>; - - using UnboundRunType = MakeFunctionType<ReturnType, UnboundParamsList>; -}; - -template <typename Functor> -std::enable_if_t<FunctorTraits<Functor>::is_nullable, bool> IsNull( - const Functor& functor) { - return !functor; -} - -template <typename Functor> -std::enable_if_t<!FunctorTraits<Functor>::is_nullable, bool> IsNull( - const Functor&) { - return false; -} - -// Used by ApplyCancellationTraits below. -template <typename Functor, typename BoundArgsTuple, size_t... indices> -bool ApplyCancellationTraitsImpl(const Functor& functor, - const BoundArgsTuple& bound_args, - std::index_sequence<indices...>) { - return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled( - functor, std::get<indices>(bound_args)...); -} - -// Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns -// true if the callback |base| represents is canceled. -template <typename BindStateType> -bool ApplyCancellationTraits(const BindStateBase* base) { - const BindStateType* storage = static_cast<const BindStateType*>(base); - static constexpr size_t num_bound_args = - std::tuple_size<decltype(storage->bound_args_)>::value; - return ApplyCancellationTraitsImpl( - storage->functor_, storage->bound_args_, - std::make_index_sequence<num_bound_args>()); -}; - -// BindState<> -// -// This stores all the state passed into Bind(). -template <typename Functor, typename... BoundArgs> -struct BindState final : BindStateBase { - using IsCancellable = std::integral_constant< - bool, - CallbackCancellationTraits<Functor, - std::tuple<BoundArgs...>>::is_cancellable>; - - template <typename ForwardFunctor, typename... ForwardBoundArgs> - explicit BindState(BindStateBase::InvokeFuncStorage invoke_func, - ForwardFunctor&& functor, - ForwardBoundArgs&&... bound_args) - // IsCancellable is std::false_type if - // CallbackCancellationTraits<>::IsCancelled returns always false. - // Otherwise, it's std::true_type. - : BindState(IsCancellable{}, - invoke_func, - std::forward<ForwardFunctor>(functor), - std::forward<ForwardBoundArgs>(bound_args)...) {} - - Functor functor_; - std::tuple<BoundArgs...> bound_args_; - - private: - template <typename ForwardFunctor, typename... ForwardBoundArgs> - explicit BindState(std::true_type, - BindStateBase::InvokeFuncStorage invoke_func, - ForwardFunctor&& functor, - ForwardBoundArgs&&... bound_args) - : BindStateBase(invoke_func, - &Destroy, - &ApplyCancellationTraits<BindState>), - functor_(std::forward<ForwardFunctor>(functor)), - bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { - DCHECK(!IsNull(functor_)); - } - - template <typename ForwardFunctor, typename... ForwardBoundArgs> - explicit BindState(std::false_type, - BindStateBase::InvokeFuncStorage invoke_func, - ForwardFunctor&& functor, - ForwardBoundArgs&&... bound_args) - : BindStateBase(invoke_func, &Destroy), - functor_(std::forward<ForwardFunctor>(functor)), - bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { - DCHECK(!IsNull(functor_)); - } - - ~BindState() = default; - - static void Destroy(const BindStateBase* self) { - delete static_cast<const BindState*>(self); - } -}; - -// Used to implement MakeBindStateType. -template <bool is_method, typename Functor, typename... BoundArgs> -struct MakeBindStateTypeImpl; - -template <typename Functor, typename... BoundArgs> -struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> { - static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value, - "A parameter is a refcounted type and needs scoped_refptr."); - using Type = BindState<std::decay_t<Functor>, std::decay_t<BoundArgs>...>; -}; - -template <typename Functor> -struct MakeBindStateTypeImpl<true, Functor> { - using Type = BindState<std::decay_t<Functor>>; -}; - -template <typename Functor, typename Receiver, typename... BoundArgs> -struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> { - private: - using DecayedReceiver = std::decay_t<Receiver>; - - static_assert(!std::is_array<std::remove_reference_t<Receiver>>::value, - "First bound argument to a method cannot be an array."); - static_assert( - !std::is_pointer<DecayedReceiver>::value || - IsRefCountedType<std::remove_pointer_t<DecayedReceiver>>::value, - "Receivers may not be raw pointers. If using a raw pointer here is safe" - " and has no lifetime concerns, use base::Unretained() and document why" - " it's safe."); - static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value, - "A parameter is a refcounted type and needs scoped_refptr."); - - public: - using Type = BindState< - std::decay_t<Functor>, - std::conditional_t<std::is_pointer<DecayedReceiver>::value, - scoped_refptr<std::remove_pointer_t<DecayedReceiver>>, - DecayedReceiver>, - std::decay_t<BoundArgs>...>; -}; - -template <typename Functor, typename... BoundArgs> -using MakeBindStateType = - typename MakeBindStateTypeImpl<MakeFunctorTraits<Functor>::is_method, - Functor, - BoundArgs...>::Type; - -} // namespace internal - -// An injection point to control |this| pointer behavior on a method invocation. -// If IsWeakReceiver<> is true_type for |T| and |T| is used for a receiver of a -// method, base::Bind cancels the method invocation if the receiver is tested as -// false. -// E.g. Foo::bar() is not called: -// struct Foo : base::SupportsWeakPtr<Foo> { -// void bar() {} -// }; -// -// WeakPtr<Foo> oo = nullptr; -// base::Bind(&Foo::bar, oo).Run(); -template <typename T> -struct IsWeakReceiver : std::false_type {}; - -template <typename T> -struct IsWeakReceiver<internal::ConstRefWrapper<T>> : IsWeakReceiver<T> {}; - -template <typename T> -struct IsWeakReceiver<WeakPtr<T>> : std::true_type {}; - -// An injection point to control how bound objects passed to the target -// function. BindUnwrapTraits<>::Unwrap() is called for each bound objects right -// before the target function is invoked. -template <typename> -struct BindUnwrapTraits { - template <typename T> - static T&& Unwrap(T&& o) { - return std::forward<T>(o); - } -}; - -template <typename T> -struct BindUnwrapTraits<internal::UnretainedWrapper<T>> { - static T* Unwrap(const internal::UnretainedWrapper<T>& o) { return o.get(); } -}; - -template <typename T> -struct BindUnwrapTraits<internal::ConstRefWrapper<T>> { - static const T& Unwrap(const internal::ConstRefWrapper<T>& o) { - return o.get(); - } -}; - -template <typename T> -struct BindUnwrapTraits<internal::RetainedRefWrapper<T>> { - static T* Unwrap(const internal::RetainedRefWrapper<T>& o) { return o.get(); } -}; - -template <typename T> -struct BindUnwrapTraits<internal::OwnedWrapper<T>> { - static T* Unwrap(const internal::OwnedWrapper<T>& o) { return o.get(); } -}; - -template <typename T> -struct BindUnwrapTraits<internal::PassedWrapper<T>> { - static T Unwrap(const internal::PassedWrapper<T>& o) { return o.Take(); } -}; - -// CallbackCancellationTraits allows customization of Callback's cancellation -// semantics. By default, callbacks are not cancellable. A specialization should -// set is_cancellable = true and implement an IsCancelled() that returns if the -// callback should be cancelled. -template <typename Functor, typename BoundArgsTuple, typename SFINAE> -struct CallbackCancellationTraits { - static constexpr bool is_cancellable = false; -}; - -// Specialization for method bound to weak pointer receiver. -template <typename Functor, typename... BoundArgs> -struct CallbackCancellationTraits< - Functor, - std::tuple<BoundArgs...>, - std::enable_if_t< - internal::IsWeakMethod<internal::FunctorTraits<Functor>::is_method, - BoundArgs...>::value>> { - static constexpr bool is_cancellable = true; - - template <typename Receiver, typename... Args> - static bool IsCancelled(const Functor&, - const Receiver& receiver, - const Args&...) { - return !receiver; - } -}; - -// Specialization for a nested bind. -template <typename Signature, typename... BoundArgs> -struct CallbackCancellationTraits<OnceCallback<Signature>, - std::tuple<BoundArgs...>> { - static constexpr bool is_cancellable = true; - - template <typename Functor> - static bool IsCancelled(const Functor& functor, const BoundArgs&...) { - return functor.IsCancelled(); - } -}; - -template <typename Signature, typename... BoundArgs> -struct CallbackCancellationTraits<RepeatingCallback<Signature>, - std::tuple<BoundArgs...>> { - static constexpr bool is_cancellable = true; - - template <typename Functor> - static bool IsCancelled(const Functor& functor, const BoundArgs&...) { - return functor.IsCancelled(); - } -}; - -// Returns a RunType of bound functor. -// E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). -template <typename Functor, typename... BoundArgs> -using MakeUnboundRunType = - typename internal::BindTypeHelper<Functor, BoundArgs...>::UnboundRunType; - -} // namespace base - -#endif // BASE_BIND_INTERNAL_H_
diff --git a/base/callback.h b/base/callback.h deleted file mode 100644 index 1b84f40..0000000 --- a/base/callback.h +++ /dev/null
@@ -1,142 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// NOTE: Header files that do not require the full definition of Callback or -// Closure should #include "base/callback_forward.h" instead of this file. - -#ifndef BASE_CALLBACK_H_ -#define BASE_CALLBACK_H_ - -#include "base/callback_forward.h" -#include "base/callback_internal.h" - -// ----------------------------------------------------------------------------- -// Usage documentation -// ----------------------------------------------------------------------------- -// -// Overview: -// A callback is similar in concept to a function pointer: it wraps a runnable -// object such as a function, method, lambda, or even another callback, allowing -// the runnable object to be invoked later via the callback object. -// -// Unlike function pointers, callbacks are created with base::BindOnce() or -// base::BindRepeating() and support partial function application. -// -// A base::OnceCallback may be Run() at most once; a base::RepeatingCallback may -// be Run() any number of times. |is_null()| is guaranteed to return true for a -// moved-from callback. -// -// // The lambda takes two arguments, but the first argument |x| is bound at -// // callback creation. -// base::OnceCallback<int(int)> cb = base::BindOnce([] (int x, int y) { -// return x + y; -// }, 1); -// // Run() only needs the remaining unbound argument |y|. -// printf("1 + 2 = %d\n", std::move(cb).Run(2)); // Prints 3 -// printf("cb is null? %s\n", -// cb.is_null() ? "true" : "false"); // Prints true -// std::move(cb).Run(2); // Crashes since |cb| has already run. -// -// Callbacks also support cancellation. A common use is binding the receiver -// object as a WeakPtr<T>. If that weak pointer is invalidated, calling Run() -// will be a no-op. Note that |is_cancelled()| and |is_null()| are distinct: -// simply cancelling a callback will not also make it null. -// -// base::Callback is currently a type alias for base::RepeatingCallback. In the -// future, we expect to flip this to default to base::OnceCallback. -// -// See //docs/callback.md for the full documentation. - -namespace base { - -template <typename R, typename... Args> -class OnceCallback<R(Args...)> : public internal::CallbackBase { - public: - using RunType = R(Args...); - using PolymorphicInvoke = R (*)(internal::BindStateBase*, - internal::PassingTraitsType<Args>...); - - constexpr OnceCallback() = default; - - explicit OnceCallback(internal::BindStateBase* bind_state) - : internal::CallbackBase(bind_state) {} - - OnceCallback(const OnceCallback&) = delete; - OnceCallback& operator=(const OnceCallback&) = delete; - - OnceCallback(OnceCallback&&) noexcept = default; - OnceCallback& operator=(OnceCallback&&) noexcept = default; - - OnceCallback(RepeatingCallback<RunType> other) - : internal::CallbackBase(std::move(other)) {} - - OnceCallback& operator=(RepeatingCallback<RunType> other) { - static_cast<internal::CallbackBase&>(*this) = std::move(other); - return *this; - } - - bool Equals(const OnceCallback& other) const { return EqualsInternal(other); } - - R Run(Args... args) const& { - static_assert(!sizeof(*this), - "OnceCallback::Run() may only be invoked on a non-const " - "rvalue, i.e. std::move(callback).Run()."); - NOTREACHED(); - } - - R Run(Args... args) && { - // Move the callback instance into a local variable before the invocation, - // that ensures the internal state is cleared after the invocation. - // It's not safe to touch |this| after the invocation, since running the - // bound function may destroy |this|. - OnceCallback cb = std::move(*this); - PolymorphicInvoke f = - reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke()); - return f(cb.bind_state_.get(), std::forward<Args>(args)...); - } -}; - -template <typename R, typename... Args> -class RepeatingCallback<R(Args...)> : public internal::CallbackBaseCopyable { - public: - using RunType = R(Args...); - using PolymorphicInvoke = R (*)(internal::BindStateBase*, - internal::PassingTraitsType<Args>...); - - constexpr RepeatingCallback() = default; - - explicit RepeatingCallback(internal::BindStateBase* bind_state) - : internal::CallbackBaseCopyable(bind_state) {} - - // Copyable and movable. - RepeatingCallback(const RepeatingCallback&) = default; - RepeatingCallback& operator=(const RepeatingCallback&) = default; - RepeatingCallback(RepeatingCallback&&) noexcept = default; - RepeatingCallback& operator=(RepeatingCallback&&) noexcept = default; - - bool Equals(const RepeatingCallback& other) const { - return EqualsInternal(other); - } - - R Run(Args... args) const& { - PolymorphicInvoke f = - reinterpret_cast<PolymorphicInvoke>(this->polymorphic_invoke()); - return f(this->bind_state_.get(), std::forward<Args>(args)...); - } - - R Run(Args... args) && { - // Move the callback instance into a local variable before the invocation, - // that ensures the internal state is cleared after the invocation. - // It's not safe to touch |this| after the invocation, since running the - // bound function may destroy |this|. - RepeatingCallback cb = std::move(*this); - PolymorphicInvoke f = - reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke()); - return f(cb.bind_state_.get(), std::forward<Args>(args)...); - } -}; - -} // namespace base - -#endif // BASE_CALLBACK_H_
diff --git a/base/callback_forward.h b/base/callback_forward.h deleted file mode 100644 index f1851c4..0000000 --- a/base/callback_forward.h +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_CALLBACK_FORWARD_H_ -#define BASE_CALLBACK_FORWARD_H_ - -namespace base { - -template <typename Signature> -class OnceCallback; - -template <typename Signature> -class RepeatingCallback; - -template <typename Signature> -using Callback = RepeatingCallback<Signature>; - -// Syntactic sugar to make Callback<void()> easier to declare since it -// will be used in a lot of APIs with delayed execution. -using OnceClosure = OnceCallback<void()>; -using RepeatingClosure = RepeatingCallback<void()>; -using Closure = Callback<void()>; - -} // namespace base - -#endif // BASE_CALLBACK_FORWARD_H_
diff --git a/base/callback_internal.cc b/base/callback_internal.cc deleted file mode 100644 index c52d8af..0000000 --- a/base/callback_internal.cc +++ /dev/null
@@ -1,93 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/callback_internal.h" - -#include "base/logging.h" - -namespace base { -namespace internal { - -namespace { - -bool ReturnFalse(const BindStateBase*) { - return false; -} - -} // namespace - -void BindStateBaseRefCountTraits::Destruct(const BindStateBase* bind_state) { - bind_state->destructor_(bind_state); -} - -BindStateBase::BindStateBase(InvokeFuncStorage polymorphic_invoke, - void (*destructor)(const BindStateBase*)) - : BindStateBase(polymorphic_invoke, destructor, &ReturnFalse) {} - -BindStateBase::BindStateBase(InvokeFuncStorage polymorphic_invoke, - void (*destructor)(const BindStateBase*), - bool (*is_cancelled)(const BindStateBase*)) - : polymorphic_invoke_(polymorphic_invoke), - destructor_(destructor), - is_cancelled_(is_cancelled) {} - -CallbackBase::CallbackBase(CallbackBase&& c) noexcept = default; -CallbackBase& CallbackBase::operator=(CallbackBase&& c) noexcept = default; -CallbackBase::CallbackBase(const CallbackBaseCopyable& c) - : bind_state_(c.bind_state_) {} - -CallbackBase& CallbackBase::operator=(const CallbackBaseCopyable& c) { - bind_state_ = c.bind_state_; - return *this; -} - -CallbackBase::CallbackBase(CallbackBaseCopyable&& c) noexcept - : bind_state_(std::move(c.bind_state_)) {} - -CallbackBase& CallbackBase::operator=(CallbackBaseCopyable&& c) noexcept { - bind_state_ = std::move(c.bind_state_); - return *this; -} - -void CallbackBase::Reset() { - // NULL the bind_state_ last, since it may be holding the last ref to whatever - // object owns us, and we may be deleted after that. - bind_state_ = nullptr; -} - -bool CallbackBase::IsCancelled() const { - DCHECK(bind_state_); - return bind_state_->IsCancelled(); -} - -bool CallbackBase::EqualsInternal(const CallbackBase& other) const { - return bind_state_ == other.bind_state_; -} - -CallbackBase::CallbackBase(BindStateBase* bind_state) - : bind_state_(bind_state ? AdoptRef(bind_state) : nullptr) { - DCHECK(!bind_state_.get() || bind_state_->HasOneRef()); -} - -CallbackBase::~CallbackBase() = default; - -CallbackBaseCopyable::CallbackBaseCopyable(const CallbackBaseCopyable& c) - : CallbackBase(nullptr) { - bind_state_ = c.bind_state_; -} - -CallbackBaseCopyable::CallbackBaseCopyable(CallbackBaseCopyable&& c) noexcept = - default; - -CallbackBaseCopyable& CallbackBaseCopyable::operator=( - const CallbackBaseCopyable& c) { - bind_state_ = c.bind_state_; - return *this; -} - -CallbackBaseCopyable& CallbackBaseCopyable::operator=( - CallbackBaseCopyable&& c) noexcept = default; - -} // namespace internal -} // namespace base
diff --git a/base/callback_internal.h b/base/callback_internal.h deleted file mode 100644 index 7e5180f..0000000 --- a/base/callback_internal.h +++ /dev/null
@@ -1,172 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains utility functions and classes that help the -// implementation, and management of the Callback objects. - -#ifndef BASE_CALLBACK_INTERNAL_H_ -#define BASE_CALLBACK_INTERNAL_H_ - -#include "base/callback_forward.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" - -namespace base { - -struct FakeBindState; - -namespace internal { - -class CallbackBase; -class CallbackBaseCopyable; - -class BindStateBase; - -template <typename Functor, typename... BoundArgs> -struct BindState; - -struct BindStateBaseRefCountTraits { - static void Destruct(const BindStateBase*); -}; - -template <typename T, bool IsScalar = std::is_scalar<T>::value> -struct PassingTraits; - -template <typename T> -struct PassingTraits<T, false> { - using Type = T&&; -}; - -template <typename T> -struct PassingTraits<T, true> { - using Type = T; -}; - -template <typename T> -using PassingTraitsType = typename PassingTraits<T>::Type; - -// BindStateBase is used to provide an opaque handle that the Callback -// class can use to represent a function object with bound arguments. It -// behaves as an existential type that is used by a corresponding -// DoInvoke function to perform the function execution. This allows -// us to shield the Callback class from the types of the bound argument via -// "type erasure." -// At the base level, the only task is to add reference counting data. Don't use -// RefCountedThreadSafe since it requires the destructor to be a virtual method. -// Creating a vtable for every BindState template instantiation results in a lot -// of bloat. Its only task is to call the destructor which can be done with a -// function pointer. -class BindStateBase - : public RefCountedThreadSafe<BindStateBase, BindStateBaseRefCountTraits> { - public: - REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); - - using InvokeFuncStorage = void (*)(); - - private: - BindStateBase(InvokeFuncStorage polymorphic_invoke, - void (*destructor)(const BindStateBase*)); - BindStateBase(InvokeFuncStorage polymorphic_invoke, - void (*destructor)(const BindStateBase*), - bool (*is_cancelled)(const BindStateBase*)); - - ~BindStateBase() = default; - - friend struct BindStateBaseRefCountTraits; - friend class RefCountedThreadSafe<BindStateBase, BindStateBaseRefCountTraits>; - - friend class CallbackBase; - friend class CallbackBaseCopyable; - - // Whitelist subclasses that access the destructor of BindStateBase. - template <typename Functor, typename... BoundArgs> - friend struct BindState; - friend struct ::base::FakeBindState; - - bool IsCancelled() const { return is_cancelled_(this); } - - // In C++, it is safe to cast function pointers to function pointers of - // another type. It is not okay to use void*. We create a InvokeFuncStorage - // that that can store our function pointer, and then cast it back to - // the original type on usage. - InvokeFuncStorage polymorphic_invoke_; - - // Pointer to a function that will properly destroy |this|. - void (*destructor_)(const BindStateBase*); - bool (*is_cancelled_)(const BindStateBase*); - - DISALLOW_COPY_AND_ASSIGN(BindStateBase); -}; - -// Holds the Callback methods that don't require specialization to reduce -// template bloat. -// CallbackBase<MoveOnly> is a direct base class of MoveOnly callbacks, and -// CallbackBase<Copyable> uses CallbackBase<MoveOnly> for its implementation. -class CallbackBase { - public: - CallbackBase(CallbackBase&& c) noexcept; - CallbackBase& operator=(CallbackBase&& c) noexcept; - - explicit CallbackBase(const CallbackBaseCopyable& c); - CallbackBase& operator=(const CallbackBaseCopyable& c); - - explicit CallbackBase(CallbackBaseCopyable&& c) noexcept; - CallbackBase& operator=(CallbackBaseCopyable&& c) noexcept; - - // Returns true if Callback is null (doesn't refer to anything). - bool is_null() const { return !bind_state_; } - explicit operator bool() const { return !is_null(); } - - // Returns true if the callback invocation will be nop due to an cancellation. - // It's invalid to call this on uninitialized callback. - bool IsCancelled() const; - - // Returns the Callback into an uninitialized state. - void Reset(); - - protected: - using InvokeFuncStorage = BindStateBase::InvokeFuncStorage; - - // Returns true if this callback equals |other|. |other| may be null. - bool EqualsInternal(const CallbackBase& other) const; - - constexpr inline CallbackBase(); - - // Allow initializing of |bind_state_| via the constructor to avoid default - // initialization of the scoped_refptr. - explicit CallbackBase(BindStateBase* bind_state); - - InvokeFuncStorage polymorphic_invoke() const { - return bind_state_->polymorphic_invoke_; - } - - // Force the destructor to be instantiated inside this translation unit so - // that our subclasses will not get inlined versions. Avoids more template - // bloat. - ~CallbackBase(); - - scoped_refptr<BindStateBase> bind_state_; -}; - -constexpr CallbackBase::CallbackBase() = default; - -// CallbackBase<Copyable> is a direct base class of Copyable Callbacks. -class CallbackBaseCopyable : public CallbackBase { - public: - CallbackBaseCopyable(const CallbackBaseCopyable& c); - CallbackBaseCopyable(CallbackBaseCopyable&& c) noexcept; - CallbackBaseCopyable& operator=(const CallbackBaseCopyable& c); - CallbackBaseCopyable& operator=(CallbackBaseCopyable&& c) noexcept; - - protected: - constexpr CallbackBaseCopyable() = default; - explicit CallbackBaseCopyable(BindStateBase* bind_state) - : CallbackBase(bind_state) {} - ~CallbackBaseCopyable() = default; -}; - -} // namespace internal -} // namespace base - -#endif // BASE_CALLBACK_INTERNAL_H_
diff --git a/base/logging.cc b/base/logging.cc index 11cef81..a8ccd6f 100644 --- a/base/logging.cc +++ b/base/logging.cc
@@ -46,8 +46,6 @@ #include <string_view> #include <utility> -#include "base/callback.h" -#include "base/containers/stack.h" #include "base/posix/eintr_wrapper.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h"
diff --git a/base/logging.h b/base/logging.h index 78c0861..c581d33 100644 --- a/base/logging.h +++ b/base/logging.h
@@ -15,7 +15,6 @@ #include <type_traits> #include <utility> -#include "base/callback_forward.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "base/template_util.h"
diff --git a/build/gen.py b/build/gen.py index 5011ea9..64e3f55 100755 --- a/build/gen.py +++ b/build/gen.py
@@ -387,7 +387,6 @@ static_libraries = { 'base': {'sources': [ - 'base/callback_internal.cc', 'base/command_line.cc', 'base/environment.cc', 'base/files/file.cc',
diff --git a/tools/gn/build_settings.cc b/tools/gn/build_settings.cc index 711c6b8..46e7944 100644 --- a/tools/gn/build_settings.cc +++ b/tools/gn/build_settings.cc
@@ -70,6 +70,6 @@ void BuildSettings::ItemDefined(std::unique_ptr<Item> item) const { DCHECK(item); - if (!item_defined_callback_.is_null()) - item_defined_callback_.Run(std::move(item)); + if (item_defined_callback_) + item_defined_callback_(std::move(item)); }
diff --git a/tools/gn/build_settings.h b/tools/gn/build_settings.h index 40049d9..ef84f15 100644 --- a/tools/gn/build_settings.h +++ b/tools/gn/build_settings.h
@@ -5,12 +5,12 @@ #ifndef TOOLS_GN_BUILD_SETTINGS_H_ #define TOOLS_GN_BUILD_SETTINGS_H_ +#include <functional> #include <map> #include <memory> #include <set> #include <utility> -#include "base/callback.h" #include "base/files/file_path.h" #include "base/macros.h" #include "tools/gn/args.h" @@ -25,8 +25,8 @@ // may be multiple Settings objects that refer to this, one for each toolchain. class BuildSettings { public: - using ItemDefinedCallback = base::Callback<void(std::unique_ptr<Item>)>; - using PrintCallback = base::Callback<void(const std::string&)>; + using ItemDefinedCallback = std::function<void(std::unique_ptr<Item>)>; + using PrintCallback = std::function<void(const std::string&)>; BuildSettings(); BuildSettings(const BuildSettings& other);
diff --git a/tools/gn/builder.cc b/tools/gn/builder.cc index bbdb182..2482983 100644 --- a/tools/gn/builder.cc +++ b/tools/gn/builder.cc
@@ -438,8 +438,8 @@ record->set_should_generate(true); // This may have caused the item to go into "resolved and generated" state. - if (record->resolved() && !resolved_and_generated_callback_.is_null()) - resolved_and_generated_callback_.Run(record); + if (record->resolved() && resolved_and_generated_callback_) + resolved_and_generated_callback_(record); } else if (!force) { return; // Already set and we're not required to iterate dependencies. } @@ -487,8 +487,8 @@ if (!record->item()->OnResolved(err)) return false; - if (record->should_generate() && !resolved_and_generated_callback_.is_null()) - resolved_and_generated_callback_.Run(record); + if (record->should_generate() && resolved_and_generated_callback_) + resolved_and_generated_callback_(record); // Recursively update everybody waiting on this item to be resolved. for (BuilderRecord* waiting : record->waiting_on_resolution()) {
diff --git a/tools/gn/builder.h b/tools/gn/builder.h index 62f4f96..f2996ca 100644 --- a/tools/gn/builder.h +++ b/tools/gn/builder.h
@@ -5,10 +5,10 @@ #ifndef TOOLS_GN_BUILDER_H_ #define TOOLS_GN_BUILDER_H_ +#include <functional> #include <map> #include <memory> -#include "base/callback.h" #include "base/macros.h" #include "tools/gn/builder_record.h" #include "tools/gn/label.h" @@ -24,7 +24,7 @@ // the main thread only. See also BuilderRecord. class Builder { public: - using ResolvedGeneratedCallback = base::Callback<void(const BuilderRecord*)>; + using ResolvedGeneratedCallback = std::function<void(const BuilderRecord*)>; explicit Builder(Loader* loader); ~Builder();
diff --git a/tools/gn/command_gen.cc b/tools/gn/command_gen.cc index 200aad8..707c9e2 100644 --- a/tools/gn/command_gen.cc +++ b/tools/gn/command_gen.cc
@@ -4,7 +4,6 @@ #include <mutex> -#include "base/bind.h" #include "base/command_line.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" @@ -78,7 +77,7 @@ const Target* target = item->AsTarget(); if (target) { g_scheduler->ScheduleWork( - base::Bind(&BackgroundDoWrite, write_info, target)); + [write_info, target]() { BackgroundDoWrite(write_info, target); }); } } @@ -461,7 +460,9 @@ // Cause the load to also generate the ninja files for each target. TargetWriteInfo write_info; setup->builder().set_resolved_and_generated_callback( - base::Bind(&ItemResolvedAndGeneratedCallback, &write_info)); + [&write_info](const BuilderRecord* record) { + ItemResolvedAndGeneratedCallback(&write_info, record); + }); // Do the actual load. This will also write out the target ninja files. if (!setup->Run())
diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc index 74b48bc..937ffd2 100644 --- a/tools/gn/functions.cc +++ b/tools/gn/functions.cc
@@ -1022,11 +1022,12 @@ const BuildSettings::PrintCallback& cb = scope->settings()->build_settings()->print_callback(); - if (cb.is_null()) { + if (cb) { + cb(output); + } else { printf("%s", output.c_str()); fflush(stdout); - } else - cb.Run(output); + } return Value(); }
diff --git a/tools/gn/header_checker.cc b/tools/gn/header_checker.cc index f4af9d8..d9ff4b2 100644 --- a/tools/gn/header_checker.cc +++ b/tools/gn/header_checker.cc
@@ -6,7 +6,6 @@ #include <algorithm> -#include "base/bind.h" #include "base/containers/queue.h" #include "base/files/file_util.h" #include "base/strings/string_util.h" @@ -173,8 +172,9 @@ for (const auto& vect_i : file.second) { if (vect_i.target->check_includes()) { task_count_.Increment(); - pool.PostTask(base::BindOnce(&HeaderChecker::DoWork, this, - vect_i.target, file.first)); + pool.PostTask([this, target = vect_i.target, file = file.first]() { + DoWork(target, file); + }); } } }
diff --git a/tools/gn/header_checker.h b/tools/gn/header_checker.h index 786edcb..b668441 100644 --- a/tools/gn/header_checker.h +++ b/tools/gn/header_checker.h
@@ -6,6 +6,7 @@ #define TOOLS_GN_HEADER_CHECKER_H_ #include <condition_variable> +#include <functional> #include <map> #include <mutex> #include <set> @@ -96,8 +97,7 @@ using TargetVector = std::vector<TargetInfo>; using FileMap = std::map<SourceFile, TargetVector>; - using PathExistsCallback = - base::RepeatingCallback<bool(const base::FilePath& path)>; + using PathExistsCallback = std::function<bool(const base::FilePath& path)>; // Backend for Run() that takes the list of files to check. The errors_ list // will be populate on failure.
diff --git a/tools/gn/header_checker_unittest.cc b/tools/gn/header_checker_unittest.cc index c6529d5..4243696 100644 --- a/tools/gn/header_checker_unittest.cc +++ b/tools/gn/header_checker_unittest.cc
@@ -5,7 +5,6 @@ #include <ostream> #include <vector> -#include "base/bind.h" #include "tools/gn/config.h" #include "tools/gn/header_checker.h" #include "tools/gn/scheduler.h"
diff --git a/tools/gn/input_file_manager.cc b/tools/gn/input_file_manager.cc index aad8cc8..320e7a5 100644 --- a/tools/gn/input_file_manager.cc +++ b/tools/gn/input_file_manager.cc
@@ -7,7 +7,6 @@ #include <memory> #include <utility> -#include "base/bind.h" #include "base/stl_util.h" #include "tools/gn/filesystem_utils.h" #include "tools/gn/parser.h" @@ -31,7 +30,7 @@ void InvokeFileLoadCallback(const InputFileManager::FileLoadCallback& cb, const ParseNode* node) { - cb.Run(node); + cb(node); } bool DoLoadFile(const LocationRange& origin, @@ -111,7 +110,7 @@ // Try not to schedule callbacks while holding the lock. All cases that don't // want to schedule should return early. Otherwise, this will be scheduled // after we leave the lock. - Task schedule_this; + std::function<void()> schedule_this; { std::lock_guard<std::mutex> lock(lock_); @@ -121,9 +120,10 @@ std::unique_ptr<InputFileData> data = std::make_unique<InputFileData>(file_name); data->scheduled_callbacks.push_back(callback); - schedule_this = - base::BindOnce(&InputFileManager::BackgroundLoadFile, this, origin, - build_settings, file_name, &data->file); + schedule_this = [this, origin, build_settings, file_name, + file = &data->file]() { + BackgroundLoadFile(origin, build_settings, file_name, file); + }; input_files_[file_name] = std::move(data); } else { @@ -146,8 +146,9 @@ if (data->loaded) { // Can just directly issue the callback on the background thread. - schedule_this = base::BindOnce(&InvokeFileLoadCallback, callback, - data->parsed_root.get()); + schedule_this = [callback, root = data->parsed_root.get()]() { + InvokeFileLoadCallback(callback, root); + }; } else { // Load is pending on this file, schedule the invoke. data->scheduled_callbacks.push_back(callback); @@ -326,7 +327,7 @@ // item in the list, so that's extra overhead and complexity for no gain. if (success) { for (const auto& cb : callbacks) - cb.Run(unowned_root); + cb(unowned_root); } return success; }
diff --git a/tools/gn/input_file_manager.h b/tools/gn/input_file_manager.h index c4f19e9..9676f2f 100644 --- a/tools/gn/input_file_manager.h +++ b/tools/gn/input_file_manager.h
@@ -5,13 +5,13 @@ #ifndef TOOLS_GN_INPUT_FILE_MANAGER_H_ #define TOOLS_GN_INPUT_FILE_MANAGER_H_ +#include <functional> #include <mutex> #include <set> #include <unordered_map> #include <utility> #include <vector> -#include "base/callback.h" #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -38,7 +38,7 @@ public: // Callback issued when a file is laoded. On auccess, the parse node will // refer to the root block of the file. On failure, this will be NULL. - using FileLoadCallback = base::Callback<void(const ParseNode*)>; + using FileLoadCallback = std::function<void(const ParseNode*)>; InputFileManager();
diff --git a/tools/gn/loader.cc b/tools/gn/loader.cc index d1a2953..148ba39 100644 --- a/tools/gn/loader.cc +++ b/tools/gn/loader.cc
@@ -6,7 +6,6 @@ #include <memory> -#include "base/bind.h" #include "tools/gn/build_settings.h" #include "tools/gn/err.h" #include "tools/gn/filesystem_utils.h" @@ -208,10 +207,12 @@ const SourceFile& file) { Err err; pending_loads_++; - if (!AsyncLoadFile(origin, settings->build_settings(), file, - base::Bind(&LoaderImpl::BackgroundLoadFile, this, settings, - file, origin), - &err)) { + if (!AsyncLoadFile( + origin, settings->build_settings(), file, + [this, settings, file, origin](const ParseNode* parse_node) { + BackgroundLoadFile(settings, file, origin, parse_node); + }, + &err)) { g_scheduler->FailWithError(err); DecrementPendingLoads(); } @@ -222,11 +223,13 @@ const Scope::KeyValueMap& toolchain_overrides) { Err err; pending_loads_++; - if (!AsyncLoadFile(LocationRange(), settings->build_settings(), - settings->build_settings()->build_config_file(), - base::Bind(&LoaderImpl::BackgroundLoadBuildConfig, this, - settings, toolchain_overrides), - &err)) { + if (!AsyncLoadFile( + LocationRange(), settings->build_settings(), + settings->build_settings()->build_config_file(), + [this, settings, toolchain_overrides](const ParseNode* root) { + BackgroundLoadBuildConfig(settings, toolchain_overrides, root); + }, + &err)) { g_scheduler->FailWithError(err); DecrementPendingLoads(); } @@ -237,8 +240,7 @@ const LocationRange& origin, const ParseNode* root) { if (!root) { - task_runner_->PostTask( - base::BindOnce(&LoaderImpl::DecrementPendingLoads, this)); + task_runner_->PostTask([this]() { DecrementPendingLoads(); }); return; } @@ -277,7 +279,7 @@ trace.Done(); - task_runner_->PostTask(base::BindOnce(&LoaderImpl::DidLoadFile, this)); + task_runner_->PostTask([this]() { DidLoadFile(); }); } void LoaderImpl::BackgroundLoadBuildConfig( @@ -285,8 +287,7 @@ const Scope::KeyValueMap& toolchain_overrides, const ParseNode* root) { if (!root) { - task_runner_->PostTask( - base::BindOnce(&LoaderImpl::DecrementPendingLoads, this)); + task_runner_->PostTask([this]() { DecrementPendingLoads(); }); return; } @@ -348,8 +349,10 @@ } } - task_runner_->PostTask(base::BindOnce(&LoaderImpl::DidLoadBuildConfig, this, - settings->toolchain_label())); + task_runner_->PostTask( + [this, toolchain_label = settings->toolchain_label()]() { + DidLoadBuildConfig(toolchain_label); + }); } void LoaderImpl::DidLoadFile() { @@ -419,19 +422,19 @@ void LoaderImpl::DecrementPendingLoads() { DCHECK_GT(pending_loads_, 0); pending_loads_--; - if (pending_loads_ == 0 && !complete_callback_.is_null()) - complete_callback_.Run(); + if (pending_loads_ == 0 && complete_callback_) + complete_callback_(); } -bool LoaderImpl::AsyncLoadFile( - const LocationRange& origin, - const BuildSettings* build_settings, - const SourceFile& file_name, - const base::Callback<void(const ParseNode*)>& callback, - Err* err) { - if (async_load_file_.is_null()) { - return g_scheduler->input_file_manager()->AsyncLoadFile( - origin, build_settings, file_name, callback, err); +bool LoaderImpl::AsyncLoadFile(const LocationRange& origin, + const BuildSettings* build_settings, + const SourceFile& file_name, + std::function<void(const ParseNode*)> callback, + Err* err) { + if (async_load_file_) { + return async_load_file_(origin, build_settings, file_name, + std::move(callback), err); } - return async_load_file_.Run(origin, build_settings, file_name, callback, err); + return g_scheduler->input_file_manager()->AsyncLoadFile( + origin, build_settings, file_name, std::move(callback), err); }
diff --git a/tools/gn/loader.h b/tools/gn/loader.h index 06737c3..bd679bb 100644 --- a/tools/gn/loader.h +++ b/tools/gn/loader.h
@@ -5,11 +5,11 @@ #ifndef TOOLS_GN_LOADER_H_ #define TOOLS_GN_LOADER_H_ +#include <functional> #include <map> #include <memory> #include <set> -#include "base/callback.h" #include "base/memory/ref_counted.h" #include "tools/gn/label.h" #include "tools/gn/scope.h" @@ -72,11 +72,11 @@ public: // Callback to emulate InputFileManager::AsyncLoadFile. using AsyncLoadFileCallback = - base::Callback<bool(const LocationRange&, - const BuildSettings*, - const SourceFile&, - const base::Callback<void(const ParseNode*)>&, - Err*)>; + std::function<bool(const LocationRange&, + const BuildSettings*, + const SourceFile&, + std::function<void(const ParseNode*)>, + Err*)>; explicit LoaderImpl(const BuildSettings* build_settings); @@ -96,13 +96,13 @@ // The complete callback is called whenever there are no more pending loads. // Called on the main thread only. This may be called more than once if the // queue is drained, but then more stuff gets added. - void set_complete_callback(const base::Closure& cb) { - complete_callback_ = cb; + void set_complete_callback(std::function<void()> cb) { + complete_callback_ = std::move(cb); } // This callback is used when the loader finds it wants to load a file. - void set_async_load_file(const AsyncLoadFileCallback& cb) { - async_load_file_ = cb; + void set_async_load_file(AsyncLoadFileCallback cb) { + async_load_file_ = std::move(cb); } const Label& default_toolchain_label() const { @@ -152,13 +152,13 @@ bool AsyncLoadFile(const LocationRange& origin, const BuildSettings* build_settings, const SourceFile& file_name, - const base::Callback<void(const ParseNode*)>& callback, + std::function<void(const ParseNode*)> callback, Err* err); MsgLoop* task_runner_; int pending_loads_; - base::Closure complete_callback_; + std::function<void()> complete_callback_; // When non-null, use this callback instead of the InputFileManager for // mocking purposes.
diff --git a/tools/gn/loader_unittest.cc b/tools/gn/loader_unittest.cc index 83a2389..ede20d7 100644 --- a/tools/gn/loader_unittest.cc +++ b/tools/gn/loader_unittest.cc
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <functional> #include <map> #include <memory> #include <utility> #include <vector> -#include "base/bind.h" #include "tools/gn/build_settings.h" #include "tools/gn/err.h" #include "tools/gn/loader.h" @@ -52,7 +52,7 @@ class MockInputFileManager { public: - using Callback = base::Callback<void(const ParseNode*)>; + using Callback = std::function<void(const ParseNode*)>; MockInputFileManager() = default; @@ -91,8 +91,11 @@ }; LoaderImpl::AsyncLoadFileCallback MockInputFileManager::GetCallback() { - return base::Bind(&MockInputFileManager::AsyncLoadFile, - base::Unretained(this)); + return + [this](const LocationRange& origin, const BuildSettings* build_settings, + const SourceFile& file_name, const Callback& callback, Err* err) { + return AsyncLoadFile(origin, build_settings, file_name, callback, err); + }; } // Sets a given response for a given source file. @@ -131,9 +134,9 @@ for (const auto& cur : pending_) { CannedResponseMap::const_iterator found = canned_responses_.find(cur.first); if (found == canned_responses_.end()) - cur.second.Run(&block); + cur.second(&block); else - cur.second.Run(found->second->root.get()); + cur.second(found->second->root.get()); } pending_.clear(); } @@ -217,8 +220,10 @@ SourceFile build_config("//build/config/BUILDCONFIG.gn"); SourceFile root_build("//BUILD.gn"); build_settings_.set_build_config_file(build_config); - build_settings_.set_item_defined_callback(base::Bind( - &MockBuilder::OnItemDefined, base::Unretained(&mock_builder_))); + build_settings_.set_item_defined_callback( + [builder = &mock_builder_](std::unique_ptr<Item> item) { + builder->OnItemDefined(std::move(item)); + }); scoped_refptr<LoaderImpl> loader(new LoaderImpl(&build_settings_)); mock_ifm_.AddCannedResponse(build_config,
diff --git a/tools/gn/scheduler.cc b/tools/gn/scheduler.cc index f4960b9..a37d62d 100644 --- a/tools/gn/scheduler.cc +++ b/tools/gn/scheduler.cc
@@ -6,7 +6,6 @@ #include <algorithm> -#include "base/bind.h" #include "tools/gn/standard_out.h" #include "tools/gn/target.h" @@ -40,8 +39,7 @@ } void Scheduler::Log(const std::string& verb, const std::string& msg) { - task_runner()->PostTask(base::BindOnce(&Scheduler::LogOnMainThread, - base::Unretained(this), verb, msg)); + task_runner()->PostTask([this, verb, msg]() { LogOnMainThread(verb, msg); }); } void Scheduler::FailWithError(const Err& err) { @@ -54,23 +52,20 @@ is_failed_ = true; } - task_runner()->PostTask(base::BindOnce(&Scheduler::FailWithErrorOnMainThread, - base::Unretained(this), err)); + task_runner()->PostTask([this, err]() { FailWithErrorOnMainThread(err); }); } -void Scheduler::ScheduleWork(Task work) { +void Scheduler::ScheduleWork(std::function<void()> work) { IncrementWorkCount(); pool_work_count_.Increment(); - worker_pool_.PostTask(base::BindOnce( - [](Scheduler* self, Task work) { - std::move(work).Run(); - self->DecrementWorkCount(); - if (!self->pool_work_count_.Decrement()) { - std::unique_lock<std::mutex> auto_lock(self->pool_work_count_lock_); - self->pool_work_count_cv_.notify_one(); - } - }, - this, std::move(work))); + worker_pool_.PostTask([this, work = std::move(work)]() { + work(); + DecrementWorkCount(); + if (!pool_work_count_.Decrement()) { + std::unique_lock<std::mutex> auto_lock(pool_work_count_lock_); + pool_work_count_cv_.notify_one(); + } + }); } void Scheduler::AddGenDependency(const base::FilePath& file) { @@ -154,8 +149,7 @@ void Scheduler::DecrementWorkCount() { if (!work_count_.Decrement()) { - task_runner()->PostTask( - base::BindOnce(&Scheduler::OnComplete, base::Unretained(this))); + task_runner()->PostTask([this]() { OnComplete(); }); } }
diff --git a/tools/gn/scheduler.h b/tools/gn/scheduler.h index d005df5..395b115 100644 --- a/tools/gn/scheduler.h +++ b/tools/gn/scheduler.h
@@ -6,6 +6,7 @@ #define TOOLS_GN_SCHEDULER_H_ #include <condition_variable> +#include <functional> #include <map> #include <mutex> @@ -17,7 +18,6 @@ #include "tools/gn/source_file.h" #include "tools/gn/token.h" #include "util/msg_loop.h" -#include "util/task.h" #include "util/worker_pool.h" class Target; @@ -46,7 +46,7 @@ void Log(const std::string& verb, const std::string& msg); void FailWithError(const Err& err); - void ScheduleWork(Task work); + void ScheduleWork(std::function<void()> work); void Shutdown();
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc index 16e09fe..7540a8c 100644 --- a/tools/gn/setup.cc +++ b/tools/gn/setup.cc
@@ -11,7 +11,6 @@ #include <sstream> #include <utility> -#include "base/bind.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -178,13 +177,15 @@ // this call completing on the main thread, the 'Complete' function will // be signaled and we'll stop running with an incomplete build. g_scheduler->IncrementWorkCount(); - task_runner->PostTask(base::BindOnce( - [](Builder* builder_call_on_main_thread_only, - std::unique_ptr<Item> item) { - builder_call_on_main_thread_only->ItemDefined(std::move(item)); + + // Work around issue binding a unique_ptr with std::function by moving into a + // shared_ptr. + auto item_shared = std::make_shared<std::unique_ptr<Item>>(std::move(item)); + task_runner->PostTask( + [builder_call_on_main_thread_only, item_shared]() mutable { + builder_call_on_main_thread_only->ItemDefined(std::move(*item_shared)); g_scheduler->DecrementWorkCount(); - }, - builder_call_on_main_thread_only, base::Passed(&item))); + }); } void DecrementWorkCount() { @@ -306,9 +307,12 @@ dotfile_settings_.set_toolchain_label(Label()); build_settings_.set_item_defined_callback( - base::Bind(&ItemDefinedCallback, scheduler_.task_runner(), &builder_)); + [task_runner = scheduler_.task_runner(), + builder = &builder_](std::unique_ptr<Item> item) { + ItemDefinedCallback(task_runner, builder, std::move(item)); + }); - loader_->set_complete_callback(base::Bind(&DecrementWorkCount)); + loader_->set_complete_callback(&DecrementWorkCount); // The scheduler's task runner wasn't created when the Loader was created, so // we need to set it now. loader_->set_task_runner(scheduler_.task_runner());
diff --git a/tools/gn/target.cc b/tools/gn/target.cc index 8a5b989..5b3d603 100644 --- a/tools/gn/target.cc +++ b/tools/gn/target.cc
@@ -6,7 +6,6 @@ #include <stddef.h> -#include "base/bind.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h"
diff --git a/tools/gn/test_with_scope.cc b/tools/gn/test_with_scope.cc index 80d9692..5025420 100644 --- a/tools/gn/test_with_scope.cc +++ b/tools/gn/test_with_scope.cc
@@ -7,7 +7,6 @@ #include <memory> #include <utility> -#include "base/bind.h" #include "tools/gn/parser.h" #include "tools/gn/tokenizer.h" @@ -28,7 +27,7 @@ scope_(&settings_), scope_progammatic_provider_(&scope_, true) { build_settings_.set_print_callback( - base::Bind(&TestWithScope::AppendPrintOutput, base::Unretained(this))); + [this](const std::string& str) { AppendPrintOutput(str); }); settings_.set_toolchain_label(toolchain_.label()); settings_.set_default_toolchain_label(toolchain_.label());
diff --git a/util/msg_loop.cc b/util/msg_loop.cc index dbb92cf..1566532 100644 --- a/util/msg_loop.cc +++ b/util/msg_loop.cc
@@ -23,7 +23,7 @@ void MsgLoop::Run() { while (!should_quit_) { - Task task; + std::function<void()> task; { std::unique_lock<std::mutex> queue_lock(queue_mutex_); notifier_.wait(queue_lock, [this]() { @@ -37,16 +37,15 @@ task_queue_.pop(); } - std::move(task).Run(); + task(); } } void MsgLoop::PostQuit() { - PostTask( - base::BindOnce([](MsgLoop* self) { self->should_quit_ = true; }, this)); + PostTask([this]() { should_quit_ = true; }); } -void MsgLoop::PostTask(Task work) { +void MsgLoop::PostTask(std::function<void()> work) { { std::unique_lock<std::mutex> queue_lock(queue_mutex_); task_queue_.emplace(std::move(work)); @@ -57,7 +56,7 @@ void MsgLoop::RunUntilIdleForTesting() { for (bool done = false; !done;) { - Task task; + std::function<void()> task; { std::unique_lock<std::mutex> queue_lock(queue_mutex_); task = std::move(task_queue_.front()); @@ -67,7 +66,7 @@ done = true; } - std::move(task).Run(); + task(); } }
diff --git a/util/msg_loop.h b/util/msg_loop.h index 267d2a9..b6e1ec7 100644 --- a/util/msg_loop.h +++ b/util/msg_loop.h
@@ -6,9 +6,9 @@ #define UTIL_RUN_LOOP_H_ #include "base/macros.h" -#include "util/task.h" #include <condition_variable> +#include <functional> #include <mutex> #include <queue> @@ -26,7 +26,7 @@ // Posts a work item to this queue. All items will be run on the thread from // which Run() was called. Can be called from any thread. - void PostTask(Task task); + void PostTask(std::function<void()> task); // Run()s until the queue is empty. Should only be used (carefully) in tests. void RunUntilIdleForTesting(); @@ -37,7 +37,7 @@ private: std::mutex queue_mutex_; - std::queue<Task> task_queue_; + std::queue<std::function<void()>> task_queue_; std::condition_variable notifier_; bool should_quit_ = false;
diff --git a/util/task.h b/util/task.h deleted file mode 100644 index 278ff13..0000000 --- a/util/task.h +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UTIL_TASK_H_ -#define UTIL_TASK_H_ - -#include "base/bind.h" -#include "base/callback.h" - -using Task = base::OnceClosure; - -#endif // UTIL_TASK_H_
diff --git a/util/worker_pool.cc b/util/worker_pool.cc index 60bcfbf..3c049a9 100644 --- a/util/worker_pool.cc +++ b/util/worker_pool.cc
@@ -117,7 +117,7 @@ } } -void WorkerPool::PostTask(Task work) { +void WorkerPool::PostTask(std::function<void()> work) { { std::unique_lock<std::mutex> queue_lock(queue_mutex_); CHECK(!should_stop_processing_); @@ -129,7 +129,7 @@ void WorkerPool::Worker() { for (;;) { - Task task; + std::function<void()> task; { std::unique_lock<std::mutex> queue_lock(queue_mutex_); @@ -145,6 +145,6 @@ task_queue_.pop(); } - std::move(task).Run(); + task(); } }
diff --git a/util/worker_pool.h b/util/worker_pool.h index d061644..7284ebe 100644 --- a/util/worker_pool.h +++ b/util/worker_pool.h
@@ -6,13 +6,13 @@ #define UTIL_WORKER_POOL_H_ #include <condition_variable> +#include <functional> #include <mutex> #include <queue> #include <thread> #include "base/logging.h" #include "base/macros.h" -#include "util/task.h" class WorkerPool { public: @@ -20,13 +20,13 @@ WorkerPool(size_t thread_count); ~WorkerPool(); - void PostTask(Task work); + void PostTask(std::function<void()> work); private: void Worker(); std::vector<std::thread> threads_; - std::queue<base::OnceClosure> task_queue_; + std::queue<std::function<void()>> task_queue_; std::mutex queue_mutex_; std::condition_variable_any pool_notifier_; bool should_stop_processing_;