@@ -3093,6 +3093,47 @@ namespace details
30933093 template <typename _Ty>
30943094 static std::false_type _IsValidCreateAsync (_Ty _Param, ...);
30953095#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+ };
30963137}
30973138// / <summary>
30983139// / 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
34243465 /* */
34253466 template <typename _Function>
34263467 __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
34283469 {
34293470 task_options _TaskOptions;
34303471 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);
34323473 }
34333474
34343475 // / <summary>
@@ -3457,10 +3498,10 @@ class task
34573498 /* */
34583499 template <typename _Function>
34593500 __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
34613502 {
34623503 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);
34643505 }
34653506
34663507 // / <summary>
@@ -3493,11 +3534,11 @@ class task
34933534 /* */
34943535 template <typename _Function>
34953536 __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
34973538 {
34983539 task_options _TaskOptions (_CancellationToken, _ContinuationContext);
34993540 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);
35013542 }
35023543
35033544 // / <summary>
@@ -3682,13 +3723,13 @@ class task
36823723 // / This function is Used for runtime internal continuations only.
36833724 // / </summary>
36843725 template <typename _Function>
3685- auto _Then (const _Function& _Func, details::_CancellationTokenState *_PTokenState,
3726+ auto _Then (_Function& & _Func, details::_CancellationTokenState *_PTokenState,
36863727 details::_TaskInliningMode_t _InliningMode = details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
36873728 {
36883729 // inherit from antecedent
36893730 auto _Scheduler = _GetImpl ()->_GetScheduler ();
36903731
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);
36923733 }
36933734
36943735private:
@@ -3801,16 +3842,17 @@ class task
38013842 typedef typename details::_NormalizeVoidToUnitType<_ContinuationReturnType>::_Type _NormalizedContinuationReturnType;
38023843
38033844 typename details::_Task_ptr<_ReturnType>::_Type _M_ancestorTaskImpl;
3804- _Function _M_function;
3845+ typename details::_CopyableFunctor< typename std::decay< _Function>::type >::_Type _M_function;
38053846
3847+ template <class _ForwardedFunction >
38063848 _ContinuationTaskHandle (const typename details::_Task_ptr<_ReturnType>::_Type & _AncestorImpl,
38073849 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)
38093851 : details::_PPLTaskHandle<typename details::_NormalizeVoidToUnitType<_ContinuationReturnType>::_Type,
38103852 _ContinuationTaskHandle<_InternalReturnType, _ContinuationReturnType, _Function, _IsTaskBased, _TypeSelection>, details::_ContinuationTaskHandleBase>
38113853 ::_PPLTaskHandle (_ContinuationImpl)
38123854 , _M_ancestorTaskImpl(_AncestorImpl)
3813- , _M_function(_Func)
3855+ , _M_function(std::forward<_ForwardedFunction>( _Func) )
38143856 {
38153857 this ->_M_isTaskBasedContinuation = _IsTaskBased::value;
38163858 this ->_M_continuationContext = _Context;
@@ -4095,7 +4137,7 @@ class task
40954137 }
40964138
40974139 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
40994141 {
41004142 if (!_M_Impl)
41014143 {
@@ -4105,14 +4147,14 @@ class task
41054147 details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token () ? _TaskOptions.get_cancellation_token ()._GetImplValue () : nullptr ;
41064148 auto _Scheduler = _TaskOptions.has_scheduler () ? _TaskOptions.get_scheduler () : _GetImpl ()->_GetScheduler ();
41074149 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);
41094151 }
41104152
41114153 // / <summary>
41124154 // / The one and only implementation of then for void and non-void tasks.
41134155 // / </summary>
41144156 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,
41164158 details::_TaskInliningMode_t _InliningMode = details::_NoInline) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
41174159 {
41184160 if (!_M_Impl)
@@ -4149,7 +4191,7 @@ class task
41494191 _ContinuationTask._SetTaskCreationCallstack (_CreationStack);
41504192
41514193 _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));
41534195
41544196 return _ContinuationTask;
41554197 }
@@ -4371,10 +4413,10 @@ class task<void>
43714413 /* */
43724414 template <typename _Function>
43734415 __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
43754417 {
43764418 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);
43784420 }
43794421
43804422 // / <summary>
@@ -4407,11 +4449,11 @@ class task<void>
44074449 /* */
44084450 template <typename _Function>
44094451 __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
44114453 {
44124454 task_options _TaskOptions (_CancellationToken, _ContinuationContext);
44134455 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);
44154457 }
44164458
44174459 // / <summary>
@@ -4555,13 +4597,13 @@ class task<void>
45554597 // / An internal version of then that takes additional flags and executes the continuation inline. Used for runtime internal continuations only.
45564598 // / </summary>
45574599 template <typename _Function>
4558- auto _Then (const _Function& _Func, details::_CancellationTokenState *_PTokenState,
4600+ auto _Then (_Function& & _Func, details::_CancellationTokenState *_PTokenState,
45594601 details::_TaskInliningMode_t _InliningMode = details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
45604602 {
45614603 // inherit from antecedent
45624604 auto _Scheduler = _GetImpl ()->_GetScheduler ();
45634605
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);
45654607 }
45664608
45674609private:
0 commit comments