Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: base/bind_internal.h

Issue 2106773002: Remove `Runnable` concept from base/bind_internal.h (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: +comment. fix spacing. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/bind_helpers.h ('k') | base/bind_internal_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_BIND_INTERNAL_H_ 5 #ifndef BASE_BIND_INTERNAL_H_
6 #define BASE_BIND_INTERNAL_H_ 6 #define BASE_BIND_INTERNAL_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <tuple> 10 #include <tuple>
11 #include <type_traits> 11 #include <type_traits>
12 12
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/callback_internal.h" 14 #include "base/callback_internal.h"
15 #include "base/memory/raw_scoped_refptr_mismatch_checker.h" 15 #include "base/memory/raw_scoped_refptr_mismatch_checker.h"
16 #include "base/memory/weak_ptr.h" 16 #include "base/memory/weak_ptr.h"
17 #include "base/template_util.h" 17 #include "base/template_util.h"
18 #include "base/tuple.h" 18 #include "base/tuple.h"
19 #include "build/build_config.h" 19 #include "build/build_config.h"
20 20
21 #if defined(OS_WIN)
22 #include "base/bind_internal_win.h"
23 #endif
24
25 namespace base { 21 namespace base {
26 namespace internal { 22 namespace internal {
27 23
28 // See base/callback.h for user documentation. 24 // See base/callback.h for user documentation.
29 // 25 //
30 // 26 //
31 // CONCEPTS: 27 // CONCEPTS:
32 // Runnable -- A type (really a type class) that has a single Run() method 28 // Functor -- A movable type representing something that should be called.
33 // and a RunType typedef that corresponds to the type of Run(). 29 // All function pointers and Callback<> are functors even if the
34 // A Runnable can declare that it should treated like a method 30 // invocation syntax differs.
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 31 // RunType -- A function type (as opposed to function _pointer_ type) for
44 // a Run() function. Usually just a convenience typedef. 32 // a Callback<>::Run(). Usually just a convenience typedef.
45 // (Bound)Args -- A set of types that stores the arguments. 33 // (Bound)Args -- A set of types that stores the arguments.
46 // 34 //
47 // Types: 35 // Types:
48 // RunnableAdapter<> -- Wraps the various "function" pointer types into an
49 // object that adheres to the Runnable interface.
50 // ForceVoidReturn<> -- Helper class for translating function signatures to 36 // ForceVoidReturn<> -- Helper class for translating function signatures to
51 // equivalent forms with a "void" return type. 37 // equivalent forms with a "void" return type.
52 // FunctorTraits<> -- Type traits used determine the correct RunType and 38 // FunctorTraits<> -- Type traits used to determine the correct RunType and
53 // RunnableType for a Functor. This is where function 39 // invocation manner for a Functor. This is where function
54 // signature adapters are applied. 40 // signature adapters are applied.
55 // MakeRunnable<> -- Takes a Functor and returns an object in the Runnable 41 // InvokeHelper<> -- Take a Functor + arguments and actully invokes it.
56 // type class that represents the underlying Functor.
57 // InvokeHelper<> -- Take a Runnable + arguments and actully invokes it.
58 // Handle the differing syntaxes needed for WeakPtr<> 42 // Handle the differing syntaxes needed for WeakPtr<>
59 // support, and for ignoring return values. This is separate 43 // support. This is separate from Invoker to avoid creating
60 // from Invoker to avoid creating multiple version of 44 // multiple version of Invoker<>.
61 // Invoker<>. 45 // Invoker<> -- Unwraps the curried parameters and executes the Functor.
62 // Invoker<> -- Unwraps the curried parameters and executes the Runnable.
63 // BindState<> -- Stores the curried parameters, and is the main entry point 46 // BindState<> -- Stores the curried parameters, and is the main entry point
64 // into the Bind() system, doing most of the type resolution. 47 // into the Bind() system.
65 // There are ARITY BindState types.
66 48
67 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw 49 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw
68 // pointer to a RefCounted type. 50 // pointer to a RefCounted type.
69 // Implementation note: This non-specialized case handles zero-arity case only. 51 // Implementation note: This non-specialized case handles zero-arity case only.
70 // Non-zero-arity cases should be handled by the specialization below. 52 // Non-zero-arity cases should be handled by the specialization below.
71 template <typename... Args> 53 template <typename... Args>
72 struct HasRefCountedTypeAsRawPtr : std::false_type {}; 54 struct HasRefCountedTypeAsRawPtr : std::false_type {};
73 55
74 // Implementation note: Select true_type if the first parameter is a raw pointer 56 // Implementation note: Select true_type if the first parameter is a raw pointer
75 // to a RefCounted type. Otherwise, skip the first parameter and check rest of 57 // to a RefCounted type. Otherwise, skip the first parameter and check rest of
76 // parameters recursively. 58 // parameters recursively.
77 template <typename T, typename... Args> 59 template <typename T, typename... Args>
78 struct HasRefCountedTypeAsRawPtr<T, Args...> 60 struct HasRefCountedTypeAsRawPtr<T, Args...>
79 : std::conditional<NeedsScopedRefptrButGetsRawPtr<T>::value, 61 : std::conditional<NeedsScopedRefptrButGetsRawPtr<T>::value,
80 std::true_type, 62 std::true_type,
81 HasRefCountedTypeAsRawPtr<Args...>>::type {}; 63 HasRefCountedTypeAsRawPtr<Args...>>::type {};
82 64
83 // BindsArrayToFirstArg selects true_type when |is_method| is true and the first
84 // item of |Args| is an array type.
85 // Implementation note: This non-specialized case handles !is_method case and
86 // zero-arity case only. Other cases should be handled by the specialization
87 // below.
88 template <bool is_method, typename... Args>
89 struct BindsArrayToFirstArg : std::false_type {};
90
91 template <typename T, typename... Args>
92 struct BindsArrayToFirstArg<true, T, Args...>
93 : std::is_array<typename std::remove_reference<T>::type> {};
94
95 // HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except
96 // when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument.
97 // Implementation note: This non-specialized case handles !is_method case and
98 // zero-arity case only. Other cases should be handled by the specialization
99 // below.
100 template <bool is_method, typename... Args>
101 struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {};
102
103 template <typename T, typename... Args>
104 struct HasRefCountedParamAsRawPtr<true, T, Args...>
105 : HasRefCountedTypeAsRawPtr<Args...> {};
106
107 // RunnableAdapter<>
108 //
109 // The RunnableAdapter<> templates provide a uniform interface for invoking
110 // a function pointer, method pointer, or const method pointer. The adapter
111 // exposes a Run() method with an appropriate signature. Using this wrapper
112 // allows for writing code that supports all three pointer types without
113 // undue repetition. Without it, a lot of code would need to be repeated 3
114 // times.
115 //
116 // For method pointers and const method pointers the first argument to Run()
117 // is considered to be the received of the method. This is similar to STL's
118 // mem_fun().
119 //
120 // This class also exposes a RunType typedef that is the function type of the
121 // Run() function.
122 //
123 // If and only if the wrapper contains a method or const method pointer, an
124 // IsMethod typedef is exposed. The existence of this typedef (NOT the value)
125 // marks that the wrapper should be considered a method wrapper.
126
127 template <typename Functor>
128 class RunnableAdapter;
129
130 // Function.
131 template <typename R, typename... Args>
132 class RunnableAdapter<R(*)(Args...)> {
133 public:
134 // MSVC 2013 doesn't support Type Alias of function types.
135 // Revisit this after we update it to newer version.
136 typedef R RunType(Args...);
137
138 explicit RunnableAdapter(R(*function)(Args...))
139 : function_(function) {
140 }
141
142 template <typename... RunArgs>
143 R Run(RunArgs&&... args) const {
144 return function_(std::forward<RunArgs>(args)...);
145 }
146
147 private:
148 R (*function_)(Args...);
149 };
150
151 // Method.
152 template <typename R, typename T, typename... Args>
153 class RunnableAdapter<R(T::*)(Args...)> {
154 public:
155 // MSVC 2013 doesn't support Type Alias of function types.
156 // Revisit this after we update it to newer version.
157 typedef R RunType(T*, Args...);
158 using IsMethod = std::true_type;
159
160 explicit RunnableAdapter(R(T::*method)(Args...))
161 : method_(method) {
162 }
163
164 template <typename Receiver, typename... RunArgs>
165 R Run(Receiver&& receiver_ptr, RunArgs&&... args) const {
166 // Clang skips CV qualifier check on a method pointer invocation when the
167 // receiver is a subclass. Store the receiver into a const reference to
168 // T to ensure the CV check works.
169 // https://llvm.org/bugs/show_bug.cgi?id=27037
170 T& receiver = *receiver_ptr;
171 return (receiver.*method_)(std::forward<RunArgs>(args)...);
172 }
173
174 private:
175 R (T::*method_)(Args...);
176 };
177
178 // Const Method.
179 template <typename R, typename T, typename... Args>
180 class RunnableAdapter<R(T::*)(Args...) const> {
181 public:
182 using RunType = R(const T*, Args...);
183 using IsMethod = std::true_type;
184
185 explicit RunnableAdapter(R(T::*method)(Args...) const)
186 : method_(method) {
187 }
188
189 template <typename Receiver, typename... RunArgs>
190 R Run(Receiver&& receiver_ptr, RunArgs&&... args) const {
191 // Clang skips CV qualifier check on a method pointer invocation when the
192 // receiver is a subclass. Store the receiver into a unqualified reference
193 // to T to ensure the CV check works.
194 // https://llvm.org/bugs/show_bug.cgi?id=27037
195 const T& receiver = *receiver_ptr;
196 return (receiver.*method_)(std::forward<RunArgs>(args)...);
197 }
198
199 private:
200 R (T::*method_)(Args...) const;
201 };
202
203
204 // ForceVoidReturn<> 65 // ForceVoidReturn<>
205 // 66 //
206 // Set of templates that support forcing the function return type to void. 67 // Set of templates that support forcing the function return type to void.
207 template <typename Sig> 68 template <typename Sig>
208 struct ForceVoidReturn; 69 struct ForceVoidReturn;
209 70
210 template <typename R, typename... Args> 71 template <typename R, typename... Args>
211 struct ForceVoidReturn<R(Args...)> { 72 struct ForceVoidReturn<R(Args...)> {
212 // MSVC 2013 doesn't support Type Alias of function types. 73 using RunType = void(Args...);
213 // Revisit this after we update it to newer version.
214 typedef void RunType(Args...);
215 }; 74 };
216 75
217
218 // FunctorTraits<> 76 // FunctorTraits<>
219 // 77 //
220 // See description at top of file. 78 // See description at top of file.
221 template <typename T> 79 template <typename Functor>
222 struct FunctorTraits { 80 struct FunctorTraits;
223 using RunnableType = RunnableAdapter<T>; 81
224 using RunType = typename RunnableType::RunType; 82 // For functions.
83 template <typename R, typename... Args>
84 struct FunctorTraits<R (*)(Args...)> {
85 using RunType = R(Args...);
86 static constexpr bool is_method = false;
87
88 template <typename... RunArgs>
89 static R Invoke(R (*function)(Args...), RunArgs&&... args) {
90 return function(std::forward<RunArgs>(args)...);
91 }
225 }; 92 };
226 93
227 template <typename T> 94 #if defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
228 struct FunctorTraits<IgnoreResultHelper<T>> { 95
229 using RunnableType = typename FunctorTraits<T>::RunnableType; 96 // For functions.
230 using RunType = 97 template <typename R, typename... Args>
231 typename ForceVoidReturn<typename RunnableType::RunType>::RunType; 98 struct FunctorTraits<R(__stdcall*)(Args...)> {
99 using RunType = R(Args...);
100 static constexpr bool is_method = false;
101
102 template <typename... RunArgs>
103 static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) {
104 return function(std::forward<RunArgs>(args)...);
105 }
232 }; 106 };
233 107
234 template <typename T> 108 // For functions.
235 struct FunctorTraits<Callback<T>> { 109 template <typename R, typename... Args>
236 using RunnableType = Callback<T> ; 110 struct FunctorTraits<R(__fastcall*)(Args...)> {
237 using RunType = typename Callback<T>::RunType; 111 using RunType = R(Args...);
112 static constexpr bool is_method = false;
113
114 template <typename... RunArgs>
115 static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) {
116 return function(std::forward<RunArgs>(args)...);
117 }
238 }; 118 };
239 119
120 #endif // defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
240 121
241 // MakeRunnable<> 122 // For methods.
242 // 123 template <typename R, typename Receiver, typename... Args>
243 // Converts a passed in functor to a RunnableType using type inference. 124 struct FunctorTraits<R (Receiver::*)(Args...)> {
125 using RunType = R(Receiver*, Args...);
126 static constexpr bool is_method = true;
244 127
128 template <typename ReceiverPtr, typename... RunArgs>
129 static R Invoke(R (Receiver::*method)(Args...),
130 ReceiverPtr&& receiver_ptr,
131 RunArgs&&... args) {
132 // Clang skips CV qualifier check on a method pointer invocation when the
133 // receiver is a subclass. Store the receiver into a const reference to
134 // T to ensure the CV check works.
135 // https://llvm.org/bugs/show_bug.cgi?id=27037
136 Receiver& receiver = *receiver_ptr;
137 return (receiver.*method)(std::forward<RunArgs>(args)...);
138 }
139 };
140
141 // For const methods.
142 template <typename R, typename Receiver, typename... Args>
143 struct FunctorTraits<R (Receiver::*)(Args...) const> {
144 using RunType = R(const Receiver*, Args...);
145 static constexpr bool is_method = true;
146
147 template <typename ReceiverPtr, typename... RunArgs>
148 static R Invoke(R (Receiver::*method)(Args...) const,
149 ReceiverPtr&& receiver_ptr,
150 RunArgs&&... args) {
151 // Clang skips CV qualifier check on a method pointer invocation when the
152 // receiver is a subclass. Store the receiver into a const reference to
153 // T to ensure the CV check works.
154 // https://llvm.org/bugs/show_bug.cgi?id=27037
155 const Receiver& receiver = *receiver_ptr;
156 return (receiver.*method)(std::forward<RunArgs>(args)...);
157 }
158 };
159
160 // For IgnoreResults.
245 template <typename T> 161 template <typename T>
246 typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) { 162 struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> {
247 return RunnableAdapter<T>(t); 163 using RunType =
248 } 164 typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType;
249 165
250 template <typename T> 166 template <typename IgnoreResultType, typename... RunArgs>
251 typename FunctorTraits<T>::RunnableType 167 static void Invoke(IgnoreResultType&& ignore_result_helper,
252 MakeRunnable(const IgnoreResultHelper<T>& t) { 168 RunArgs&&... args) {
253 return MakeRunnable(t.functor_); 169 FunctorTraits<T>::Invoke(ignore_result_helper.functor_,
254 } 170 std::forward<RunArgs>(args)...);
171 }
172 };
255 173
256 template <typename T> 174 // For Callbacks.
257 const typename FunctorTraits<Callback<T>>::RunnableType& 175 template <typename R, typename... Args, CopyMode copy_mode>
258 MakeRunnable(const Callback<T>& t) { 176 struct FunctorTraits<Callback<R(Args...), copy_mode>> {
259 DCHECK(!t.is_null()); 177 using RunType = R(Args...);
260 return t; 178 static constexpr bool is_method = false;
261 }
262 179
180 template <typename CallbackType, typename... RunArgs>
181 static R Invoke(CallbackType&& callback, RunArgs&&... args) {
182 DCHECK(!callback.is_null());
183 return std::forward<CallbackType>(callback).Run(
184 std::forward<RunArgs>(args)...);
185 }
186 };
263 187
264 // InvokeHelper<> 188 // InvokeHelper<>
265 // 189 //
266 // There are 3 logical InvokeHelper<> specializations: normal, void-return, 190 // There are 2 logical InvokeHelper<> specializations: normal, WeakCalls.
267 // WeakCalls.
268 // 191 //
269 // The normal type just calls the underlying runnable. 192 // The normal type just calls the underlying runnable.
270 // 193 //
271 // We need a InvokeHelper to handle void return types in order to support 194 // WeakCalls need special syntax that is applied to the first argument to check
272 // IgnoreResult(). Normally, if the Runnable's RunType had a void return, 195 // if they should no-op themselves.
273 // the template system would just accept "return functor.Run()" ignoring
274 // the fact that a void function is being used with return. This piece of
275 // sugar breaks though when the Runnable's RunType is not void. Thus, we
276 // need a partial specialization to change the syntax to drop the "return"
277 // from the invocation call.
278 //
279 // WeakCalls similarly need special syntax that is applied to the first
280 // argument to check if they should no-op themselves.
281 template <bool is_weak_call, typename ReturnType> 196 template <bool is_weak_call, typename ReturnType>
282 struct InvokeHelper; 197 struct InvokeHelper;
283 198
284 template <typename ReturnType> 199 template <typename ReturnType>
285 struct InvokeHelper<false, ReturnType> { 200 struct InvokeHelper<false, ReturnType> {
286 template <typename Runnable, typename... RunArgs> 201 template <typename Functor, typename... RunArgs>
287 static inline ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) { 202 static inline ReturnType MakeItSo(Functor&& functor, RunArgs&&... args) {
288 return std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); 203 using Traits = FunctorTraits<typename std::decay<Functor>::type>;
204 return Traits::Invoke(std::forward<Functor>(functor),
205 std::forward<RunArgs>(args)...);
289 } 206 }
290 }; 207 };
291 208
292 template <>
293 struct InvokeHelper<false, void> {
294 template <typename Runnable, typename... RunArgs>
295 static inline void MakeItSo(Runnable&& runnable, RunArgs&&... args) {
296 std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...);
297 }
298 };
299
300 template <>
301 struct InvokeHelper<true, void> {
302 template <typename Runnable, typename BoundWeakPtr, typename... RunArgs>
303 static void MakeItSo(Runnable&& runnable,
304 BoundWeakPtr&& weak_ptr,
305 RunArgs&&... args) {
306 if (!weak_ptr) {
307 return;
308 }
309 std::forward<Runnable>(runnable).Run(
310 std::forward<BoundWeakPtr>(weak_ptr), std::forward<RunArgs>(args)...);
311 }
312 };
313
314 #if !defined(_MSC_VER)
315
316 template <typename ReturnType> 209 template <typename ReturnType>
317 struct InvokeHelper<true, ReturnType> { 210 struct InvokeHelper<true, ReturnType> {
318 // WeakCalls are only supported for functions with a void return type. 211 // WeakCalls are only supported for functions with a void return type.
319 // Otherwise, the function result would be undefined if the the WeakPtr<> 212 // Otherwise, the function result would be undefined if the the WeakPtr<>
320 // is invalidated. 213 // is invalidated.
321 static_assert(std::is_void<ReturnType>::value, 214 static_assert(std::is_void<ReturnType>::value,
322 "weak_ptrs can only bind to methods without return values"); 215 "weak_ptrs can only bind to methods without return values");
216
217 template <typename Functor, typename BoundWeakPtr, typename... RunArgs>
218 static inline void MakeItSo(Functor&& functor,
219 BoundWeakPtr weak_ptr,
220 RunArgs&&... args) {
221 if (!weak_ptr)
222 return;
223 using Traits = FunctorTraits<typename std::decay<Functor>::type>;
224 Traits::Invoke(std::forward<Functor>(functor),
225 std::forward<BoundWeakPtr>(weak_ptr),
226 std::forward<RunArgs>(args)...);
227 }
323 }; 228 };
324 229
325 #endif
326
327 // Invoker<> 230 // Invoker<>
328 // 231 //
329 // See description at the top of the file. 232 // See description at the top of the file.
330 template <typename StorageType, typename UnboundRunType> 233 template <typename StorageType, typename UnboundRunType>
331 struct Invoker; 234 struct Invoker;
332 235
333 template <typename StorageType, typename R, typename... UnboundArgs> 236 template <typename StorageType, typename R, typename... UnboundArgs>
334 struct Invoker<StorageType, R(UnboundArgs...)> { 237 struct Invoker<StorageType, R(UnboundArgs...)> {
335 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) { 238 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) {
336 // Local references to make debugger stepping easier. If in a debugger, 239 // Local references to make debugger stepping easier. If in a debugger,
337 // you really want to warp ahead and step through the 240 // you really want to warp ahead and step through the
338 // InvokeHelper<>::MakeItSo() call below. 241 // InvokeHelper<>::MakeItSo() call below.
339 const StorageType* storage = static_cast<StorageType*>(base); 242 const StorageType* storage = static_cast<StorageType*>(base);
340 static constexpr size_t num_bound_args = 243 static constexpr size_t num_bound_args =
341 std::tuple_size<decltype(storage->bound_args_)>::value; 244 std::tuple_size<decltype(storage->bound_args_)>::value;
342 return RunImpl(storage->runnable_, 245 return RunImpl(storage->functor_,
343 storage->bound_args_, 246 storage->bound_args_,
344 MakeIndexSequence<num_bound_args>(), 247 MakeIndexSequence<num_bound_args>(),
345 std::forward<UnboundArgs>(unbound_args)...); 248 std::forward<UnboundArgs>(unbound_args)...);
346 } 249 }
347 250
348 template <typename Runnable, typename BoundArgsTuple, size_t... indices> 251 private:
349 static inline R RunImpl(Runnable&& runnable, 252 template <typename Functor, typename BoundArgsTuple, size_t... indices>
253 static inline R RunImpl(Functor&& functor,
350 BoundArgsTuple&& bound, 254 BoundArgsTuple&& bound,
351 IndexSequence<indices...>, 255 IndexSequence<indices...>,
352 UnboundArgs&&... unbound_args) { 256 UnboundArgs&&... unbound_args) {
353 static constexpr bool is_method = 257 static constexpr bool is_method =
354 HasIsMethodTag<typename std::decay<Runnable>::type>::value; 258 FunctorTraits<typename std::decay<Functor>::type>::is_method;
355 259
356 using DecayedArgsTuple = typename std::decay<BoundArgsTuple>::type; 260 using DecayedArgsTuple = typename std::decay<BoundArgsTuple>::type;
357 static constexpr bool is_weak_call = 261 static constexpr bool is_weak_call =
358 IsWeakMethod<is_method, 262 IsWeakMethod<is_method,
359 typename std::tuple_element< 263 typename std::tuple_element<
360 indices, 264 indices,
361 DecayedArgsTuple>::type...>::value; 265 DecayedArgsTuple>::type...>::value;
362 266
363 return InvokeHelper<is_weak_call, R>::MakeItSo( 267 return InvokeHelper<is_weak_call, R>::MakeItSo(
364 std::forward<Runnable>(runnable), 268 std::forward<Functor>(functor),
365 Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))..., 269 Unwrap(base::get<indices>(std::forward<BoundArgsTuple>(bound)))...,
366 std::forward<UnboundArgs>(unbound_args)...); 270 std::forward<UnboundArgs>(unbound_args)...);
367 } 271 }
368 }; 272 };
369 273
370 // Used to implement MakeArgsStorage.
371 template <bool is_method, typename... BoundArgs>
372 struct MakeArgsStorageImpl {
373 using Type = std::tuple<BoundArgs...>;
374 };
375
376 template <typename Obj, typename... BoundArgs>
377 struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> {
378 using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>;
379 };
380
381 // Constructs a tuple type to store BoundArgs into BindState.
382 // This wraps the first argument into a scoped_refptr if |is_method| is true and
383 // the first argument is a raw pointer.
384 // Other arguments are adjusted for store and packed into a tuple.
385 template <bool is_method, typename... BoundArgs>
386 using MakeArgsStorage = typename MakeArgsStorageImpl<
387 is_method, typename std::decay<BoundArgs>::type...>::Type;
388
389 // Used to implement MakeUnboundRunType. 274 // Used to implement MakeUnboundRunType.
390 template <typename Functor, typename... BoundArgs> 275 template <typename Functor, typename... BoundArgs>
391 struct MakeUnboundRunTypeImpl { 276 struct MakeUnboundRunTypeImpl {
392 using RunType = typename FunctorTraits<Functor>::RunType; 277 using RunType =
278 typename FunctorTraits<typename std::decay<Functor>::type>::RunType;
393 using ReturnType = ExtractReturnType<RunType>; 279 using ReturnType = ExtractReturnType<RunType>;
394 using Args = ExtractArgs<RunType>; 280 using Args = ExtractArgs<RunType>;
395 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>; 281 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>;
396 using Type = MakeFunctionType<ReturnType, UnboundArgs>; 282 using Type = MakeFunctionType<ReturnType, UnboundArgs>;
397 }; 283 };
398 284
399 // BindState<> 285 // BindState<>
400 // 286 //
401 // This stores all the state passed into Bind() and is also where most 287 // This stores all the state passed into Bind().
402 // of the template resolution magic occurs. 288 template <typename Functor, typename... BoundArgs>
403 // 289 struct BindState final : BindStateBase {
404 // Runnable is the functor we are binding arguments to. 290 template <typename... ForwardBoundArgs>
405 // 291 explicit BindState(Functor functor, ForwardBoundArgs&&... bound_args)
406 // BoundArgs contains the storage type for all the bound arguments. 292 : BindStateBase(&Destroy),
407 template <typename Runnable, typename... BoundArgs> 293 functor_(std::move(functor)),
408 struct BindState final : public BindStateBase { 294 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
409 private: 295 DCHECK(functor_);
410 using RunnableType = typename std::decay<Runnable>::type; 296 }
411 297
412 static constexpr bool is_method = HasIsMethodTag<RunnableType>::value; 298 Functor functor_;
413 299 std::tuple<BoundArgs...> bound_args_;
414 public:
415 template <typename... ForwardArgs>
416 explicit BindState(RunnableType runnable, ForwardArgs&&... bound_args)
417 : BindStateBase(&Destroy),
418 runnable_(std::move(runnable)),
419 bound_args_(std::forward<ForwardArgs>(bound_args)...) {}
420
421 RunnableType runnable_;
422 MakeArgsStorage<is_method, BoundArgs...> bound_args_;
423 300
424 private: 301 private:
425 ~BindState() {} 302 ~BindState() {}
426 303
427 static void Destroy(BindStateBase* self) { 304 static void Destroy(BindStateBase* self) {
428 delete static_cast<BindState*>(self); 305 delete static_cast<BindState*>(self);
429 } 306 }
430 }; 307 };
431 308
309 // Used to implement MakeBindStateType.
310 template <bool is_method, typename Functor, typename... BoundArgs>
311 struct MakeBindStateTypeImpl;
312
313 template <typename Functor, typename... BoundArgs>
314 struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> {
315 static_assert(!HasRefCountedTypeAsRawPtr<BoundArgs...>::value,
316 "A parameter is a refcounted type and needs scoped_refptr.");
317 using Type = BindState<typename std::decay<Functor>::type,
318 typename std::decay<BoundArgs>::type...>;
319 };
320
321 template <typename Functor>
322 struct MakeBindStateTypeImpl<true, Functor> {
323 using Type = BindState<typename std::decay<Functor>::type>;
324 };
325
326 template <typename Functor, typename Receiver, typename... BoundArgs>
327 struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> {
328 static_assert(
329 !std::is_array<typename std::remove_reference<Receiver>::type>::value,
330 "First bound argument to a method cannot be an array.");
331 static_assert(!HasRefCountedTypeAsRawPtr<BoundArgs...>::value,
332 "A parameter is a refcounted type and needs scoped_refptr.");
333
334 private:
335 using DecayedReceiver = typename std::decay<Receiver>::type;
336
337 public:
338 using Type = BindState<
339 typename std::decay<Functor>::type,
340 typename std::conditional<
341 std::is_pointer<DecayedReceiver>::value,
342 scoped_refptr<typename std::remove_pointer<DecayedReceiver>::type>,
343 DecayedReceiver>::type,
344 typename std::decay<BoundArgs>::type...>;
345 };
346
347 template <typename Functor, typename... BoundArgs>
348 using MakeBindStateType = typename MakeBindStateTypeImpl<
349 FunctorTraits<typename std::decay<Functor>::type>::is_method,
350 Functor,
351 BoundArgs...>::Type;
352
432 } // namespace internal 353 } // namespace internal
433 354
434 // Returns a RunType of bound functor. 355 // Returns a RunType of bound functor.
435 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). 356 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C).
436 template <typename Functor, typename... BoundArgs> 357 template <typename Functor, typename... BoundArgs>
437 using MakeUnboundRunType = 358 using MakeUnboundRunType =
438 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type; 359 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type;
439 360
440 } // namespace base 361 } // namespace base
441 362
442 #endif // BASE_BIND_INTERNAL_H_ 363 #endif // BASE_BIND_INTERNAL_H_
OLDNEW
« no previous file with comments | « base/bind_helpers.h ('k') | base/bind_internal_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698