OLD | NEW |
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 <type_traits> | 8 #include <type_traits> |
9 | 9 |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 101 |
102 // BindsArrayToFirstArg selects true_type when |is_method| is true and the first | 102 // BindsArrayToFirstArg selects true_type when |is_method| is true and the first |
103 // item of |Args| is an array type. | 103 // item of |Args| is an array type. |
104 // Implementation note: This non-specialized case handles !is_method case and | 104 // Implementation note: This non-specialized case handles !is_method case and |
105 // zero-arity case only. Other cases should be handled by the specialization | 105 // zero-arity case only. Other cases should be handled by the specialization |
106 // below. | 106 // below. |
107 template <bool is_method, typename... Args> | 107 template <bool is_method, typename... Args> |
108 struct BindsArrayToFirstArg : false_type {}; | 108 struct BindsArrayToFirstArg : false_type {}; |
109 | 109 |
110 template <typename T, typename... Args> | 110 template <typename T, typename... Args> |
111 struct BindsArrayToFirstArg<true, T, Args...> : is_array<T> {}; | 111 struct BindsArrayToFirstArg<true, T, Args...> |
| 112 : is_array<typename std::remove_reference<T>::type> {}; |
112 | 113 |
113 // HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except | 114 // HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except |
114 // when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument. | 115 // when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument. |
115 // Implementation note: This non-specialized case handles !is_method case and | 116 // Implementation note: This non-specialized case handles !is_method case and |
116 // zero-arity case only. Other cases should be handled by the specialization | 117 // zero-arity case only. Other cases should be handled by the specialization |
117 // below. | 118 // below. |
118 template <bool is_method, typename... Args> | 119 template <bool is_method, typename... Args> |
119 struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {}; | 120 struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {}; |
120 | 121 |
121 template <typename T, typename... Args> | 122 template <typename T, typename... Args> |
(...skipping 26 matching lines...) Expand all Loading... |
148 // Function. | 149 // Function. |
149 template <typename R, typename... Args> | 150 template <typename R, typename... Args> |
150 class RunnableAdapter<R(*)(Args...)> { | 151 class RunnableAdapter<R(*)(Args...)> { |
151 public: | 152 public: |
152 typedef R (RunType)(Args...); | 153 typedef R (RunType)(Args...); |
153 | 154 |
154 explicit RunnableAdapter(R(*function)(Args...)) | 155 explicit RunnableAdapter(R(*function)(Args...)) |
155 : function_(function) { | 156 : function_(function) { |
156 } | 157 } |
157 | 158 |
158 R Run(typename CallbackParamTraits<Args>::ForwardType... args) { | 159 template <typename... RunArgs> |
159 return function_(CallbackForward(args)...); | 160 R Run(RunArgs&&... args) { |
| 161 return function_(std::forward<RunArgs>(args)...); |
160 } | 162 } |
161 | 163 |
162 private: | 164 private: |
163 R (*function_)(Args...); | 165 R (*function_)(Args...); |
164 }; | 166 }; |
165 | 167 |
166 // Method. | 168 // Method. |
167 template <typename R, typename T, typename... Args> | 169 template <typename R, typename T, typename... Args> |
168 class RunnableAdapter<R(T::*)(Args...)> { | 170 class RunnableAdapter<R(T::*)(Args...)> { |
169 public: | 171 public: |
170 typedef R (RunType)(T*, Args...); | 172 typedef R (RunType)(T*, Args...); |
171 typedef true_type IsMethod; | 173 typedef true_type IsMethod; |
172 | 174 |
173 explicit RunnableAdapter(R(T::*method)(Args...)) | 175 explicit RunnableAdapter(R(T::*method)(Args...)) |
174 : method_(method) { | 176 : method_(method) { |
175 } | 177 } |
176 | 178 |
177 R Run(T* object, typename CallbackParamTraits<Args>::ForwardType... args) { | 179 template <typename... RunArgs> |
178 return (object->*method_)(CallbackForward(args)...); | 180 R Run(T* object, RunArgs&&... args) { |
| 181 return (object->*method_)(std::forward<RunArgs>(args)...); |
179 } | 182 } |
180 | 183 |
181 private: | 184 private: |
182 R (T::*method_)(Args...); | 185 R (T::*method_)(Args...); |
183 }; | 186 }; |
184 | 187 |
185 // Const Method. | 188 // Const Method. |
186 template <typename R, typename T, typename... Args> | 189 template <typename R, typename T, typename... Args> |
187 class RunnableAdapter<R(T::*)(Args...) const> { | 190 class RunnableAdapter<R(T::*)(Args...) const> { |
188 public: | 191 public: |
189 typedef R (RunType)(const T*, Args...); | 192 typedef R (RunType)(const T*, Args...); |
190 typedef true_type IsMethod; | 193 typedef true_type IsMethod; |
191 | 194 |
192 explicit RunnableAdapter(R(T::*method)(Args...) const) | 195 explicit RunnableAdapter(R(T::*method)(Args...) const) |
193 : method_(method) { | 196 : method_(method) { |
194 } | 197 } |
195 | 198 |
| 199 template <typename... RunArgs> |
196 R Run(const T* object, | 200 R Run(const T* object, |
197 typename CallbackParamTraits<Args>::ForwardType... args) { | 201 RunArgs&&... args) { |
198 return (object->*method_)(CallbackForward(args)...); | 202 return (object->*method_)(std::forward<RunArgs>(args)...); |
199 } | 203 } |
200 | 204 |
201 private: | 205 private: |
202 R (T::*method_)(Args...) const; | 206 R (T::*method_)(Args...) const; |
203 }; | 207 }; |
204 | 208 |
205 | 209 |
206 // ForceVoidReturn<> | 210 // ForceVoidReturn<> |
207 // | 211 // |
208 // Set of templates that support forcing the function return type to void. | 212 // Set of templates that support forcing the function return type to void. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 // from the invocation call. | 281 // from the invocation call. |
278 // | 282 // |
279 // WeakCalls similarly need special syntax that is applied to the first | 283 // WeakCalls similarly need special syntax that is applied to the first |
280 // argument to check if they should no-op themselves. | 284 // argument to check if they should no-op themselves. |
281 template <bool IsWeakCall, typename ReturnType, typename Runnable, | 285 template <bool IsWeakCall, typename ReturnType, typename Runnable, |
282 typename ArgsType> | 286 typename ArgsType> |
283 struct InvokeHelper; | 287 struct InvokeHelper; |
284 | 288 |
285 template <typename ReturnType, typename Runnable, typename... Args> | 289 template <typename ReturnType, typename Runnable, typename... Args> |
286 struct InvokeHelper<false, ReturnType, Runnable, TypeList<Args...>> { | 290 struct InvokeHelper<false, ReturnType, Runnable, TypeList<Args...>> { |
287 static ReturnType MakeItSo(Runnable runnable, Args... args) { | 291 template <typename... RunArgs> |
288 return runnable.Run(CallbackForward(args)...); | 292 static ReturnType MakeItSo(Runnable runnable, RunArgs&&... args) { |
| 293 return runnable.Run(std::forward<RunArgs>(args)...); |
289 } | 294 } |
290 }; | 295 }; |
291 | 296 |
292 template <typename Runnable, typename... Args> | 297 template <typename Runnable, typename... Args> |
293 struct InvokeHelper<false, void, Runnable, TypeList<Args...>> { | 298 struct InvokeHelper<false, void, Runnable, TypeList<Args...>> { |
294 static void MakeItSo(Runnable runnable, Args... args) { | 299 template <typename... RunArgs> |
295 runnable.Run(CallbackForward(args)...); | 300 static void MakeItSo(Runnable runnable, RunArgs&&... args) { |
| 301 runnable.Run(std::forward<RunArgs>(args)...); |
296 } | 302 } |
297 }; | 303 }; |
298 | 304 |
299 template <typename Runnable, typename BoundWeakPtr, typename... Args> | 305 template <typename Runnable, typename BoundWeakPtr, typename... Args> |
300 struct InvokeHelper<true, void, Runnable, TypeList<BoundWeakPtr, Args...>> { | 306 struct InvokeHelper<true, void, Runnable, TypeList<BoundWeakPtr, Args...>> { |
301 static void MakeItSo(Runnable runnable, BoundWeakPtr weak_ptr, Args... args) { | 307 template <typename... RunArgs> |
| 308 static void MakeItSo(Runnable runnable, |
| 309 BoundWeakPtr weak_ptr, |
| 310 RunArgs&&... args) { |
302 if (!weak_ptr.get()) { | 311 if (!weak_ptr.get()) { |
303 return; | 312 return; |
304 } | 313 } |
305 runnable.Run(weak_ptr.get(), CallbackForward(args)...); | 314 runnable.Run(weak_ptr.get(), std::forward<RunArgs>(args)...); |
306 } | 315 } |
307 }; | 316 }; |
308 | 317 |
309 #if !defined(_MSC_VER) | 318 #if !defined(_MSC_VER) |
310 | 319 |
311 template <typename ReturnType, typename Runnable, typename ArgsType> | 320 template <typename ReturnType, typename Runnable, typename ArgsType> |
312 struct InvokeHelper<true, ReturnType, Runnable, ArgsType> { | 321 struct InvokeHelper<true, ReturnType, Runnable, ArgsType> { |
313 // WeakCalls are only supported for functions with a void return type. | 322 // WeakCalls are only supported for functions with a void return type. |
314 // Otherwise, the function result would be undefined if the the WeakPtr<> | 323 // Otherwise, the function result would be undefined if the the WeakPtr<> |
315 // is invalidated. | 324 // is invalidated. |
(...skipping 14 matching lines...) Expand all Loading... |
330 template <size_t... bound_indices, | 339 template <size_t... bound_indices, |
331 typename StorageType, | 340 typename StorageType, |
332 typename... Unwrappers, | 341 typename... Unwrappers, |
333 typename InvokeHelperType, | 342 typename InvokeHelperType, |
334 typename R, | 343 typename R, |
335 typename... UnboundForwardArgs> | 344 typename... UnboundForwardArgs> |
336 struct Invoker<IndexSequence<bound_indices...>, | 345 struct Invoker<IndexSequence<bound_indices...>, |
337 StorageType, TypeList<Unwrappers...>, | 346 StorageType, TypeList<Unwrappers...>, |
338 InvokeHelperType, R(UnboundForwardArgs...)> { | 347 InvokeHelperType, R(UnboundForwardArgs...)> { |
339 static R Run(BindStateBase* base, | 348 static R Run(BindStateBase* base, |
340 UnboundForwardArgs... unbound_args) { | 349 typename CallbackParamTraits< |
| 350 UnboundForwardArgs>::ForwardType... unbound_args) { |
341 StorageType* storage = static_cast<StorageType*>(base); | 351 StorageType* storage = static_cast<StorageType*>(base); |
342 // Local references to make debugger stepping easier. If in a debugger, | 352 // Local references to make debugger stepping easier. If in a debugger, |
343 // you really want to warp ahead and step through the | 353 // you really want to warp ahead and step through the |
344 // InvokeHelper<>::MakeItSo() call below. | 354 // InvokeHelper<>::MakeItSo() call below. |
345 return InvokeHelperType::MakeItSo( | 355 return InvokeHelperType::MakeItSo( |
346 storage->runnable_, | 356 storage->runnable_, |
347 Unwrappers::Unwrap(get<bound_indices>(storage->bound_args_))..., | 357 Unwrappers::Unwrap(get<bound_indices>(storage->bound_args_))..., |
348 CallbackForward(unbound_args)...); | 358 CallbackForward2(unbound_args)...); |
349 } | 359 } |
350 }; | 360 }; |
351 | 361 |
352 | |
353 // BindState<> | 362 // BindState<> |
354 // | 363 // |
355 // This stores all the state passed into Bind() and is also where most | 364 // This stores all the state passed into Bind() and is also where most |
356 // of the template resolution magic occurs. | 365 // of the template resolution magic occurs. |
357 // | 366 // |
358 // Runnable is the functor we are binding arguments to. | 367 // Runnable is the functor we are binding arguments to. |
359 // RunType is type of the Run() function that the Invoker<> should use. | 368 // RunType is type of the Run() function that the Invoker<> should use. |
360 // Normally, this is the same as the RunType of the Runnable, but it can | 369 // Normally, this is the same as the RunType of the Runnable, but it can |
361 // be different if an adapter like IgnoreResult() has been used. | 370 // be different if an adapter like IgnoreResult() has been used. |
362 // | 371 // |
(...skipping 12 matching lines...) Expand all Loading... |
375 using StorageType = BindState<Runnable, R(Args...), TypeList<BoundArgs...>>; | 384 using StorageType = BindState<Runnable, R(Args...), TypeList<BoundArgs...>>; |
376 using RunnableType = Runnable; | 385 using RunnableType = Runnable; |
377 | 386 |
378 // true_type if Runnable is a method invocation and the first bound argument | 387 // true_type if Runnable is a method invocation and the first bound argument |
379 // is a WeakPtr. | 388 // is a WeakPtr. |
380 using IsWeakCall = | 389 using IsWeakCall = |
381 IsWeakMethod<HasIsMethodTag<Runnable>::value, BoundArgs...>; | 390 IsWeakMethod<HasIsMethodTag<Runnable>::value, BoundArgs...>; |
382 | 391 |
383 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; | 392 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; |
384 using Unwrappers = TypeList<UnwrapTraits<BoundArgs>...>; | 393 using Unwrappers = TypeList<UnwrapTraits<BoundArgs>...>; |
385 using UnboundForwardArgs = DropTypeListItem< | 394 using UnboundForwardArgs = |
386 sizeof...(BoundArgs), | 395 DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; |
387 TypeList<typename CallbackParamTraits<Args>::ForwardType...>>; | |
388 using UnboundForwardRunType = MakeFunctionType<R, UnboundForwardArgs>; | 396 using UnboundForwardRunType = MakeFunctionType<R, UnboundForwardArgs>; |
389 | 397 |
390 using InvokeHelperArgs = ConcatTypeLists< | 398 using InvokeHelperArgs = ConcatTypeLists< |
391 TypeList<typename UnwrapTraits<BoundArgs>::ForwardType...>, | 399 TypeList<typename UnwrapTraits<BoundArgs>::ForwardType...>, |
392 UnboundForwardArgs>; | 400 UnboundForwardArgs>; |
393 using InvokeHelperType = | 401 using InvokeHelperType = |
394 InvokeHelper<IsWeakCall::value, R, Runnable, InvokeHelperArgs>; | 402 InvokeHelper<IsWeakCall::value, R, Runnable, InvokeHelperArgs>; |
395 | 403 |
396 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; | 404 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; |
397 | 405 |
398 public: | 406 public: |
399 using InvokerType = Invoker<BoundIndices, StorageType, Unwrappers, | 407 using InvokerType = Invoker<BoundIndices, StorageType, Unwrappers, |
400 InvokeHelperType, UnboundForwardRunType>; | 408 InvokeHelperType, UnboundForwardRunType>; |
401 using UnboundRunType = MakeFunctionType<R, UnboundArgs>; | 409 using UnboundRunType = MakeFunctionType<R, UnboundArgs>; |
402 | 410 |
403 BindState(const Runnable& runnable, const BoundArgs&... bound_args) | 411 template <typename... PassedBoundArgs> |
| 412 BindState(const Runnable& runnable, PassedBoundArgs&&... bound_args) |
404 : BindStateBase(&Destroy), | 413 : BindStateBase(&Destroy), |
405 runnable_(runnable), | 414 runnable_(runnable), |
406 ref_(bound_args...), | 415 ref_(bound_args...), |
407 bound_args_(bound_args...) {} | 416 bound_args_(std::forward<PassedBoundArgs>(bound_args)...) {} |
408 | 417 |
409 RunnableType runnable_; | 418 RunnableType runnable_; |
410 MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_; | 419 MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_; |
411 Tuple<BoundArgs...> bound_args_; | 420 std::tuple<BoundArgs...> bound_args_; |
412 | 421 |
413 private: | 422 private: |
414 ~BindState() {} | 423 ~BindState() {} |
415 | 424 |
416 static void Destroy(BindStateBase* self) { | 425 static void Destroy(BindStateBase* self) { |
417 delete static_cast<BindState*>(self); | 426 delete static_cast<BindState*>(self); |
418 } | 427 } |
419 }; | 428 }; |
420 | 429 |
421 } // namespace internal | 430 } // namespace internal |
422 } // namespace base | 431 } // namespace base |
423 | 432 |
424 #endif // BASE_BIND_INTERNAL_H_ | 433 #endif // BASE_BIND_INTERNAL_H_ |
OLD | NEW |