blob: 077c0e478362a3ac2118659a66109e0a8cc44483 [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
avi9b6f42932015-12-26 22:15:148#include <stddef.h>
9
tzik1068f1be2016-06-03 07:25:2010#include <tuple>
vmpstrc52317f2015-11-18 08:43:2611#include <type_traits>
12
[email protected]b38d3572011-02-15 01:27:3813#include "base/bind_helpers.h"
[email protected]59eff912011-02-18 23:29:3114#include "base/callback_internal.h"
[email protected]8217d4542011-10-01 06:31:4115#include "base/memory/raw_scoped_refptr_mismatch_checker.h"
[email protected]93540582011-05-16 22:35:1416#include "base/memory/weak_ptr.h"
[email protected]b38d3572011-02-15 01:27:3817#include "base/template_util.h"
tzik8ce65702015-02-05 19:11:2618#include "base/tuple.h"
[email protected]054ac7542011-02-27 01:25:5919#include "build/build_config.h"
20
21#if defined(OS_WIN)
22#include "base/bind_internal_win.h"
23#endif
[email protected]b38d3572011-02-15 01:27:3824
25namespace base {
26namespace internal {
27
[email protected]24292642012-07-12 20:06:4028// See base/callback.h for user documentation.
29//
30//
[email protected]7296f2762011-11-21 19:23:4431// CONCEPTS:
32// Runnable -- A type (really a type class) that has a single Run() method
33// and a RunType typedef that corresponds to the type of Run().
34// A Runnable can declare that it should treated like a method
35// call by including a typedef named IsMethod. The value of
36// this typedef is NOT inspected, only the existence. When a
37// Runnable declares itself a method, Bind() will enforce special
38// refcounting + WeakPtr handling semantics for the first
39// parameter which is expected to be an object.
40// Functor -- A copyable type representing something that should be called.
41// All function pointers, Callback<>, and Runnables are functors
42// even if the invocation syntax differs.
43// RunType -- A function type (as opposed to function _pointer_ type) for
44// a Run() function. Usually just a convenience typedef.
tzikce3ecf82015-12-15 06:41:4945// (Bound)Args -- A set of types that stores the arguments.
[email protected]b38d3572011-02-15 01:27:3846//
[email protected]7296f2762011-11-21 19:23:4447// Types:
48// RunnableAdapter<> -- Wraps the various "function" pointer types into an
49// object that adheres to the Runnable interface.
[email protected]7296f2762011-11-21 19:23:4450// ForceVoidReturn<> -- Helper class for translating function signatures to
51// equivalent forms with a "void" return type.
[email protected]7296f2762011-11-21 19:23:4452// FunctorTraits<> -- Type traits used determine the correct RunType and
53// RunnableType for a Functor. This is where function
54// signature adapters are applied.
[email protected]7296f2762011-11-21 19:23:4455// MakeRunnable<> -- Takes a Functor and returns an object in the Runnable
56// type class that represents the underlying Functor.
[email protected]7296f2762011-11-21 19:23:4457// InvokeHelper<> -- Take a Runnable + arguments and actully invokes it.
tzik8ce65702015-02-05 19:11:2658// Handle the differing syntaxes needed for WeakPtr<>
59// support, and for ignoring return values. This is separate
60// from Invoker to avoid creating multiple version of
61// Invoker<>.
[email protected]7296f2762011-11-21 19:23:4462// Invoker<> -- Unwraps the curried parameters and executes the Runnable.
[email protected]7296f2762011-11-21 19:23:4463// BindState<> -- Stores the curried parameters, and is the main entry point
64// into the Bind() system, doing most of the type resolution.
65// There are ARITY BindState types.
[email protected]4346ef912011-02-19 00:52:1566
tzik401dd3672014-11-26 07:54:5867// HasNonConstReferenceParam selects true_type when any of the parameters in
68// |Sig| is a non-const reference.
69// Implementation note: This non-specialized case handles zero-arity case only.
70// Non-zero-arity cases should be handled by the specialization below.
tzik7fe3a682015-12-18 02:23:2671template <typename List>
tzik403cb6c2016-03-10 07:17:2572struct HasNonConstReferenceItem : std::false_type {};
tzik401dd3672014-11-26 07:54:5873
74// Implementation note: Select true_type if the first parameter is a non-const
75// reference. Otherwise, skip the first parameter and check rest of parameters
76// recursively.
tzik7fe3a682015-12-18 02:23:2677template <typename T, typename... Args>
78struct HasNonConstReferenceItem<TypeList<T, Args...>>
vmpstrc52317f2015-11-18 08:43:2679 : std::conditional<is_non_const_reference<T>::value,
tzik403cb6c2016-03-10 07:17:2580 std::true_type,
tzik7fe3a682015-12-18 02:23:2681 HasNonConstReferenceItem<TypeList<Args...>>>::type {};
tzik401dd3672014-11-26 07:54:5882
83// HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw
84// pointer to a RefCounted type.
85// Implementation note: This non-specialized case handles zero-arity case only.
86// Non-zero-arity cases should be handled by the specialization below.
87template <typename... Args>
tzik403cb6c2016-03-10 07:17:2588struct HasRefCountedTypeAsRawPtr : std::false_type {};
tzik401dd3672014-11-26 07:54:5889
90// Implementation note: Select true_type if the first parameter is a raw pointer
91// to a RefCounted type. Otherwise, skip the first parameter and check rest of
92// parameters recursively.
93template <typename T, typename... Args>
94struct HasRefCountedTypeAsRawPtr<T, Args...>
vmpstrc52317f2015-11-18 08:43:2695 : std::conditional<NeedsScopedRefptrButGetsRawPtr<T>::value,
tzik403cb6c2016-03-10 07:17:2596 std::true_type,
vmpstrc52317f2015-11-18 08:43:2697 HasRefCountedTypeAsRawPtr<Args...>>::type {};
tzik401dd3672014-11-26 07:54:5898
99// BindsArrayToFirstArg selects true_type when |is_method| is true and the first
100// item of |Args| is an array type.
101// Implementation note: This non-specialized case handles !is_method case and
102// zero-arity case only. Other cases should be handled by the specialization
103// below.
104template <bool is_method, typename... Args>
tzik403cb6c2016-03-10 07:17:25105struct BindsArrayToFirstArg : std::false_type {};
tzik401dd3672014-11-26 07:54:58106
107template <typename T, typename... Args>
tzik0e9150f2016-02-03 04:42:30108struct BindsArrayToFirstArg<true, T, Args...>
tzik403cb6c2016-03-10 07:17:25109 : std::is_array<typename std::remove_reference<T>::type> {};
tzik401dd3672014-11-26 07:54:58110
111// HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except
112// when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument.
113// Implementation note: This non-specialized case handles !is_method case and
114// zero-arity case only. Other cases should be handled by the specialization
115// below.
116template <bool is_method, typename... Args>
117struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {};
118
119template <typename T, typename... Args>
120struct HasRefCountedParamAsRawPtr<true, T, Args...>
121 : HasRefCountedTypeAsRawPtr<Args...> {};
122
[email protected]7296f2762011-11-21 19:23:44123// RunnableAdapter<>
124//
125// The RunnableAdapter<> templates provide a uniform interface for invoking
126// a function pointer, method pointer, or const method pointer. The adapter
127// exposes a Run() method with an appropriate signature. Using this wrapper
128// allows for writing code that supports all three pointer types without
129// undue repetition. Without it, a lot of code would need to be repeated 3
130// times.
131//
132// For method pointers and const method pointers the first argument to Run()
133// is considered to be the received of the method. This is similar to STL's
134// mem_fun().
135//
136// This class also exposes a RunType typedef that is the function type of the
137// Run() function.
138//
139// If and only if the wrapper contains a method or const method pointer, an
140// IsMethod typedef is exposed. The existence of this typedef (NOT the value)
141// marks that the wrapper should be considered a method wrapper.
[email protected]93540582011-05-16 22:35:14142
[email protected]7296f2762011-11-21 19:23:44143template <typename Functor>
144class RunnableAdapter;
[email protected]4346ef912011-02-19 00:52:15145
tzikc82149922014-11-20 10:09:45146// Function.
147template <typename R, typename... Args>
148class RunnableAdapter<R(*)(Args...)> {
[email protected]7296f2762011-11-21 19:23:44149 public:
tzik3bc7779b2015-12-19 09:18:46150 // MSVC 2013 doesn't support Type Alias of function types.
151 // Revisit this after we update it to newer version.
152 typedef R RunType(Args...);
[email protected]c18b1052011-03-24 02:02:17153
tzikc82149922014-11-20 10:09:45154 explicit RunnableAdapter(R(*function)(Args...))
[email protected]7296f2762011-11-21 19:23:44155 : function_(function) {
156 }
[email protected]93540582011-05-16 22:35:14157
tzik6ba91a9d2016-02-15 20:51:34158 template <typename... RunArgs>
tzik9921447d2016-06-25 09:59:34159 R Run(RunArgs&&... args) const {
tzik6ba91a9d2016-02-15 20:51:34160 return function_(std::forward<RunArgs>(args)...);
[email protected]7296f2762011-11-21 19:23:44161 }
162
163 private:
tzikc82149922014-11-20 10:09:45164 R (*function_)(Args...);
[email protected]4346ef912011-02-19 00:52:15165};
166
tzikc82149922014-11-20 10:09:45167// Method.
168template <typename R, typename T, typename... Args>
169class RunnableAdapter<R(T::*)(Args...)> {
[email protected]7296f2762011-11-21 19:23:44170 public:
tzik3bc7779b2015-12-19 09:18:46171 // MSVC 2013 doesn't support Type Alias of function types.
172 // Revisit this after we update it to newer version.
173 typedef R RunType(T*, Args...);
tzik403cb6c2016-03-10 07:17:25174 using IsMethod = std::true_type;
[email protected]c18b1052011-03-24 02:02:17175
tzikc82149922014-11-20 10:09:45176 explicit RunnableAdapter(R(T::*method)(Args...))
[email protected]7296f2762011-11-21 19:23:44177 : method_(method) {
178 }
[email protected]93540582011-05-16 22:35:14179
tzik4435e8042016-05-11 23:05:05180 template <typename Receiver, typename... RunArgs>
tzik9921447d2016-06-25 09:59:34181 R Run(Receiver&& receiver_ptr, RunArgs&&... args) const {
tzikaf92fc3f2016-04-11 15:30:04182 // Clang skips CV qualifier check on a method pointer invocation when the
tzik4435e8042016-05-11 23:05:05183 // receiver is a subclass. Store the receiver into a const reference to
tzikaf92fc3f2016-04-11 15:30:04184 // T to ensure the CV check works.
185 // https://llvm.org/bugs/show_bug.cgi?id=27037
tzik4435e8042016-05-11 23:05:05186 T& receiver = *receiver_ptr;
187 return (receiver.*method_)(std::forward<RunArgs>(args)...);
vmpstr56b73902016-03-22 23:33:49188 }
189
[email protected]7296f2762011-11-21 19:23:44190 private:
tzikc82149922014-11-20 10:09:45191 R (T::*method_)(Args...);
[email protected]4346ef912011-02-19 00:52:15192};
193
tzikc82149922014-11-20 10:09:45194// Const Method.
195template <typename R, typename T, typename... Args>
196class RunnableAdapter<R(T::*)(Args...) const> {
[email protected]7296f2762011-11-21 19:23:44197 public:
tzik3bc7779b2015-12-19 09:18:46198 using RunType = R(const T*, Args...);
tzik403cb6c2016-03-10 07:17:25199 using IsMethod = std::true_type;
[email protected]c18b1052011-03-24 02:02:17200
tzikc82149922014-11-20 10:09:45201 explicit RunnableAdapter(R(T::*method)(Args...) const)
[email protected]7296f2762011-11-21 19:23:44202 : method_(method) {
203 }
[email protected]93540582011-05-16 22:35:14204
tzik4435e8042016-05-11 23:05:05205 template <typename Receiver, typename... RunArgs>
tzik9921447d2016-06-25 09:59:34206 R Run(Receiver&& receiver_ptr, RunArgs&&... args) const {
tzikaf92fc3f2016-04-11 15:30:04207 // Clang skips CV qualifier check on a method pointer invocation when the
tzik4435e8042016-05-11 23:05:05208 // receiver is a subclass. Store the receiver into a unqualified reference
209 // to T to ensure the CV check works.
tzikaf92fc3f2016-04-11 15:30:04210 // https://llvm.org/bugs/show_bug.cgi?id=27037
tzik4435e8042016-05-11 23:05:05211 const T& receiver = *receiver_ptr;
212 return (receiver.*method_)(std::forward<RunArgs>(args)...);
vmpstr56b73902016-03-22 23:33:49213 }
214
[email protected]7296f2762011-11-21 19:23:44215 private:
tzikc82149922014-11-20 10:09:45216 R (T::*method_)(Args...) const;
[email protected]4346ef912011-02-19 00:52:15217};
218
[email protected]7296f2762011-11-21 19:23:44219
220// ForceVoidReturn<>
221//
222// Set of templates that support forcing the function return type to void.
223template <typename Sig>
224struct ForceVoidReturn;
225
tzikc82149922014-11-20 10:09:45226template <typename R, typename... Args>
227struct ForceVoidReturn<R(Args...)> {
tzik3bc7779b2015-12-19 09:18:46228 // MSVC 2013 doesn't support Type Alias of function types.
229 // Revisit this after we update it to newer version.
230 typedef void RunType(Args...);
[email protected]fccef1552011-11-28 22:13:54231};
232
[email protected]7296f2762011-11-21 19:23:44233
234// FunctorTraits<>
235//
236// See description at top of file.
237template <typename T>
238struct FunctorTraits {
tzik3bc7779b2015-12-19 09:18:46239 using RunnableType = RunnableAdapter<T>;
240 using RunType = typename RunnableType::RunType;
[email protected]7296f2762011-11-21 19:23:44241};
242
243template <typename T>
tzik8ce65702015-02-05 19:11:26244struct FunctorTraits<IgnoreResultHelper<T>> {
tzik3bc7779b2015-12-19 09:18:46245 using RunnableType = typename FunctorTraits<T>::RunnableType;
246 using RunType =
247 typename ForceVoidReturn<typename RunnableType::RunType>::RunType;
[email protected]7296f2762011-11-21 19:23:44248};
249
250template <typename T>
tzik8ce65702015-02-05 19:11:26251struct FunctorTraits<Callback<T>> {
tzik3bc7779b2015-12-19 09:18:46252 using RunnableType = Callback<T> ;
253 using RunType = typename Callback<T>::RunType;
[email protected]7296f2762011-11-21 19:23:44254};
255
256
257// MakeRunnable<>
258//
259// Converts a passed in functor to a RunnableType using type inference.
260
261template <typename T>
262typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) {
263 return RunnableAdapter<T>(t);
264}
265
266template <typename T>
267typename FunctorTraits<T>::RunnableType
268MakeRunnable(const IgnoreResultHelper<T>& t) {
269 return MakeRunnable(t.functor_);
270}
271
272template <typename T>
tzik8ce65702015-02-05 19:11:26273const typename FunctorTraits<Callback<T>>::RunnableType&
[email protected]7296f2762011-11-21 19:23:44274MakeRunnable(const Callback<T>& t) {
[email protected]8cf362c2012-11-20 08:28:14275 DCHECK(!t.is_null());
[email protected]7296f2762011-11-21 19:23:44276 return t;
277}
278
279
280// InvokeHelper<>
281//
282// There are 3 logical InvokeHelper<> specializations: normal, void-return,
283// WeakCalls.
284//
285// The normal type just calls the underlying runnable.
286//
287// We need a InvokeHelper to handle void return types in order to support
288// IgnoreResult(). Normally, if the Runnable's RunType had a void return,
289// the template system would just accept "return functor.Run()" ignoring
290// the fact that a void function is being used with return. This piece of
291// sugar breaks though when the Runnable's RunType is not void. Thus, we
292// need a partial specialization to change the syntax to drop the "return"
293// from the invocation call.
294//
295// WeakCalls similarly need special syntax that is applied to the first
296// argument to check if they should no-op themselves.
tzikee248722016-06-01 08:22:51297template <bool is_weak_call, typename ReturnType>
[email protected]7296f2762011-11-21 19:23:44298struct InvokeHelper;
299
tzikee248722016-06-01 08:22:51300template <typename ReturnType>
301struct InvokeHelper<false, ReturnType> {
302 template <typename Runnable, typename... RunArgs>
tzikcaf1d84b2016-06-28 12:22:21303 static inline ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) {
tzikee248722016-06-01 08:22:51304 return std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...);
[email protected]7296f2762011-11-21 19:23:44305 }
306};
307
tzikee248722016-06-01 08:22:51308template <>
309struct InvokeHelper<false, void> {
310 template <typename Runnable, typename... RunArgs>
tzikcaf1d84b2016-06-28 12:22:21311 static inline void MakeItSo(Runnable&& runnable, RunArgs&&... args) {
tzikee248722016-06-01 08:22:51312 std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...);
[email protected]7296f2762011-11-21 19:23:44313 }
314};
315
tzikee248722016-06-01 08:22:51316template <>
317struct InvokeHelper<true, void> {
318 template <typename Runnable, typename BoundWeakPtr, typename... RunArgs>
319 static void MakeItSo(Runnable&& runnable,
tzik1ae80b22016-06-14 13:17:31320 BoundWeakPtr&& weak_ptr,
tzik6ba91a9d2016-02-15 20:51:34321 RunArgs&&... args) {
tzik1ae80b22016-06-14 13:17:31322 if (!weak_ptr) {
[email protected]7296f2762011-11-21 19:23:44323 return;
324 }
tzikee248722016-06-01 08:22:51325 std::forward<Runnable>(runnable).Run(
tzik1ae80b22016-06-14 13:17:31326 std::forward<BoundWeakPtr>(weak_ptr), std::forward<RunArgs>(args)...);
[email protected]fccef1552011-11-28 22:13:54327 }
328};
329
[email protected]7296f2762011-11-21 19:23:44330#if !defined(_MSC_VER)
331
tzikee248722016-06-01 08:22:51332template <typename ReturnType>
333struct InvokeHelper<true, ReturnType> {
[email protected]7296f2762011-11-21 19:23:44334 // WeakCalls are only supported for functions with a void return type.
335 // Otherwise, the function result would be undefined if the the WeakPtr<>
336 // is invalidated.
tzik403cb6c2016-03-10 07:17:25337 static_assert(std::is_void<ReturnType>::value,
avi4ec0dff2015-11-24 14:26:24338 "weak_ptrs can only bind to methods without return values");
[email protected]7296f2762011-11-21 19:23:44339};
[email protected]c18b1052011-03-24 02:02:17340
[email protected]7296f2762011-11-21 19:23:44341#endif
[email protected]b38d3572011-02-15 01:27:38342
[email protected]7296f2762011-11-21 19:23:44343// Invoker<>
344//
345// See description at the top of the file.
tzikcaf1d84b2016-06-28 12:22:21346template <typename StorageType, typename UnboundRunType>
[email protected]7296f2762011-11-21 19:23:44347struct Invoker;
348
tzikcaf1d84b2016-06-28 12:22:21349template <typename StorageType, typename R, typename... UnboundArgs>
350struct Invoker<StorageType, R(UnboundArgs...)> {
tzika43eff02016-03-09 05:46:05351 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) {
[email protected]7296f2762011-11-21 19:23:44352 // Local references to make debugger stepping easier. If in a debugger,
353 // you really want to warp ahead and step through the
354 // InvokeHelper<>::MakeItSo() call below.
tzikcaf1d84b2016-06-28 12:22:21355 const StorageType* storage = static_cast<StorageType*>(base);
356 static constexpr size_t num_bound_args =
357 std::tuple_size<decltype(storage->bound_args_)>::value;
358 return RunImpl(storage->runnable_,
359 storage->bound_args_,
360 MakeIndexSequence<num_bound_args>(),
361 std::forward<UnboundArgs>(unbound_args)...);
362 }
363
364 template <typename Runnable, typename BoundArgsTuple, size_t... indices>
365 static inline R RunImpl(Runnable&& runnable,
366 BoundArgsTuple&& bound,
367 IndexSequence<indices...>,
368 UnboundArgs&&... unbound_args) {
369 static constexpr bool is_method =
370 HasIsMethodTag<typename std::decay<Runnable>::type>::value;
371
372 using DecayedArgsTuple = typename std::decay<BoundArgsTuple>::type;
373 static constexpr bool is_weak_call =
374 IsWeakMethod<is_method,
375 typename std::tuple_element<
376 indices,
377 DecayedArgsTuple>::type...>::value;
378
tzikee248722016-06-01 08:22:51379 return InvokeHelper<is_weak_call, R>::MakeItSo(
tzikcaf1d84b2016-06-28 12:22:21380 std::forward<Runnable>(runnable),
381 Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))...,
tzika43eff02016-03-09 05:46:05382 std::forward<UnboundArgs>(unbound_args)...);
[email protected]fccef1552011-11-28 22:13:54383 }
384};
385
tzikc5849de52016-02-17 00:14:53386// Used to implement MakeArgsStorage.
387template <bool is_method, typename... BoundArgs>
388struct MakeArgsStorageImpl {
389 using Type = std::tuple<BoundArgs...>;
390};
391
392template <typename Obj, typename... BoundArgs>
393struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> {
394 using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>;
395};
396
397// Constructs a tuple type to store BoundArgs into BindState.
398// This wraps the first argument into a scoped_refptr if |is_method| is true and
399// the first argument is a raw pointer.
400// Other arguments are adjusted for store and packed into a tuple.
401template <bool is_method, typename... BoundArgs>
402using MakeArgsStorage = typename MakeArgsStorageImpl<
403 is_method, typename std::decay<BoundArgs>::type...>::Type;
[email protected]b38d3572011-02-15 01:27:38404
tzikcaf1d84b2016-06-28 12:22:21405// Used to implement MakeUnboundRunType.
406template <typename Functor, typename... BoundArgs>
407struct MakeUnboundRunTypeImpl {
408 using RunType = typename FunctorTraits<Functor>::RunType;
409 using ReturnType = ExtractReturnType<RunType>;
410 using Args = ExtractArgs<RunType>;
411 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>;
412 using Type = MakeFunctionType<ReturnType, UnboundArgs>;
413};
414
[email protected]7296f2762011-11-21 19:23:44415// BindState<>
416//
417// This stores all the state passed into Bind() and is also where most
418// of the template resolution magic occurs.
419//
420// Runnable is the functor we are binding arguments to.
[email protected]7296f2762011-11-21 19:23:44421//
tzikce3ecf82015-12-15 06:41:49422// BoundArgs contains the storage type for all the bound arguments.
tzikcaf1d84b2016-06-28 12:22:21423template <typename Runnable, typename... BoundArgs>
424struct BindState final : public BindStateBase {
tzik8ce65702015-02-05 19:11:26425 private:
tzikee248722016-06-01 08:22:51426 using RunnableType = typename std::decay<Runnable>::type;
tzik8ce65702015-02-05 19:11:26427
tzikcaf1d84b2016-06-28 12:22:21428 static constexpr bool is_method = HasIsMethodTag<RunnableType>::value;
tzik8ce65702015-02-05 19:11:26429
430 public:
tzik0e9150f2016-02-03 04:42:30431 template <typename... ForwardArgs>
tzikcaf1d84b2016-06-28 12:22:21432 explicit BindState(RunnableType runnable, ForwardArgs&&... bound_args)
taptede7e804c2015-05-14 08:03:32433 : BindStateBase(&Destroy),
tzikee248722016-06-01 08:22:51434 runnable_(std::move(runnable)),
tzik0e9150f2016-02-03 04:42:30435 bound_args_(std::forward<ForwardArgs>(bound_args)...) {}
[email protected]7296f2762011-11-21 19:23:44436
[email protected]7296f2762011-11-21 19:23:44437 RunnableType runnable_;
tzikc5849de52016-02-17 00:14:53438 MakeArgsStorage<is_method, BoundArgs...> bound_args_;
dmichael7d09007e2014-12-18 22:30:11439
440 private:
taptede7e804c2015-05-14 08:03:32441 ~BindState() {}
442
443 static void Destroy(BindStateBase* self) {
444 delete static_cast<BindState*>(self);
445 }
[email protected]fccef1552011-11-28 22:13:54446};
447
[email protected]b38d3572011-02-15 01:27:38448} // namespace internal
tzikcaf1d84b2016-06-28 12:22:21449
450// Returns a RunType of bound functor.
451// E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C).
452template <typename Functor, typename... BoundArgs>
453using MakeUnboundRunType =
454 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type;
455
[email protected]b38d3572011-02-15 01:27:38456} // namespace base
457
458#endif // BASE_BIND_INTERNAL_H_