aboutsummaryrefslogtreecommitdiff
path: root/third_party/chromium/base/bind_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/chromium/base/bind_internal.h')
-rw-r--r--third_party/chromium/base/bind_internal.h615
1 files changed, 315 insertions, 300 deletions
diff --git a/third_party/chromium/base/bind_internal.h b/third_party/chromium/base/bind_internal.h
index 199467c..3d6ca09 100644
--- a/third_party/chromium/base/bind_internal.h
+++ b/third_party/chromium/base/bind_internal.h
@@ -7,6 +7,7 @@
#include <stddef.h>
+#include <tuple>
#include <type_traits>
#include "base/bind_helpers.h"
@@ -17,10 +18,6 @@
#include "base/tuple.h"
#include "build/build_config.h"
-#if defined(OS_WIN)
-#include "base/bind_internal_win.h"
-#endif
-
namespace base {
namespace internal {
@@ -28,56 +25,80 @@ namespace internal {
//
//
// CONCEPTS:
-// Runnable -- A type (really a type class) that has a single Run() method
-// and a RunType typedef that corresponds to the type of Run().
-// A Runnable can declare that it should treated like a method
-// call by including a typedef named IsMethod. The value of
-// this typedef is NOT inspected, only the existence. When a
-// Runnable declares itself a method, Bind() will enforce special
-// refcounting + WeakPtr handling semantics for the first
-// parameter which is expected to be an object.
-// Functor -- A copyable type representing something that should be called.
-// All function pointers, Callback<>, and Runnables are functors
-// even if the invocation syntax differs.
+// 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 Run() function. Usually just a convenience typedef.
+// a Callback<>::Run(). Usually just a convenience typedef.
// (Bound)Args -- A set of types that stores the arguments.
//
// Types:
-// RunnableAdapter<> -- Wraps the various "function" pointer types into an
-// object that adheres to the Runnable interface.
// ForceVoidReturn<> -- Helper class for translating function signatures to
// equivalent forms with a "void" return type.
-// FunctorTraits<> -- Type traits used determine the correct RunType and
-// RunnableType for a Functor. This is where function
+// FunctorTraits<> -- Type traits used to determine the correct RunType and
+// invocation manner for a Functor. This is where function
// signature adapters are applied.
-// MakeRunnable<> -- Takes a Functor and returns an object in the Runnable
-// type class that represents the underlying Functor.
-// InvokeHelper<> -- Take a Runnable + arguments and actully invokes it.
+// InvokeHelper<> -- Take a Functor + arguments and actully invokes it.
// Handle the differing syntaxes needed for WeakPtr<>
-// support, and for ignoring return values. This is separate
-// from Invoker to avoid creating multiple version of
-// Invoker<>.
-// Invoker<> -- Unwraps the curried parameters and executes the Runnable.
+// 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, doing most of the type resolution.
-// There are ARITY BindState types.
+// into the Bind() system.
-// HasNonConstReferenceParam selects true_type when any of the parameters in
-// |Sig| is a non-const reference.
-// Implementation note: This non-specialized case handles zero-arity case only.
-// Non-zero-arity cases should be handled by the specialization below.
-template <typename List>
-struct HasNonConstReferenceItem : std::false_type {};
+template <typename...>
+struct make_void {
+ using type = void;
+};
-// Implementation note: Select true_type if the first parameter is a non-const
-// reference. Otherwise, skip the first parameter and check rest of parameters
-// recursively.
-template <typename T, typename... Args>
-struct HasNonConstReferenceItem<TypeList<T, Args...>>
- : std::conditional<is_non_const_reference<T>::value,
- std::true_type,
- HasNonConstReferenceItem<TypeList<Args...>>>::type {};
+// A clone of C++17 std::void_t.
+// Unlike the original version, we need |make_void| as a helper struct to avoid
+// a C++14 defect.
+// ref: http://en.cppreference.com/w/cpp/types/void_t
+// ref: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558
+template <typename... Ts>
+using void_t = typename make_void<Ts...>::type;
+
+template <typename Callable,
+ typename Signature = decltype(&Callable::operator())>
+struct ExtractCallableRunTypeImpl;
+
+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;
+
+// IsConvertibleToRunType<Functor> is std::true_type if |Functor| has operator()
+// and convertible to the corresponding function pointer. Otherwise, it's
+// std::false_type.
+// Example:
+// IsConvertibleToRunType<void(*)()>::value is false.
+//
+// struct Foo {};
+// IsConvertibleToRunType<void(Foo::*)()>::value is false.
+//
+// auto f = []() {};
+// IsConvertibleToRunType<decltype(f)>::value is true.
+//
+// int i = 0;
+// auto g = [i]() {};
+// IsConvertibleToRunType<decltype(g)>::value is false.
+template <typename Functor, typename SFINAE = void>
+struct IsConvertibleToRunType : std::false_type {};
+
+template <typename Callable>
+struct IsConvertibleToRunType<Callable, void_t<decltype(&Callable::operator())>>
+ : std::is_convertible<Callable, ExtractCallableRunType<Callable>*> {};
// HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw
// pointer to a RefCounted type.
@@ -95,344 +116,338 @@ struct HasRefCountedTypeAsRawPtr<T, Args...>
std::true_type,
HasRefCountedTypeAsRawPtr<Args...>>::type {};
-// BindsArrayToFirstArg selects true_type when |is_method| is true and the first
-// item of |Args| is an array type.
-// Implementation note: This non-specialized case handles !is_method case and
-// zero-arity case only. Other cases should be handled by the specialization
-// below.
-template <bool is_method, typename... Args>
-struct BindsArrayToFirstArg : std::false_type {};
-
-template <typename T, typename... Args>
-struct BindsArrayToFirstArg<true, T, Args...>
- : std::is_array<typename std::remove_reference<T>::type> {};
-
-// HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except
-// when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument.
-// Implementation note: This non-specialized case handles !is_method case and
-// zero-arity case only. Other cases should be handled by the specialization
-// below.
-template <bool is_method, typename... Args>
-struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {};
+// ForceVoidReturn<>
+//
+// Set of templates that support forcing the function return type to void.
+template <typename Sig>
+struct ForceVoidReturn;
-template <typename T, typename... Args>
-struct HasRefCountedParamAsRawPtr<true, T, Args...>
- : HasRefCountedTypeAsRawPtr<Args...> {};
+template <typename R, typename... Args>
+struct ForceVoidReturn<R(Args...)> {
+ using RunType = void(Args...);
+};
-// RunnableAdapter<>
-//
-// The RunnableAdapter<> templates provide a uniform interface for invoking
-// a function pointer, method pointer, or const method pointer. The adapter
-// exposes a Run() method with an appropriate signature. Using this wrapper
-// allows for writing code that supports all three pointer types without
-// undue repetition. Without it, a lot of code would need to be repeated 3
-// times.
-//
-// For method pointers and const method pointers the first argument to Run()
-// is considered to be the received of the method. This is similar to STL's
-// mem_fun().
-//
-// This class also exposes a RunType typedef that is the function type of the
-// Run() function.
+// FunctorTraits<>
//
-// If and only if the wrapper contains a method or const method pointer, an
-// IsMethod typedef is exposed. The existence of this typedef (NOT the value)
-// marks that the wrapper should be considered a method wrapper.
+// See description at top of file.
+template <typename Functor, typename SFINAE = void>
+struct FunctorTraits;
+// For a callable type that is convertible to the corresponding function type.
+// This specialization is intended to allow binding captureless lambdas by
+// base::Bind(), based on the fact that captureless lambdas can be convertible
+// to the function type while capturing lambdas can't.
template <typename Functor>
-class RunnableAdapter;
-
-// Function.
-template <typename R, typename... Args>
-class RunnableAdapter<R(*)(Args...)> {
- public:
- // MSVC 2013 doesn't support Type Alias of function types.
- // Revisit this after we update it to newer version.
- typedef R RunType(Args...);
-
- explicit RunnableAdapter(R(*function)(Args...))
- : function_(function) {
- }
+struct FunctorTraits<
+ Functor,
+ typename std::enable_if<IsConvertibleToRunType<Functor>::value>::type> {
+ using RunType = ExtractCallableRunType<Functor>;
+ static constexpr bool is_method = false;
+ static constexpr bool is_nullable = false;
template <typename... RunArgs>
- R Run(RunArgs&&... args) {
- return function_(std::forward<RunArgs>(args)...);
+ static ExtractReturnType<RunType>
+ Invoke(const Functor& functor, RunArgs&&... args) {
+ return functor(std::forward<RunArgs>(args)...);
}
-
- private:
- R (*function_)(Args...);
};
-// Method.
-template <typename R, typename T, typename... Args>
-class RunnableAdapter<R(T::*)(Args...)> {
- public:
- // MSVC 2013 doesn't support Type Alias of function types.
- // Revisit this after we update it to newer version.
- typedef R RunType(T*, Args...);
- using IsMethod = std::true_type;
-
- explicit RunnableAdapter(R(T::*method)(Args...))
- : method_(method) {
- }
+// 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... RunArgs>
- R Run(T* object, RunArgs&&... args) {
- return (object->*method_)(std::forward<RunArgs>(args)...);
+ static R Invoke(R (*function)(Args...), RunArgs&&... args) {
+ return function(std::forward<RunArgs>(args)...);
}
-
- private:
- R (T::*method_)(Args...);
};
-// Const Method.
-template <typename R, typename T, typename... Args>
-class RunnableAdapter<R(T::*)(Args...) const> {
- public:
- using RunType = R(const T*, Args...);
- using IsMethod = std::true_type;
+#if defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
- explicit RunnableAdapter(R(T::*method)(Args...) const)
- : method_(method) {
- }
+// 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>
- R Run(const T* object, RunArgs&&... args) {
- return (object->*method_)(std::forward<RunArgs>(args)...);
+ static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) {
+ return function(std::forward<RunArgs>(args)...);
}
-
- private:
- R (T::*method_)(Args...) const;
};
-
-// ForceVoidReturn<>
-//
-// Set of templates that support forcing the function return type to void.
-template <typename Sig>
-struct ForceVoidReturn;
-
+// For functions.
template <typename R, typename... Args>
-struct ForceVoidReturn<R(Args...)> {
- // MSVC 2013 doesn't support Type Alias of function types.
- // Revisit this after we update it to newer version.
- typedef void RunType(Args...);
-};
+struct FunctorTraits<R(__fastcall*)(Args...)> {
+ using RunType = R(Args...);
+ static constexpr bool is_method = false;
+ static constexpr bool is_nullable = true;
-
-// FunctorTraits<>
-//
-// See description at top of file.
-template <typename T>
-struct FunctorTraits {
- using RunnableType = RunnableAdapter<T>;
- using RunType = typename RunnableType::RunType;
+ template <typename... RunArgs>
+ static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) {
+ return function(std::forward<RunArgs>(args)...);
+ }
};
-template <typename T>
-struct FunctorTraits<IgnoreResultHelper<T>> {
- using RunnableType = typename FunctorTraits<T>::RunnableType;
- using RunType =
- typename ForceVoidReturn<typename RunnableType::RunType>::RunType;
+#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 ReceiverPtr, typename... RunArgs>
+ static R Invoke(R (Receiver::*method)(Args...),
+ ReceiverPtr&& receiver_ptr,
+ RunArgs&&... args) {
+ // Clang skips CV qualifier check on a method pointer invocation when the
+ // receiver is a subclass. Store the receiver into a const reference to
+ // T to ensure the CV check works.
+ // https://llvm.org/bugs/show_bug.cgi?id=27037
+ Receiver& receiver = *receiver_ptr;
+ return (receiver.*method)(std::forward<RunArgs>(args)...);
+ }
};
-template <typename T>
-struct FunctorTraits<Callback<T>> {
- using RunnableType = Callback<T> ;
- using RunType = typename Callback<T>::RunType;
+// 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 ReceiverPtr, typename... RunArgs>
+ static R Invoke(R (Receiver::*method)(Args...) const,
+ ReceiverPtr&& receiver_ptr,
+ RunArgs&&... args) {
+ // Clang skips CV qualifier check on a method pointer invocation when the
+ // receiver is a subclass. Store the receiver into a const reference to
+ // T to ensure the CV check works.
+ // https://llvm.org/bugs/show_bug.cgi?id=27037
+ const Receiver& receiver = *receiver_ptr;
+ return (receiver.*method)(std::forward<RunArgs>(args)...);
+ }
};
-
-// MakeRunnable<>
-//
-// Converts a passed in functor to a RunnableType using type inference.
-
+// For IgnoreResults.
template <typename T>
-typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) {
- return RunnableAdapter<T>(t);
-}
-
-template <typename T>
-typename FunctorTraits<T>::RunnableType
-MakeRunnable(const IgnoreResultHelper<T>& t) {
- return MakeRunnable(t.functor_);
-}
+struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> {
+ using RunType =
+ typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType;
-template <typename T>
-const typename FunctorTraits<Callback<T>>::RunnableType&
-MakeRunnable(const Callback<T>& t) {
- DCHECK(!t.is_null());
- return t;
-}
+ template <typename IgnoreResultType, typename... RunArgs>
+ static void Invoke(IgnoreResultType&& ignore_result_helper,
+ RunArgs&&... args) {
+ FunctorTraits<T>::Invoke(ignore_result_helper.functor_,
+ std::forward<RunArgs>(args)...);
+ }
+};
+// For Callbacks.
+template <typename R, typename... Args, CopyMode copy_mode>
+struct FunctorTraits<Callback<R(Args...), copy_mode>> {
+ 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)...);
+ }
+};
// InvokeHelper<>
//
-// There are 3 logical InvokeHelper<> specializations: normal, void-return,
-// WeakCalls.
+// There are 2 logical InvokeHelper<> specializations: normal, WeakCalls.
//
// The normal type just calls the underlying runnable.
//
-// We need a InvokeHelper to handle void return types in order to support
-// IgnoreResult(). Normally, if the Runnable's RunType had a void return,
-// the template system would just accept "return functor.Run()" ignoring
-// the fact that a void function is being used with return. This piece of
-// sugar breaks though when the Runnable's RunType is not void. Thus, we
-// need a partial specialization to change the syntax to drop the "return"
-// from the invocation call.
-//
-// WeakCalls similarly need special syntax that is applied to the first
-// argument to check if they should no-op themselves.
-template <bool IsWeakCall, typename ReturnType, typename 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, typename Runnable>
-struct InvokeHelper<false, ReturnType, Runnable> {
- template <typename... RunArgs>
- static ReturnType MakeItSo(Runnable runnable, RunArgs&&... args) {
- return runnable.Run(std::forward<RunArgs>(args)...);
- }
-};
-
-template <typename Runnable>
-struct InvokeHelper<false, void, Runnable> {
- template <typename... RunArgs>
- static void MakeItSo(Runnable runnable, RunArgs&&... args) {
- runnable.Run(std::forward<RunArgs>(args)...);
- }
-};
-
-template <typename Runnable>
-struct InvokeHelper<true, void, Runnable> {
- template <typename BoundWeakPtr, typename... RunArgs>
- static void MakeItSo(Runnable runnable,
- BoundWeakPtr weak_ptr,
- RunArgs&&... args) {
- if (!weak_ptr.get()) {
- return;
- }
- runnable.Run(weak_ptr.get(), std::forward<RunArgs>(args)...);
+template <typename ReturnType>
+struct InvokeHelper<false, ReturnType> {
+ template <typename Functor, typename... RunArgs>
+ static inline ReturnType MakeItSo(Functor&& functor, RunArgs&&... args) {
+ using Traits = FunctorTraits<typename std::decay<Functor>::type>;
+ return Traits::Invoke(std::forward<Functor>(functor),
+ std::forward<RunArgs>(args)...);
}
};
-#if !defined(_MSC_VER)
-
-template <typename ReturnType, typename Runnable>
-struct InvokeHelper<true, ReturnType, Runnable> {
+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");
-};
-#endif
+ template <typename Functor, typename BoundWeakPtr, typename... RunArgs>
+ static inline void MakeItSo(Functor&& functor,
+ BoundWeakPtr&& weak_ptr,
+ RunArgs&&... args) {
+ if (!weak_ptr)
+ return;
+ using Traits = FunctorTraits<typename std::decay<Functor>::type>;
+ 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 BoundIndices, typename StorageType,
- typename InvokeHelperType, typename UnboundForwardRunType>
+template <typename StorageType, typename UnboundRunType>
struct Invoker;
-template <size_t... bound_indices,
- typename StorageType,
- typename InvokeHelperType,
- typename R,
- typename... UnboundArgs>
-struct Invoker<IndexSequence<bound_indices...>,
- StorageType,
- InvokeHelperType,
- R(UnboundArgs...)> {
+template <typename StorageType, typename R, typename... UnboundArgs>
+struct Invoker<StorageType, R(UnboundArgs...)> {
static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) {
- StorageType* storage = static_cast<StorageType*>(base);
// 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.
- return InvokeHelperType::MakeItSo(
- storage->runnable_, Unwrap(get<bound_indices>(storage->bound_args_))...,
- std::forward<UnboundArgs>(unbound_args)...);
+ 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_,
+ MakeIndexSequence<num_bound_args>(),
+ std::forward<UnboundArgs>(unbound_args)...);
}
-};
-// Used to implement MakeArgsStorage.
-template <bool is_method, typename... BoundArgs>
-struct MakeArgsStorageImpl {
- using Type = std::tuple<BoundArgs...>;
+ private:
+ template <typename Functor, typename BoundArgsTuple, size_t... indices>
+ static inline R RunImpl(Functor&& functor,
+ BoundArgsTuple&& bound,
+ IndexSequence<indices...>,
+ UnboundArgs&&... unbound_args) {
+ static constexpr bool is_method =
+ FunctorTraits<typename std::decay<Functor>::type>::is_method;
+
+ using DecayedArgsTuple = typename std::decay<BoundArgsTuple>::type;
+ static constexpr bool is_weak_call =
+ IsWeakMethod<is_method,
+ typename std::tuple_element<
+ indices,
+ DecayedArgsTuple>::type...>::value;
+
+ return InvokeHelper<is_weak_call, R>::MakeItSo(
+ std::forward<Functor>(functor),
+ Unwrap(base::get<indices>(std::forward<BoundArgsTuple>(bound)))...,
+ std::forward<UnboundArgs>(unbound_args)...);
+ }
};
-template <typename Obj, typename... BoundArgs>
-struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> {
- using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>;
+// Used to implement MakeUnboundRunType.
+template <typename Functor, typename... BoundArgs>
+struct MakeUnboundRunTypeImpl {
+ using RunType =
+ typename FunctorTraits<typename std::decay<Functor>::type>::RunType;
+ using ReturnType = ExtractReturnType<RunType>;
+ using Args = ExtractArgs<RunType>;
+ using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>;
+ using Type = MakeFunctionType<ReturnType, UnboundArgs>;
};
+template <typename Functor>
+typename std::enable_if<FunctorTraits<Functor>::is_nullable, bool>::type
+IsNull(const Functor& functor) {
+ return !functor;
+}
-// Constructs a tuple type to store BoundArgs into BindState.
-// This wraps the first argument into a scoped_refptr if |is_method| is true and
-// the first argument is a raw pointer.
-// Other arguments are adjusted for store and packed into a tuple.
-template <bool is_method, typename... BoundArgs>
-using MakeArgsStorage = typename MakeArgsStorageImpl<
- is_method, typename std::decay<BoundArgs>::type...>::Type;
+template <typename Functor>
+typename std::enable_if<!FunctorTraits<Functor>::is_nullable, bool>::type
+IsNull(const Functor&) {
+ return false;
+}
// BindState<>
//
-// This stores all the state passed into Bind() and is also where most
-// of the template resolution magic occurs.
-//
-// Runnable is the functor we are binding arguments to.
-// RunType is type of the Run() function that the Invoker<> should use.
-// Normally, this is the same as the RunType of the Runnable, but it can
-// be different if an adapter like IgnoreResult() has been used.
-//
-// BoundArgs contains the storage type for all the bound arguments.
-template <typename Runnable, typename RunType, typename... BoundArgs>
-struct BindState;
-
-template <typename Runnable,
- typename R,
- typename... Args,
- typename... BoundArgs>
-struct BindState<Runnable, R(Args...), BoundArgs...> final
- : public BindStateBase {
- private:
- using StorageType = BindState<Runnable, R(Args...), BoundArgs...>;
- using RunnableType = Runnable;
+// This stores all the state passed into Bind().
+template <typename Functor, typename... BoundArgs>
+struct BindState final : BindStateBase {
+ template <typename ForwardFunctor, typename... ForwardBoundArgs>
+ explicit BindState(ForwardFunctor&& functor, ForwardBoundArgs&&... bound_args)
+ : BindStateBase(&Destroy),
+ functor_(std::forward<ForwardFunctor>(functor)),
+ bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
+ DCHECK(!IsNull(functor_));
+ }
- enum { is_method = HasIsMethodTag<Runnable>::value };
+ Functor functor_;
+ std::tuple<BoundArgs...> bound_args_;
- // true_type if Runnable is a method invocation and the first bound argument
- // is a WeakPtr.
- using IsWeakCall =
- IsWeakMethod<is_method, typename std::decay<BoundArgs>::type...>;
+ private:
+ ~BindState() {}
- using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>;
- using InvokeHelperType = InvokeHelper<IsWeakCall::value, R, Runnable>;
+ static void Destroy(BindStateBase* self) {
+ delete static_cast<BindState*>(self);
+ }
+};
- using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>;
+// Used to implement MakeBindStateType.
+template <bool is_method, typename Functor, typename... BoundArgs>
+struct MakeBindStateTypeImpl;
- public:
- using UnboundRunType = MakeFunctionType<R, UnboundArgs>;
- using InvokerType =
- Invoker<BoundIndices, StorageType, InvokeHelperType, UnboundRunType>;
+template <typename Functor, typename... BoundArgs>
+struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> {
+ static_assert(!HasRefCountedTypeAsRawPtr<BoundArgs...>::value,
+ "A parameter is a refcounted type and needs scoped_refptr.");
+ using Type = BindState<typename std::decay<Functor>::type,
+ typename std::decay<BoundArgs>::type...>;
+};
- template <typename... ForwardArgs>
- BindState(const Runnable& runnable, ForwardArgs&&... bound_args)
- : BindStateBase(&Destroy),
- runnable_(runnable),
- bound_args_(std::forward<ForwardArgs>(bound_args)...) {}
+template <typename Functor>
+struct MakeBindStateTypeImpl<true, Functor> {
+ using Type = BindState<typename std::decay<Functor>::type>;
+};
- RunnableType runnable_;
- MakeArgsStorage<is_method, BoundArgs...> bound_args_;
+template <typename Functor, typename Receiver, typename... BoundArgs>
+struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> {
+ static_assert(
+ !std::is_array<typename std::remove_reference<Receiver>::type>::value,
+ "First bound argument to a method cannot be an array.");
+ static_assert(!HasRefCountedTypeAsRawPtr<BoundArgs...>::value,
+ "A parameter is a refcounted type and needs scoped_refptr.");
private:
- ~BindState() {}
+ using DecayedReceiver = typename std::decay<Receiver>::type;
- static void Destroy(BindStateBase* self) {
- delete static_cast<BindState*>(self);
- }
+ public:
+ using Type = BindState<
+ typename std::decay<Functor>::type,
+ typename std::conditional<
+ std::is_pointer<DecayedReceiver>::value,
+ scoped_refptr<typename std::remove_pointer<DecayedReceiver>::type>,
+ DecayedReceiver>::type,
+ typename std::decay<BoundArgs>::type...>;
};
+template <typename Functor, typename... BoundArgs>
+using MakeBindStateType = typename MakeBindStateTypeImpl<
+ FunctorTraits<typename std::decay<Functor>::type>::is_method,
+ Functor,
+ BoundArgs...>::Type;
+
} // namespace internal
+
+// 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::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type;
+
} // namespace base
#endif // BASE_BIND_INTERNAL_H_