static auto _Perform(std::function<_OutType(void)> _Func) -> decltype(details::_MakeUnitToTFunc<_OutType>(_Func)) { return details::_MakeUnitToTFunc<_OutType>(_Func); } }; template<typename _InType> class _Continuation_func_transformer<_InType, void> { public: static auto _Perform(std::function<void(_InType)> _Func) -> decltype(details::_MakeTToUnitFunc<_InType>(_Func)) { return details::_MakeTToUnitFunc<_InType>(_Func); } }; template<> class _Continuation_func_transformer<void, void> { public: static auto _Perform(std::function<void(void)> _Func) -> decltype(details::_MakeUnitToUnitFunc(_Func)) { return details::_MakeUnitToUnitFunc(_Func); } }; /// <summary> /// The task handle type used to create a 'continuation task'. /// </summary> template <typename _InternalReturnType, typename _ContinuationReturnType, typename _Function, typename _IsTaskBased, typename _TypeSelection> struct _ContinuationTaskHandle : details::_PPLTaskHandle<typename details::_NormalizeVoidToUnitType<_ContinuationReturnType>::_Type, _ContinuationTaskHandle<_InternalReturnType, _ContinuationReturnType, _Function, _IsTaskBased, _TypeSelection>, details::_ContinuationTaskHandleBase> { typedef typename details::_NormalizeVoidToUnitType<_ContinuationReturnType>::_Type _NormalizedContinuationReturnType; typename details::_Task_ptr<_ReturnType>::_Type _M_ancestorTaskImpl; _Function _M_function; _ContinuationTaskHandle(const typename details::_Task_ptr<_ReturnType>::_Type & _AncestorImpl, const typename details::_Task_ptr<_NormalizedContinuationReturnType>::_Type & _ContinuationImpl, const _Function & _Func, const task_continuation_context & _Context, details::_TaskInliningMode _InliningMode) : _M_ancestorTaskImpl(_AncestorImpl), _PPLTaskHandle(_ContinuationImpl), _M_function(_Func) { _M_isTaskBasedContinuation = _IsTaskBased::value; _M_continuationContext = _Context; _M_continuationContext._Resolve(_AncestorImpl->_IsApartmentAware()); _M_inliningMode = _InliningMode; } virtual ~_ContinuationTaskHandle() {} void _Perform() const { _Continue(_IsTaskBased(), _TypeSelection()); } // // Overload 0-0: _InternalReturnType -> _TaskType // // This is a straight task continuation which simply invokes its target with the ancestor's completion argument // void _Continue(std::false_type, details::_TypeSelectorNoAsync) const { _M_pTask->_FinalizeAndRunContinuations(_Continuation_func_transformer<_InternalReturnType, _ContinuationReturnType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult())); } // // Overload 0-1: _InternalReturnType -> IAsyncOperation<_TaskType>^ (only uder /ZW) // or // _InternalReturnType -> task<_TaskType> // // This is a straight task continuation which returns an async operation or a task which will be unwrapped for continuation // Depending on the output type, the right _AsyncInit gets invoked // void _Continue(std::false_type, details::_TypeSelectorAsyncOperationOrTask) const { typedef details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType; details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>( _M_pTask, _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult()) ); }