blob: fbf43a06337fc37488463e31d931c7fec5a60f43 [file] [log] [blame]
[email protected]b38d3572011-02-15 01:27:381// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_BIND_INTERNAL_H_
6#define BASE_BIND_INTERNAL_H_
[email protected]b38d3572011-02-15 01:27:387
vmpstrc52317f2015-11-18 08:43:268#include <type_traits>
9
[email protected]b38d3572011-02-15 01:27:3810#include "base/bind_helpers.h"
[email protected]59eff912011-02-18 23:29:3111#include "base/callback_internal.h"
[email protected]8217d4542011-10-01 06:31:4112#include "base/memory/raw_scoped_refptr_mismatch_checker.h"
[email protected]93540582011-05-16 22:35:1413#include "base/memory/weak_ptr.h"
[email protected]b38d3572011-02-15 01:27:3814#include "base/template_util.h"
tzik8ce65702015-02-05 19:11:2615#include "base/tuple.h"
[email protected]054ac7542011-02-27 01:25:5916#include "build/build_config.h"
17
18#if defined(OS_WIN)
19#include "base/bind_internal_win.h"
20#endif
[email protected]b38d3572011-02-15 01:27:3821
22namespace base {
23namespace internal {
24
[email protected]24292642012-07-12 20:06:4025// See base/callback.h for user documentation.
26//
27//
[email protected]7296f2762011-11-21 19:23:4428// CONCEPTS:
29// Runnable -- A type (really a type class) that has a single Run() method
30// and a RunType typedef that corresponds to the type of Run().
31// A Runnable can declare that it should treated like a method
32// call by including a typedef named IsMethod. The value of
33// this typedef is NOT inspected, only the existence. When a
34// Runnable declares itself a method, Bind() will enforce special
35// refcounting + WeakPtr handling semantics for the first
36// parameter which is expected to be an object.
37// Functor -- A copyable type representing something that should be called.
38// All function pointers, Callback<>, and Runnables are functors
39// even if the invocation syntax differs.
40// RunType -- A function type (as opposed to function _pointer_ type) for
41// a Run() function. Usually just a convenience typedef.
tzikce3ecf82015-12-15 06:41:4942// (Bound)Args -- A set of types that stores the arguments.
[email protected]b38d3572011-02-15 01:27:3843//
[email protected]7296f2762011-11-21 19:23:4444// Types:
45// RunnableAdapter<> -- Wraps the various "function" pointer types into an
46// object that adheres to the Runnable interface.
[email protected]7296f2762011-11-21 19:23:4447// ForceVoidReturn<> -- Helper class for translating function signatures to
48// equivalent forms with a "void" return type.
[email protected]7296f2762011-11-21 19:23:4449// FunctorTraits<> -- Type traits used determine the correct RunType and
50// RunnableType for a Functor. This is where function
51// signature adapters are applied.
[email protected]7296f2762011-11-21 19:23:4452// MakeRunnable<> -- Takes a Functor and returns an object in the Runnable
53// type class that represents the underlying Functor.
[email protected]7296f2762011-11-21 19:23:4454// InvokeHelper<> -- Take a Runnable + arguments and actully invokes it.
tzik8ce65702015-02-05 19:11:2655// Handle the differing syntaxes needed for WeakPtr<>
56// support, and for ignoring return values. This is separate
57// from Invoker to avoid creating multiple version of
58// Invoker<>.
[email protected]7296f2762011-11-21 19:23:4459// Invoker<> -- Unwraps the curried parameters and executes the Runnable.
[email protected]7296f2762011-11-21 19:23:4460// BindState<> -- Stores the curried parameters, and is the main entry point
61// into the Bind() system, doing most of the type resolution.
62// There are ARITY BindState types.
[email protected]4346ef912011-02-19 00:52:1563
tzik401dd3672014-11-26 07:54:5864// HasNonConstReferenceParam selects true_type when any of the parameters in
65// |Sig| is a non-const reference.
66// Implementation note: This non-specialized case handles zero-arity case only.
67// Non-zero-arity cases should be handled by the specialization below.
tzik7fe3a682015-12-18 02:23:2668template <typename List>
69struct HasNonConstReferenceItem : false_type {};
tzik401dd3672014-11-26 07:54:5870
71// Implementation note: Select true_type if the first parameter is a non-const
72// reference. Otherwise, skip the first parameter and check rest of parameters
73// recursively.
tzik7fe3a682015-12-18 02:23:2674template <typename T, typename... Args>
75struct HasNonConstReferenceItem<TypeList<T, Args...>>
vmpstrc52317f2015-11-18 08:43:2676 : std::conditional<is_non_const_reference<T>::value,
77 true_type,
tzik7fe3a682015-12-18 02:23:2678 HasNonConstReferenceItem<TypeList<Args...>>>::type {};
tzik401dd3672014-11-26 07:54:5879
80// HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw
81// pointer to a RefCounted type.
82// Implementation note: This non-specialized case handles zero-arity case only.
83// Non-zero-arity cases should be handled by the specialization below.
84template <typename... Args>
85struct HasRefCountedTypeAsRawPtr : false_type {};
86
87// Implementation note: Select true_type if the first parameter is a raw pointer
88// to a RefCounted type. Otherwise, skip the first parameter and check rest of
89// parameters recursively.
90template <typename T, typename... Args>
91struct HasRefCountedTypeAsRawPtr<T, Args...>
vmpstrc52317f2015-11-18 08:43:2692 : std::conditional<NeedsScopedRefptrButGetsRawPtr<T>::value,
93 true_type,
94 HasRefCountedTypeAsRawPtr<Args...>>::type {};
tzik401dd3672014-11-26 07:54:5895
96// BindsArrayToFirstArg selects true_type when |is_method| is true and the first
97// item of |Args| is an array type.
98// Implementation note: This non-specialized case handles !is_method case and
99// zero-arity case only. Other cases should be handled by the specialization
100// below.
101template <bool is_method, typename... Args>
102struct BindsArrayToFirstArg : false_type {};
103
104template <typename T, typename... Args>
105struct BindsArrayToFirstArg<true, T, Args...> : is_array<T> {};
106
107// HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except
108// when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument.
109// Implementation note: This non-specialized case handles !is_method case and
110// zero-arity case only. Other cases should be handled by the specialization
111// below.
112template <bool is_method, typename... Args>
113struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {};
114
115template <typename T, typename... Args>
116struct HasRefCountedParamAsRawPtr<true, T, Args...>
117 : HasRefCountedTypeAsRawPtr<Args...> {};
118
[email protected]7296f2762011-11-21 19:23:44119// RunnableAdapter<>
120//
121// The RunnableAdapter<> templates provide a uniform interface for invoking
122// a function pointer, method pointer, or const method pointer. The adapter
123// exposes a Run() method with an appropriate signature. Using this wrapper
124// allows for writing code that supports all three pointer types without
125// undue repetition. Without it, a lot of code would need to be repeated 3
126// times.
127//
128// For method pointers and const method pointers the first argument to Run()
129// is considered to be the received of the method. This is similar to STL's
130// mem_fun().
131//
132// This class also exposes a RunType typedef that is the function type of the
133// Run() function.
134//
135// If and only if the wrapper contains a method or const method pointer, an
136// IsMethod typedef is exposed. The existence of this typedef (NOT the value)
137// marks that the wrapper should be considered a method wrapper.
[email protected]93540582011-05-16 22:35:14138
[email protected]7296f2762011-11-21 19:23:44139template <typename Functor>
140class RunnableAdapter;
[email protected]4346ef912011-02-19 00:52:15141
tzikc82149922014-11-20 10:09:45142// Function.
143template <typename R, typename... Args>
144class RunnableAdapter<R(*)(Args...)> {
[email protected]7296f2762011-11-21 19:23:44145 public:
tzikc82149922014-11-20 10:09:45146 typedef R (RunType)(Args...);
[email protected]c18b1052011-03-24 02:02:17147
tzikc82149922014-11-20 10:09:45148 explicit RunnableAdapter(R(*function)(Args...))
[email protected]7296f2762011-11-21 19:23:44149 : function_(function) {
150 }
[email protected]93540582011-05-16 22:35:14151
tzikc82149922014-11-20 10:09:45152 R Run(typename CallbackParamTraits<Args>::ForwardType... args) {
153 return function_(CallbackForward(args)...);
[email protected]7296f2762011-11-21 19:23:44154 }
155
156 private:
tzikc82149922014-11-20 10:09:45157 R (*function_)(Args...);
[email protected]4346ef912011-02-19 00:52:15158};
159
tzikc82149922014-11-20 10:09:45160// Method.
161template <typename R, typename T, typename... Args>
162class RunnableAdapter<R(T::*)(Args...)> {
[email protected]7296f2762011-11-21 19:23:44163 public:
tzikc82149922014-11-20 10:09:45164 typedef R (RunType)(T*, Args...);
[email protected]054ac7542011-02-27 01:25:59165 typedef true_type IsMethod;
[email protected]c18b1052011-03-24 02:02:17166
tzikc82149922014-11-20 10:09:45167 explicit RunnableAdapter(R(T::*method)(Args...))
[email protected]7296f2762011-11-21 19:23:44168 : method_(method) {
169 }
[email protected]93540582011-05-16 22:35:14170
tzikc82149922014-11-20 10:09:45171 R Run(T* object, typename CallbackParamTraits<Args>::ForwardType... args) {
172 return (object->*method_)(CallbackForward(args)...);
[email protected]7296f2762011-11-21 19:23:44173 }
[email protected]c18b1052011-03-24 02:02:17174
[email protected]7296f2762011-11-21 19:23:44175 private:
tzikc82149922014-11-20 10:09:45176 R (T::*method_)(Args...);
[email protected]4346ef912011-02-19 00:52:15177};
178
tzikc82149922014-11-20 10:09:45179// Const Method.
180template <typename R, typename T, typename... Args>
181class RunnableAdapter<R(T::*)(Args...) const> {
[email protected]7296f2762011-11-21 19:23:44182 public:
tzikc82149922014-11-20 10:09:45183 typedef R (RunType)(const T*, Args...);
[email protected]054ac7542011-02-27 01:25:59184 typedef true_type IsMethod;
[email protected]c18b1052011-03-24 02:02:17185
tzikc82149922014-11-20 10:09:45186 explicit RunnableAdapter(R(T::*method)(Args...) const)
[email protected]7296f2762011-11-21 19:23:44187 : method_(method) {
188 }
[email protected]93540582011-05-16 22:35:14189
tzikc82149922014-11-20 10:09:45190 R Run(const T* object,
191 typename CallbackParamTraits<Args>::ForwardType... args) {
192 return (object->*method_)(CallbackForward(args)...);
[email protected]7296f2762011-11-21 19:23:44193 }
[email protected]c18b1052011-03-24 02:02:17194
[email protected]7296f2762011-11-21 19:23:44195 private:
tzikc82149922014-11-20 10:09:45196 R (T::*method_)(Args...) const;
[email protected]4346ef912011-02-19 00:52:15197};
198
[email protected]7296f2762011-11-21 19:23:44199
200// ForceVoidReturn<>
201//
202// Set of templates that support forcing the function return type to void.
203template <typename Sig>
204struct ForceVoidReturn;
205
tzikc82149922014-11-20 10:09:45206template <typename R, typename... Args>
207struct ForceVoidReturn<R(Args...)> {
208 typedef void(RunType)(Args...);
[email protected]fccef1552011-11-28 22:13:54209};
210
[email protected]7296f2762011-11-21 19:23:44211
212// FunctorTraits<>
213//
214// See description at top of file.
215template <typename T>
216struct FunctorTraits {
217 typedef RunnableAdapter<T> RunnableType;
218 typedef typename RunnableType::RunType RunType;
219};
220
221template <typename T>
tzik8ce65702015-02-05 19:11:26222struct FunctorTraits<IgnoreResultHelper<T>> {
[email protected]7296f2762011-11-21 19:23:44223 typedef typename FunctorTraits<T>::RunnableType RunnableType;
224 typedef typename ForceVoidReturn<
225 typename RunnableType::RunType>::RunType RunType;
226};
227
228template <typename T>
tzik8ce65702015-02-05 19:11:26229struct FunctorTraits<Callback<T>> {
[email protected]7296f2762011-11-21 19:23:44230 typedef Callback<T> RunnableType;
231 typedef typename Callback<T>::RunType RunType;
232};
233
234
235// MakeRunnable<>
236//
237// Converts a passed in functor to a RunnableType using type inference.
238
239template <typename T>
240typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) {
241 return RunnableAdapter<T>(t);
242}
243
244template <typename T>
245typename FunctorTraits<T>::RunnableType
246MakeRunnable(const IgnoreResultHelper<T>& t) {
247 return MakeRunnable(t.functor_);
248}
249
250template <typename T>
tzik8ce65702015-02-05 19:11:26251const typename FunctorTraits<Callback<T>>::RunnableType&
[email protected]7296f2762011-11-21 19:23:44252MakeRunnable(const Callback<T>& t) {
[email protected]8cf362c2012-11-20 08:28:14253 DCHECK(!t.is_null());
[email protected]7296f2762011-11-21 19:23:44254 return t;
255}
256
257
258// InvokeHelper<>
259//
260// There are 3 logical InvokeHelper<> specializations: normal, void-return,
261// WeakCalls.
262//
263// The normal type just calls the underlying runnable.
264//
265// We need a InvokeHelper to handle void return types in order to support
266// IgnoreResult(). Normally, if the Runnable's RunType had a void return,
267// the template system would just accept "return functor.Run()" ignoring
268// the fact that a void function is being used with return. This piece of
269// sugar breaks though when the Runnable's RunType is not void. Thus, we
270// need a partial specialization to change the syntax to drop the "return"
271// from the invocation call.
272//
273// WeakCalls similarly need special syntax that is applied to the first
274// argument to check if they should no-op themselves.
275template <bool IsWeakCall, typename ReturnType, typename Runnable,
276 typename ArgsType>
277struct InvokeHelper;
278
tzikc82149922014-11-20 10:09:45279template <typename ReturnType, typename Runnable, typename... Args>
tzik8ce65702015-02-05 19:11:26280struct InvokeHelper<false, ReturnType, Runnable, TypeList<Args...>> {
tzikc82149922014-11-20 10:09:45281 static ReturnType MakeItSo(Runnable runnable, Args... args) {
282 return runnable.Run(CallbackForward(args)...);
[email protected]7296f2762011-11-21 19:23:44283 }
284};
285
tzikc82149922014-11-20 10:09:45286template <typename Runnable, typename... Args>
tzik8ce65702015-02-05 19:11:26287struct InvokeHelper<false, void, Runnable, TypeList<Args...>> {
tzikc82149922014-11-20 10:09:45288 static void MakeItSo(Runnable runnable, Args... args) {
289 runnable.Run(CallbackForward(args)...);
[email protected]7296f2762011-11-21 19:23:44290 }
291};
292
tzikc82149922014-11-20 10:09:45293template <typename Runnable, typename BoundWeakPtr, typename... Args>
tzik8ce65702015-02-05 19:11:26294struct InvokeHelper<true, void, Runnable, TypeList<BoundWeakPtr, Args...>> {
tzikc82149922014-11-20 10:09:45295 static void MakeItSo(Runnable runnable, BoundWeakPtr weak_ptr, Args... args) {
[email protected]f0737afd2013-06-03 22:15:21296 if (!weak_ptr.get()) {
[email protected]7296f2762011-11-21 19:23:44297 return;
298 }
tzikc82149922014-11-20 10:09:45299 runnable.Run(weak_ptr.get(), CallbackForward(args)...);
[email protected]fccef1552011-11-28 22:13:54300 }
301};
302
[email protected]7296f2762011-11-21 19:23:44303#if !defined(_MSC_VER)
304
305template <typename ReturnType, typename Runnable, typename ArgsType>
306struct InvokeHelper<true, ReturnType, Runnable, ArgsType> {
307 // WeakCalls are only supported for functions with a void return type.
308 // Otherwise, the function result would be undefined if the the WeakPtr<>
309 // is invalidated.
avi4ec0dff2015-11-24 14:26:24310 static_assert(is_void<ReturnType>::value,
311 "weak_ptrs can only bind to methods without return values");
[email protected]7296f2762011-11-21 19:23:44312};
[email protected]c18b1052011-03-24 02:02:17313
[email protected]7296f2762011-11-21 19:23:44314#endif
[email protected]b38d3572011-02-15 01:27:38315
[email protected]7296f2762011-11-21 19:23:44316// Invoker<>
317//
318// See description at the top of the file.
tzik8ce65702015-02-05 19:11:26319template <typename BoundIndices,
320 typename StorageType, typename Unwrappers,
321 typename InvokeHelperType, typename UnboundForwardRunType>
[email protected]7296f2762011-11-21 19:23:44322struct Invoker;
323
tzik8ce65702015-02-05 19:11:26324template <size_t... bound_indices,
325 typename StorageType,
326 typename... Unwrappers,
327 typename InvokeHelperType,
328 typename R,
329 typename... UnboundForwardArgs>
330struct Invoker<IndexSequence<bound_indices...>,
331 StorageType, TypeList<Unwrappers...>,
332 InvokeHelperType, R(UnboundForwardArgs...)> {
[email protected]7296f2762011-11-21 19:23:44333 static R Run(BindStateBase* base,
tzik8ce65702015-02-05 19:11:26334 UnboundForwardArgs... unbound_args) {
[email protected]7296f2762011-11-21 19:23:44335 StorageType* storage = static_cast<StorageType*>(base);
[email protected]7296f2762011-11-21 19:23:44336 // Local references to make debugger stepping easier. If in a debugger,
337 // you really want to warp ahead and step through the
338 // InvokeHelper<>::MakeItSo() call below.
tzik8ce65702015-02-05 19:11:26339 return InvokeHelperType::MakeItSo(
340 storage->runnable_,
341 Unwrappers::Unwrap(get<bound_indices>(storage->bound_args_))...,
342 CallbackForward(unbound_args)...);
[email protected]fccef1552011-11-28 22:13:54343 }
344};
345
[email protected]b38d3572011-02-15 01:27:38346
[email protected]7296f2762011-11-21 19:23:44347// BindState<>
348//
349// This stores all the state passed into Bind() and is also where most
350// of the template resolution magic occurs.
351//
352// Runnable is the functor we are binding arguments to.
353// RunType is type of the Run() function that the Invoker<> should use.
354// Normally, this is the same as the RunType of the Runnable, but it can
355// be different if an adapter like IgnoreResult() has been used.
356//
tzikce3ecf82015-12-15 06:41:49357// BoundArgs contains the storage type for all the bound arguments.
358template <typename Runnable, typename RunType, typename... BoundArgs>
[email protected]7296f2762011-11-21 19:23:44359struct BindState;
360
tzik8ce65702015-02-05 19:11:26361template <typename Runnable,
taptede7e804c2015-05-14 08:03:32362 typename R,
363 typename... Args,
tzik8ce65702015-02-05 19:11:26364 typename... BoundArgs>
tzikce3ecf82015-12-15 06:41:49365struct BindState<Runnable, R(Args...), BoundArgs...> final
tzik8ce65702015-02-05 19:11:26366 : public BindStateBase {
367 private:
tzikce3ecf82015-12-15 06:41:49368 using StorageType = BindState<Runnable, R(Args...), BoundArgs...>;
tzik8ce65702015-02-05 19:11:26369 using RunnableType = Runnable;
370
371 // true_type if Runnable is a method invocation and the first bound argument
372 // is a WeakPtr.
373 using IsWeakCall =
374 IsWeakMethod<HasIsMethodTag<Runnable>::value, BoundArgs...>;
375
376 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>;
377 using Unwrappers = TypeList<UnwrapTraits<BoundArgs>...>;
378 using UnboundForwardArgs = DropTypeListItem<
379 sizeof...(BoundArgs),
380 TypeList<typename CallbackParamTraits<Args>::ForwardType...>>;
381 using UnboundForwardRunType = MakeFunctionType<R, UnboundForwardArgs>;
382
383 using InvokeHelperArgs = ConcatTypeLists<
384 TypeList<typename UnwrapTraits<BoundArgs>::ForwardType...>,
385 UnboundForwardArgs>;
386 using InvokeHelperType =
387 InvokeHelper<IsWeakCall::value, R, Runnable, InvokeHelperArgs>;
388
389 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>;
390
391 public:
392 using InvokerType = Invoker<BoundIndices, StorageType, Unwrappers,
393 InvokeHelperType, UnboundForwardRunType>;
394 using UnboundRunType = MakeFunctionType<R, UnboundArgs>;
395
396 BindState(const Runnable& runnable, const BoundArgs&... bound_args)
taptede7e804c2015-05-14 08:03:32397 : BindStateBase(&Destroy),
398 runnable_(runnable),
399 ref_(bound_args...),
400 bound_args_(bound_args...) {}
[email protected]7296f2762011-11-21 19:23:44401
[email protected]7296f2762011-11-21 19:23:44402 RunnableType runnable_;
tzik8ce65702015-02-05 19:11:26403 MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_;
404 Tuple<BoundArgs...> bound_args_;
dmichael7d09007e2014-12-18 22:30:11405
406 private:
taptede7e804c2015-05-14 08:03:32407 ~BindState() {}
408
409 static void Destroy(BindStateBase* self) {
410 delete static_cast<BindState*>(self);
411 }
[email protected]fccef1552011-11-28 22:13:54412};
413
[email protected]b38d3572011-02-15 01:27:38414} // namespace internal
415} // namespace base
416
417#endif // BASE_BIND_INTERNAL_H_