| 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 |