@@ -3093,6 +3093,47 @@ namespace details
3093
3093
template <typename _Ty>
3094
3094
static std::false_type _IsValidCreateAsync (_Ty _Param, ...);
3095
3095
#endif /* defined (__cplusplus_winrt) */
3096
+
3097
+ // / <summary>
3098
+ // / A helper class template that makes only movable functions be able to be passed to std::function
3099
+ // / </summary>
3100
+ template <typename _Ty>
3101
+ struct _NonCopyableFunctorWrapper
3102
+ {
3103
+ template <typename _Tx, typename =
3104
+ typename std::enable_if<!std::is_base_of<_NonCopyableFunctorWrapper<_Ty>,
3105
+ typename std::decay<_Tx>::type>::value>::type>
3106
+ explicit _NonCopyableFunctorWrapper (_Tx&& f)
3107
+ : _M_functor{std::make_shared<_Ty>(std::forward<_Tx>(f))}
3108
+ {}
3109
+
3110
+ template <class ... _Args>
3111
+ auto operator ()(_Args&&... args) -> decltype(std::declval<_Ty>()(std::forward<_Args>(args)...))
3112
+ {
3113
+ return _M_functor->operator ()(std::forward<_Args>(args)...);
3114
+ }
3115
+
3116
+ template <class ... _Args>
3117
+ auto operator ()(_Args&&... args) const -> decltype(std::declval<_Ty>()(std::forward<_Args>(args)...))
3118
+ {
3119
+ return _M_functor->operator ()(std::forward<_Args>(args)...);
3120
+ }
3121
+
3122
+ std::shared_ptr<_Ty> _M_functor;
3123
+ };
3124
+
3125
+ template <typename _Ty, typename Enable = void >
3126
+ struct _CopyableFunctor
3127
+ {
3128
+ typedef _Ty _Type;
3129
+ };
3130
+
3131
+ template <typename _Ty>
3132
+ struct _CopyableFunctor <_Ty, typename std::enable_if<
3133
+ std::is_move_constructible<_Ty>::value && !std::is_copy_constructible<_Ty>::value>::type>
3134
+ {
3135
+ typedef _NonCopyableFunctorWrapper<_Ty> _Type;
3136
+ };
3096
3137
}
3097
3138
// / <summary>
3098
3139
// / A helper class template that transforms a continuation lambda that either takes or returns void, or both, into a lambda that takes and returns a
@@ -3424,11 +3465,11 @@ class task
3424
3465
/* */
3425
3466
template <typename _Function>
3426
3467
__declspec (noinline) // Ask for no inlining so that the _CAPTURE_CALLSTACK gives us the expected result
3427
- auto then (const _Function& _Func) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
3468
+ auto then (_Function& & _Func) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
3428
3469
{
3429
3470
task_options _TaskOptions;
3430
3471
details::_get_internal_task_options (_TaskOptions)._set_creation_callstack (_CAPTURE_CALLSTACK ());
3431
- return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
3472
+ return _ThenImpl<_ReturnType, _Function>(std::forward<_Function>( _Func) , _TaskOptions);
3432
3473
}
3433
3474
3434
3475
// / <summary>
@@ -3457,10 +3498,10 @@ class task
3457
3498
/* */
3458
3499
template <typename _Function>
3459
3500
__declspec (noinline) // Ask for no inlining so that the _CAPTURE_CALLSTACK gives us the expected result
3460
- auto then (const _Function& _Func, task_options _TaskOptions) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
3501
+ auto then (_Function& & _Func, task_options _TaskOptions) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
3461
3502
{
3462
3503
details::_get_internal_task_options (_TaskOptions)._set_creation_callstack (_CAPTURE_CALLSTACK ());
3463
- return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
3504
+ return _ThenImpl<_ReturnType, _Function>(std::forward<_Function>( _Func) , _TaskOptions);
3464
3505
}
3465
3506
3466
3507
// / <summary>
@@ -3493,11 +3534,11 @@ class task
3493
3534
/* */
3494
3535
template <typename _Function>
3495
3536
__declspec (noinline) // Ask for no inlining so that the _CAPTURE_CALLSTACK gives us the expected result
3496
- auto then (const _Function& _Func, cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
3537
+ auto then (_Function& & _Func, cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
3497
3538
{
3498
3539
task_options _TaskOptions (_CancellationToken, _ContinuationContext);
3499
3540
details::_get_internal_task_options (_TaskOptions)._set_creation_callstack (_CAPTURE_CALLSTACK ());
3500
- return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
3541
+ return _ThenImpl<_ReturnType, _Function>(std::forward<_Function>( _Func) , _TaskOptions);
3501
3542
}
3502
3543
3503
3544
// / <summary>
@@ -3682,13 +3723,13 @@ class task
3682
3723
// / This function is Used for runtime internal continuations only.
3683
3724
// / </summary>
3684
3725
template <typename _Function>
3685
- auto _Then (const _Function& _Func, details::_CancellationTokenState *_PTokenState,
3726
+ auto _Then (_Function& & _Func, details::_CancellationTokenState *_PTokenState,
3686
3727
details::_TaskInliningMode_t _InliningMode = details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
3687
3728
{
3688
3729
// inherit from antecedent
3689
3730
auto _Scheduler = _GetImpl ()->_GetScheduler ();
3690
3731
3691
- return _ThenImpl<_ReturnType, _Function>(_Func, _PTokenState, task_continuation_context::use_default (), _Scheduler, _CAPTURE_CALLSTACK (), _InliningMode);
3732
+ return _ThenImpl<_ReturnType, _Function>(std::forward<_Function>( _Func) , _PTokenState, task_continuation_context::use_default (), _Scheduler, _CAPTURE_CALLSTACK (), _InliningMode);
3692
3733
}
3693
3734
3694
3735
private:
@@ -3801,16 +3842,17 @@ class task
3801
3842
typedef typename details::_NormalizeVoidToUnitType<_ContinuationReturnType>::_Type _NormalizedContinuationReturnType;
3802
3843
3803
3844
typename details::_Task_ptr<_ReturnType>::_Type _M_ancestorTaskImpl;
3804
- _Function _M_function;
3845
+ typename details::_CopyableFunctor< typename std::decay< _Function>::type >::_Type _M_function;
3805
3846
3847
+ template <class _ForwardedFunction >
3806
3848
_ContinuationTaskHandle (const typename details::_Task_ptr<_ReturnType>::_Type & _AncestorImpl,
3807
3849
const typename details::_Task_ptr<_NormalizedContinuationReturnType>::_Type & _ContinuationImpl,
3808
- const _Function & _Func, const task_continuation_context & _Context, details::_TaskInliningMode_t _InliningMode)
3850
+ _ForwardedFunction& & _Func, const task_continuation_context & _Context, details::_TaskInliningMode_t _InliningMode)
3809
3851
: details::_PPLTaskHandle<typename details::_NormalizeVoidToUnitType<_ContinuationReturnType>::_Type,
3810
3852
_ContinuationTaskHandle<_InternalReturnType, _ContinuationReturnType, _Function, _IsTaskBased, _TypeSelection>, details::_ContinuationTaskHandleBase>
3811
3853
::_PPLTaskHandle (_ContinuationImpl)
3812
3854
, _M_ancestorTaskImpl(_AncestorImpl)
3813
- , _M_function(_Func)
3855
+ , _M_function(std::forward<_ForwardedFunction>( _Func) )
3814
3856
{
3815
3857
this ->_M_isTaskBasedContinuation = _IsTaskBased::value;
3816
3858
this ->_M_continuationContext = _Context;
@@ -4095,7 +4137,7 @@ class task
4095
4137
}
4096
4138
4097
4139
template <typename _InternalReturnType, typename _Function>
4098
- auto _ThenImpl (const _Function& _Func, const task_options& _TaskOptions) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
4140
+ auto _ThenImpl (_Function& & _Func, const task_options& _TaskOptions) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
4099
4141
{
4100
4142
if (!_M_Impl)
4101
4143
{
@@ -4105,14 +4147,14 @@ class task
4105
4147
details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token () ? _TaskOptions.get_cancellation_token ()._GetImplValue () : nullptr ;
4106
4148
auto _Scheduler = _TaskOptions.has_scheduler () ? _TaskOptions.get_scheduler () : _GetImpl ()->_GetScheduler ();
4107
4149
auto _CreationStack = details::_get_internal_task_options (_TaskOptions)._M_hasPresetCreationCallstack ? details::_get_internal_task_options (_TaskOptions)._M_presetCreationCallstack : details::_TaskCreationCallstack ();
4108
- return _ThenImpl<_InternalReturnType, _Function>(_Func, _PTokenState, _TaskOptions.get_continuation_context (), _Scheduler, _CreationStack);
4150
+ return _ThenImpl<_InternalReturnType, _Function>(std::forward<_Function>( _Func) , _PTokenState, _TaskOptions.get_continuation_context (), _Scheduler, _CreationStack);
4109
4151
}
4110
4152
4111
4153
// / <summary>
4112
4154
// / The one and only implementation of then for void and non-void tasks.
4113
4155
// / </summary>
4114
4156
template <typename _InternalReturnType, typename _Function>
4115
- auto _ThenImpl (const _Function& _Func, details::_CancellationTokenState *_PTokenState, const task_continuation_context& _ContinuationContext, scheduler_ptr _Scheduler, details::_TaskCreationCallstack _CreationStack,
4157
+ auto _ThenImpl (_Function& & _Func, details::_CancellationTokenState *_PTokenState, const task_continuation_context& _ContinuationContext, scheduler_ptr _Scheduler, details::_TaskCreationCallstack _CreationStack,
4116
4158
details::_TaskInliningMode_t _InliningMode = details::_NoInline) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
4117
4159
{
4118
4160
if (!_M_Impl)
@@ -4149,7 +4191,7 @@ class task
4149
4191
_ContinuationTask._SetTaskCreationCallstack (_CreationStack);
4150
4192
4151
4193
_GetImpl ()->_ScheduleContinuation (new _ContinuationTaskHandle<_InternalReturnType, _TaskType, _Function, typename _Function_type_traits::_Takes_task, typename _Async_type_traits::_AsyncKind>(
4152
- _GetImpl (), _ContinuationTask._GetImpl (), _Func, _ContinuationContext, _InliningMode));
4194
+ _GetImpl (), _ContinuationTask._GetImpl (), std::forward<_Function>( _Func) , _ContinuationContext, _InliningMode));
4153
4195
4154
4196
return _ContinuationTask;
4155
4197
}
@@ -4371,10 +4413,10 @@ class task<void>
4371
4413
/* */
4372
4414
template <typename _Function>
4373
4415
__declspec (noinline) // Ask for no inlining so that the _CAPTURE_CALLSTACK gives us the expected result
4374
- auto then (const _Function& _Func, task_options _TaskOptions = task_options()) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
4416
+ auto then (_Function& & _Func, task_options _TaskOptions = task_options()) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
4375
4417
{
4376
4418
details::_get_internal_task_options (_TaskOptions)._set_creation_callstack (_CAPTURE_CALLSTACK ());
4377
- return _M_unitTask._ThenImpl <void , _Function>(_Func, _TaskOptions);
4419
+ return _M_unitTask._ThenImpl <void , _Function>(std::forward<_Function>( _Func) , _TaskOptions);
4378
4420
}
4379
4421
4380
4422
// / <summary>
@@ -4407,11 +4449,11 @@ class task<void>
4407
4449
/* */
4408
4450
template <typename _Function>
4409
4451
__declspec (noinline) // Ask for no inlining so that the _CAPTURE_CALLSTACK gives us the expected result
4410
- auto then (const _Function& _Func, cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
4452
+ auto then (_Function& & _Func, cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
4411
4453
{
4412
4454
task_options _TaskOptions (_CancellationToken, _ContinuationContext);
4413
4455
details::_get_internal_task_options (_TaskOptions)._set_creation_callstack (_CAPTURE_CALLSTACK ());
4414
- return _M_unitTask._ThenImpl <void , _Function>(_Func, _TaskOptions);
4456
+ return _M_unitTask._ThenImpl <void , _Function>(std::forward<_Function>( _Func) , _TaskOptions);
4415
4457
}
4416
4458
4417
4459
// / <summary>
@@ -4555,13 +4597,13 @@ class task<void>
4555
4597
// / An internal version of then that takes additional flags and executes the continuation inline. Used for runtime internal continuations only.
4556
4598
// / </summary>
4557
4599
template <typename _Function>
4558
- auto _Then (const _Function& _Func, details::_CancellationTokenState *_PTokenState,
4600
+ auto _Then (_Function& & _Func, details::_CancellationTokenState *_PTokenState,
4559
4601
details::_TaskInliningMode_t _InliningMode = details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
4560
4602
{
4561
4603
// inherit from antecedent
4562
4604
auto _Scheduler = _GetImpl ()->_GetScheduler ();
4563
4605
4564
- return _M_unitTask._ThenImpl <void , _Function>(_Func, _PTokenState, task_continuation_context::use_default (), _Scheduler, _CAPTURE_CALLSTACK (), _InliningMode);
4606
+ return _M_unitTask._ThenImpl <void , _Function>(std::forward<_Function>( _Func) , _PTokenState, task_continuation_context::use_default (), _Scheduler, _CAPTURE_CALLSTACK (), _InliningMode);
4565
4607
}
4566
4608
4567
4609
private:
0 commit comments