This source file includes following definitions.
- create_task
- __declspec
- __declspec
- __declspec
- when_all
- when_all
- when_all
- when_any
- when_any
- when_any
- task_from_result
- task_from_result
- task_from_result
- task_from_exception
#pragma once
#ifndef _PPLTASKS_WINRT_H
#define _PPLTASKS_WINRT_H
#include <concrt.h>
#include <ppltasks.h>
#if _MSC_VER >= 1800
#include <pplconcrt.h>
#ifdef _MSC_VER
#if _MSC_FULL_VER < 160040219
#error ERROR: Visual Studio 2010 SP1 or later is required to build ppltasks
#endif
#endif
#else
#include <ppl.h>
#endif
#include <functional>
#include <vector>
#include <utility>
#include <exception>
#if _MSC_VER >= 1800
#include <algorithm>
#endif
#ifndef __cplusplus_winrt
#include <wrl\implements.h>
#include <wrl\async.h>
#if _MSC_VER >= 1800
#include "agile_wrl.h"
#endif
#include <windows.foundation.h>
#include <ctxtcall.h>
#ifndef _UITHREADCTXT_SUPPORT
#ifdef WINAPI_FAMILY
#include <winapifamily.h>
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
#define _UITHREADCTXT_SUPPORT 0
#elif WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP
#define _UITHREADCTXT_SUPPORT 0
#else
#define _UITHREADCTXT_SUPPORT 1
#endif
#else
#define _UITHREADCTXT_SUPPORT 0
#endif
#endif
#if _UITHREADCTXT_SUPPORT
#include <uithreadctxt.h>
#endif
#pragma detect_mismatch("_PPLTASKS_WITH_WINRT", "0")
#ifdef _DEBUG
#define _DBG_ONLY(X) X
#else
#define _DBG_ONLY(X)
#endif
#ifdef _MSC_VER
#if _MSC_VER < 1700
namespace std
{
template<class _E> exception_ptr make_exception_ptr(_E _Except)
{
return copy_exception(_Except);
}
}
#endif
#ifndef _PPLTASK_ASYNC_LOGGING
#if _MSC_VER >= 1800 && defined(__cplusplus_winrt)
#define _PPLTASK_ASYNC_LOGGING 1
#else
#define _PPLTASK_ASYNC_LOGGING 0
#endif
#endif
#endif
#pragma pack(push,_CRT_PACKING)
#pragma warning(push)
#pragma warning(disable: 28197)
#pragma warning(disable: 4100)
#if _MSC_VER >= 1800
#pragma warning(disable: 4127)
#else
#pragma warning(disable: 4702)
#endif
#pragma push_macro("new")
#undef new
namespace stdx
{
template<class _T>
_T&& declval();
}
namespace Concurrency_winrt
{
#ifndef PPL_TASK_SAVE_FRAME_COUNT
#ifdef _DEBUG
#define PPL_TASK_SAVE_FRAME_COUNT 10
#else
#define PPL_TASK_SAVE_FRAME_COUNT 1
#endif
#endif
#ifdef _CAPTURE_CALLSTACK
#undef _CAPTURE_CALLSTACK
#endif
#if PPL_TASK_SAVE_FRAME_COUNT > 1
#if !defined(_DEBUG)
#pragma message ("WARNING: Redefinning PPL_TASK_SAVE_FRAME_COUNT under Release build for non-desktop applications is not supported; only one frame will be captured!")
#define _CAPTURE_CALLSTACK() ::Concurrency_winrt::details::_TaskCreationCallstack::_CaptureSingleFrameCallstack(_ReturnAddress())
#else
#define _CAPTURE_CALLSTACK() ::Concurrency_winrt::details::_TaskCreationCallstack::_CaptureMultiFramesCallstack(PPL_TASK_SAVE_FRAME_COUNT)
#endif
#else
#define _CAPTURE_CALLSTACK() ::Concurrency_winrt::details::_TaskCreationCallstack::_CaptureSingleFrameCallstack(_ReturnAddress())
#endif
typedef Concurrency::task_group_status task_status;
template <typename _Type> class task;
template <> class task<void>;
#if _MSC_VER >= 1800
inline bool __cdecl is_task_cancellation_requested()
{
return ::Concurrency::details::_TaskCollection_t::_Is_cancellation_requested();
}
#else
inline bool __cdecl is_task_cancellation_requested()
{
return ::Concurrency::is_current_task_group_canceling();
}
#endif
inline __declspec(noreturn) void __cdecl cancel_current_task()
{
throw Concurrency::task_canceled();
}
namespace details
{
#if _MSC_VER >= 1800
class _TaskCreationCallstack
{
private:
void* _M_SingleFrame;
std::vector<void *> _M_frames;
public:
_TaskCreationCallstack()
{
_M_SingleFrame = nullptr;
}
static _TaskCreationCallstack _CaptureSingleFrameCallstack(void *_SingleFrame)
{
_TaskCreationCallstack _csc;
_csc._M_SingleFrame = _SingleFrame;
return _csc;
}
__declspec(noinline)
static _TaskCreationCallstack _CaptureMultiFramesCallstack(size_t _CaptureFrames)
{
_TaskCreationCallstack _csc;
_csc._M_frames.resize(_CaptureFrames);
_csc._M_frames.resize(::Concurrency::details::platform::CaptureCallstack(&_csc._M_frames[0], 2, _CaptureFrames));
return _csc;
}
};
#endif
typedef UINT32 _Unit_type;
struct _TypeSelectorNoAsync {};
struct _TypeSelectorAsyncOperationOrTask {};
struct _TypeSelectorAsyncOperation : public _TypeSelectorAsyncOperationOrTask { };
struct _TypeSelectorAsyncTask : public _TypeSelectorAsyncOperationOrTask { };
struct _TypeSelectorAsyncAction {};
struct _TypeSelectorAsyncActionWithProgress {};
struct _TypeSelectorAsyncOperationWithProgress {};
template<typename _Ty>
struct _NormalizeVoidToUnitType
{
typedef _Ty _Type;
};
template<>
struct _NormalizeVoidToUnitType<void>
{
typedef _Unit_type _Type;
};
template<typename _T>
struct _IsUnwrappedAsyncSelector
{
static const bool _Value = true;
};
template<>
struct _IsUnwrappedAsyncSelector<_TypeSelectorNoAsync>
{
static const bool _Value = false;
};
template <typename _Ty>
struct _UnwrapTaskType
{
typedef _Ty _Type;
};
template <typename _Ty>
struct _UnwrapTaskType<task<_Ty>>
{
typedef _Ty _Type;
};
template <typename _T>
_TypeSelectorAsyncTask _AsyncOperationKindSelector(task<_T>);
_TypeSelectorNoAsync _AsyncOperationKindSelector(...);
template <typename _Type>
struct _Unhat
{
typedef _Type _Value;
};
template <typename _Type>
struct _Unhat<_Type*>
{
typedef _Type _Value;
};
template <typename _Type, bool _IsValueTypeOrRefType = __is_valid_winrt_type(_Type)>
struct _ValueTypeOrRefType
{
typedef _Unit_type _Value;
};
template <typename _Type>
struct _ValueTypeOrRefType<_Type, true>
{
typedef _Type _Value;
};
template <typename _Ty>
_Ty _UnwrapAsyncActionWithProgressSelector(ABI::Windows::Foundation::IAsyncActionWithProgress_impl<_Ty>*);
template <typename _Ty>
_Ty _UnwrapAsyncActionWithProgressSelector(...);
template <typename _Ty, typename _Progress>
_Progress _UnwrapAsyncOperationWithProgressProgressSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress_impl<_Ty, _Progress>*);
template <typename _Ty, typename _Progress>
_Progress _UnwrapAsyncOperationWithProgressProgressSelector(...);
template <typename _T1, typename _T2>
_T2 _ProgressTypeSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T1, _T2>*);
template <typename _T1>
_T1 _ProgressTypeSelector(ABI::Windows::Foundation::IAsyncActionWithProgress<_T1>*);
template <typename _Type>
struct _GetProgressType
{
typedef decltype(_ProgressTypeSelector(stdx::declval<_Type>())) _Value;
};
template <typename _T>
_TypeSelectorAsyncOperation _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperation<_T>*);
_TypeSelectorAsyncAction _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncAction*);
template <typename _T1, typename _T2>
_TypeSelectorAsyncOperationWithProgress _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T1, _T2>*);
template <typename _T>
_TypeSelectorAsyncActionWithProgress _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncActionWithProgress<_T>*);
template <typename _Type>
struct _IsIAsyncInfo
{
static const bool _Value = std::is_base_of<ABI::Windows::Foundation::IAsyncInfo, typename _Unhat<_Type>::_Value>::value ||
std::is_same<_TypeSelectorAsyncAction, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value ||
std::is_same<_TypeSelectorAsyncOperation, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value ||
std::is_same<_TypeSelectorAsyncOperationWithProgress, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value ||
std::is_same<_TypeSelectorAsyncActionWithProgress, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value;
};
template <>
struct _IsIAsyncInfo<void>
{
static const bool _Value = false;
};
template <typename _Ty>
_Ty _UnwrapAsyncOperationSelector(ABI::Windows::Foundation::IAsyncOperation_impl<_Ty>*);
template <typename _Ty>
_Ty _UnwrapAsyncOperationSelector(...);
template <typename _Ty, typename _Progress>
_Ty _UnwrapAsyncOperationWithProgressSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress_impl<_Ty, _Progress>*);
template <typename _Ty, typename _Progress>
_Ty _UnwrapAsyncOperationWithProgressSelector(...);
template<typename _Ty>
auto _GetUnwrappedType(ABI::Windows::Foundation::IAsyncOperation<_Ty>*) -> typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperation<_Ty>*>()))>::type;
void _GetUnwrappedType(ABI::Windows::Foundation::IAsyncAction*);
template<typename _Ty, typename _Progress>
auto _GetUnwrappedType(ABI::Windows::Foundation::IAsyncOperationWithProgress<_Ty, _Progress>*) -> typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperationWithProgress<_Ty, _Progress>*>()))>::type;
template<typename _Progress>
void _GetUnwrappedType(ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>*);
template <typename _T>
_T _ReturnAsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperation<_T>*);
void _ReturnAsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncAction*);
template <typename _T1, typename _T2>
_T1 _ReturnAsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T1, _T2>*);
template <typename _T>
void _ReturnAsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncActionWithProgress<_T>*);
class _ProgressReporterCtorArgType{};
template <typename _Type, bool _IsAsync = _IsIAsyncInfo<_Type>::_Value>
struct _TaskTypeTraits
{
typedef typename details::_UnwrapTaskType<_Type>::_Type _TaskRetType;
typedef _TaskRetType _TaskRetType_abi;
typedef decltype(_AsyncOperationKindSelector(stdx::declval<_Type>())) _AsyncKind;
typedef typename details::_NormalizeVoidToUnitType<_TaskRetType>::_Type _NormalizedTaskRetType;
static const bool _IsAsyncTask = _IsAsync;
static const bool _IsUnwrappedTaskOrAsync = details::_IsUnwrappedAsyncSelector<_AsyncKind>::_Value;
};
template<typename _Type>
struct _TaskTypeTraits<_Type, true>
{
typedef decltype(_ReturnAsyncOperationKindSelector(stdx::declval<_Type>())) _TaskRetType;
typedef decltype(_GetUnwrappedType(stdx::declval<_Type>())) _TaskRetType_abi;
typedef _TaskRetType _NormalizedTaskRetType;
typedef decltype(_AsyncOperationKindSelector(stdx::declval<_Type>())) _AsyncKind;
static const bool _IsAsyncTask = true;
static const bool _IsUnwrappedTaskOrAsync = details::_IsUnwrappedAsyncSelector<_AsyncKind>::_Value;
};
template <typename _ReturnType, typename _Function> auto _IsCallable(_Function _Func, int, int, int) -> decltype(_Func(stdx::declval<task<_ReturnType>*>()), std::true_type()) { (void)_Func; return std::true_type(); }
template <typename _ReturnType, typename _Function> auto _IsCallable(_Function _Func, int, int, ...) -> decltype(_Func(stdx::declval<_ReturnType*>()), std::true_type()) { (void)_Func; return std::true_type(); }
template <typename _ReturnType, typename _Function> auto _IsCallable(_Function _Func, int, ...) -> decltype(_Func(), std::true_type()) { (void)_Func; return std::true_type(); }
template <typename _ReturnType, typename _Function> std::false_type _IsCallable(_Function, ...) { return std::false_type(); }
template <>
struct _TaskTypeTraits<void>
{
typedef void _TaskRetType;
typedef void _TaskRetType_abi;
typedef _TypeSelectorNoAsync _AsyncKind;
typedef _Unit_type _NormalizedTaskRetType;
static const bool _IsAsyncTask = false;
static const bool _IsUnwrappedTaskOrAsync = false;
};
struct _ZeroArgumentFunctor { };
struct _OneArgumentFunctor { };
struct _TwoArgumentFunctor { };
struct _ThreeArgumentFunctor { };
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3));
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3));
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg3 _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3));
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3));
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3));
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
_Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2));
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
_Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2));
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2));
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
_ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2));
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
_TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2));
template<typename _Class, typename _ReturnType, typename _Arg1>
_Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1));
template<typename _Class, typename _ReturnType, typename _Arg1>
void _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1));
template<typename _Class, typename _ReturnType, typename _Arg1>
void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1));
template<typename _Class, typename _ReturnType, typename _Arg1>
_ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1));
template<typename _Class, typename _ReturnType, typename _Arg1>
_OneArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1));
template<typename _Class, typename _ReturnType>
void _Arg1ClassHelperThunk(_ReturnType(_Class::*)());
template<typename _Class, typename _ReturnType>
void _Arg2ClassHelperThunk(_ReturnType(_Class::*)());
template<typename _Class, typename _ReturnType>
void _Arg3ClassHelperThunk(_ReturnType(_Class::*)());
template<typename _Class, typename _ReturnType>
_ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)());
template<typename _Class, typename _ReturnType>
_ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)());
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg3 _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const);
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
_Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
_Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
_ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
template<typename _Class, typename _ReturnType, typename _Arg1, typename _Arg2>
_TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2) const);
template<typename _Class, typename _ReturnType, typename _Arg1>
_Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
template<typename _Class, typename _ReturnType, typename _Arg1>
void _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
template<typename _Class, typename _ReturnType, typename _Arg1>
void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
template<typename _Class, typename _ReturnType, typename _Arg1>
_ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const);
template<typename _Class, typename _ReturnType, typename _Arg1>
_OneArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1) const);
template<typename _Class, typename _ReturnType>
void _Arg1ClassHelperThunk(_ReturnType(_Class::*)() const);
template<typename _Class, typename _ReturnType>
void _Arg2ClassHelperThunk(_ReturnType(_Class::*)() const);
template<typename _Class, typename _ReturnType>
void _Arg3ClassHelperThunk(_ReturnType(_Class::*)() const);
template<typename _Class, typename _ReturnType>
_ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)() const);
template<typename _Class, typename _ReturnType>
_ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)() const);
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg2 _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg3 _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg2 _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg3 _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg2 _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_Arg3 _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2, typename _Arg3>
_ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_Arg2 _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_Arg2 _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_Arg2 _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1, typename _Arg2>
_TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1, _Arg2));
template<typename _ReturnType, typename _Arg1>
_Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
void _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
_OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
_Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
void _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
_OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
_Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
void _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));
template<typename _ReturnType, typename _Arg1>
_OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1));
template<typename _ReturnType>
void _Arg1PFNHelperThunk(_ReturnType(__cdecl *)());
template<typename _ReturnType>
void _Arg2PFNHelperThunk(_ReturnType(__cdecl *)());
template<typename _ReturnType>
void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)());
template<typename _ReturnType>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)());
template<typename _ReturnType>
_ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)());
template<typename _ReturnType>
void _Arg1PFNHelperThunk(_ReturnType(__stdcall *)());
template<typename _ReturnType>
void _Arg2PFNHelperThunk(_ReturnType(__stdcall *)());
template<typename _ReturnType>
void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)());
template<typename _ReturnType>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)());
template<typename _ReturnType>
_ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)());
template<typename _ReturnType>
void _Arg1PFNHelperThunk(_ReturnType(__fastcall *)());
template<typename _ReturnType>
void _Arg2PFNHelperThunk(_ReturnType(__fastcall *)());
template<typename _ReturnType>
void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)());
template<typename _ReturnType>
_ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)());
template<typename _ReturnType>
_ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)());
template<typename _T>
struct _FunctorArguments
{
static const size_t _Count = 0;
};
template<>
struct _FunctorArguments<_OneArgumentFunctor>
{
static const size_t _Count = 1;
};
template<>
struct _FunctorArguments<_TwoArgumentFunctor>
{
static const size_t _Count = 2;
};
template<>
struct _FunctorArguments<_ThreeArgumentFunctor>
{
static const size_t _Count = 3;
};
template<typename _T>
struct _FunctorTypeTraits
{
typedef decltype(_ArgumentCountHelper(&(_T::operator()))) _ArgumentCountType;
static const size_t _ArgumentCount = _FunctorArguments<_ArgumentCountType>::_Count;
typedef decltype(_ReturnTypeClassHelperThunk(&(_T::operator()))) _ReturnType;
typedef decltype(_Arg1ClassHelperThunk(&(_T::operator()))) _Argument1Type;
typedef decltype(_Arg2ClassHelperThunk(&(_T::operator()))) _Argument2Type;
typedef decltype(_Arg3ClassHelperThunk(&(_T::operator()))) _Argument3Type;
};
template<typename _T>
struct _FunctorTypeTraits<_T *>
{
typedef decltype(_ArgumentCountHelper(stdx::declval<_T*>())) _ArgumentCountType;
static const size_t _ArgumentCount = _FunctorArguments<_ArgumentCountType>::_Count;
typedef decltype(_ReturnTypePFNHelperThunk(stdx::declval<_T*>())) _ReturnType;
typedef decltype(_Arg1PFNHelperThunk(stdx::declval<_T*>())) _Argument1Type;
typedef decltype(_Arg2PFNHelperThunk(stdx::declval<_T*>())) _Argument2Type;
typedef decltype(_Arg3PFNHelperThunk(stdx::declval<_T*>())) _Argument3Type;
};
task<void> _To_task();
template <typename _Function> auto _IsVoidConversionHelper(_Function _Func, int) -> typename decltype(_Func(_To_task()), std::true_type());
template <typename _Function> std::false_type _IsVoidConversionHelper(_Function _Func, ...);
template <typename T> std::true_type _VoidIsTaskHelper(task<T> _Arg, int);
template <typename T> std::false_type _VoidIsTaskHelper(T _Arg, ...);
template<typename _Function, typename _ExpectedParameterType, const bool _IsVoidConversion = std::is_same<decltype(_IsVoidConversionHelper(stdx::declval<_Function>(), 0)), std::true_type>::value, const size_t _Count = _FunctorTypeTraits<_Function>::_ArgumentCount>
struct _FunctionTypeTraits
{
typedef typename _Unhat<typename _FunctorTypeTraits<_Function>::_Argument2Type>::_Value _FuncRetType;
static_assert(std::is_same<typename _FunctorTypeTraits<_Function>::_Argument1Type, _ExpectedParameterType>::value ||
std::is_same<typename _FunctorTypeTraits<_Function>::_Argument1Type, task<_ExpectedParameterType>>::value, "incorrect parameter type for the callable object in 'then'; consider _ExpectedParameterType or task<_ExpectedParameterType> (see below)");
typedef decltype(_VoidIsTaskHelper(stdx::declval<_FunctorTypeTraits<_Function>::_Argument1Type>(), 0)) _Takes_task;
};
template<typename _Function, typename _ExpectedParameterType, const bool _IsVoidConversion>
struct _FunctionTypeTraits<_Function, _ExpectedParameterType, _IsVoidConversion, 1>
{
typedef void _FuncRetType;
static_assert(std::is_same<typename _FunctorTypeTraits<_Function>::_Argument1Type, _ExpectedParameterType>::value ||
std::is_same<typename _FunctorTypeTraits<_Function>::_Argument1Type, task<_ExpectedParameterType>>::value, "incorrect parameter type for the callable object in 'then'; consider _ExpectedParameterType or task<_ExpectedParameterType> (see below)");
typedef decltype(_VoidIsTaskHelper(stdx::declval<_FunctorTypeTraits<_Function>::_Argument1Type>(), 0)) _Takes_task;
};
template<typename _Function>
struct _FunctionTypeTraits<_Function, void, true, 1>
{
typedef void _FuncRetType;
static_assert(std::is_same<typename _FunctorTypeTraits<_Function>::_Argument1Type, decltype(_To_task())>::value, "incorrect parameter type for the callable object in 'then'; consider _ExpectedParameterType or task<_ExpectedParameterType> (see below)");
typedef decltype(_VoidIsTaskHelper(stdx::declval<_FunctorTypeTraits<_Function>::_Argument1Type>(), 0)) _Takes_task;
};
template<typename _Function>
struct _FunctionTypeTraits<_Function, void, false, 1>
{
typedef typename _Unhat<typename _FunctorTypeTraits<_Function>::_Argument1Type>::_Value _FuncRetType;
typedef std::false_type _Takes_task;
};
template<typename _Function, typename _ExpectedParameterType, const bool _IsVoidConversion>
struct _FunctionTypeTraits<_Function, _ExpectedParameterType, _IsVoidConversion, 0>
{
typedef void _FuncRetType;
typedef std::false_type _Takes_task;
};
template<typename _Function, typename _ReturnType>
struct _ContinuationTypeTraits
{
typedef typename task<typename _TaskTypeTraits<typename _FunctionTypeTraits<_Function, _ReturnType>::_FuncRetType>::_TaskRetType_abi> _TaskOfType;
};
template <typename _TaskType, typename _FuncRetType>
struct _InitFunctorTypeTraits
{
typedef typename _TaskTypeTraits<_FuncRetType>::_AsyncKind _AsyncKind;
static const bool _IsAsyncTask = _TaskTypeTraits<_FuncRetType>::_IsAsyncTask;
static const bool _IsUnwrappedTaskOrAsync = _TaskTypeTraits<_FuncRetType>::_IsUnwrappedTaskOrAsync;
};
template<typename T>
struct _InitFunctorTypeTraits<T, T>
{
typedef _TypeSelectorNoAsync _AsyncKind;
static const bool _IsAsyncTask = false;
static const bool _IsUnwrappedTaskOrAsync = false;
};
struct _TaskProcThunk
{
_TaskProcThunk(const std::function<HRESULT(void)> & _Callback) :
_M_func(_Callback)
{
}
static void __cdecl _Bridge(void *_PData)
{
_TaskProcThunk *_PThunk = reinterpret_cast<_TaskProcThunk *>(_PData);
#if _MSC_VER >= 1800
_Holder _ThunkHolder(_PThunk);
#endif
_PThunk->_M_func();
#if _MSC_VER < 1800
delete _PThunk;
#endif
}
private:
#if _MSC_VER >= 1800
struct _Holder
{
_Holder(_TaskProcThunk * _PThunk) : _M_pThunk(_PThunk)
{
}
~_Holder()
{
delete _M_pThunk;
}
_TaskProcThunk * _M_pThunk;
private:
_Holder& operator=(const _Holder&);
};
#endif
std::function<HRESULT(void)> _M_func;
_TaskProcThunk& operator=(const _TaskProcThunk&);
};
#if _MSC_VER >= 1800
typedef Concurrency::details::_TaskInliningMode_t _TaskInliningMode;
#else
typedef Concurrency::details::_TaskInliningMode _TaskInliningMode;
#endif
static void _ScheduleFuncWithAutoInline(const std::function<HRESULT(void)> & _Func, _TaskInliningMode _InliningMode)
{
#if _MSC_VER >= 1800
Concurrency::details::_TaskCollection_t::_RunTask(&_TaskProcThunk::_Bridge, new _TaskProcThunk(_Func), _InliningMode);
#else
Concurrency::details::_StackGuard _Guard;
if (_Guard._ShouldInline(_InliningMode))
{
_Func();
}
else
{
Concurrency::details::_CurrentScheduler::_ScheduleTask(reinterpret_cast<Concurrency::TaskProc>(&_TaskProcThunk::_Bridge), new _TaskProcThunk(_Func));
}
#endif
}
class _ContextCallback
{
typedef std::function<HRESULT(void)> _CallbackFunction;
public:
static _ContextCallback _CaptureCurrent()
{
_ContextCallback _Context;
_Context._Capture();
return _Context;
}
~_ContextCallback()
{
_Reset();
}
_ContextCallback(bool _DeferCapture = false)
{
if (_DeferCapture)
{
_M_context._M_captureMethod = _S_captureDeferred;
}
else
{
_M_context._M_pContextCallback = nullptr;
}
}
void _Resolve(bool _CaptureCurrent)
{
if (_M_context._M_captureMethod == _S_captureDeferred)
{
_M_context._M_pContextCallback = nullptr;
if (_CaptureCurrent)
{
if (_IsCurrentOriginSTA())
{
_Capture();
}
#if _UITHREADCTXT_SUPPORT
else
{
HRESULT _Hr = CaptureUiThreadContext(&_M_context._M_pContextCallback);
if (FAILED(_Hr))
{
_M_context._M_pContextCallback = nullptr;
}
}
#endif
}
}
}
void _Capture()
{
HRESULT _Hr = CoGetObjectContext(IID_IContextCallback, reinterpret_cast<void **>(&_M_context._M_pContextCallback));
if (FAILED(_Hr))
{
_M_context._M_pContextCallback = nullptr;
}
}
_ContextCallback(const _ContextCallback& _Src)
{
_Assign(_Src._M_context._M_pContextCallback);
}
_ContextCallback(_ContextCallback&& _Src)
{
_M_context._M_pContextCallback = _Src._M_context._M_pContextCallback;
_Src._M_context._M_pContextCallback = nullptr;
}
_ContextCallback& operator=(const _ContextCallback& _Src)
{
if (this != &_Src)
{
_Reset();
_Assign(_Src._M_context._M_pContextCallback);
}
return *this;
}
_ContextCallback& operator=(_ContextCallback&& _Src)
{
if (this != &_Src)
{
_M_context._M_pContextCallback = _Src._M_context._M_pContextCallback;
_Src._M_context._M_pContextCallback = nullptr;
}
return *this;
}
bool _HasCapturedContext() const
{
_CONCRT_ASSERT(_M_context._M_captureMethod != _S_captureDeferred);
return (_M_context._M_pContextCallback != nullptr);
}
HRESULT _CallInContext(_CallbackFunction _Func) const
{
if (!_HasCapturedContext())
{
_Func();
}
else
{
ComCallData callData;
ZeroMemory(&callData, sizeof(callData));
callData.pUserDefined = reinterpret_cast<void *>(&_Func);
HRESULT _Hr = _M_context._M_pContextCallback->ContextCallback(&_Bridge, &callData, IID_ICallbackWithNoReentrancyToApplicationSTA, 5, nullptr);
if (FAILED(_Hr))
{
return _Hr;
}
}
return S_OK;
}
bool operator==(const _ContextCallback& _Rhs) const
{
return (_M_context._M_pContextCallback == _Rhs._M_context._M_pContextCallback);
}
bool operator!=(const _ContextCallback& _Rhs) const
{
return !(operator==(_Rhs));
}
private:
void _Reset()
{
if (_M_context._M_captureMethod != _S_captureDeferred && _M_context._M_pContextCallback != nullptr)
{
_M_context._M_pContextCallback->Release();
}
}
void _Assign(IContextCallback *_PContextCallback)
{
_M_context._M_pContextCallback = _PContextCallback;
if (_M_context._M_captureMethod != _S_captureDeferred && _M_context._M_pContextCallback != nullptr)
{
_M_context._M_pContextCallback->AddRef();
}
}
static HRESULT __stdcall _Bridge(ComCallData *_PParam)
{
_CallbackFunction *pFunc = reinterpret_cast<_CallbackFunction *>(_PParam->pUserDefined);
return (*pFunc)();
}
static bool _IsCurrentOriginSTA()
{
APTTYPE _AptType;
APTTYPEQUALIFIER _AptTypeQualifier;
HRESULT hr = CoGetApartmentType(&_AptType, &_AptTypeQualifier);
if (SUCCEEDED(hr))
{
switch (_AptType)
{
case APTTYPE_MAINSTA:
case APTTYPE_STA:
return true;
default:
break;
}
}
return false;
}
union
{
IContextCallback *_M_pContextCallback;
size_t _M_captureMethod;
} _M_context;
static const size_t _S_captureDeferred = 1;
};
#if _MSC_VER >= 1800
template<typename _Type>
struct _ResultHolder
{
void Set(const _Type& _type)
{
_Result = _type;
}
_Type Get()
{
return _Result;
}
_Type _Result;
};
template<typename _Type>
struct _ResultHolder<_Type*>
{
void Set(_Type* const & _type)
{
_M_Result = _type;
}
_Type* Get()
{
return _M_Result.Get();
}
private:
Agile<_Type*> _M_Result;
};
template<typename _Type>
struct _ResultHolder<std::vector<_Type*>>
{
void Set(const std::vector<_Type*>& _type)
{
_Result.reserve(_type.size());
for (auto _PTask = _type.begin(); _PTask != _type.end(); ++_PTask)
{
_Result.emplace_back(*_PTask);
}
}
std::vector<_Type*> Get()
{
std::vector<_Type*> _Return;
_Return.reserve(_Result.size());
for (auto _PTask = _Result.begin(); _PTask != _Result.end(); ++_PTask)
{
_Return.push_back(_PTask->Get());
}
return _Return;
}
std::vector< Agile<_Type*> > _Result;
};
template<typename _Type>
struct _ResultHolder<std::pair<_Type*, void*> >
{
void Set(const std::pair<_Type*, size_t>& _type)
{
_M_Result = _type;
}
std::pair<_Type*, size_t> Get()
{
return std::make_pair(_M_Result.first, _M_Result.second);
}
private:
std::pair<Agile<_Type*>, size_t> _M_Result;
};
#else
template<typename _Type>
struct _ResultContext
{
static _ContextCallback _GetContext(bool )
{
return _ContextCallback();
}
static _Type _GetValue(_Type _ObjInCtx, const _ContextCallback & , bool )
{
return _ObjInCtx;
}
};
template<typename _Type, size_t N = 0, bool bIsArray = std::is_array<_Type>::value>
struct _MarshalHelper
{
};
template<typename _Type, size_t N>
struct _MarshalHelper<_Type, N, true>
{
static _Type* _Perform(_Type(&_ObjInCtx)[N], const _ContextCallback& _Ctx)
{
static_assert(__is_valid_winrt_type(_Type*), "must be a WinRT array compatible type");
if (_ObjInCtx == nullptr)
{
return nullptr;
}
HRESULT _Hr;
IStream * _PStream;
_Ctx._CallInContext([&]() -> HRESULT {
IUnknown * _PUnk = winrt_array_type::create(_ObjInCtx, N);
_Hr = CoMarshalInterThreadInterfaceInStream(winrt_type<_Type>::getuuid(), _PUnk, &_PStream);
return S_OK;
});
_CONCRT_ASSERT(SUCCEEDED(_Hr));
_Type* _Proxy;
_Hr = CoGetInterfaceAndReleaseStream(_PStream, winrt_type<_Type>::getuuid(), reinterpret_cast<void**>(&_Proxy));
if (FAILED(_Hr))
{
throw std::make_exception_ptr(_Hr);
}
return _Proxy;
}
};
template<typename _Type>
struct _MarshalHelper<_Type, 0, false>
{
static _Type* _Perform(_Type* _ObjInCtx, const _ContextCallback& _Ctx)
{
static_assert(std::is_base_of<IUnknown, _Type>::value || __is_valid_winrt_type(_Type), "must be a COM or WinRT type");
if (_ObjInCtx == nullptr)
{
return nullptr;
}
HRESULT _Hr;
IStream * _PStream;
_Ctx._CallInContext([&]() -> HRESULT {
IUnknown * _PUnk = winrt_type<_Type>::create(_ObjInCtx);
_Hr = CoMarshalInterThreadInterfaceInStream(winrt_type<_Type>::getuuid(), _PUnk, &_PStream);
return S_OK;
});
_CONCRT_ASSERT(SUCCEEDED(_Hr));
_Type* _Proxy;
_Hr = CoGetInterfaceAndReleaseStream(_PStream, winrt_type<_Type>::getuuid(), reinterpret_cast<void**>(&_Proxy));
if (FAILED(_Hr))
{
throw std::make_exception_ptr(_Hr);
}
return _Proxy;
}
};
template<>
struct _MarshalHelper<HSTRING__>
{
static HSTRING _Perform(HSTRING _ObjInCtx, const _ContextCallback& _Ctx)
{
return _ObjInCtx;
}
};
template<typename _Type>
_Type* _Marshal(_Type* _ObjInCtx, const _ContextCallback& _Ctx)
{
return _MarshalHelper<_Type>::_Perform(_ObjInCtx, _Ctx);
}
template<typename _Type>
struct _InContext
{
static _Type _Get(_Type _ObjInCtx, const _ContextCallback& _Ctx)
{
return _ObjInCtx;
}
};
template<typename _Type>
struct _InContext<_Type*>
{
static _Type* _Get(_Type* _ObjInCtx, const _ContextCallback& _Ctx)
{
_ContextCallback _CurrentContext = _ContextCallback::_CaptureCurrent();
if (!_Ctx._HasCapturedContext() || _Ctx == _CurrentContext)
{
return _ObjInCtx;
}
return _Marshal<_Type>(_ObjInCtx, _Ctx);
}
};
template<typename _Type>
struct _ResultContext<_Type*>
{
static _Type* _GetValue(_Type* _ObjInCtx, const _ContextCallback& _Ctx, bool )
{
return _InContext<_Type*>::_Get(_ObjInCtx, _Ctx);
}
static _ContextCallback _GetContext(bool )
{
return _ContextCallback::_CaptureCurrent();
}
};
template<typename _Type>
struct _ResultContext<std::vector<_Type*>>
{
static std::vector<_Type*> _GetValue(std::vector<_Type*> _ObjInCtx, const _ContextCallback& _Ctx, bool _RuntimeAggregate)
{
if (!_RuntimeAggregate)
{
return _ObjInCtx;
}
_ContextCallback _CurrentContext = _ContextCallback::_CaptureCurrent();
if (!_Ctx._HasCapturedContext() || _Ctx == _CurrentContext)
{
return _ObjInCtx;
}
for (auto _It = _ObjInCtx.begin(); _It != _ObjInCtx.end(); ++_It)
{
*_It = _Marshal<_Type>(*_It, _Ctx);
}
return _ObjInCtx;
}
static _ContextCallback _GetContext(bool _RuntimeAggregate)
{
if (!_RuntimeAggregate)
{
return _ContextCallback();
}
else
{
return _ContextCallback::_CaptureCurrent();
}
}
};
template<typename _Type>
struct _ResultContext<std::pair<_Type*, size_t>>
{
static std::pair<_Type*, size_t> _GetValue(std::pair<_Type*, size_t> _ObjInCtx, const _ContextCallback& _Ctx, bool _RuntimeAggregate)
{
if (!_RuntimeAggregate)
{
return _ObjInCtx;
}
_ContextCallback _CurrentContext = _ContextCallback::_CaptureCurrent();
if (!_Ctx._HasCapturedContext() || _Ctx == _CurrentContext)
{
return _ObjInCtx;
}
return std::pair<_Type*, size_t>(_Marshal<_Type>(_ObjInCtx.first, _Ctx), _ObjInCtx.second);
}
static _ContextCallback _GetContext(bool _RuntimeAggregate)
{
if (!_RuntimeAggregate)
{
return _ContextCallback();
}
else
{
return _ContextCallback::_CaptureCurrent();
}
}
};
#endif
struct _ExceptionHolder
{
#if _MSC_VER >= 1800
private:
void ReportUnhandledError()
{
if (_M_winRTException != nullptr)
{
throw _M_winRTException.Get();
}
}
public:
explicit _ExceptionHolder(const std::exception_ptr& _E, const _TaskCreationCallstack &_stackTrace) :
_M_exceptionObserved(0), _M_stdException(_E), _M_stackTrace(_stackTrace)
{
}
explicit _ExceptionHolder(IRestrictedErrorInfo*& _E, const _TaskCreationCallstack &_stackTrace) :
_M_exceptionObserved(0), _M_winRTException(_E), _M_stackTrace(_stackTrace)
{
}
#else
explicit _ExceptionHolder(const std::exception_ptr& _E, void* _SourceAddressHint) :
_M_exceptionObserved(0), _M_stdException(_E), _M_disassembleMe(_SourceAddressHint)
{
}
explicit _ExceptionHolder(IRestrictedErrorInfo*& _E, void* _SourceAddressHint) :
_M_exceptionObserved(0), _M_disassembleMe(_SourceAddressHint), _M_winRTException(_E)
{
}
#endif
__declspec(noinline)
~_ExceptionHolder()
{
if (_M_exceptionObserved == 0)
{
#if _MSC_VER >= 1800
_REPORT_PPLTASK_UNOBSERVED_EXCEPTION();
#else
Concurrency::details::_ReportUnobservedException();
#endif
}
}
void _RethrowUserException()
{
if (_M_exceptionObserved == 0)
{
#if _MSC_VER >= 1800
Concurrency::details::atomic_exchange(_M_exceptionObserved, 1l);
#else
_InterlockedExchange(&_M_exceptionObserved, 1);
#endif
}
if (_M_winRTException != nullptr)
{
throw _M_winRTException.Get();
}
std::rethrow_exception(_M_stdException);
}
#if _MSC_VER >= 1800
Concurrency::details::atomic_long _M_exceptionObserved;
#else
long volatile _M_exceptionObserved;
#endif
std::exception_ptr _M_stdException;
Microsoft::WRL::ComPtr<IRestrictedErrorInfo> _M_winRTException;
#if _MSC_VER >= 1800
_TaskCreationCallstack _M_stackTrace;
#else
void* _M_disassembleMe;
#endif
};
#ifndef RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoImpl_DEFINED
#define RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoImpl_DEFINED
extern const __declspec(selectany) WCHAR RuntimeClass_Concurrency_winrt_details__AsyncInfoImpl[] = L"Concurrency_winrt.details._AsyncInfoImpl";
#endif
template<typename _AsyncOperationType, typename _CompletionHandlerType, typename _Result_abi>
struct _AsyncInfoImpl abstract : public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRt>,
Microsoft::WRL::Implements<Microsoft::WRL::AsyncBase<_CompletionHandlerType>>>
{
InspectableClass(RuntimeClass_Concurrency_winrt_details__AsyncInfoImpl, BaseTrust)
public:
#if _MSC_VER >= 1800
Agile<_AsyncOperationType> _M_asyncInfo;
#else
Microsoft::WRL::ComPtr<_AsyncOperationType> _M_asyncInfo;
_ContextCallback _M_asyncInfoContext;
#endif
Microsoft::WRL::ComPtr<_CompletionHandlerType> _M_CompletedHandler;
_AsyncInfoImpl(_AsyncOperationType* _AsyncInfo) : _M_asyncInfo(_AsyncInfo)
#if _MSC_VER < 1800
, _M_asyncInfoContext(_ContextCallback::_CaptureCurrent())
#endif
{}
public:
virtual HRESULT OnStart() { return S_OK; }
virtual void OnCancel() {
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
HRESULT hr;
#if _MSC_VER >= 1800
if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())))
#else
if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo)))
#endif
pAsyncInfo->Cancel();
else
throw std::make_exception_ptr(hr);
}
virtual void OnClose() {
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
HRESULT hr;
#if _MSC_VER >= 1800
if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())))
#else
if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo)))
#endif
pAsyncInfo->Close();
else
throw std::make_exception_ptr(hr);
}
virtual STDMETHODIMP get_ErrorCode(HRESULT* errorCode)
{
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
HRESULT hr;
#if _MSC_VER >= 1800
if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())))
#else
if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo)))
#endif
return pAsyncInfo->get_ErrorCode(errorCode);
return hr;
}
virtual STDMETHODIMP get_Id(UINT* id)
{
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
HRESULT hr;
#if _MSC_VER >= 1800
if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())))
#else
if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo)))
#endif
return pAsyncInfo->get_Id(id);
return hr;
}
virtual STDMETHODIMP get_Status(ABI::Windows::Foundation::AsyncStatus *status)
{
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
HRESULT hr;
#if _MSC_VER >= 1800
if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())))
#else
if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo)))
#endif
return pAsyncInfo->get_Status(status);
return hr;
}
virtual STDMETHODIMP GetResults(_Result_abi*) { throw std::runtime_error("derived class must implement"); }
virtual STDMETHODIMP get_Completed(_CompletionHandlerType** handler)
{
if (!handler) return E_POINTER;
_M_CompletedHandler.CopyTo(handler);
return S_OK;
}
virtual STDMETHODIMP put_Completed(_CompletionHandlerType* value)
{
_M_CompletedHandler = value;
Microsoft::WRL::ComPtr<_CompletionHandlerType> handler = Microsoft::WRL::Callback<_CompletionHandlerType>([&](_AsyncOperationType*, ABI::Windows::Foundation::AsyncStatus status) -> HRESULT {
#if _MSC_VER < 1800
_M_asyncInfo = _ResultContext<_AsyncOperationType*>::_GetValue(_M_asyncInfo.Get(), _M_asyncInfoContext, false);
#endif
return _M_CompletedHandler->Invoke(_M_asyncInfo.Get(), status);
});
#if _MSC_VER >= 1800
return _M_asyncInfo.Get()->put_Completed(handler.Get());
#else
return _M_asyncInfo->put_Completed(handler.Get());
#endif
}
};
extern const __declspec(selectany) WCHAR RuntimeClass_IAsyncOperationToAsyncOperationConverter[] = L"_IAsyncOperationToAsyncOperationConverter";
template<typename _Result>
struct _IAsyncOperationToAsyncOperationConverter :
_AsyncInfoImpl<ABI::Windows::Foundation::IAsyncOperation<_Result>,
ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_Result>,
typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperation<_Result>*>()))>::type>
{
typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperation<_Result>*>()))>::type _Result_abi;
InspectableClass(RuntimeClass_IAsyncOperationToAsyncOperationConverter, BaseTrust)
public:
_IAsyncOperationToAsyncOperationConverter(ABI::Windows::Foundation::IAsyncOperation<_Result>* _Operation) :
_AsyncInfoImpl<ABI::Windows::Foundation::IAsyncOperation<_Result>,
ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_Result>,
_Result_abi>(_Operation) {}
public:
virtual STDMETHODIMP GetResults(_Result_abi* results) override {
if (!results) return E_POINTER;
#if _MSC_VER >= 1800
return _M_asyncInfo.Get()->GetResults(results);
#else
return _M_asyncInfo->GetResults(results);
#endif
}
};
extern const __declspec(selectany) WCHAR RuntimeClass_IAsyncOperationWithProgressToAsyncOperationConverter[] = L"_IAsyncOperationWithProgressToAsyncOperationConverter";
template<typename _Result, typename _Progress>
struct _IAsyncOperationWithProgressToAsyncOperationConverter :
_AsyncInfoImpl<ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>,
ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<_Result, _Progress>,
typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>*>()))>::type>
{
typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>*>()))>::type _Result_abi;
InspectableClass(RuntimeClass_IAsyncOperationWithProgressToAsyncOperationConverter, BaseTrust)
public:
_IAsyncOperationWithProgressToAsyncOperationConverter(ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>* _Operation) :
_AsyncInfoImpl<ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>,
ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<_Result, _Progress>,
_Result_abi>(_Operation) {}
public:
virtual STDMETHODIMP GetResults(_Result_abi* results) override {
if (!results) return E_POINTER;
#if _MSC_VER >= 1800
return _M_asyncInfo.Get()->GetResults(results);
#else
return _M_asyncInfo->GetResults(results);
#endif
}
};
extern const __declspec(selectany) WCHAR RuntimeClass_IAsyncActionToAsyncOperationConverter[] = L"_IAsyncActionToAsyncOperationConverter";
struct _IAsyncActionToAsyncOperationConverter :
_AsyncInfoImpl<ABI::Windows::Foundation::IAsyncAction,
ABI::Windows::Foundation::IAsyncActionCompletedHandler,
_Unit_type>
{
InspectableClass(RuntimeClass_IAsyncActionToAsyncOperationConverter, BaseTrust)
public:
_IAsyncActionToAsyncOperationConverter(ABI::Windows::Foundation::IAsyncAction* _Operation) :
_AsyncInfoImpl<ABI::Windows::Foundation::IAsyncAction,
ABI::Windows::Foundation::IAsyncActionCompletedHandler,
_Unit_type>(_Operation) {}
public:
virtual STDMETHODIMP GetResults(details::_Unit_type* results)
{
if (!results) return E_POINTER;
#if _MSC_VER >= 1800
HRESULT hr = _M_asyncInfo.Get()->GetResults();
#else
HRESULT hr = _M_asyncInfo->GetResults();
#endif
if (SUCCEEDED(hr)) *results = _Unit_type();
return hr;
}
};
extern const __declspec(selectany) WCHAR RuntimeClass_IAsyncActionWithProgressToAsyncOperationConverter[] = L"_IAsyncActionWithProgressToAsyncOperationConverter";
template<typename _Progress>
struct _IAsyncActionWithProgressToAsyncOperationConverter :
_AsyncInfoImpl<ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>,
ABI::Windows::Foundation::IAsyncActionWithProgressCompletedHandler<_Progress>,
_Unit_type>
{
InspectableClass(RuntimeClass_IAsyncActionWithProgressToAsyncOperationConverter, BaseTrust)
public:
_IAsyncActionWithProgressToAsyncOperationConverter(ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>* _Action) :
_AsyncInfoImpl<ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>,
ABI::Windows::Foundation::IAsyncActionWithProgressCompletedHandler<_Progress>,
_Unit_type>(_Action) {}
public:
virtual STDMETHODIMP GetResults(_Unit_type* results) override
{
if (!results) return E_POINTER;
#if _MSC_VER >= 1800
HRESULT hr = _M_asyncInfo.Get()->GetResults();
#else
HRESULT hr = _M_asyncInfo->GetResults();
#endif
if (SUCCEEDED(hr)) *results = _Unit_type();
return hr;
}
};
}
class task_continuation_context : public details::_ContextCallback
{
public:
static task_continuation_context use_default()
{
return task_continuation_context(true);
}
static task_continuation_context use_arbitrary()
{
task_continuation_context _Arbitrary(true);
_Arbitrary._Resolve(false);
return _Arbitrary;
}
static task_continuation_context use_current()
{
task_continuation_context _Current(true);
_Current._Resolve(true);
return _Current;
}
private:
task_continuation_context(bool _DeferCapture = false) : details::_ContextCallback(_DeferCapture)
{
}
};
#if _MSC_VER >= 1800
class task_options;
namespace details
{
struct _Internal_task_options
{
bool _M_hasPresetCreationCallstack;
_TaskCreationCallstack _M_presetCreationCallstack;
void _set_creation_callstack(const _TaskCreationCallstack &_callstack)
{
_M_hasPresetCreationCallstack = true;
_M_presetCreationCallstack = _callstack;
}
_Internal_task_options()
{
_M_hasPresetCreationCallstack = false;
}
};
inline _Internal_task_options &_get_internal_task_options(task_options &options);
inline const _Internal_task_options &_get_internal_task_options(const task_options &options);
}
class task_options
{
public:
task_options()
: _M_Scheduler(Concurrency::get_ambient_scheduler()),
_M_CancellationToken(Concurrency::cancellation_token::none()),
_M_ContinuationContext(task_continuation_context::use_default()),
_M_HasCancellationToken(false),
_M_HasScheduler(false)
{
}
task_options(Concurrency::cancellation_token _Token)
: _M_Scheduler(Concurrency::get_ambient_scheduler()),
_M_CancellationToken(_Token),
_M_ContinuationContext(task_continuation_context::use_default()),
_M_HasCancellationToken(true),
_M_HasScheduler(false)
{
}
task_options(task_continuation_context _ContinuationContext)
: _M_Scheduler(Concurrency::get_ambient_scheduler()),
_M_CancellationToken(Concurrency::cancellation_token::none()),
_M_ContinuationContext(_ContinuationContext),
_M_HasCancellationToken(false),
_M_HasScheduler(false)
{
}
task_options(Concurrency::cancellation_token _Token, task_continuation_context _ContinuationContext)
: _M_Scheduler(Concurrency::get_ambient_scheduler()),
_M_CancellationToken(_Token),
_M_ContinuationContext(_ContinuationContext),
_M_HasCancellationToken(false),
_M_HasScheduler(false)
{
}
template<typename _SchedType>
task_options(std::shared_ptr<_SchedType> _Scheduler)
: _M_Scheduler(std::move(_Scheduler)),
_M_CancellationToken(cancellation_token::none()),
_M_ContinuationContext(task_continuation_context::use_default()),
_M_HasCancellationToken(false),
_M_HasScheduler(true)
{
}
task_options(Concurrency::scheduler_interface& _Scheduler)
: _M_Scheduler(&_Scheduler),
_M_CancellationToken(Concurrency::cancellation_token::none()),
_M_ContinuationContext(task_continuation_context::use_default()),
_M_HasCancellationToken(false),
_M_HasScheduler(true)
{
}
task_options(Concurrency::scheduler_ptr _Scheduler)
: _M_Scheduler(std::move(_Scheduler)),
_M_CancellationToken(Concurrency::cancellation_token::none()),
_M_ContinuationContext(task_continuation_context::use_default()),
_M_HasCancellationToken(false),
_M_HasScheduler(true)
{
}
task_options(const task_options& _TaskOptions)
: _M_Scheduler(_TaskOptions.get_scheduler()),
_M_CancellationToken(_TaskOptions.get_cancellation_token()),
_M_ContinuationContext(_TaskOptions.get_continuation_context()),
_M_HasCancellationToken(_TaskOptions.has_cancellation_token()),
_M_HasScheduler(_TaskOptions.has_scheduler())
{
}
void set_cancellation_token(Concurrency::cancellation_token _Token)
{
_M_CancellationToken = _Token;
_M_HasCancellationToken = true;
}
void set_continuation_context(task_continuation_context _ContinuationContext)
{
_M_ContinuationContext = _ContinuationContext;
}
bool has_cancellation_token() const
{
return _M_HasCancellationToken;
}
Concurrency::cancellation_token get_cancellation_token() const
{
return _M_CancellationToken;
}
task_continuation_context get_continuation_context() const
{
return _M_ContinuationContext;
}
bool has_scheduler() const
{
return _M_HasScheduler;
}
Concurrency::scheduler_ptr get_scheduler() const
{
return _M_Scheduler;
}
private:
task_options const& operator=(task_options const& _Right);
friend details::_Internal_task_options &details::_get_internal_task_options(task_options &);
friend const details::_Internal_task_options &details::_get_internal_task_options(const task_options &);
Concurrency::scheduler_ptr _M_Scheduler;
Concurrency::cancellation_token _M_CancellationToken;
task_continuation_context _M_ContinuationContext;
details::_Internal_task_options _M_InternalTaskOptions;
bool _M_HasCancellationToken;
bool _M_HasScheduler;
};
#endif
namespace details
{
#if _MSC_VER >= 1800
inline _Internal_task_options & _get_internal_task_options(task_options &options)
{
return options._M_InternalTaskOptions;
}
inline const _Internal_task_options & _get_internal_task_options(const task_options &options)
{
return options._M_InternalTaskOptions;
}
#endif
struct _Task_impl_base;
template<typename _ReturnType> struct _Task_impl;
template<typename _ReturnType>
struct _Task_ptr
{
typedef std::shared_ptr<_Task_impl<_ReturnType>> _Type;
#if _MSC_VER >= 1800
static _Type _Make(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler_arg) { return std::make_shared<_Task_impl<_ReturnType>>(_Ct, _Scheduler_arg); }
#else
static _Type _Make(Concurrency::details::_CancellationTokenState * _Ct) { return std::make_shared<_Task_impl<_ReturnType>>(_Ct); }
#endif
};
#if _MSC_VER >= 1800
typedef Concurrency::details::_TaskCollection_t::_TaskProcHandle_t _UnrealizedChore_t;
typedef _UnrealizedChore_t _UnrealizedChore;
typedef Concurrency::extensibility::scoped_critical_section_t scoped_lock;
typedef Concurrency::extensibility::critical_section_t critical_section;
typedef Concurrency::details::atomic_size_t atomic_size_t;
#else
typedef Concurrency::details::_UnrealizedChore _UnrealizedChore;
typedef Concurrency::critical_section::scoped_lock scoped_lock;
typedef Concurrency::critical_section critical_section;
typedef volatile size_t atomic_size_t;
#endif
typedef std::shared_ptr<_Task_impl_base> _Task_ptr_base;
struct _ContinuationTaskHandleBase : _UnrealizedChore
{
_ContinuationTaskHandleBase * _M_next;
task_continuation_context _M_continuationContext;
bool _M_isTaskBasedContinuation;
_TaskInliningMode _M_inliningMode;
virtual _Task_ptr_base _GetTaskImplBase() const = 0;
_ContinuationTaskHandleBase() :
_M_next(nullptr), _M_isTaskBasedContinuation(false), _M_continuationContext(task_continuation_context::use_default()), _M_inliningMode(Concurrency::details::_NoInline)
{
}
virtual ~_ContinuationTaskHandleBase() {}
};
#if _MSC_VER >= 1800
#if _PPLTASK_ASYNC_LOGGING
const ::Platform::Guid _PPLTaskCausalityPlatformID(0x7A76B220, 0xA758, 0x4E6E, 0xB0, 0xE0, 0xD7, 0xC6, 0xD7, 0x4A, 0x88, 0xFE);
__declspec(selectany) volatile long _isCausalitySupported = 0;
inline bool _IsCausalitySupported()
{
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
if (_isCausalitySupported == 0)
{
long _causality = 1;
OSVERSIONINFOEX _osvi = {};
_osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
_osvi.dwMajorVersion = 6;
_osvi.dwMinorVersion = 3;
DWORDLONG _conditionMask = 0;
VER_SET_CONDITION(_conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(_conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
if (::VerifyVersionInfo(&_osvi, VER_MAJORVERSION | VER_MINORVERSION, _conditionMask))
{
_causality = 2;
}
_isCausalitySupported = _causality;
return _causality == 2;
}
return _isCausalitySupported == 2 ? true : false;
#else
return true;
#endif
}
struct _TaskEventLogger
{
_Task_impl_base *_M_task;
bool _M_scheduled;
bool _M_taskPostEventStarted;
void _LogScheduleTask(bool _isContinuation)
{
if (details::_IsCausalitySupported())
{
::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceOperationCreation(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
_PPLTaskCausalityPlatformID, reinterpret_cast<unsigned long long>(_M_task),
_isContinuation ? "Concurrency::PPLTask::ScheduleContinuationTask" : "Concurrency::PPLTask::ScheduleTask", 0);
_M_scheduled = true;
}
}
void _LogCancelTask()
{
if (details::_IsCausalitySupported())
{
::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceOperationRelation(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Important, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
_PPLTaskCausalityPlatformID, reinterpret_cast<unsigned long long>(_M_task), ::Windows::Foundation::Diagnostics::CausalityRelation::Cancel);
}
}
void _LogTaskCompleted();
void _LogTaskExecutionStarted() { }
void _LogTaskExecutionCompleted()
{
if (_M_taskPostEventStarted && details::_IsCausalitySupported())
{
::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkCompletion(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
::Windows::Foundation::Diagnostics::CausalitySynchronousWork::CompletionNotification);
}
}
void _LogWorkItemStarted()
{
if (details::_IsCausalitySupported())
{
::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkStart(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
_PPLTaskCausalityPlatformID, reinterpret_cast<unsigned long long>(_M_task), ::Windows::Foundation::Diagnostics::CausalitySynchronousWork::Execution);
}
}
void _LogWorkItemCompleted()
{
if (details::_IsCausalitySupported())
{
::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkCompletion(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
::Windows::Foundation::Diagnostics::CausalitySynchronousWork::Execution);
::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkStart(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
_PPLTaskCausalityPlatformID, reinterpret_cast<unsigned long long>(_M_task), ::Windows::Foundation::Diagnostics::CausalitySynchronousWork::CompletionNotification);
_M_taskPostEventStarted = true;
}
}
_TaskEventLogger(_Task_impl_base *_task) : _M_task(_task)
{
_M_scheduled = false;
_M_taskPostEventStarted = false;
}
};
struct _TaskWorkItemRAIILogger
{
_TaskEventLogger &_M_logger;
_TaskWorkItemRAIILogger(_TaskEventLogger &_taskHandleLogger) : _M_logger(_taskHandleLogger)
{
_M_logger._LogWorkItemStarted();
}
~_TaskWorkItemRAIILogger()
{
_M_logger._LogWorkItemCompleted();
}
_TaskWorkItemRAIILogger &operator =(const _TaskWorkItemRAIILogger &);
};
#else
inline void _LogCancelTask(_Task_impl_base *) {}
struct _TaskEventLogger
{
void _LogScheduleTask(bool) {}
void _LogCancelTask() {}
void _LogWorkItemStarted() {}
void _LogWorkItemCompleted() {}
void _LogTaskExecutionStarted() {}
void _LogTaskExecutionCompleted() {}
void _LogTaskCompleted() {}
_TaskEventLogger(_Task_impl_base *) {}
};
struct _TaskWorkItemRAIILogger
{
_TaskWorkItemRAIILogger(_TaskEventLogger &) {}
};
#endif
#endif
template<typename _ReturnType, typename _DerivedTaskHandle, typename _BaseTaskHandle>
struct _PPLTaskHandle : _BaseTaskHandle
{
_PPLTaskHandle(const typename _Task_ptr<_ReturnType>::_Type & _PTask) : _M_pTask(_PTask)
{
#if _MSC_VER < 1800
m_pFunction = reinterpret_cast <Concurrency::TaskProc> (&_UnrealizedChore::_InvokeBridge<_PPLTaskHandle>);
_SetRuntimeOwnsLifetime(true);
#endif
}
virtual ~_PPLTaskHandle() {
#if _MSC_VER >= 1800
_M_pTask->_M_taskEventLogger._LogTaskCompleted();
#endif
}
#if _MSC_VER >= 1800
virtual void invoke() const
#else
void operator()() const
#endif
{
_CONCRT_ASSERT(_M_pTask != nullptr);
if (!_M_pTask->_TransitionedToStarted()) {
#if _MSC_VER >= 1800
static_cast<const _DerivedTaskHandle *>(this)->_SyncCancelAndPropagateException();
#endif
return;
}
#if _MSC_VER >= 1800
_M_pTask->_M_taskEventLogger._LogTaskExecutionStarted();
#endif
try
{
static_cast<const _DerivedTaskHandle *>(this)->_Perform();
}
catch (const Concurrency::task_canceled &)
{
_M_pTask->_Cancel(true);
#if _MSC_VER < 1800
throw;
#endif
}
catch (const Concurrency::details::_Interruption_exception &)
{
_M_pTask->_Cancel(true);
#if _MSC_VER < 1800
throw;
#endif
}
catch (IRestrictedErrorInfo*& _E)
{
_M_pTask->_CancelWithException(_E);
#if _MSC_VER < 1800
throw;
#endif
}
catch (...)
{
_M_pTask->_CancelWithException(std::current_exception());
#if _MSC_VER < 1800
throw;
#endif
}
#if _MSC_VER >= 1800
_M_pTask->_M_taskEventLogger._LogTaskExecutionCompleted();
#endif
}
_Task_ptr_base _GetTaskImplBase() const
{
return _M_pTask;
}
typename _Task_ptr<_ReturnType>::_Type _M_pTask;
private:
_PPLTaskHandle const & operator=(_PPLTaskHandle const&);
};
struct _Task_impl_base
{
enum _TaskInternalState
{
_Created,
_Started,
_PendingCancel,
_Completed,
_Canceled
};
#if _MSC_VER >= 1800
_Task_impl_base(Concurrency::details::_CancellationTokenState * _PTokenState, Concurrency::scheduler_ptr _Scheduler_arg)
: _M_TaskState(_Created),
_M_fFromAsync(false), _M_fUnwrappedTask(false),
_M_pRegistration(nullptr), _M_Continuations(nullptr), _M_TaskCollection(_Scheduler_arg),
_M_taskEventLogger(this)
#else
_Task_impl_base(Concurrency::details::_CancellationTokenState * _PTokenState) : _M_TaskState(_Created),
_M_fFromAsync(false), _M_fRuntimeAggregate(false), _M_fUnwrappedTask(false),
_M_pRegistration(nullptr), _M_Continuations(nullptr), _M_pTaskCollection(nullptr),
_M_pTaskCreationAddressHint(nullptr)
#endif
{
_M_pTokenState = _PTokenState;
_CONCRT_ASSERT(_M_pTokenState != nullptr);
if (_M_pTokenState != Concurrency::details::_CancellationTokenState::_None())
_M_pTokenState->_Reference();
}
virtual ~_Task_impl_base()
{
_CONCRT_ASSERT(_M_pTokenState != nullptr);
if (_M_pTokenState != Concurrency::details::_CancellationTokenState::_None())
{
_M_pTokenState->_Release();
}
#if _MSC_VER < 1800
if (_M_pTaskCollection != nullptr)
{
_M_pTaskCollection->_Release();
_M_pTaskCollection = nullptr;
}
#endif
}
task_status _Wait()
{
bool _DoWait = true;
if (_IsNonBlockingThread())
{
if (!_IsCompleted() && !_IsCanceled())
{
throw Concurrency::invalid_operation("Illegal to wait on a task in a Windows Runtime STA");
}
else
{
_DoWait = false;
}
}
if (_DoWait)
{
#if _MSC_VER < 1800
_M_Scheduled.wait();
#endif
#if _MSC_VER >= 1800
if (_M_fFromAsync)
#else
if ((_M_pTaskCollection == nullptr) || _M_fFromAsync)
#endif
{
#if _MSC_VER >= 1800
_M_TaskCollection._Wait();
#else
_M_Completed.wait();
#endif
}
else
{
try
{
#if _MSC_VER >= 1800
_M_TaskCollection._RunAndWait();
#else
_M_pTaskCollection->_RunAndWait();
#endif
}
catch (Concurrency::details::_Interruption_exception&)
{
_CONCRT_ASSERT(false);
}
catch (Concurrency::task_canceled&)
{
_CONCRT_ASSERT(_IsCanceled());
}
catch (IRestrictedErrorInfo*& _E)
{
if(!_HasUserException())
{
_CancelWithException(_E);
}
_M_exceptionHolder->_RethrowUserException();
}
catch (...)
{
if (!_HasUserException())
{
_CancelWithException(std::current_exception());
}
_M_exceptionHolder->_RethrowUserException();
}
if (_M_fUnwrappedTask)
{
#if _MSC_VER >= 1800
_M_TaskCollection._Wait();
#else
_M_Completed.wait();
#endif
}
}
}
if (_HasUserException())
{
_M_exceptionHolder->_RethrowUserException();
}
else if (_IsCanceled())
{
return Concurrency::canceled;
}
_CONCRT_ASSERT(_IsCompleted());
return Concurrency::completed;
}
virtual bool _CancelAndRunContinuations(bool _SynchronousCancel, bool _UserException, bool _PropagatedFromAncestor, const std::shared_ptr<_ExceptionHolder>& _ExHolder) = 0;
bool _Cancel(bool _SynchronousCancel)
{
return _CancelAndRunContinuations(_SynchronousCancel, false, false, _M_exceptionHolder);
}
bool _CancelWithExceptionHolder(const std::shared_ptr<_ExceptionHolder>& _ExHolder, bool _PropagatedFromAncestor)
{
return _CancelAndRunContinuations(true, true, _PropagatedFromAncestor, _ExHolder);
}
bool _CancelWithException(IRestrictedErrorInfo*& _Exception)
{
_CONCRT_ASSERT(!_HasUserException());
#if _MSC_VER >= 1800
return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationCallstack()));
#else
return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationAddressHint()));
#endif
}
bool _CancelWithException(const std::exception_ptr& _Exception)
{
_CONCRT_ASSERT(!_HasUserException());
#if _MSC_VER >= 1800
return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationCallstack()));
#else
return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationAddressHint()));
#endif
}
#if _MSC_VER >= 1800
void _RegisterCancellation(std::weak_ptr<_Task_impl_base> _WeakPtr)
#else
void _RegisterCancellation()
#endif
{
_CONCRT_ASSERT(Concurrency::details::_CancellationTokenState::_IsValid(_M_pTokenState));
#if _MSC_VER >= 1800
auto _CancellationCallback = [_WeakPtr](){
auto _task = _WeakPtr.lock();
if (_task != nullptr)
_task->_Cancel(false);
};
_M_pRegistration = new Concurrency::details::_CancellationTokenCallback<decltype(_CancellationCallback)>(_CancellationCallback);
_M_pTokenState->_RegisterCallback(_M_pRegistration);
#else
_M_pRegistration = _M_pTokenState->_RegisterCallback(reinterpret_cast<Concurrency::TaskProc>(&_CancelViaToken), (_Task_impl_base *)this);
#endif
}
void _DeregisterCancellation()
{
if (_M_pRegistration != nullptr)
{
_M_pTokenState->_DeregisterCallback(_M_pRegistration);
_M_pRegistration->_Release();
_M_pRegistration = nullptr;
}
}
#if _MSC_VER < 1800
static void _CancelViaToken(_Task_impl_base *_PImpl)
{
_PImpl->_Cancel(false);
}
#endif
bool _IsCreated()
{
return (_M_TaskState == _Created);
}
bool _IsStarted()
{
return (_M_TaskState == _Started);
}
bool _IsPendingCancel()
{
return (_M_TaskState == _PendingCancel);
}
bool _IsCompleted()
{
return (_M_TaskState == _Completed);
}
bool _IsCanceled()
{
return (_M_TaskState == _Canceled);
}
bool _HasUserException()
{
return static_cast<bool>(_M_exceptionHolder);
}
#if _MSC_VER < 1800
void _SetScheduledEvent()
{
_M_Scheduled.set();
}
#endif
const std::shared_ptr<_ExceptionHolder>& _GetExceptionHolder()
{
_CONCRT_ASSERT(_HasUserException());
return _M_exceptionHolder;
}
bool _IsApartmentAware()
{
return _M_fFromAsync;
}
void _SetAsync(bool _Async = true)
{
_M_fFromAsync = _Async;
}
#if _MSC_VER >= 1800
_TaskCreationCallstack _GetTaskCreationCallstack()
{
return _M_pTaskCreationCallstack;
}
void _SetTaskCreationCallstack(const _TaskCreationCallstack &_Callstack)
{
_M_pTaskCreationCallstack = _Callstack;
}
#else
void* _GetTaskCreationAddressHint()
{
return _M_pTaskCreationAddressHint;
}
void _SetTaskCreationAddressHint(void* _AddressHint)
{
_M_pTaskCreationAddressHint = _AddressHint;
}
#endif
void _ScheduleTask(_UnrealizedChore * _PTaskHandle, _TaskInliningMode _InliningMode)
{
#if _MSC_VER < 1800
_M_pTaskCollection = Concurrency::details::_AsyncTaskCollection::_NewCollection(Concurrency::details::_CancellationTokenState::_None());
#endif
try
{
#if _MSC_VER >= 1800
_M_TaskCollection._ScheduleTask(_PTaskHandle, _InliningMode);
#else
_M_pTaskCollection->_ScheduleWithAutoInline(_PTaskHandle, _InliningMode);
#endif
}
catch (const Concurrency::task_canceled &)
{
_CONCRT_ASSERT(_IsCanceled());
}
catch (const Concurrency::details::_Interruption_exception &)
{
_CONCRT_ASSERT(false);
}
catch (...)
{
_CONCRT_ASSERT(_HasUserException());
}
#if _MSC_VER < 1800
_SetScheduledEvent();
#endif
}
void _RunContinuation(_ContinuationTaskHandleBase * _PTaskHandle)
{
_Task_ptr_base _ImplBase = _PTaskHandle->_GetTaskImplBase();
if (_IsCanceled() && !_PTaskHandle->_M_isTaskBasedContinuation)
{
if (_HasUserException())
{
_ImplBase->_CancelWithExceptionHolder(_GetExceptionHolder(), true);
}
else
{
_ImplBase->_Cancel(true);
}
}
else
{
_CONCRT_ASSERT(_IsCompleted() || _PTaskHandle->_M_isTaskBasedContinuation);
#if _MSC_VER >= 1800
_CONCRT_ASSERT(!_ImplBase->_IsCanceled());
return _ImplBase->_ScheduleContinuationTask(_PTaskHandle);
#else
if (!_ImplBase->_IsCanceled())
{
return _ImplBase->_ScheduleContinuationTask(_PTaskHandle);
}
#endif
}
delete _PTaskHandle;
}
void _ScheduleContinuationTask(_ContinuationTaskHandleBase * _PTaskHandle)
{
#if _MSC_VER >= 1800
_M_taskEventLogger._LogScheduleTask(true);
#endif
if (_PTaskHandle->_M_continuationContext._HasCapturedContext())
{
if (_PTaskHandle->_M_inliningMode != Concurrency::details::_ForceInline)
{
_PTaskHandle->_M_inliningMode = Concurrency::details::_DefaultAutoInline;
}
details::_ScheduleFuncWithAutoInline([_PTaskHandle]() -> HRESULT {
auto _TaskImplPtr = _PTaskHandle->_GetTaskImplBase();
if (details::_ContextCallback::_CaptureCurrent() == _PTaskHandle->_M_continuationContext)
{
_TaskImplPtr->_ScheduleTask(_PTaskHandle, Concurrency::details::_ForceInline);
}
else
{
try
{
auto _PTaskHandle1 = _PTaskHandle;
_PTaskHandle->_M_continuationContext._CallInContext([_PTaskHandle1, _TaskImplPtr]() -> HRESULT {
_TaskImplPtr->_ScheduleTask(_PTaskHandle1, Concurrency::details::_ForceInline);
return S_OK;
});
}
catch (IRestrictedErrorInfo*& _E)
{
_TaskImplPtr->_CancelWithException(_E);
}
catch (...)
{
_TaskImplPtr->_CancelWithException(std::current_exception());
}
}
return S_OK;
}, _PTaskHandle->_M_inliningMode);
}
else
{
_ScheduleTask(_PTaskHandle, _PTaskHandle->_M_inliningMode);
}
}
void _ScheduleContinuation(_ContinuationTaskHandleBase * _PTaskHandle)
{
enum { _Nothing, _Schedule, _Cancel, _CancelWithException } _Do = _Nothing;
{
scoped_lock _LockHolder(_M_ContinuationsCritSec);
if (_IsCompleted() || (_IsCanceled() && _PTaskHandle->_M_isTaskBasedContinuation))
{
_Do = _Schedule;
}
else if (_IsCanceled())
{
if (_HasUserException())
{
_Do = _CancelWithException;
}
else
{
_Do = _Cancel;
}
}
else
{
_PTaskHandle->_M_next = _M_Continuations;
_M_Continuations = _PTaskHandle;
}
}
switch (_Do)
{
case _Schedule:
{
_PTaskHandle->_GetTaskImplBase()->_ScheduleContinuationTask(_PTaskHandle);
break;
}
case _Cancel:
{
_PTaskHandle->_GetTaskImplBase()->_Cancel(true);
delete _PTaskHandle;
break;
}
case _CancelWithException:
{
_PTaskHandle->_GetTaskImplBase()->_CancelWithExceptionHolder(_GetExceptionHolder(), true);
delete _PTaskHandle;
break;
}
case _Nothing:
default:
break;
}
}
void _RunTaskContinuations()
{
_ContinuationList _Cur = _M_Continuations, _Next;
_M_Continuations = nullptr;
while (_Cur)
{
_Next = _Cur->_M_next;
_RunContinuation(_Cur);
_Cur = _Next;
}
}
static bool _IsNonBlockingThread()
{
APTTYPE _AptType;
APTTYPEQUALIFIER _AptTypeQualifier;
HRESULT hr = CoGetApartmentType(&_AptType, &_AptTypeQualifier);
if (SUCCEEDED(hr))
{
switch (_AptType)
{
case APTTYPE_STA:
case APTTYPE_MAINSTA:
return true;
break;
case APTTYPE_NA:
switch (_AptTypeQualifier)
{
case APTTYPEQUALIFIER_NA_ON_STA:
case APTTYPEQUALIFIER_NA_ON_MAINSTA:
return true;
break;
}
break;
}
}
#if _UITHREADCTXT_SUPPORT
if (SUCCEEDED(CaptureUiThreadContext(nullptr)))
{
return true;
}
#endif
return false;
}
template<typename _ReturnType, typename _Result, typename _OpType, typename _CompHandlerType, typename _ResultType>
static void _AsyncInit(const typename _Task_ptr<_ReturnType>::_Type & _OuterTask,
_AsyncInfoImpl<_OpType, _CompHandlerType, _ResultType>* _AsyncOp)
{
typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_GetUnwrappedType(stdx::declval<_OpType*>()))>::type _Result_abi;
#if _MSC_VER < 1800
_CONCRT_ASSERT(((_OuterTask->_M_pTaskCollection == nullptr) || _OuterTask->_M_fUnwrappedTask) && !_OuterTask->_IsCanceled());
#endif
_AsyncOp->put_Completed(Microsoft::WRL::Callback<_CompHandlerType>(
[_OuterTask, _AsyncOp](_OpType* _Operation, ABI::Windows::Foundation::AsyncStatus _Status) mutable -> HRESULT
{
HRESULT hr = S_OK;
if (_Status == ABI::Windows::Foundation::AsyncStatus::Canceled)
{
_OuterTask->_Cancel(true);
}
else if (_Status == ABI::Windows::Foundation::AsyncStatus::Error)
{
HRESULT _hr;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo;
if (SUCCEEDED(hr = _Operation->QueryInterface<ABI::Windows::Foundation::IAsyncInfo>(pAsyncInfo.GetAddressOf())) && SUCCEEDED(hr = pAsyncInfo->get_ErrorCode(&_hr)))
_OuterTask->_CancelWithException(std::make_exception_ptr(_hr));
}
else
{
_CONCRT_ASSERT(_Status == ABI::Windows::Foundation::AsyncStatus::Completed);
_NormalizeVoidToUnitType<_Result_abi>::_Type results;
if (SUCCEEDED(hr = _AsyncOp->GetResults(&results)))
_OuterTask->_FinalizeAndRunContinuations(results);
}
const_cast<_Task_ptr<_ReturnType>::_Type &>(_OuterTask).reset();
return hr;
}).Get());
_OuterTask->_SetUnwrappedAsyncOp(_AsyncOp);
}
template<typename _ReturnType, typename _InternalReturnType>
static void _AsyncInit(const typename _Task_ptr<_ReturnType>::_Type& _OuterTask, const task<_InternalReturnType> & _UnwrappedTask)
{
_CONCRT_ASSERT(_OuterTask->_M_fUnwrappedTask && !_OuterTask->_IsCanceled());
_UnwrappedTask._Then([_OuterTask](task<_InternalReturnType> _AncestorTask) -> HRESULT {
if (_AncestorTask._GetImpl()->_IsCompleted())
{
_OuterTask->_FinalizeAndRunContinuations(_AncestorTask._GetImpl()->_GetResult());
}
else
{
_CONCRT_ASSERT(_AncestorTask._GetImpl()->_IsCanceled());
if (_AncestorTask._GetImpl()->_HasUserException())
{
_OuterTask->_CancelWithExceptionHolder(_AncestorTask._GetImpl()->_GetExceptionHolder(), false);
}
else
{
_OuterTask->_Cancel(true);
}
}
return S_OK;
#if _MSC_VER >= 1800
}, nullptr, Concurrency::details::_DefaultAutoInline);
#else
}, nullptr, false, Concurrency::details::_DefaultAutoInline);
#endif
}
#if _MSC_VER >= 1800
Concurrency::scheduler_ptr _GetScheduler() const
{
return _M_TaskCollection._GetScheduler();
}
#else
Concurrency::event _M_Completed;
Concurrency::event _M_Scheduled;
#endif
volatile _TaskInternalState _M_TaskState;
bool _M_fFromAsync;
#if _MSC_VER < 1800
bool _M_fRuntimeAggregate;
#endif
bool _M_fUnwrappedTask;
std::shared_ptr<_ExceptionHolder> _M_exceptionHolder;
typedef _ContinuationTaskHandleBase * _ContinuationList;
critical_section _M_ContinuationsCritSec;
_ContinuationList _M_Continuations;
Concurrency::details::_CancellationTokenState * _M_pTokenState;
Concurrency::details::_CancellationTokenRegistration * _M_pRegistration;
#if _MSC_VER >= 1800
Concurrency::details::_TaskCollection_t _M_TaskCollection;
_TaskCreationCallstack _M_pTaskCreationCallstack;
_TaskEventLogger _M_taskEventLogger;
#else
Concurrency::details::_AsyncTaskCollection * _M_pTaskCollection;
void* _M_pTaskCreationAddressHint;
#endif
private:
_Task_impl_base(const _Task_impl_base&);
_Task_impl_base const & operator=(_Task_impl_base const&);
};
#if _MSC_VER >= 1800
#if _PPLTASK_ASYNC_LOGGING
inline void _TaskEventLogger::_LogTaskCompleted()
{
if (_M_scheduled)
{
::Windows::Foundation::AsyncStatus _State;
if (_M_task->_IsCompleted())
_State = ::Windows::Foundation::AsyncStatus::Completed;
else if (_M_task->_HasUserException())
_State = ::Windows::Foundation::AsyncStatus::Error;
else
_State = ::Windows::Foundation::AsyncStatus::Canceled;
if (details::_IsCausalitySupported())
{
::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceOperationCompletion(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library,
_PPLTaskCausalityPlatformID, reinterpret_cast<unsigned long long>(_M_task), _State);
}
}
}
#endif
#endif
template<typename _ReturnType>
struct _Task_impl : public _Task_impl_base
{
typedef ABI::Windows::Foundation::IAsyncInfo _AsyncOperationType;
#if _MSC_VER >= 1800
_Task_impl(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler_arg)
: _Task_impl_base(_Ct, _Scheduler_arg)
#else
_Task_impl(Concurrency::details::_CancellationTokenState * _Ct) : _Task_impl_base(_Ct)
#endif
{
_M_unwrapped_async_op = nullptr;
}
virtual ~_Task_impl()
{
_DeregisterCancellation();
}
virtual bool _CancelAndRunContinuations(bool _SynchronousCancel, bool _UserException, bool _PropagatedFromAncestor, const std::shared_ptr<_ExceptionHolder> & _ExceptionHolder)
{
enum { _Nothing, _RunContinuations, _Cancel } _Do = _Nothing;
{
scoped_lock _LockHolder(_M_ContinuationsCritSec);
if (_UserException)
{
_CONCRT_ASSERT(_SynchronousCancel && !_IsCompleted());
_CONCRT_ASSERT(!_IsCanceled() || _PropagatedFromAncestor);
#if _MSC_VER < 1800
_CONCRT_ASSERT((!_IsStarted() && !_IsPendingCancel()) || !_PropagatedFromAncestor);
#endif
_CONCRT_ASSERT(!_HasUserException());
if (_M_TaskState == _Canceled)
{
return false;
}
else
{
_CONCRT_ASSERT(_M_TaskState != _Completed);
_M_exceptionHolder = _ExceptionHolder;
}
}
else
{
if (_IsCompleted() || _IsCanceled() || (_IsPendingCancel() && !_SynchronousCancel))
{
_CONCRT_ASSERT(!_IsCompleted() || !_HasUserException());
return false;
}
_CONCRT_ASSERT(!_SynchronousCancel || !_HasUserException());
}
#if _MSC_VER >= 1800
if (_SynchronousCancel)
#else
if (_SynchronousCancel || _IsCreated())
#endif
{
_M_TaskState = _Canceled;
#if _MSC_VER < 1800
_M_Scheduled.set();
#endif
_Do = _RunContinuations;
}
else
{
#if _MSC_VER >= 1800
_CONCRT_ASSERT(!_UserException);
if (_IsStarted())
{
_Do = _Cancel;
}
_M_TaskState = _PendingCancel;
_M_taskEventLogger._LogCancelTask();
}
}
switch (_Do)
{
case _Cancel:
{
#else
_CONCRT_ASSERT(_IsStarted() && !_UserException);
#endif
_M_TaskState = _PendingCancel;
if (_M_unwrapped_async_op != nullptr)
{
if (_M_unwrapped_async_op) _M_unwrapped_async_op->Cancel();
}
#if _MSC_VER >= 1800
_M_TaskCollection._Cancel();
break;
#else
if (_M_pTaskCollection != nullptr)
{
_M_pTaskCollection->_Cancel();
}
#endif
}
#if _MSC_VER < 1800
}
#endif
#if _MSC_VER >= 1800
case _RunContinuations:
{
_M_TaskCollection._Complete();
#else
if (_RunContinuations)
{
_M_Completed.set();
#endif
if (_M_Continuations)
{
details::_ScheduleFuncWithAutoInline([=]() -> HRESULT { _RunTaskContinuations(); return S_OK; }, Concurrency::details::_DefaultAutoInline);
}
#if _MSC_VER >= 1800
break;
}
#endif
}
return true;
}
void _FinalizeAndRunContinuations(_ReturnType _Result)
{
#if _MSC_VER >= 1800
_M_Result.Set(_Result);
#else
_M_Result = _Result;
_M_ResultContext = _ResultContext<_ReturnType>::_GetContext(_M_fRuntimeAggregate);
#endif
{
scoped_lock _LockHolder(_M_ContinuationsCritSec);
_CONCRT_ASSERT(!_HasUserException() && !_IsCompleted());
if (_IsCanceled())
{
return;
}
_M_TaskState = _Completed;
}
#if _MSC_VER >= 1800
_M_TaskCollection._Complete();
#else
_M_Completed.set();
#endif
_RunTaskContinuations();
}
bool _TransitionedToStarted()
{
scoped_lock _LockHolder(_M_ContinuationsCritSec);
#if _MSC_VER >= 1800
_ASSERT(!_IsCanceled());
if (_IsPendingCancel())
#else
if (_IsCanceled())
#endif
{
return false;
}
_CONCRT_ASSERT(_IsCreated());
_M_TaskState = _Started;
return true;
}
void _SetUnwrappedAsyncOp(_AsyncOperationType* _AsyncOp)
{
scoped_lock _LockHolder(_M_ContinuationsCritSec);
if (_IsPendingCancel())
{
_CONCRT_ASSERT(!_IsCanceled());
if (_AsyncOp) _AsyncOp->Cancel();
}
else
{
_M_unwrapped_async_op = _AsyncOp;
}
}
#if _MSC_VER >= 1800
bool _IsDone()
{
return _IsCompleted() || _IsCanceled();
}
#endif
_ReturnType _GetResult()
{
#if _MSC_VER >= 1800
return _M_Result.Get();
#else
return _ResultContext<_ReturnType>::_GetValue(_M_Result, _M_ResultContext, _M_fRuntimeAggregate);
#endif
}
#if _MSC_VER >= 1800
_ResultHolder<_ReturnType> _M_Result;
#else
_ReturnType _M_Result;
#endif
Microsoft::WRL::ComPtr<_AsyncOperationType> _M_unwrapped_async_op;
#if _MSC_VER < 1800
_ContextCallback _M_ResultContext;
#endif
};
template<typename _ResultType>
struct _Task_completion_event_impl
{
#if _MSC_VER >= 1800
private:
_Task_completion_event_impl(const _Task_completion_event_impl&);
_Task_completion_event_impl& operator=(const _Task_completion_event_impl&);
public:
#endif
typedef std::vector<typename _Task_ptr<_ResultType>::_Type> _TaskList;
_Task_completion_event_impl() : _M_fHasValue(false), _M_fIsCanceled(false)
{
}
bool _HasUserException()
{
return _M_exceptionHolder != nullptr;
}
~_Task_completion_event_impl()
{
for (auto _TaskIt = _M_tasks.begin(); _TaskIt != _M_tasks.end(); ++_TaskIt)
{
_CONCRT_ASSERT(!_M_fHasValue && !_M_fIsCanceled);
(*_TaskIt)->_Cancel(true);
}
}
_TaskList _M_tasks;
critical_section _M_taskListCritSec;
#if _MSC_VER >= 1800
_ResultHolder<_ResultType> _M_value;
#else
_ResultType _M_value;
#endif
std::shared_ptr<_ExceptionHolder> _M_exceptionHolder;
bool _M_fHasValue;
bool _M_fIsCanceled;
};
inline std::function<HRESULT(_Unit_type*)> _MakeVoidToUnitFunc(const std::function<HRESULT(void)>& _Func)
{
return [=](_Unit_type* retVal) -> HRESULT { HRESULT hr = _Func(); *retVal = _Unit_type(); return hr; };
}
template <typename _Type>
std::function<HRESULT(_Unit_type, _Type*)> _MakeUnitToTFunc(const std::function<HRESULT(_Type*)>& _Func)
{
return [=](_Unit_type, _Type* retVal) -> HRESULT { HRESULT hr = _Func(retVal); return hr; };
}
template <typename _Type>
std::function<HRESULT(_Type, _Unit_type*)> _MakeTToUnitFunc(const std::function<HRESULT(_Type)>& _Func)
{
return[=](_Type t, _Unit_type* retVal) -> HRESULT { HRESULT hr = _Func(t); *retVal = _Unit_type(); return hr; };
}
inline std::function<HRESULT(_Unit_type, _Unit_type*)> _MakeUnitToUnitFunc(const std::function<HRESULT(void)>& _Func)
{
return [=](_Unit_type, _Unit_type* retVal) -> HRESULT { HRESULT hr = _Func(); *retVal = _Unit_type(); return hr; };
}
}
template<typename _ResultType>
class task_completion_event
{
public:
task_completion_event() : _M_Impl(std::make_shared<details::_Task_completion_event_impl<_ResultType>>())
{
}
bool set(_ResultType _Result) const
{
if (_IsTriggered())
{
return false;
}
_TaskList _Tasks;
bool _RunContinuations = false;
{
details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
if (!_IsTriggered())
{
#if _MSC_VER >= 1800
_M_Impl->_M_value.Set(_Result);
#else
_M_Impl->_M_value = _Result;
#endif
_M_Impl->_M_fHasValue = true;
_Tasks.swap(_M_Impl->_M_tasks);
_RunContinuations = true;
}
}
if (_RunContinuations)
{
for (auto _TaskIt = _Tasks.begin(); _TaskIt != _Tasks.end(); ++_TaskIt)
{
#if _MSC_VER >= 1800
if ((*_TaskIt)->_IsPendingCancel())
(*_TaskIt)->_Cancel(true);
else
{
(*_TaskIt)->_FinalizeAndRunContinuations(_M_Impl->_M_value.Get());
}
#else
(*_TaskIt)->_FinalizeAndRunContinuations(_M_Impl->_M_value);
#endif
}
if (_M_Impl->_HasUserException())
{
_M_Impl->_M_exceptionHolder.reset();
}
return true;
}
return false;
}
#if _MSC_VER >= 1800
template<typename _E>
__declspec(noinline)
bool set_exception(_E _Except) const
{
return _Cancel(std::make_exception_ptr(_Except), _CAPTURE_CALLSTACK());
}
#endif
__declspec(noinline)
bool set_exception(std::exception_ptr _ExceptionPtr) const
{
#if _MSC_VER >= 1800
return _Cancel(_ExceptionPtr, _CAPTURE_CALLSTACK());
#else
return _Cancel(_ExceptionPtr, _ReturnAddress());
#endif
}
bool _Cancel() const
{
return _CancelInternal();
}
template<typename _ExHolderType>
#if _MSC_VER >= 1800
bool _Cancel(_ExHolderType _ExHolder, const details::_TaskCreationCallstack &_SetExceptionAddressHint = details::_TaskCreationCallstack()) const
#else
bool _Cancel(_ExHolderType _ExHolder, void* _SetExceptionAddressHint = nullptr) const
#endif
{
(void)_SetExceptionAddressHint;
bool _Canceled;
#if _MSC_VER >= 1800
if(_StoreException(_ExHolder, _SetExceptionAddressHint))
#else
if (_StoreException(_ExHolder))
#endif
{
_Canceled = _CancelInternal();
_CONCRT_ASSERT(_Canceled);
}
else
{
_Canceled = false;
}
return _Canceled;
}
template<typename _ExHolderType>
#if _MSC_VER >= 1800
bool _StoreException(_ExHolderType _ExHolder, const details::_TaskCreationCallstack &_SetExceptionAddressHint = details::_TaskCreationCallstack()) const
#else
bool _StoreException(_ExHolderType _ExHolder, void* _SetExceptionAddressHint = nullptr) const
#endif
{
details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
if (!_IsTriggered() && !_M_Impl->_HasUserException())
{
_M_Impl->_M_exceptionHolder = _ToExceptionHolder(_ExHolder, _SetExceptionAddressHint);
return true;
}
return false;
}
bool _IsTriggered() const
{
return _M_Impl->_M_fHasValue || _M_Impl->_M_fIsCanceled;
}
private:
#if _MSC_VER >= 1800
static std::shared_ptr<details::_ExceptionHolder> _ToExceptionHolder(const std::shared_ptr<details::_ExceptionHolder>& _ExHolder, const details::_TaskCreationCallstack&)
#else
static std::shared_ptr<details::_ExceptionHolder> _ToExceptionHolder(const std::shared_ptr<details::_ExceptionHolder>& _ExHolder, void*)
#endif
{
return _ExHolder;
}
#if _MSC_VER >= 1800
static std::shared_ptr<details::_ExceptionHolder> _ToExceptionHolder(std::exception_ptr _ExceptionPtr, const details::_TaskCreationCallstack &_SetExceptionAddressHint)
#else
static std::shared_ptr<details::_ExceptionHolder> _ToExceptionHolder(std::exception_ptr _ExceptionPtr, void* _SetExceptionAddressHint)
#endif
{
return std::make_shared<details::_ExceptionHolder>(_ExceptionPtr, _SetExceptionAddressHint);
}
template <typename T> friend class task;
template <typename T> friend class task_completion_event;
typedef typename details::_Task_completion_event_impl<_ResultType>::_TaskList _TaskList;
bool _CancelInternal() const
{
_CONCRT_ASSERT(!_M_Impl->_M_fHasValue);
if (_M_Impl->_M_fIsCanceled)
{
return false;
}
_TaskList _Tasks;
bool _Cancel = false;
{
details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
_CONCRT_ASSERT(!_M_Impl->_M_fHasValue);
if (!_M_Impl->_M_fIsCanceled)
{
_M_Impl->_M_fIsCanceled = true;
_Tasks.swap(_M_Impl->_M_tasks);
_Cancel = true;
}
}
bool _UserException = _M_Impl->_HasUserException();
if (_Cancel)
{
for (auto _TaskIt = _Tasks.begin(); _TaskIt != _Tasks.end(); ++_TaskIt)
{
if (_UserException)
{
(*_TaskIt)->_CancelWithExceptionHolder(_M_Impl->_M_exceptionHolder, true);
}
else
{
(*_TaskIt)->_Cancel(true);
}
}
}
return _Cancel;
}
void _RegisterTask(const typename details::_Task_ptr<_ResultType>::_Type & _TaskParam)
{
details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec);
#if _MSC_VER < 1800
_TaskParam->_SetScheduledEvent();
#endif
if (_M_Impl->_HasUserException())
{
_TaskParam->_CancelWithExceptionHolder(_M_Impl->_M_exceptionHolder, true);
}
else if (_M_Impl->_M_fHasValue)
{
#if _MSC_VER >= 1800
_TaskParam->_FinalizeAndRunContinuations(_M_Impl->_M_value.Get());
#else
_TaskParam->_FinalizeAndRunContinuations(_M_Impl->_M_value);
#endif
}
else
{
_M_Impl->_M_tasks.push_back(_TaskParam);
}
}
std::shared_ptr<details::_Task_completion_event_impl<_ResultType>> _M_Impl;
};
template<>
class task_completion_event<void>
{
public:
bool set() const
{
return _M_unitEvent.set(details::_Unit_type());
}
#if _MSC_VER >= 1800
template<typename _E>
__declspec(noinline)
bool set_exception(_E _Except) const
{
return _M_unitEvent._Cancel(std::make_exception_ptr(_Except), _CAPTURE_CALLSTACK());
}
#endif
__declspec(noinline)
bool set_exception(std::exception_ptr _ExceptionPtr) const
{
#if _MSC_VER >= 1800
return _M_unitEvent._Cancel(_ExceptionPtr, _CAPTURE_CALLSTACK());
#else
return _M_unitEvent._Cancel(_ExceptionPtr, _ReturnAddress());
#endif
}
void _Cancel() const
{
_M_unitEvent._Cancel();
}
void _Cancel(const std::shared_ptr<details::_ExceptionHolder>& _ExHolder) const
{
_M_unitEvent._Cancel(_ExHolder);
}
bool _StoreException(const std::shared_ptr<details::_ExceptionHolder>& _ExHolder) const
{
return _M_unitEvent._StoreException(_ExHolder);
}
bool _IsTriggered() const
{
return _M_unitEvent._IsTriggered();
}
private:
template <typename T> friend class task;
void _RegisterTask(details::_Task_ptr<details::_Unit_type>::_Type _TaskParam)
{
_M_unitEvent._RegisterTask(_TaskParam);
}
task_completion_event<details::_Unit_type> _M_unitEvent;
};
namespace details
{
template<typename _ReturnType, typename _Ty>
auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, int, int, int) -> typename decltype(_Param(), std::true_type());
template<typename _ReturnType, typename _Ty>
auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, int, int, ...) -> typename decltype(_Param(stdx::declval<task<_ReturnType>*>()), std::true_type());
template<typename _ReturnType, typename _Ty>
auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, int, ...) -> typename decltype(_Param(stdx::declval<_ReturnType*>()), std::true_type());
template<typename _ReturnType, typename _Ty>
auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, ...) -> typename decltype(_Param->GetResults(), std::true_type());
template<typename _ReturnType, typename _Ty>
auto _IsValidTaskCtor(_Ty _Param, int, int, int, ...) -> typename decltype(_Param->GetResults(stdx::declval<decltype(_GetUnwrappedType(stdx::declval<_Ty>()))*>()), std::true_type());
template<typename _ReturnType, typename _Ty>
auto _IsValidTaskCtor(_Ty _Param, int, int, ...) -> typename decltype(_Param.set(stdx::declval<_ReturnType>()), std::true_type());
template<typename _ReturnType, typename _Ty>
auto _IsValidTaskCtor(_Ty _Param, int, ...) -> typename decltype(_Param.set(), std::true_type());
template<typename _ReturnType, typename _Ty>
std::false_type _IsValidTaskCtor(_Ty _Param, ...);
template<typename _ReturnType, typename _Ty>
void _ValidateTaskConstructorArgs(_Ty _Param)
{
(void)_Param;
static_assert(std::is_same<decltype(details::_IsValidTaskCtor<_ReturnType>(_Param, 0, 0, 0, 0, 0, 0, 0)), std::true_type>::value,
"incorrect argument for task constructor; can be a callable object, an asynchronous operation, or a task_completion_event"
);
static_assert(!(std::is_same<_Ty, _ReturnType>::value && details::_IsIAsyncInfo<_Ty>::_Value),
"incorrect template argument for task; consider using the return type of the async operation");
}
template<typename _ReturnType, typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, int, int, int) -> typename decltype(_Param(), std::true_type());
template<typename _ReturnType, typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, int, int, ...) -> typename decltype(_Param(stdx::declval<_ReturnType*>()), std::true_type());
template<typename _ReturnType, typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, int, ...) -> typename decltype(_Param(Concurrency::cancellation_token::none()), std::true_type());
template<typename _ReturnType, typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, ...) -> typename decltype(_Param(Concurrency::cancellation_token::none(), stdx::declval<_ReturnType*>()), std::true_type());
template<typename _ReturnType, typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType()), std::true_type());
template<typename _ReturnType, typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), stdx::declval<_ReturnType*>()), std::true_type());
template<typename _ReturnType, typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), Concurrency::cancellation_token::none()), std::true_type());
template<typename _ReturnType, typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), Concurrency::cancellation_token::none(), stdx::declval<_ReturnType*>()), std::true_type());
template<typename _ReturnType, typename _Ty>
static std::false_type _IsValidCreateAsync(_Ty _Param, ...);
}
template<typename _ReturnType>
class task
{
public:
typedef _ReturnType result_type;
task() : _M_Impl(nullptr)
{
}
template<typename _Ty>
__declspec(noinline)
explicit task(_Ty _Param)
{
#if _MSC_VER >= 1800
task_options _TaskOptions;
#endif
details::_ValidateTaskConstructorArgs<_ReturnType, _Ty>(_Param);
#if _MSC_VER >= 1800
_CreateImpl(_TaskOptions.get_cancellation_token()._GetImplValue(), _TaskOptions.get_scheduler());
#else
_CreateImpl(Concurrency::cancellation_token::none()._GetImplValue());
#endif
#if _MSC_VER >= 1800
_SetTaskCreationCallstack(_CAPTURE_CALLSTACK());
#else
_SetTaskCreationAddressHint(_ReturnAddress());
#endif
_TaskInitMaybeFunctor(_Param, details::_IsCallable<_ReturnType>(_Param, 0, 0, 0));
}
template<typename _Ty>
__declspec(noinline)
#if _MSC_VER >= 1800
explicit task(_Ty _Param, const task_options &_TaskOptions)
#else
explicit task(_Ty _Param, Concurrency::cancellation_token _Token)
#endif
{
details::_ValidateTaskConstructorArgs<_ReturnType, _Ty>(_Param);
#if _MSC_VER >= 1800
_CreateImpl(_TaskOptions.get_cancellation_token()._GetImplValue(), _TaskOptions.get_scheduler());
#else
_CreateImpl(_Token._GetImplValue());
#endif
#if _MSC_VER >= 1800
_SetTaskCreationCallstack(details::_get_internal_task_options(_TaskOptions)._M_hasPresetCreationCallstack ? details::_get_internal_task_options(_TaskOptions)._M_presetCreationCallstack : _CAPTURE_CALLSTACK());
#else
_SetTaskCreationAddressHint(_ReturnAddress());
#endif
_TaskInitMaybeFunctor(_Param, details::_IsCallable<_ReturnType>(_Param, 0, 0, 0));
}
task(const task& _Other) : _M_Impl(_Other._M_Impl) {}
task(task&& _Other) : _M_Impl(std::move(_Other._M_Impl)) {}
task& operator=(const task& _Other)
{
if (this != &_Other)
{
_M_Impl = _Other._M_Impl;
}
return *this;
}
task& operator=(task&& _Other)
{
if (this != &_Other)
{
_M_Impl = std::move(_Other._M_Impl);
}
return *this;
}
template<typename _Function>
__declspec(noinline)
auto then(const _Function& _Func) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
{
#if _MSC_VER >= 1800
task_options _TaskOptions;
details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
#else
auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, nullptr, task_continuation_context::use_default());
_ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
return _ContinuationTask;
#endif
}
template<typename _Function>
__declspec(noinline)
#if _MSC_VER >= 1800
auto then(const _Function& _Func, task_options _TaskOptions) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
#else
auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
#endif
{
#if _MSC_VER >= 1800
details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
#else
auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, _CancellationToken._GetImplValue(), task_continuation_context::use_default());
_ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
return _ContinuationTask;
#endif
}
#if _MSC_VER < 1800
template<typename _Function>
__declspec(noinline)
auto then(const _Function& _Func, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
{
auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, nullptr, _ContinuationContext);
_ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
return _ContinuationTask;
}
#endif
template<typename _Function>
__declspec(noinline)
auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
{
#if _MSC_VER >= 1800
task_options _TaskOptions(_CancellationToken, _ContinuationContext);
details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
#else
auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, _CancellationToken._GetImplValue(), _ContinuationContext);
_ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
return _ContinuationTask;
#endif
}
task_status wait() const
{
if (_M_Impl == nullptr)
{
throw Concurrency::invalid_operation("wait() cannot be called on a default constructed task.");
}
return _M_Impl->_Wait();
}
_ReturnType get() const
{
if (_M_Impl == nullptr)
{
throw Concurrency::invalid_operation("get() cannot be called on a default constructed task.");
}
if (_M_Impl->_Wait() == Concurrency::canceled)
{
throw Concurrency::task_canceled();
}
return _M_Impl->_GetResult();
}
#if _MSC_VER >= 1800
bool is_done() const
{
if (!_M_Impl)
{
throw Concurrency::invalid_operation("is_done() cannot be called on a default constructed task.");
}
return _M_Impl->_IsDone();
}
Concurrency::scheduler_ptr scheduler() const
{
if (!_M_Impl)
{
throw Concurrency::invalid_operation("scheduler() cannot be called on a default constructed task.");
}
return _M_Impl->_GetScheduler();
}
#endif
bool is_apartment_aware() const
{
if (_M_Impl == nullptr)
{
throw Concurrency::invalid_operation("is_apartment_aware() cannot be called on a default constructed task.");
}
return _M_Impl->_IsApartmentAware();
}
bool operator==(const task<_ReturnType>& _Rhs) const
{
return (_M_Impl == _Rhs._M_Impl);
}
bool operator!=(const task<_ReturnType>& _Rhs) const
{
return !operator==(_Rhs);
}
#if _MSC_VER >= 1800
void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler)
#else
void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct)
#endif
{
_CONCRT_ASSERT(_Ct != nullptr);
#if _MSC_VER >= 1800
_M_Impl = details::_Task_ptr<_ReturnType>::_Make(_Ct, _Scheduler);
#else
_M_Impl = details::_Task_ptr<_ReturnType>::_Make(_Ct);
#endif
if (_Ct != Concurrency::details::_CancellationTokenState::_None())
{
#if _MSC_VER >= 1800
_M_Impl->_RegisterCancellation(_M_Impl);
#else
_M_Impl->_RegisterCancellation();
#endif
}
}
const typename details::_Task_ptr<_ReturnType>::_Type & _GetImpl() const
{
return _M_Impl;
}
void _SetImpl(const typename details::_Task_ptr<_ReturnType>::_Type & _Impl)
{
_CONCRT_ASSERT(_M_Impl == nullptr);
_M_Impl = _Impl;
}
void _SetImpl(typename details::_Task_ptr<_ReturnType>::_Type && _Impl)
{
_CONCRT_ASSERT(_M_Impl == nullptr);
_M_Impl = std::move(_Impl);
}
void _SetAsync(bool _Async = true)
{
_GetImpl()->_SetAsync(_Async);
}
#if _MSC_VER >= 1800
void _SetTaskCreationCallstack(const details::_TaskCreationCallstack &_callstack)
{
_GetImpl()->_SetTaskCreationCallstack(_callstack);
}
#else
void _SetTaskCreationAddressHint(void* _Address)
{
_GetImpl()->_SetTaskCreationAddressHint(_Address);
}
#endif
template<typename _Function>
#if _MSC_VER >= 1800
auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState,
details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
{
auto _Scheduler = _GetImpl()->_GetScheduler();
return _ThenImpl<_ReturnType, _Function>(_Func, _PTokenState, task_continuation_context::use_default(), _Scheduler, _CAPTURE_CALLSTACK(), _InliningMode);
}
#else
auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, bool _Aggregating,
details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType
{
return _ThenImpl<_ReturnType, _Function>(_Func, _PTokenState, task_continuation_context::use_default(), _Aggregating, _InliningMode);
}
#endif
private:
template <typename T> friend class task;
template<typename _RetType>
class _Init_func_transformer
{
public:
static auto _Perform(std::function<HRESULT(_RetType*)> _Func) -> decltype(_Func)
{
return _Func;
}
};
template<>
class _Init_func_transformer<void>
{
public:
static auto _Perform(std::function<HRESULT(void)> _Func) -> decltype(details::_MakeVoidToUnitFunc(_Func))
{
return details::_MakeVoidToUnitFunc(_Func);
}
};
template <typename _InternalReturnType, typename _Function, typename _TypeSelection>
struct _InitialTaskHandle :
details::_PPLTaskHandle<_ReturnType, _InitialTaskHandle<_InternalReturnType, _Function, _TypeSelection>, details::_UnrealizedChore>
{
_Function _M_function;
_InitialTaskHandle(const typename details::_Task_ptr<_ReturnType>::_Type & _TaskImpl, const _Function & _Function) : _M_function(_Function), _PPLTaskHandle(_TaskImpl)
{
}
virtual ~_InitialTaskHandle() {}
#if _MSC_VER >= 1800
template <typename _Func, typename _RetArg>
auto _LogWorkItemAndInvokeUserLambda(_Func && _func, _RetArg && _retArg) const -> decltype(_func(std::forward<_RetArg>(_retArg)))
{
details::_TaskWorkItemRAIILogger _LogWorkItem(this->_M_pTask->_M_taskEventLogger);
return _func(std::forward<_RetArg>(_retArg));
}
#endif
void _Perform() const
{
_Init(_TypeSelection());
}
#if _MSC_VER >= 1800
void _SyncCancelAndPropagateException() const
{
this->_M_pTask->_Cancel(true);
}
#endif
void _Init(details::_TypeSelectorNoAsync) const
{
_ReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Init_func_transformer<_InternalReturnType>::_Perform(_M_function), &retVal);
#else
HRESULT hr = _Init_func_transformer<_InternalReturnType>::_Perform(_M_function)(&retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
_M_pTask->_FinalizeAndRunContinuations(retVal);
}
void _Init(details::_TypeSelectorAsyncTask) const
{
task<_InternalReturnType> retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal);
#else
HRESULT hr = _M_function(&retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, retVal);
}
void _Init(details::_TypeSelectorAsyncOperation) const
{
_ReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal);
#else
HRESULT hr = _M_function(&retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask,
Microsoft::WRL::Make<details::_IAsyncOperationToAsyncOperationConverter<_InternalReturnType>>(retVal).Get());
}
void _Init(details::_TypeSelectorAsyncAction) const
{
_ReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal);
#else
HRESULT hr = _M_function(&retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(retVal).Get());
}
void _Init(details::_TypeSelectorAsyncOperationWithProgress) const
{
typedef details::_GetProgressType<decltype(_M_function())>::_Value _ProgressType;
_ReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal);
#else
HRESULT hr = _M_function(&retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask,
Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_InternalReturnType, _ProgressType>>(retVal).Get());
}
void _Init(details::_TypeSelectorAsyncActionWithProgress) const
{
typedef details::_GetProgressType<decltype(_M_function())>::_Value _ProgressType;
_ReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal);
#else
HRESULT hr = _M_function(&retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask,
Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>>(retVal).Get());
}
};
template<typename _InpType, typename _OutType>
class _Continuation_func_transformer
{
public:
static auto _Perform(std::function<HRESULT(_InpType, _OutType*)> _Func) -> decltype(_Func)
{
return _Func;
}
};
template<typename _OutType>
class _Continuation_func_transformer<void, _OutType>
{
public:
static auto _Perform(std::function<HRESULT(_OutType*)> _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<HRESULT(_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<HRESULT(void)> _Func) -> decltype(details::_MakeUnitToUnitFunc(_Func))
{
return details::_MakeUnitToUnitFunc(_Func);
}
};
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) :
#if _MSC_VER >= 1800
details::_PPLTaskHandle<typename details::_NormalizeVoidToUnitType<_ContinuationReturnType>::_Type,
_ContinuationTaskHandle<_InternalReturnType, _ContinuationReturnType, _Function, _IsTaskBased, _TypeSelection>, details::_ContinuationTaskHandleBase>
::_PPLTaskHandle(_ContinuationImpl)
, _M_ancestorTaskImpl(_AncestorImpl)
, _M_function(_Func)
#else
_M_ancestorTaskImpl(_AncestorImpl), _PPLTaskHandle(_ContinuationImpl), _M_function(_Func)
#endif
{
_M_isTaskBasedContinuation = _IsTaskBased::value;
_M_continuationContext = _Context;
_M_continuationContext._Resolve(_AncestorImpl->_IsApartmentAware());
_M_inliningMode = _InliningMode;
}
virtual ~_ContinuationTaskHandle() {}
#if _MSC_VER >= 1800
template <typename _Func, typename _Arg, typename _RetArg>
auto _LogWorkItemAndInvokeUserLambda(_Func && _func, _Arg && _value, _RetArg && _retArg) const -> decltype(_func(std::forward<_Arg>(_value), std::forward<_RetArg>(_retArg)))
{
details::_TaskWorkItemRAIILogger _LogWorkItem(this->_M_pTask->_M_taskEventLogger);
return _func(std::forward<_Arg>(_value), std::forward<_RetArg>(_retArg));
}
#endif
void _Perform() const
{
_Continue(_IsTaskBased(), _TypeSelection());
}
#if _MSC_VER >= 1800
void _SyncCancelAndPropagateException() const
{
if (_M_ancestorTaskImpl->_HasUserException())
{
this->_M_pTask->_CancelWithExceptionHolder(_M_ancestorTaskImpl->_GetExceptionHolder(), true);
}
else
{
this->_M_pTask->_Cancel(true);
}
}
#endif
void _Continue(std::false_type, details::_TypeSelectorNoAsync) const
{
_NormalizedContinuationReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _ContinuationReturnType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal);
#else
HRESULT hr =_Continuation_func_transformer<_InternalReturnType, _ContinuationReturnType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
_M_pTask->_FinalizeAndRunContinuations(retVal);
}
void _Continue(std::false_type, details::_TypeSelectorAsyncTask) const
{
typedef typename details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;
_FuncOutputType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal);
#else
HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(
_M_pTask,
retVal
);
}
void _Continue(std::false_type, details::_TypeSelectorAsyncOperation) const
{
typedef typename details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;
_FuncOutputType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal);
#else
HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(
_M_pTask,
Microsoft::WRL::Make<details::_IAsyncOperationToAsyncOperationConverter<_ContinuationReturnType>>(retVal).Get());
}
void _Continue(std::false_type, details::_TypeSelectorAsyncAction) const
{
typedef details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;
_FuncOutputType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal);
#else
HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(
_M_pTask,
Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(
retVal).Get());
}
void _Continue(std::false_type, details::_TypeSelectorAsyncOperationWithProgress) const
{
typedef details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;
_FuncOutputType _OpWithProgress;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &_OpWithProgress);
#else
HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &_OpWithProgress);
#endif
typedef details::_GetProgressType<decltype(_OpWithProgress)>::_Value _ProgressType;
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(
_M_pTask,
Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_ContinuationReturnType, _ProgressType>>(_OpWithProgress).Get());
}
void _Continue(std::false_type, details::_TypeSelectorAsyncActionWithProgress) const
{
typedef details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;
_FuncOutputType _OpWithProgress;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &_OpWithProgress);
#else
HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &_OpWithProgress);
#endif
typedef details::_GetProgressType<decltype(_OpWithProgress)>::_Value _ProgressType;
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(
_M_pTask,
Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>>(_OpWithProgress).Get());
}
void _Continue(std::true_type, details::_TypeSelectorNoAsync) const
{
typedef task<_InternalReturnType> _FuncInputType;
task<_InternalReturnType> _ResultTask;
_ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
_NormalizedContinuationReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_FuncInputType, _ContinuationReturnType>::_Perform(_M_function), std::move(_ResultTask), &retVal);
#else
HRESULT hr = _Continuation_func_transformer<_FuncInputType, _ContinuationReturnType>::_Perform(_M_function)(std::move(_ResultTask), &retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
_M_pTask->_FinalizeAndRunContinuations(retVal);
}
void _Continue(std::true_type, details::_TypeSelectorAsyncTask) const
{
task<_InternalReturnType> _ResultTask;
_ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
_ContinuationReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal);
#else
HRESULT hr = _M_function(std::move(_ResultTask), &retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask, retVal);
}
void _Continue(std::true_type, details::_TypeSelectorAsyncOperation) const
{
task<_InternalReturnType> _ResultTask;
_ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
_ContinuationReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal);
#else
HRESULT hr = _M_function(std::move(_ResultTask), &retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask,
Microsoft::WRL::Make<details::_IAsyncOperationToAsyncOperationConverter<_ContinuationReturnType>>(retVal));
}
void _Continue(std::true_type, details::_TypeSelectorAsyncAction) const
{
task<_InternalReturnType> _ResultTask;
_ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
_ContinuationReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal);
#else
HRESULT hr = _M_function(std::move(_ResultTask), &retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask,
Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(retVal));
}
void _Continue(std::true_type, details::_TypeSelectorAsyncOperationWithProgress) const
{
task<_InternalReturnType> _ResultTask;
_ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
typedef details::_GetProgressType<decltype(_M_function(_ResultTask))>::_Value _ProgressType;
_ContinuationReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal);
#else
HRESULT hr = _M_function(std::move(_ResultTask), &retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask,
Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_ContinuationReturnType, _ProgressType>>(retVal));
}
void _Continue(std::true_type, details::_TypeSelectorAsyncActionWithProgress) const
{
task<_InternalReturnType> _ResultTask;
_ResultTask._SetImpl(std::move(_M_ancestorTaskImpl));
typedef details::_GetProgressType<decltype(_M_function(_ResultTask))>::_Value _ProgressType;
_ContinuationReturnType retVal;
#if _MSC_VER >= 1800
HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal);
#else
HRESULT hr = _M_function(std::move(_ResultTask), &retVal);
#endif
if (FAILED(hr)) throw std::make_exception_ptr(hr);
details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask,
Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>>(retVal));
}
};
template<typename _InternalReturnType, typename _Function>
void _TaskInitWithFunctor(const _Function& _Func)
{
typedef details::_InitFunctorTypeTraits<_InternalReturnType, details::_FunctionTypeTraits<_Function, void>::_FuncRetType> _Async_type_traits;
_M_Impl->_M_fFromAsync = _Async_type_traits::_IsAsyncTask;
_M_Impl->_M_fUnwrappedTask = _Async_type_traits::_IsUnwrappedTaskOrAsync;
#if _MSC_VER >= 1800
_M_Impl->_M_taskEventLogger._LogScheduleTask(false);
#endif
_M_Impl->_ScheduleTask(new _InitialTaskHandle<_InternalReturnType, _Function, typename _Async_type_traits::_AsyncKind>(_GetImpl(), _Func), Concurrency::details::_NoInline);
}
void _TaskInitNoFunctor(task_completion_event<_ReturnType>& _Event)
{
_Event._RegisterTask(_M_Impl);
}
template<typename _Result, typename _OpType, typename _CompHandlerType, typename _ResultType>
void _TaskInitAsyncOp(details::_AsyncInfoImpl<_OpType, _CompHandlerType, _ResultType>* _AsyncOp)
{
_M_Impl->_M_fFromAsync = true;
#if _MSC_VER < 1800
_M_Impl->_SetScheduledEvent();
#endif
_M_Impl->_M_TaskState = details::_Task_impl_base::_Started;
details::_Task_impl_base::_AsyncInit<_ReturnType, _Result>(_M_Impl, _AsyncOp);
}
template<typename _Result>
void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncOperation<_Result>* _AsyncOp)
{
_TaskInitAsyncOp<_Result>(Microsoft::WRL::Make<details::_IAsyncOperationToAsyncOperationConverter<_Result>>(_AsyncOp).Get());
}
template<typename _Result, typename _Progress>
void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>* _AsyncOp)
{
_TaskInitAsyncOp<_Result>(Microsoft::WRL::Make<details::_IAsyncOperationWithProgressToAsyncOperationConverter<_Result, _Progress>>(_AsyncOp).Get());
}
template<typename _Function>
void _TaskInitMaybeFunctor(_Function & _Func, std::true_type)
{
_TaskInitWithFunctor<_ReturnType, _Function>(_Func);
}
template<typename _Ty>
void _TaskInitMaybeFunctor(_Ty & _Param, std::false_type)
{
_TaskInitNoFunctor(_Param);
}
#if _MSC_VER >= 1800
template<typename _InternalReturnType, typename _Function>
auto _ThenImpl(const _Function& _Func, const task_options& _TaskOptions) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
{
if (!_M_Impl)
{
throw Concurrency::invalid_operation("then() cannot be called on a default constructed task.");
}
Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
auto _Scheduler = _TaskOptions.has_scheduler() ? _TaskOptions.get_scheduler() : _GetImpl()->_GetScheduler();
auto _CreationStack = details::_get_internal_task_options(_TaskOptions)._M_hasPresetCreationCallstack ? details::_get_internal_task_options(_TaskOptions)._M_presetCreationCallstack : details::_TaskCreationCallstack();
return _ThenImpl<_InternalReturnType, _Function>(_Func, _PTokenState, _TaskOptions.get_continuation_context(), _Scheduler, _CreationStack);
}
#endif
template<typename _InternalReturnType, typename _Function>
#if _MSC_VER >= 1800
auto _ThenImpl(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, const task_continuation_context& _ContinuationContext, Concurrency::scheduler_ptr _Scheduler, details::_TaskCreationCallstack _CreationStack,
details::_TaskInliningMode _InliningMode = Concurrency::details::_NoInline) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
#else
auto _ThenImpl(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, const task_continuation_context& _ContinuationContext,
bool _Aggregating = false, details::_TaskInliningMode _InliningMode = Concurrency::details::_NoInline) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType
#endif
{
if (_M_Impl == nullptr)
{
throw Concurrency::invalid_operation("then() cannot be called on a default constructed task.");
}
typedef details::_FunctionTypeTraits<_Function, _InternalReturnType> _Function_type_traits;
typedef details::_TaskTypeTraits<typename _Function_type_traits::_FuncRetType> _Async_type_traits;
typedef typename _Async_type_traits::_TaskRetType _TaskType;
if (_PTokenState == nullptr)
{
#if _MSC_VER >= 1800
if (_Function_type_traits::_Takes_task::value)
#else
if (_Function_type_traits::_Takes_task())
#endif
{
_PTokenState = Concurrency::details::_CancellationTokenState::_None();
}
else
{
_PTokenState = _GetImpl()->_M_pTokenState;
}
}
task<_TaskType> _ContinuationTask;
#if _MSC_VER >= 1800
_ContinuationTask._CreateImpl(_PTokenState, _Scheduler);
#else
_ContinuationTask._CreateImpl(_PTokenState);
#endif
_ContinuationTask._GetImpl()->_M_fFromAsync = (_GetImpl()->_M_fFromAsync || _Async_type_traits::_IsAsyncTask);
#if _MSC_VER < 1800
_ContinuationTask._GetImpl()->_M_fRuntimeAggregate = _Aggregating;
#endif
_ContinuationTask._GetImpl()->_M_fUnwrappedTask = _Async_type_traits::_IsUnwrappedTaskOrAsync;
#if _MSC_VER >= 1800
_ContinuationTask._SetTaskCreationCallstack(_CreationStack);
#endif
_GetImpl()->_ScheduleContinuation(new _ContinuationTaskHandle<_InternalReturnType, _TaskType, _Function, typename _Function_type_traits::_Takes_task, typename _Async_type_traits::_AsyncKind>(
_GetImpl(), _ContinuationTask._GetImpl(), _Func, _ContinuationContext, _InliningMode));
return _ContinuationTask;
}
typename details::_Task_ptr<_ReturnType>::_Type _M_Impl;
};
template<>
class task<void>
{
public:
typedef void result_type;
task() : _M_unitTask()
{
}
#if _MSC_VER < 1800
template<typename _Ty>
__declspec(noinline)
explicit task(_Ty _Param)
{
details::_ValidateTaskConstructorArgs<void, _Ty>(_Param);
_M_unitTask._CreateImpl(Concurrency::cancellation_token::none()._GetImplValue());
_M_unitTask._SetTaskCreationAddressHint(_ReturnAddress());
_TaskInitMaybeFunctor(_Param, details::_IsCallable<void>(_Param, 0, 0, 0));
}
#endif
template<typename _Ty>
__declspec(noinline)
#if _MSC_VER >= 1800
explicit task(_Ty _Param, const task_options& _TaskOptions = task_options())
#else
explicit task(_Ty _Param, Concurrency::cancellation_token _CancellationToken)
#endif
{
details::_ValidateTaskConstructorArgs<void, _Ty>(_Param);
#if _MSC_VER >= 1800
_M_unitTask._CreateImpl(_TaskOptions.get_cancellation_token()._GetImplValue(), _TaskOptions.get_scheduler());
#else
_M_unitTask._CreateImpl(_CancellationToken._GetImplValue());
#endif
#if _MSC_VER >= 1800
_M_unitTask._SetTaskCreationCallstack(details::_get_internal_task_options(_TaskOptions)._M_hasPresetCreationCallstack ? details::_get_internal_task_options(_TaskOptions)._M_presetCreationCallstack : _CAPTURE_CALLSTACK());
#else
_M_unitTask._SetTaskCreationAddressHint(_ReturnAddress());
#endif
_TaskInitMaybeFunctor(_Param, details::_IsCallable<void>(_Param, 0, 0, 0));
}
task(const task& _Other) : _M_unitTask(_Other._M_unitTask){}
task(task&& _Other) : _M_unitTask(std::move(_Other._M_unitTask)) {}
task& operator=(const task& _Other)
{
if (this != &_Other)
{
_M_unitTask = _Other._M_unitTask;
}
return *this;
}
task& operator=(task&& _Other)
{
if (this != &_Other)
{
_M_unitTask = std::move(_Other._M_unitTask);
}
return *this;
}
#if _MSC_VER < 1800
template<typename _Function>
__declspec(noinline)
auto then(const _Function& _Func) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
{
auto _ContinuationTask = _M_unitTask._ThenImpl<void, _Function>(_Func, nullptr, task_continuation_context::use_default());
_ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
return _ContinuationTask;
}
#endif
template<typename _Function>
__declspec(noinline)
#if _MSC_VER >= 1800
auto then(const _Function& _Func, task_options _TaskOptions = task_options()) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
{
details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
return _M_unitTask._ThenImpl<void, _Function>(_Func, _TaskOptions);
}
#else
auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
{
auto _ContinuationTask = _M_unitTask._ThenImpl<void, _Function>(_Func, _CancellationToken._GetImplValue(), task_continuation_context::use_default());
_ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
return _ContinuationTask;
}
template<typename _Function>
__declspec(noinline)
auto then(const _Function& _Func, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
{
auto _ContinuationTask = _M_unitTask._ThenImpl<void, _Function>(_Func, nullptr, _ContinuationContext);
_ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
return _ContinuationTask;
}
#endif
template<typename _Function>
__declspec(noinline)
#if _MSC_VER >= 1800
auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
{
task_options _TaskOptions(_CancellationToken, _ContinuationContext);
details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
return _M_unitTask._ThenImpl<void, _Function>(_Func, _TaskOptions);
}
#else
auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
{
auto _ContinuationTask = _M_unitTask._ThenImpl<void, _Function>(_Func, _CancellationToken._GetImplValue(), _ContinuationContext);
_ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress());
return _ContinuationTask;
}
#endif
task_status wait() const
{
return _M_unitTask.wait();
}
void get() const
{
_M_unitTask.get();
}
#if _MSC_VER >= 1800
bool is_done() const
{
return _M_unitTask.is_done();
}
Concurrency::scheduler_ptr scheduler() const
{
return _M_unitTask.scheduler();
}
#endif
bool is_apartment_aware() const
{
return _M_unitTask.is_apartment_aware();
}
bool operator==(const task<void>& _Rhs) const
{
return (_M_unitTask == _Rhs._M_unitTask);
}
bool operator!=(const task<void>& _Rhs) const
{
return !operator==(_Rhs);
}
#if _MSC_VER >= 1800
void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler)
{
_M_unitTask._CreateImpl(_Ct, _Scheduler);
}
#else
void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct)
{
_M_unitTask._CreateImpl(_Ct);
}
#endif
const details::_Task_ptr<details::_Unit_type>::_Type & _GetImpl() const
{
return _M_unitTask._M_Impl;
}
void _SetImpl(const details::_Task_ptr<details::_Unit_type>::_Type & _Impl)
{
_M_unitTask._SetImpl(_Impl);
}
void _SetImpl(details::_Task_ptr<details::_Unit_type>::_Type && _Impl)
{
_M_unitTask._SetImpl(std::move(_Impl));
}
void _SetAsync(bool _Async = true)
{
_M_unitTask._SetAsync(_Async);
}
#if _MSC_VER >= 1800
void _SetTaskCreationCallstack(const details::_TaskCreationCallstack &_callstack)
{
_M_unitTask._SetTaskCreationCallstack(_callstack);
}
#else
void _SetTaskCreationAddressHint(void* _Address)
{
_M_unitTask._SetTaskCreationAddressHint(_Address);
}
#endif
template<typename _Function>
#if _MSC_VER >= 1800
auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState,
details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
{
auto _Scheduler = _GetImpl()->_GetScheduler();
return _M_unitTask._ThenImpl<void, _Function>(_Func, _PTokenState, task_continuation_context::use_default(), _Scheduler, _CAPTURE_CALLSTACK(), _InliningMode);
}
#else
auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState,
bool _Aggregating, details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType
{
return _M_unitTask._ThenImpl<void, _Function>(_Func, _PTokenState, task_continuation_context::use_default(), _Aggregating, _InliningMode);
}
#endif
private:
template <typename T> friend class task;
template <typename T> friend class task_completion_event;
void _TaskInitNoFunctor(task_completion_event<void>& _Event)
{
_M_unitTask._TaskInitNoFunctor(_Event._M_unitEvent);
}
void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncAction* _AsyncAction)
{
_M_unitTask._TaskInitAsyncOp<details::_Unit_type>(Microsoft::WRL::Make<details::_IAsyncActionToAsyncOperationConverter>(_AsyncAction).Get());
}
template<typename _P>
void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncActionWithProgress<_P>* _AsyncActionWithProgress)
{
_M_unitTask._TaskInitAsyncOp<details::_Unit_type>(Microsoft::WRL::Make<details::_IAsyncActionWithProgressToAsyncOperationConverter<_P>>(_AsyncActionWithProgress).Get());
}
template<typename _Function>
void _TaskInitMaybeFunctor(_Function & _Func, std::true_type)
{
_M_unitTask._TaskInitWithFunctor<void, _Function>(_Func);
}
template<typename _T>
void _TaskInitMaybeFunctor(_T & _Param, std::false_type)
{
_TaskInitNoFunctor(_Param);
}
task<details::_Unit_type> _M_unitTask;
};
namespace details
{
template<typename _Ty>
_Ty _GetUnwrappedType(task<_Ty>);
template<typename _Ty>
auto _GetUnwrappedReturnType(_Ty _Arg, int) -> decltype(_GetUnwrappedType(_Arg));
template<typename _Ty>
_Ty _GetUnwrappedReturnType(_Ty, ...);
template<typename _Ty>
_Ty _GetTaskType(task_completion_event<_Ty>, std::false_type);
template<typename _Ty>
auto _GetTaskType(_Ty _NonFunc, std::false_type) -> decltype(_GetUnwrappedType(_NonFunc));
template<typename _Ty>
auto _GetTaskType(_Ty _Func, std::true_type) -> decltype(_GetUnwrappedReturnType(stdx::declval<_FunctionTypeTraits<_Ty, void>::_FuncRetType>(), 0));
void _GetTaskType(std::function<HRESULT()>, std::true_type);
struct _BadArgType{};
template<typename _ReturnType, typename _Ty>
auto _FilterValidTaskType(_Ty _Param, int) -> decltype(_GetTaskType(_Param, _IsCallable<_ReturnType>(_Param, 0, 0, 0)));
template<typename _ReturnType, typename _Ty>
_BadArgType _FilterValidTaskType(_Ty _Param, ...);
template<typename _ReturnType, typename _Ty>
struct _TaskTypeFromParam
{
typedef decltype(_FilterValidTaskType<_ReturnType>(stdx::declval<_Ty>(), 0)) _Type;
};
}
template<typename _ReturnType, typename _Ty>
__declspec(noinline)
#if _MSC_VER >= 1800
auto create_task(_Ty _Param, task_options _TaskOptions = task_options()) -> task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type>
#else
auto create_task(_Ty _Param) -> task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type>
#endif
{
static_assert(!std::is_same<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type, details::_BadArgType>::value,
"incorrect argument for create_task; can be a callable object, an asynchronous operation, or a task_completion_event"
);
#if _MSC_VER >= 1800
details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK());
task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type> _CreatedTask(_Param, _TaskOptions);
#else
task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type> _CreatedTask(_Param);
_CreatedTask._SetTaskCreationAddressHint(_ReturnAddress());
#endif
return _CreatedTask;
}
#if _MSC_VER >= 1800
template<typename _ReturnType>
__declspec(noinline)
task<_ReturnType> create_task(const task<_ReturnType>& _Task)
{
task<_ReturnType> _CreatedTask(_Task);
return _CreatedTask;
}
#else
template<typename _ReturnType, typename _Ty>
__declspec(noinline)
auto create_task(_Ty _Param, Concurrency::cancellation_token _Token) -> task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type>
{
static_assert(!std::is_same<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type, details::_BadArgType>::value,
"incorrect argument for create_task; can be a callable object, an asynchronous operation, or a task_completion_event"
);
task<typename details::_TaskTypeFromParam<_ReturnType, _Ty>::_Type> _CreatedTask(_Param, _Token);
_CreatedTask._SetTaskCreationAddressHint(_ReturnAddress());
return _CreatedTask;
}
#endif
namespace details
{
template<typename _T>
task<typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperation<_T>*>()))>::type> _To_task_helper(ABI::Windows::Foundation::IAsyncOperation<_T>* op)
{
return task<_T>(op);
}
template<typename _T, typename _Progress>
task<typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressSelector(stdx::declval<ABI::Windows::Foundation::IAsyncOperationWithProgress<_T, _Progress>*>()))>::type> _To_task_helper(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T, _Progress>* op)
{
return task<_T>(op);
}
inline task<void> _To_task_helper(ABI::Windows::Foundation::IAsyncAction* op)
{
return task<void>(op);
}
template<typename _Progress>
task<void> _To_task_helper(ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>* op)
{
return task<void>(op);
}
template<typename _ProgressType>
class _ProgressDispatcherBase
{
public:
virtual ~_ProgressDispatcherBase()
{
}
virtual void _Report(const _ProgressType& _Val) = 0;
};
template<typename _ProgressType, typename _ClassPtrType>
class _ProgressDispatcher : public _ProgressDispatcherBase<_ProgressType>
{
public:
virtual ~_ProgressDispatcher()
{
}
_ProgressDispatcher(_ClassPtrType _Ptr) : _M_ptr(_Ptr)
{
}
virtual void _Report(const _ProgressType& _Val)
{
_M_ptr->_FireProgress(_Val);
}
private:
_ClassPtrType _M_ptr;
};
}
template<typename _ProgressType>
class progress_reporter
{
typedef std::shared_ptr<details::_ProgressDispatcherBase<_ProgressType>> _PtrType;
public:
void report(const _ProgressType& _Val) const
{
_M_dispatcher->_Report(_Val);
}
template<typename _ClassPtrType>
static progress_reporter _CreateReporter(_ClassPtrType _Ptr)
{
progress_reporter _Reporter;
details::_ProgressDispatcherBase<_ProgressType> *_PDispatcher = new details::_ProgressDispatcher<_ProgressType, _ClassPtrType>(_Ptr);
_Reporter._M_dispatcher = _PtrType(_PDispatcher);
return _Reporter;
}
progress_reporter() {}
private:
progress_reporter(details::_ProgressReporterCtorArgType);
_PtrType _M_dispatcher;
};
namespace details
{
enum _AsyncStatusInternal
{
_AsyncCreated = -1,
_AsyncStarted = ABI::Windows::Foundation::AsyncStatus::Started,
_AsyncCompleted = ABI::Windows::Foundation::AsyncStatus::Completed,
_AsyncCanceled = ABI::Windows::Foundation::AsyncStatus::Canceled,
_AsyncError = ABI::Windows::Foundation::AsyncStatus::Error,
_AsyncCancelPending,
_AsyncClosed,
_AsyncUndefined
};
enum _AsyncResultType
{
SingleResult = 0x0001,
MultipleResults = 0x0002
};
template<typename _T>
struct _ProgressTypeTraits
{
static const bool _TakesProgress = false;
typedef void _ProgressType;
};
template<typename _T>
struct _ProgressTypeTraits<progress_reporter<_T>>
{
static const bool _TakesProgress = true;
typedef typename _T _ProgressType;
};
template<typename _T, bool bTakesToken = std::is_same<_T, Concurrency::cancellation_token>::value, bool bTakesProgress = _ProgressTypeTraits<_T>::_TakesProgress>
struct _TokenTypeTraits
{
static const bool _TakesToken = false;
typedef typename _T _ReturnType;
};
template<typename _T>
struct _TokenTypeTraits<_T, false, true>
{
static const bool _TakesToken = false;
typedef void _ReturnType;
};
template<typename _T>
struct _TokenTypeTraits<_T, true, false>
{
static const bool _TakesToken = true;
typedef void _ReturnType;
};
template<typename _T, size_t count = _FunctorTypeTraits<_T>::_ArgumentCount>
struct _CAFunctorOptions
{
static const bool _TakesProgress = false;
static const bool _TakesToken = false;
typedef void _ProgressType;
typedef void _ReturnType;
};
template<typename _T>
struct _CAFunctorOptions<_T, 1>
{
private:
typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type;
public:
static const bool _TakesProgress = _ProgressTypeTraits<_Argument1Type>::_TakesProgress;
static const bool _TakesToken = _TokenTypeTraits<_Argument1Type>::_TakesToken;
typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType;
typedef typename _TokenTypeTraits<_Argument1Type>::_ReturnType _ReturnType;
};
template<typename _T>
struct _CAFunctorOptions<_T, 2>
{
private:
typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type;
typedef typename _FunctorTypeTraits<_T>::_Argument2Type _Argument2Type;
public:
static const bool _TakesProgress = _ProgressTypeTraits<_Argument1Type>::_TakesProgress;
static const bool _TakesToken = !_TakesProgress ? true : _TokenTypeTraits<_Argument2Type>::_TakesToken;
typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType;
typedef typename _TokenTypeTraits<_Argument2Type>::_ReturnType _ReturnType;
};
template<typename _T>
struct _CAFunctorOptions<_T, 3>
{
private:
typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type;
public:
static const bool _TakesProgress = true;
static const bool _TakesToken = true;
typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType;
typedef typename _FunctorTypeTraits<_T>::_Argument3Type _ReturnType;
};
class _Zip
{
};
template<typename _AsyncSelector, typename _ReturnType>
struct _SelectorTaskGenerator
{
#if _MSC_VER >= 1800
template<typename _Function>
static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<_ReturnType>(_Func(_pRet), _taskOptinos);
}
template<typename _Function>
static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<_ReturnType>(_Func(_Cts.get_token(), _pRet), _taskOptinos);
}
template<typename _Function, typename _ProgressObject>
static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<_ReturnType>(_Func(_Progress, _pRet), _taskOptinos);
}
template<typename _Function, typename _ProgressObject>
static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<_ReturnType>(_Func(_Progress, _Cts.get_token(), _pRet), _taskOptinos);
}
#else
template<typename _Function>
static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return task<_ReturnType>(_Func(_pRet), _Cts.get_token());
}
template<typename _Function>
static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return task<_ReturnType>(_Func(_Cts.get_token(), _pRet), _Cts.get_token());
}
template<typename _Function, typename _ProgressObject>
static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return task<_ReturnType>(_Func(_Progress, _pRet), _Cts.get_token());
}
template<typename _Function, typename _ProgressObject>
static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return task<_ReturnType>(_Func(_Progress, _Cts.get_token(), _pRet), _Cts.get_token());
}
#endif
};
template<typename _AsyncSelector>
struct _SelectorTaskGenerator<_AsyncSelector, void>
{
#if _MSC_VER >= 1800
template<typename _Function>
static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<void>(_Func(), _taskOptinos);
}
template<typename _Function>
static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<void>(_Func(_Cts.get_token()), _taskOptinos);
}
template<typename _Function, typename _ProgressObject>
static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<void>(_Func(_Progress), _taskOptinos);
}
template<typename _Function, typename _ProgressObject>
static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<void>(_Func(_Progress, _Cts.get_token()), _taskOptinos);
}
#else
template<typename _Function>
static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
{
return task<void>(_Func(), _Cts.get_token());
}
template<typename _Function>
static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
{
return task<void>(_Func(_Cts.get_token()), _Cts.get_token());
}
template<typename _Function, typename _ProgressObject>
static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
{
return task<void>(_Func(_Progress), _Cts.get_token());
}
template<typename _Function, typename _ProgressObject>
static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
{
return task<void>(_Func(_Progress, _Cts.get_token()), _Cts.get_token());
}
#endif
};
#if _MSC_VER < 1800
struct _Task_generator_oversubscriber
{
_Task_generator_oversubscriber()
{
Concurrency::details::_Context::_Oversubscribe(true);
}
~_Task_generator_oversubscriber()
{
Concurrency::details::_Context::_Oversubscribe(false);
}
};
#endif
template<typename _ReturnType>
struct _SelectorTaskGenerator<details::_TypeSelectorNoAsync, _ReturnType>
{
#if _MSC_VER >= 1800
#pragma warning(push)
#pragma warning(disable: 4702)
template<typename _Function>
static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
(_Oversubscriber);
HRESULT hr = _Func(_pRet);
retVal = _pRet;
return hr;
}, _taskOptinos);
}
#pragma warning(pop)
template<typename _Function>
static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
(_Oversubscriber);
HRESULT hr = _Func(_Cts.get_token(), _pRet);
retVal = _pRet;
return hr;
}, _taskOptinos);
}
template<typename _Function, typename _ProgressObject>
static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
(_Oversubscriber);
HRESULT hr = _Func(_Progress, _pRet);
retVal = _pRet;
return hr;
}, _taskOptinos);
}
template<typename _Function, typename _ProgressObject>
static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
(_Oversubscriber);
HRESULT hr = _Func(_Progress, _Cts.get_token(), _pRet);
retVal = _pRet;
return hr;
}, _taskOptinos);
}
#else
template<typename _Function>
static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
_Task_generator_oversubscriber _Oversubscriber;
HRESULT hr = _Func(_pRet);
retVal = _pRet;
return hr;
}, _Cts.get_token());
}
template<typename _Function>
static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
_Task_generator_oversubscriber _Oversubscriber;
HRESULT hr = _Func(_Cts.get_token(), _pRet);
retVal = _pRet;
return hr;
}, _Cts.get_token());
}
template<typename _Function, typename _ProgressObject>
static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
_Task_generator_oversubscriber _Oversubscriber;
HRESULT hr = _Func(_Progress, _pRet);
retVal = _pRet;
return hr;
}, _Cts.get_token());
}
template<typename _Function, typename _ProgressObject>
static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT {
_Task_generator_oversubscriber _Oversubscriber;
HRESULT hr = _Func(_Progress, _Cts.get_token(), _pRet);
retVal = _pRet;
return hr;
}, _Cts.get_token());
}
#endif
};
template<>
struct _SelectorTaskGenerator<details::_TypeSelectorNoAsync, void>
{
#if _MSC_VER >= 1800
template<typename _Function>
static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<void>([=]() -> HRESULT {
Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
(_Oversubscriber);
return _Func();
}, _taskOptinos);
}
template<typename _Function>
static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<void>([=]() -> HRESULT {
Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
(_Oversubscriber);
return _Func(_Cts.get_token());
}, _taskOptinos);
}
template<typename _Function, typename _ProgressObject>
static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<void>([=]() -> HRESULT {
Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
(_Oversubscriber);
return _Func(_Progress);
}, _taskOptinos);
}
template<typename _Function, typename _ProgressObject>
static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
{
task_options _taskOptinos(_Cts.get_token());
details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack);
return task<void>([=]() -> HRESULT {
Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber;
(_Oversubscriber);
return _Func(_Progress, _Cts.get_token());
}, _taskOptinos);
}
#else
template<typename _Function>
static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
{
return task<void>([=]() -> HRESULT {
_Task_generator_oversubscriber _Oversubscriber;
return _Func();
}, _Cts.get_token());
}
template<typename _Function>
static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
{
return task<void>([=]() -> HRESULT {
_Task_generator_oversubscriber _Oversubscriber;
return _Func(_Cts.get_token());
}, _Cts.get_token());
}
template<typename _Function, typename _ProgressObject>
static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
{
return task<void>([=]() -> HRESULT {
_Task_generator_oversubscriber _Oversubscriber;
return _Func(_Progress);
}, _Cts.get_token());
}
template<typename _Function, typename _ProgressObject>
static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
{
return task<void>([=]() -> HRESULT {
_Task_generator_oversubscriber _Oversubscriber;
return _Func(_Progress, _Cts.get_token());
}, _Cts.get_token());
}
#endif
};
template<typename _ReturnType>
struct _SelectorTaskGenerator<details::_TypeSelectorAsyncTask, _ReturnType>
{
template<typename _Function>
#if _MSC_VER >= 1800
static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
#else
static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
#endif
{
task<_ReturnType> _task;
_Func(&_task);
return _task;
}
template<typename _Function>
#if _MSC_VER >= 1800
static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
#else
static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
#endif
{
task<_ReturnType> _task;
_Func(_Cts.get_token(), &_task);
return _task;
}
template<typename _Function, typename _ProgressObject>
#if _MSC_VER >= 1800
static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
#else
static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
#endif
{
task<_ReturnType> _task;
_Func(_Progress, &_task);
return _task;
}
template<typename _Function, typename _ProgressObject>
#if _MSC_VER >= 1800
static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
#else
static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
#endif
{
task<_ReturnType> _task;
_Func(_Progress, _Cts.get_token(), &_task);
return _task;
}
};
template<>
struct _SelectorTaskGenerator<details::_TypeSelectorAsyncTask, void>
{
template<typename _Function>
#if _MSC_VER >= 1800
static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
#else
static task<void> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
#endif
{
task<void> _task;
_Func(&_task);
return _task;
}
template<typename _Function>
#if _MSC_VER >= 1800
static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
#else
static task<void> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts)
#endif
{
task<void> _task;
_Func(_Cts.get_token(), &_task);
return _task;
}
template<typename _Function, typename _ProgressObject>
#if _MSC_VER >= 1800
static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
#else
static task<void> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
#endif
{
task<void> _task;
_Func(_Progress, &_task);
return _task;
}
template<typename _Function, typename _ProgressObject>
#if _MSC_VER >= 1800
static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
#else
static task<void> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts)
#endif
{
task<void> _task;
_Func(_Progress, _Cts.get_token(), &_task);
return _task;
}
};
template<typename _Generator, bool _TakesToken, bool TakesProgress>
struct _TaskGenerator
{
};
template<typename _Generator>
struct _TaskGenerator<_Generator, false, false>
{
#if _MSC_VER >= 1800
template<typename _Function, typename _ClassPtr, typename _ProgressType>
static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack))
{
(void)_Ptr;
return _Generator::_GenerateTask_0(_Func, _Cts, _callstack);
}
template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack))
{
return _Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack);
}
#else
template<typename _Function, typename _ClassPtr, typename _ProgressType>
static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
{
(void)_Ptr;
return _Generator::_GenerateTask_0(_Func, _Cts);
}
template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
{
return _Generator::_GenerateTask_0(_Func, _Cts, _pRet);
}
#endif
};
template<typename _Generator>
struct _TaskGenerator<_Generator, true, false>
{
#if _MSC_VER >= 1800
template<typename _Function, typename _ClassPtr, typename _ProgressType>
static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack))
{
return _Generator::_GenerateTask_1C(_Func, _Cts, _callstack);
}
template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack))
{
return _Generator::_GenerateTask_1C(_Func, _Cts, _pRet, _callstack);
}
#else
template<typename _Function, typename _ClassPtr, typename _ProgressType>
static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
{
return _Generator::_GenerateTask_1C(_Func, _Cts);
}
template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
{
return _Generator::_GenerateTask_1C(_Func, _Cts, _pRet);
}
#endif
};
template<typename _Generator>
struct _TaskGenerator<_Generator, false, true>
{
#if _MSC_VER >= 1800
template<typename _Function, typename _ClassPtr, typename _ProgressType>
static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack))
{
return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _callstack);
}
template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack))
{
return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet, _callstack);
}
#else
template<typename _Function, typename _ClassPtr, typename _ProgressType>
static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
{
return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts);
}
template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
{
return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet);
}
#endif
};
template<typename _Generator>
struct _TaskGenerator<_Generator, true, true>
{
#if _MSC_VER >= 1800
template<typename _Function, typename _ClassPtr, typename _ProgressType>
static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack))
{
return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _callstack);
}
template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack))
{
return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet, _callstack);
}
#else
template<typename _Function, typename _ClassPtr, typename _ProgressType>
static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts))
{
return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts);
}
template<typename _Function, typename _ClassPtr, typename _ProgressType, typename _ReturnType>
static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
-> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet))
{
return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet);
}
#endif
};
template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits, bool _TakesToken, bool _TakesProgress>
struct _AsyncAttributes
{
};
template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits, bool _TakesToken>
struct _AsyncAttributes<_Function, _ProgressType, _ReturnType, _TaskTraits, _TakesToken, true>
{
typedef typename ABI::Windows::Foundation::IAsyncOperationWithProgress<_ReturnType, _ProgressType> _AsyncBaseType;
typedef typename ABI::Windows::Foundation::IAsyncOperationProgressHandler<_ReturnType, _ProgressType> _ProgressDelegateType;
typedef typename ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<_ReturnType, _ProgressType> _CompletionDelegateType;
typedef typename _ReturnType _ReturnType;
typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressSelector(stdx::declval<_AsyncBaseType*>()))>::type _ReturnType_abi;
typedef typename _ProgressType _ProgressType;
typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationWithProgressProgressSelector(stdx::declval<_AsyncBaseType*>()))>::type _ProgressType_abi;
typedef typename _TaskTraits::_AsyncKind _AsyncKind;
typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, true> _TaskGenerator;
static const bool _TakesProgress = true;
static const bool _TakesToken = _TakesToken;
template<typename _Function, typename _ClassPtr>
#if _MSC_VER >= 1800
static task<typename _TaskTraits::_TaskRetType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi, _ReturnType>(_Func, _Ptr, _Cts, _pRet, _callstack);
}
#else
static task<typename _TaskTraits::_TaskRetType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi, _ReturnType>(_Func, _Ptr, _Cts, _pRet);
}
#endif
};
template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits, bool _TakesToken>
struct _AsyncAttributes<_Function, _ProgressType, _ReturnType, _TaskTraits, _TakesToken, false>
{
typedef typename ABI::Windows::Foundation::IAsyncOperation<_ReturnType> _AsyncBaseType;
typedef _Zip _ProgressDelegateType;
typedef typename ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_ReturnType> _CompletionDelegateType;
typedef typename _ReturnType _ReturnType;
typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncOperationSelector(stdx::declval<_AsyncBaseType*>()))>::type _ReturnType_abi;
typedef typename _TaskTraits::_AsyncKind _AsyncKind;
typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, false> _TaskGenerator;
static const bool _TakesProgress = false;
static const bool _TakesToken = _TakesToken;
template<typename _Function, typename _ClassPtr>
#if _MSC_VER >= 1800
static task<typename _TaskTraits::_TaskRetType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType, _ReturnType>(_Func, _Ptr, _Cts, _pRet, _callstack);
}
#else
static task<typename _TaskTraits::_TaskRetType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType, _ReturnType>(_Func, _Ptr, _Cts, _pRet);
}
#endif
};
template<typename _Function, typename _ProgressType, typename _TaskTraits, bool _TakesToken>
struct _AsyncAttributes<_Function, _ProgressType, void, _TaskTraits, _TakesToken, true>
{
typedef typename ABI::Windows::Foundation::IAsyncActionWithProgress<_ProgressType> _AsyncBaseType;
typedef typename ABI::Windows::Foundation::IAsyncActionProgressHandler<_ProgressType> _ProgressDelegateType;
typedef typename ABI::Windows::Foundation::IAsyncActionWithProgressCompletedHandler<_ProgressType> _CompletionDelegateType;
typedef void _ReturnType;
typedef void _ReturnType_abi;
typedef typename _ProgressType _ProgressType;
typedef typename ABI::Windows::Foundation::Internal::GetAbiType<decltype(_UnwrapAsyncActionWithProgressSelector(stdx::declval<_AsyncBaseType*>()))>::type _ProgressType_abi;
typedef typename _TaskTraits::_AsyncKind _AsyncKind;
typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, true> _TaskGenerator;
static const bool _TakesProgress = true;
static const bool _TakesToken = _TakesToken;
#if _MSC_VER >= 1800
template<typename _Function, typename _ClassPtr>
static task<void> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
{
return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts, _callstack);
}
template<typename _Function, typename _ClassPtr>
static task<task<void>> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts, _pRet, _callstack);
}
#else
template<typename _Function, typename _ClassPtr>
static task<void> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
{
return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts);
}
template<typename _Function, typename _ClassPtr>
static task<task<void>> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts, _pRet);
}
#endif
};
template<typename _Function, typename _ProgressType, typename _TaskTraits, bool _TakesToken>
struct _AsyncAttributes<_Function, _ProgressType, void, _TaskTraits, _TakesToken, false>
{
typedef typename ABI::Windows::Foundation::IAsyncAction _AsyncBaseType;
typedef _Zip _ProgressDelegateType;
typedef typename ABI::Windows::Foundation::IAsyncActionCompletedHandler _CompletionDelegateType;
typedef void _ReturnType;
typedef void _ReturnType_abi;
typedef typename _TaskTraits::_AsyncKind _AsyncKind;
typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator;
typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, false> _TaskGenerator;
static const bool _TakesProgress = false;
static const bool _TakesToken = _TakesToken;
#if _MSC_VER >= 1800
template<typename _Function, typename _ClassPtr>
static task<void> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack)
{
return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts, _callstack);
}
template<typename _Function, typename _ClassPtr>
static task<task<void>> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack)
{
return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts, _pRet, _callstack);
}
#else
template<typename _Function, typename _ClassPtr>
static task<void> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts)
{
return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts);
}
template<typename _Function, typename _ClassPtr>
static task<task<void>> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet)
{
return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts, _pRet);
}
#endif
};
template<typename _Function>
struct _AsyncLambdaTypeTraits
{
typedef typename _Unhat<typename _CAFunctorOptions<_Function>::_ReturnType>::_Value _ReturnType;
typedef typename _FunctorTypeTraits<_Function>::_Argument1Type _Argument1Type;
typedef typename _CAFunctorOptions<_Function>::_ProgressType _ProgressType;
static const bool _TakesProgress = _CAFunctorOptions<_Function>::_TakesProgress;
static const bool _TakesToken = _CAFunctorOptions<_Function>::_TakesToken;
typedef typename _TaskTypeTraits<_ReturnType> _TaskTraits;
typedef typename _AsyncAttributes<_Function, _ProgressType, typename _TaskTraits::_TaskRetType, _TaskTraits, _TakesToken, _TakesProgress> _AsyncAttributes;
};
#ifndef RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoBase_DEFINED
#define RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoBase_DEFINED
extern const __declspec(selectany) WCHAR RuntimeClass_Concurrency_winrt_details__AsyncInfoBase[] = L"Concurrency_winrt.details._AsyncInfoBase";
#endif
template < typename _Attributes, _AsyncResultType resultType = SingleResult >
class _AsyncInfoBase abstract : public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRt>, Microsoft::WRL::Implements<typename _Attributes::_AsyncBaseType, ABI::Windows::Foundation::IAsyncInfo>>
{
InspectableClass(RuntimeClass_Concurrency_winrt_details__AsyncInfoBase, BaseTrust)
public:
_AsyncInfoBase() :
_M_currentStatus(_AsyncStatusInternal::_AsyncCreated),
_M_errorCode(S_OK),
_M_completeDelegate(nullptr),
_M_CompleteDelegateAssigned(0),
_M_CallbackMade(0)
{
#if _MSC_VER < 1800
_M_id = Concurrency::details::_GetNextAsyncId();
#else
_M_id = Concurrency::details::platform::GetNextAsyncId();
#endif
}
public:
virtual STDMETHODIMP GetResults(typename _Attributes::_ReturnType_abi* results)
{
(void)results;
return E_UNEXPECTED;
}
virtual STDMETHODIMP get_Id(unsigned int* id)
{
HRESULT hr = _CheckValidStateForAsyncInfoCall();
if (FAILED(hr)) return hr;
if (!id) return E_POINTER;
*id = _M_id;
return S_OK;
}
virtual STDMETHODIMP put_Id(unsigned int id)
{
HRESULT hr = _CheckValidStateForAsyncInfoCall();
if (FAILED(hr)) return hr;
if (id == 0)
{
return E_INVALIDARG;
}
else if (_M_currentStatus != _AsyncStatusInternal::_AsyncCreated)
{
return E_ILLEGAL_METHOD_CALL;
}
_M_id = id;
return S_OK;
}
virtual STDMETHODIMP get_Status(ABI::Windows::Foundation::AsyncStatus* status)
{
HRESULT hr = _CheckValidStateForAsyncInfoCall();
if (FAILED(hr)) return hr;
if (!status) return E_POINTER;
_AsyncStatusInternal _Current = _M_currentStatus;
switch (_Current)
{
case _AsyncCancelPending:
_Current = _AsyncCanceled;
break;
case _AsyncCreated:
_Current = _AsyncStarted;
break;
default:
break;
}
*status = static_cast<ABI::Windows::Foundation::AsyncStatus>(_Current);
return S_OK;
}
virtual STDMETHODIMP get_ErrorCode(HRESULT* errorCode)
{
HRESULT hr = _CheckValidStateForAsyncInfoCall();
if (FAILED(hr)) return hr;
if (!hr) return hr;
*errorCode = _M_errorCode;
return S_OK;
}
virtual STDMETHODIMP get_Progress(typename _Attributes::_ProgressDelegateType** _ProgressHandler)
{
return _GetOnProgress(_ProgressHandler);
}
virtual STDMETHODIMP put_Progress(typename _Attributes::_ProgressDelegateType* _ProgressHandler)
{
return _PutOnProgress(_ProgressHandler);
}
virtual STDMETHODIMP Cancel()
{
if (_TransitionToState(_AsyncCancelPending))
{
_OnCancel();
}
return S_OK;
}
virtual STDMETHODIMP Close()
{
if (_TransitionToState(_AsyncClosed))
{
_OnClose();
}
else
{
if (_M_currentStatus != _AsyncClosed)
{
return E_ILLEGAL_STATE_CHANGE;
}
}
return S_OK;
}
virtual STDMETHODIMP get_Completed(typename _Attributes::_CompletionDelegateType** _CompleteHandler)
{
_CheckValidStateForDelegateCall();
if (!_CompleteHandler) return E_POINTER;
*_CompleteHandler = _M_completeDelegate.Get();
return S_OK;
}
virtual STDMETHODIMP put_Completed(typename _Attributes::_CompletionDelegateType* _CompleteHandler)
{
_CheckValidStateForDelegateCall();
if (InterlockedIncrement(&_M_CompleteDelegateAssigned) == 1)
{
_M_completeDelegateContext = _ContextCallback::_CaptureCurrent();
_M_completeDelegate = _CompleteHandler;
MemoryBarrier();
if (_IsTerminalState())
{
_FireCompletion();
}
}
else
{
return E_ILLEGAL_DELEGATE_ASSIGNMENT;
}
return S_OK;
}
protected:
STDMETHODIMP _Start()
{
if (_TransitionToState(_AsyncStarted))
{
_OnStart();
}
else
{
return E_ILLEGAL_STATE_CHANGE;
}
return S_OK;
}
HRESULT _FireCompletion()
{
HRESULT hr = S_OK;
_TryTransitionToCompleted();
if (_M_completeDelegate != nullptr && InterlockedIncrement(&_M_CallbackMade) == 1)
{
hr = _M_completeDelegateContext._CallInContext([=]() -> HRESULT {
ABI::Windows::Foundation::AsyncStatus status;
HRESULT hr;
if (SUCCEEDED(hr = this->get_Status(&status)))
_M_completeDelegate->Invoke((_Attributes::_AsyncBaseType*)this, status);
_M_completeDelegate = nullptr;
return hr;
});
}
return hr;
}
virtual STDMETHODIMP _GetOnProgress(typename _Attributes::_ProgressDelegateType** _ProgressHandler)
{
(void)_ProgressHandler;
return E_UNEXPECTED;
}
virtual STDMETHODIMP _PutOnProgress(typename _Attributes::_ProgressDelegateType* _ProgressHandler)
{
(void)_ProgressHandler;
return E_UNEXPECTED;
}
bool _TryTransitionToCompleted()
{
return _TransitionToState(_AsyncStatusInternal::_AsyncCompleted);
}
bool _TryTransitionToCancelled()
{
return _TransitionToState(_AsyncStatusInternal::_AsyncCanceled);
}
bool _TryTransitionToError(const HRESULT error)
{
_InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&_M_errorCode), error, S_OK);
return _TransitionToState(_AsyncStatusInternal::_AsyncError);
}
inline HRESULT _CheckValidStateForDelegateCall()
{
if (_M_currentStatus == _AsyncClosed)
{
return E_ILLEGAL_METHOD_CALL;
}
return S_OK;
}
inline HRESULT _CheckValidStateForResultsCall()
{
_AsyncStatusInternal _Current = _M_currentStatus;
if (_Current == _AsyncError)
{
return _M_errorCode;
}
#pragma warning(push)
#pragma warning(disable: 4127)
if (resultType == SingleResult)
#pragma warning(pop)
{
if (_Current != _AsyncCompleted)
{
return E_ILLEGAL_METHOD_CALL;
}
}
else if (_Current != _AsyncStarted &&
_Current != _AsyncCancelPending &&
_Current != _AsyncCanceled &&
_Current != _AsyncCompleted)
{
return E_ILLEGAL_METHOD_CALL;
}
return S_OK;
}
inline bool _ContinueAsyncOperation()
{
return _M_currentStatus == _AsyncStarted;
}
virtual void _OnStart() = 0;
virtual void _OnClose() = 0;
virtual void _OnCancel() = 0;
private:
inline HRESULT _CheckValidStateForAsyncInfoCall()
{
_AsyncStatusInternal _Current = _M_currentStatus;
if (_Current == _AsyncClosed)
{
return E_ILLEGAL_METHOD_CALL;
}
else if (_Current == _AsyncCreated)
{
return E_ASYNC_OPERATION_NOT_STARTED;
}
return S_OK;
}
inline bool _TransitionToState(const _AsyncStatusInternal _NewState)
{
_AsyncStatusInternal _Current = _M_currentStatus;
switch (_NewState)
{
case _AsyncStatusInternal::_AsyncStarted:
if (_Current != _AsyncCreated)
{
return false;
}
break;
case _AsyncStatusInternal::_AsyncCompleted:
if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)
{
return false;
}
break;
case _AsyncStatusInternal::_AsyncCancelPending:
if (_Current != _AsyncStarted)
{
return false;
}
break;
case _AsyncStatusInternal::_AsyncCanceled:
if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)
{
return false;
}
break;
case _AsyncStatusInternal::_AsyncError:
if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)
{
return false;
}
break;
case _AsyncStatusInternal::_AsyncClosed:
if (!_IsTerminalState(_Current))
{
return false;
}
break;
default:
return false;
break;
}
_AsyncStatusInternal _RetState = static_cast<_AsyncStatusInternal>(
_InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&_M_currentStatus),
_NewState,
static_cast<LONG>(_Current)));
return (_RetState == _Current);
}
inline bool _IsTerminalState()
{
return _IsTerminalState(_M_currentStatus);
}
inline bool _IsTerminalState(_AsyncStatusInternal status)
{
return (status == _AsyncError ||
status == _AsyncCanceled ||
status == _AsyncCompleted ||
status == _AsyncClosed);
}
private:
_ContextCallback _M_completeDelegateContext;
Microsoft::WRL::ComPtr<typename _Attributes::_CompletionDelegateType> _M_completeDelegate;
_AsyncStatusInternal volatile _M_currentStatus;
HRESULT volatile _M_errorCode;
unsigned int _M_id;
long volatile _M_CompleteDelegateAssigned;
long volatile _M_CallbackMade;
};
template< typename _Attributes, bool _HasProgress, _AsyncResultType _ResultType = SingleResult >
class _AsyncProgressBase abstract : public _AsyncInfoBase<_Attributes, _ResultType>
{
};
template< typename _Attributes, _AsyncResultType _ResultType>
class _AsyncProgressBase<_Attributes, true, _ResultType> abstract : public _AsyncInfoBase<_Attributes, _ResultType>
{
public:
_AsyncProgressBase() : _AsyncInfoBase<_Attributes, _ResultType>(),
_M_progressDelegate(nullptr)
{
}
virtual STDMETHODIMP _GetOnProgress(typename _Attributes::_ProgressDelegateType** _ProgressHandler) override
{
HRESULT hr = _CheckValidStateForDelegateCall();
if (FAILED(hr)) return hr;
*_ProgressHandler = _M_progressDelegate;
return S_OK;
}
virtual STDMETHODIMP _PutOnProgress(typename _Attributes::_ProgressDelegateType* _ProgressHandler) override
{
HRESULT hr = _CheckValidStateForDelegateCall();
if (FAILED(hr)) return hr;
_M_progressDelegate = _ProgressHandler;
_M_progressDelegateContext = _ContextCallback::_CaptureCurrent();
return S_OK;
}
public:
void _FireProgress(const typename _Attributes::_ProgressType_abi& _ProgressValue)
{
if (_M_progressDelegate != nullptr)
{
_M_progressDelegateContext._CallInContext([=]() -> HRESULT {
_M_progressDelegate->Invoke((_Attributes::_AsyncBaseType*)this, _ProgressValue);
return S_OK;
});
}
}
private:
_ContextCallback _M_progressDelegateContext;
typename _Attributes::_ProgressDelegateType* _M_progressDelegate;
};
template<typename _Attributes, _AsyncResultType _ResultType = SingleResult>
class _AsyncBaseProgressLayer abstract : public _AsyncProgressBase<_Attributes, _Attributes::_TakesProgress, _ResultType>
{
};
template<typename _Attributes, typename _ReturnType>
class _AsyncTaskThunkBase abstract : public _AsyncBaseProgressLayer<_Attributes>
{
public:
virtual STDMETHODIMP GetResults()
{
HRESULT hr = _CheckValidStateForResultsCall();
if (FAILED(hr)) return hr;
_M_task.get();
return S_OK;
}
public:
typedef task<_ReturnType> _TaskType;
_AsyncTaskThunkBase(const _TaskType& _Task)
: _M_task(_Task)
{
}
_AsyncTaskThunkBase()
{
}
#if _MSC_VER < 1800
void _SetTaskCreationAddressHint(void* _SourceAddressHint)
{
if (!(std::is_same<_Attributes::_AsyncKind, _TypeSelectorAsyncTask>::value))
{
_M_task._SetTaskCreationAddressHint(_SourceAddressHint);
}
}
#endif
protected:
virtual void _OnStart() override
{
_M_task.then([=](_TaskType _Antecedent) -> HRESULT {
try
{
_Antecedent.get();
}
catch (Concurrency::task_canceled&)
{
_TryTransitionToCancelled();
}
catch (IRestrictedErrorInfo*& _Ex)
{
HRESULT hr;
HRESULT _hr;
hr = _Ex->GetErrorDetails(NULL, &_hr, NULL, NULL);
if (SUCCEEDED(hr)) hr = _hr;
_TryTransitionToError(hr);
}
catch (...)
{
_TryTransitionToError(E_FAIL);
}
return _FireCompletion();
});
}
protected:
_TaskType _M_task;
Concurrency::cancellation_token_source _M_cts;
};
template<typename _Attributes, typename _ReturnType, typename _Return>
class _AsyncTaskReturn abstract : public _AsyncTaskThunkBase<_Attributes, _Return>
{
public:
virtual STDMETHODIMP GetResults(_ReturnType* results)
{
HRESULT hr = _CheckValidStateForResultsCall();
if (FAILED(hr)) return hr;
_M_task.get();
*results = _M_results;
return S_OK;
}
template <typename _Function>
#if _MSC_VER >= 1800
void DoCreateTask(_Function _func, const _TaskCreationCallstack & _callstack)
{
_M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results, _callstack);
}
#else
void DoCreateTask(_Function _func)
{
_M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results);
}
#endif
protected:
_ReturnType _M_results;
};
template<typename _Attributes, typename _ReturnType>
class _AsyncTaskReturn<_Attributes, _ReturnType, void> abstract : public _AsyncTaskThunkBase<_Attributes, void>
{
public:
template <typename _Function>
#if _MSC_VER >= 1800
void DoCreateTask(_Function _func, const _TaskCreationCallstack & _callstack)
{
_M_task = _Attributes::_Generate_Task(_func, this, _M_cts, _callstack);
}
#else
void DoCreateTask(_Function _func)
{
_M_task = _Attributes::_Generate_Task(_func, this, _M_cts);
}
#endif
};
template<typename _Attributes>
class _AsyncTaskReturn<_Attributes, void, task<void>> abstract : public _AsyncTaskThunkBase<_Attributes, task<void>>
{
public:
template <typename _Function>
#if _MSC_VER >= 1800
void DoCreateTask(_Function _func, const _TaskCreationCallstack & _callstack)
{
_M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results, _callstack);
}
#else
void DoCreateTask(_Function _func)
{
_M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results);
}
#endif
protected:
task<void> _M_results;
};
template<typename _Attributes>
class _AsyncTaskThunk : public _AsyncTaskReturn<_Attributes, typename _Attributes::_ReturnType_abi, typename _Attributes::_ReturnType>
{
public:
_AsyncTaskThunk(const _TaskType& _Task) :
_AsyncTaskThunkBase(_Task)
{
}
_AsyncTaskThunk()
{
}
protected:
virtual void _OnClose() override
{
}
virtual void _OnCancel() override
{
_M_cts.cancel();
}
};
template<typename _Function>
class _AsyncTaskGeneratorThunk : public _AsyncTaskThunk<typename _AsyncLambdaTypeTraits<_Function>::_AsyncAttributes>
{
public:
typedef typename _AsyncLambdaTypeTraits<_Function>::_AsyncAttributes _Attributes;
typedef typename _AsyncTaskThunk<_Attributes> _Base;
typedef typename _Attributes::_AsyncBaseType _AsyncBaseType;
#if _MSC_VER >= 1800
_AsyncTaskGeneratorThunk(const _Function& _Func, const _TaskCreationCallstack &_callstack) : _M_func(_Func), _M_creationCallstack(_callstack)
#else
_AsyncTaskGeneratorThunk(const _Function& _Func) : _M_func(_Func)
#endif
{
_Start();
}
protected:
virtual void _OnStart() override
{
#if _MSC_VER >= 1800
DoCreateTask<_Function>(_M_func, _M_creationCallstack);
#else
DoCreateTask<_Function>(_M_func);
#endif
_Base::_OnStart();
}
virtual void _OnCancel() override
{
_Base::_OnCancel();
}
private:
#if _MSC_VER >= 1800
_TaskCreationCallstack _M_creationCallstack;
#endif
_Function _M_func;
};
}
template<typename _ReturnType, typename _Function>
__declspec(noinline)
details::_AsyncTaskGeneratorThunk<_Function>* create_async(const _Function& _Func)
{
static_assert(std::is_same<decltype(details::_IsValidCreateAsync<_ReturnType>(_Func, 0, 0, 0, 0, 0, 0, 0, 0)), std::true_type>::value,
"argument to create_async must be a callable object taking zero, one, two or three arguments");
#if _MSC_VER >= 1800
Microsoft::WRL::ComPtr<details::_AsyncTaskGeneratorThunk<_Function>> _AsyncInfo = Microsoft::WRL::Make<details::_AsyncTaskGeneratorThunk<_Function>>(_Func, _CAPTURE_CALLSTACK());
#else
Microsoft::WRL::ComPtr<details::_AsyncTaskGeneratorThunk<_Function>> _AsyncInfo = Microsoft::WRL::Make<details::_AsyncTaskGeneratorThunk<_Function>>(_Func);
_AsyncInfo->_SetTaskCreationAddressHint(_ReturnAddress());
#endif
return _AsyncInfo.Detach();
}
namespace details
{
#if _MSC_VER < 1800
_CRTIMP2 unsigned int __cdecl _GetNextAsyncId();
#endif
template<typename _Type>
struct _RunAllParam
{
_RunAllParam() : _M_completeCount(0), _M_numTasks(0)
{
}
void _Resize(size_t _Len, bool _SkipVector = false)
{
_M_numTasks = _Len;
if (!_SkipVector)
#if _MSC_VER >= 1800
{
_M_vector._Result.resize(_Len);
}
#else
_M_vector.resize(_Len);
_M_contexts.resize(_Len);
#endif
}
task_completion_event<_Unit_type> _M_completed;
atomic_size_t _M_completeCount;
#if _MSC_VER >= 1800
_ResultHolder<std::vector<_Type> > _M_vector;
_ResultHolder<_Type> _M_mergeVal;
#else
std::vector<_Type> _M_vector;
std::vector<_ContextCallback> _M_contexts;
_Type _M_mergeVal;
#endif
size_t _M_numTasks;
};
#if _MSC_VER >= 1800
template<typename _Type>
struct _RunAllParam<std::vector<_Type> >
{
_RunAllParam() : _M_completeCount(0), _M_numTasks(0)
{
}
void _Resize(size_t _Len, bool _SkipVector = false)
{
_M_numTasks = _Len;
if (!_SkipVector)
{
_M_vector.resize(_Len);
}
}
task_completion_event<_Unit_type> _M_completed;
std::vector<_ResultHolder<std::vector<_Type> > > _M_vector;
atomic_size_t _M_completeCount;
size_t _M_numTasks;
};
#endif
template<>
#if _MSC_VER >= 1800
struct _RunAllParam<_Unit_type>
#else
struct _RunAllParam<void>
#endif
{
_RunAllParam() : _M_completeCount(0), _M_numTasks(0)
{
}
void _Resize(size_t _Len)
{
_M_numTasks = _Len;
}
task_completion_event<_Unit_type> _M_completed;
atomic_size_t _M_completeCount;
size_t _M_numTasks;
};
inline void _JoinAllTokens_Add(const Concurrency::cancellation_token_source& _MergedSrc, Concurrency::details::_CancellationTokenState *_PJoinedTokenState)
{
if (_PJoinedTokenState != nullptr && _PJoinedTokenState != Concurrency::details::_CancellationTokenState::_None())
{
Concurrency::cancellation_token _T = Concurrency::cancellation_token::_FromImpl(_PJoinedTokenState);
_T.register_callback([=](){
_MergedSrc.cancel();
});
}
}
template<typename _ElementType, typename _Function, typename _TaskType>
void _WhenAllContinuationWrapper(_RunAllParam<_ElementType>* _PParam, _Function _Func, task<_TaskType>& _Task)
{
if (_Task._GetImpl()->_IsCompleted())
{
_Func();
#if _MSC_VER >= 1800
if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks)
#else
if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks)
#endif
{
_PParam->_M_completed.set(_Unit_type());
delete _PParam;
}
}
else
{
_CONCRT_ASSERT(_Task._GetImpl()->_IsCanceled());
if (_Task._GetImpl()->_HasUserException())
{
_PParam->_M_completed._Cancel(_Task._GetImpl()->_GetExceptionHolder());
}
else
{
_PParam->_M_completed._Cancel();
}
#if _MSC_VER >= 1800
if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks)
#else
if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks)
#endif
{
delete _PParam;
}
}
}
template<typename _ElementType, typename _Iterator>
struct _WhenAllImpl
{
#if _MSC_VER >= 1800
static task<std::vector<_ElementType>> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End)
#else
static task<std::vector<_ElementType>> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End)
#endif
{
#if _MSC_VER >= 1800
Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
#endif
auto _PParam = new _RunAllParam<_ElementType>();
Concurrency::cancellation_token_source _MergedSource;
#if _MSC_VER >= 1800
task_options _Options(_TaskOptions);
_Options.set_cancellation_token(_MergedSource.get_token());
task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _Options);
#else
task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token());
#endif
auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type, std::vector<_ElementType>* retVal) -> HRESULT {
#if _MSC_VER >= 1800
* retVal = _PParam->_M_vector.Get();
#else
auto _Result = _PParam->_M_vector;
size_t _Index = 0;
for (auto _It = _Result.begin(); _It != _Result.end(); ++_It)
{
*_It = _ResultContext<_ElementType>::_GetValue(*_It, _PParam->_M_contexts[_Index++], false);
}
*retVal = _Result;
#endif
return S_OK;
#if _MSC_VER >= 1800
}, nullptr);
#else
}, nullptr, true);
#endif
if (_PTokenState)
{
details::_JoinAllTokens_Add(_MergedSource, _PTokenState);
_PParam->_Resize(static_cast<size_t>(std::distance(_Begin, _End)));
}
else
{
size_t _TaskNum = 0;
for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
{
_TaskNum++;
details::_JoinAllTokens_Add(_MergedSource, _PTask->_GetImpl()->_M_pTokenState);
}
_PParam->_Resize(_TaskNum);
}
if (_Begin == _End)
{
_PParam->_M_completed.set(_Unit_type());
delete _PParam;
}
else
{
size_t _Index = 0;
for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
{
if (_PTask->is_apartment_aware())
{
_ReturnTask._SetAsync();
}
_PTask->_Then([_PParam, _Index](task<_ElementType> _ResultTask) -> HRESULT {
#if _MSC_VER >= 1800
typedef _ElementType _ElementTypeDev10;
auto _PParamCopy = _PParam;
auto _IndexCopy = _Index;
auto _Func = [_PParamCopy, _IndexCopy, &_ResultTask](){
_PParamCopy->_M_vector._Result[_IndexCopy] = _ResultTask._GetImpl()->_GetResult();
};
#else
auto _Func = [_PParam, _Index, &_ResultTask](){
_PParam->_M_vector[_Index] = _ResultTask._GetImpl()->_GetResult();
_PParam->_M_contexts[_Index] = _ResultContext<_ElementType>::_GetContext(false);
};
#endif
_WhenAllContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
#if _MSC_VER >= 1800
}, Concurrency::details::_CancellationTokenState::_None());
#else
}, Concurrency::details::_CancellationTokenState::_None(), false);
#endif
_Index++;
}
}
return _ReturnTask;
}
};
template<typename _ElementType, typename _Iterator>
struct _WhenAllImpl<std::vector<_ElementType>, _Iterator>
{
#if _MSC_VER >= 1800
static task<std::vector<_ElementType>> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End)
#else
static task<std::vector<_ElementType>> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End)
#endif
{
#if _MSC_VER >= 1800
Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
#endif
auto _PParam = new _RunAllParam<std::vector<_ElementType>>();
Concurrency::cancellation_token_source _MergedSource;
#if _MSC_VER >= 1800
task_options _Options(_TaskOptions);
_Options.set_cancellation_token(_MergedSource.get_token());
task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _Options);
#else
task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token());
#endif
auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type, std::vector<_ElementType>* retVal) -> HRESULT {
_CONCRT_ASSERT(_PParam->_M_completeCount == _PParam->_M_numTasks);
std::vector<_ElementType> _Result;
for (size_t _I = 0; _I < _PParam->_M_numTasks; _I++)
{
#if _MSC_VER >= 1800
const std::vector<_ElementType>& _Vec = _PParam->_M_vector[_I].Get();
#else
std::vector<_ElementType>& _Vec = _PParam->_M_vector[_I];
for (auto _It = _Vec.begin(); _It != _Vec.end(); ++_It)
{
*_It = _ResultContext<_ElementType>::_GetValue(*_It, _PParam->_M_contexts[_I], false);
}
#endif
_Result.insert(_Result.end(), _Vec.begin(), _Vec.end());
}
*retVal = _Result;
return S_OK;
#if _MSC_VER >= 1800
}, nullptr);
#else
}, nullptr, true);
#endif
if (_PTokenState)
{
details::_JoinAllTokens_Add(_MergedSource, _PTokenState);
_PParam->_Resize(static_cast<size_t>(std::distance(_Begin, _End)));
}
else
{
size_t _TaskNum = 0;
for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
{
_TaskNum++;
details::_JoinAllTokens_Add(_MergedSource, _PTask->_GetImpl()->_M_pTokenState);
}
_PParam->_Resize(_TaskNum);
}
if (_Begin == _End)
{
_PParam->_M_completed.set(_Unit_type());
delete _PParam;
}
else
{
size_t _Index = 0;
for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
{
if (_PTask->is_apartment_aware())
{
_ReturnTask._SetAsync();
}
_PTask->_Then([_PParam, _Index](task<std::vector<_ElementType>> _ResultTask) -> HRESULT {
#if _MSC_VER >= 1800
typedef _ElementType _ElementTypeDev10;
auto _PParamCopy = _PParam;
auto _IndexCopy = _Index;
auto _Func = [_PParamCopy, _IndexCopy, &_ResultTask]() {
_PParamCopy->_M_vector[_IndexCopy].Set(_ResultTask._GetImpl()->_GetResult());
};
#else
auto _Func = [_PParam, _Index, &_ResultTask]() {
_PParam->_M_vector[_Index] = _ResultTask._GetImpl()->_GetResult();
_PParam->_M_contexts[_Index] = _ResultContext<_ElementType>::_GetContext(false);
};
#endif
_WhenAllContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
#if _MSC_VER >= 1800
}, Concurrency::details::_CancellationTokenState::_None());
#else
}, Concurrency::details::_CancellationTokenState::_None(), false);
#endif
_Index++;
}
}
return _ReturnTask;
}
};
template<typename _Iterator>
struct _WhenAllImpl<void, _Iterator>
{
#if _MSC_VER >= 1800
static task<void> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End)
#else
static task<void> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End)
#endif
{
#if _MSC_VER >= 1800
Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
#endif
auto _PParam = new _RunAllParam<_Unit_type>();
Concurrency::cancellation_token_source _MergedSource;
#if _MSC_VER >= 1800
task_options _Options(_TaskOptions);
_Options.set_cancellation_token(_MergedSource.get_token());
task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _Options);
#else
task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token());
#endif
auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type) -> HRESULT { return S_OK;
#if _MSC_VER >= 1800
}, nullptr);
#else
}, nullptr, false);
#endif
if (_PTokenState)
{
details::_JoinAllTokens_Add(_MergedSource, _PTokenState);
_PParam->_Resize(static_cast<size_t>(std::distance(_Begin, _End)));
}
else
{
size_t _TaskNum = 0;
for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
{
_TaskNum++;
details::_JoinAllTokens_Add(_MergedSource, _PTask->_GetImpl()->_M_pTokenState);
}
_PParam->_Resize(_TaskNum);
}
if (_Begin == _End)
{
_PParam->_M_completed.set(_Unit_type());
delete _PParam;
}
else
{
for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
{
if (_PTask->is_apartment_aware())
{
_ReturnTask._SetAsync();
}
_PTask->_Then([_PParam](task<void> _ResultTask) -> HRESULT {
auto _Func = []() -> HRESULT { return S_OK; };
_WhenAllContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
#if _MSC_VER >= 1800
}, Concurrency::details::_CancellationTokenState::_None());
#else
}, Concurrency::details::_CancellationTokenState::_None(), false);
#endif
}
}
return _ReturnTask;
}
};
template<typename _ReturnType>
task<std::vector<_ReturnType>> _WhenAllVectorAndValue(const task<std::vector<_ReturnType>>& _VectorTask, const task<_ReturnType>& _ValueTask,
bool _OutputVectorFirst)
{
auto _PParam = new _RunAllParam<_ReturnType>();
Concurrency::cancellation_token_source _MergedSource;
task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token());
auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type, std::vector<_ReturnType>* retVal) -> HRESULT {
_CONCRT_ASSERT(_PParam->_M_completeCount == 2);
#if _MSC_VER >= 1800
auto _Result = _PParam->_M_vector.Get();
auto _mergeVal = _PParam->_M_mergeVal.Get();
#else
auto _Result = _PParam->_M_vector;
for (auto _It = _Result.begin(); _It != _Result.end(); ++_It)
{
*_It = _ResultContext<_ReturnType>::_GetValue(*_It, _PParam->_M_contexts[0], false);
}
#endif
if (_OutputVectorFirst == true)
{
#if _MSC_VER >= 1800
_Result.push_back(_mergeVal);
#else
_Result.push_back(_ResultContext<_ReturnType>::_GetValue(_PParam->_M_mergeVal, _PParam->_M_contexts[1], false));
#endif
}
else
{
#if _MSC_VER >= 1800
_Result.insert(_Result.begin(), _mergeVal);
#else
_Result.insert(_Result.begin(), _ResultContext<_ReturnType>::_GetValue(_PParam->_M_mergeVal, _PParam->_M_contexts[1], false));
#endif
}
*retVal = _Result;
return S_OK;
}, nullptr, true);
_JoinAllTokens_Add(_MergedSource, _VectorTask._GetImpl()->_M_pTokenState);
_JoinAllTokens_Add(_MergedSource, _ValueTask._GetImpl()->_M_pTokenState);
_PParam->_Resize(2, true);
if (_VectorTask.is_apartment_aware() || _ValueTask.is_apartment_aware())
{
_ReturnTask._SetAsync();
}
_VectorTask._Then([_PParam](task<std::vector<_ReturnType>> _ResultTask) -> HRESULT {
#if _MSC_VER >= 1800
typedef _ReturnType _ReturnTypeDev10;
auto _PParamCopy = _PParam;
auto _Func = [_PParamCopy, &_ResultTask]() {
auto _ResultLocal = _ResultTask._GetImpl()->_GetResult();
_PParamCopy->_M_vector.Set(_ResultLocal);
};
#else
auto _Func = [_PParam, &_ResultTask]() {
_PParam->_M_vector = _ResultTask._GetImpl()->_GetResult();
_PParam->_M_contexts[0] = _ResultContext<_ReturnType>::_GetContext(false);
};
#endif
_WhenAllContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
#if _MSC_VER >= 1800
}, _CancellationTokenState::_None());
#else
}, _CancellationTokenState::_None(), false);
#endif
_ValueTask._Then([_PParam](task<_ReturnType> _ResultTask) -> HRESULT {
#if _MSC_VER >= 1800
typedef _ReturnType _ReturnTypeDev10;
auto _PParamCopy = _PParam;
auto _Func = [_PParamCopy, &_ResultTask]() {
auto _ResultLocal = _ResultTask._GetImpl()->_GetResult();
_PParamCopy->_M_mergeVal.Set(_ResultLocal);
};
#else
auto _Func = [_PParam, &_ResultTask]() {
_PParam->_M_mergeVal = _ResultTask._GetImpl()->_GetResult();
_PParam->_M_contexts[1] = _ResultContext<_ReturnType>::_GetContext(false);
};
#endif
_WhenAllContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
#if _MSC_VER >= 1800
}, _CancellationTokenState::_None());
#else
}, _CancellationTokenState::_None(), false);
#endif
return _ReturnTask;
}
}
#if _MSC_VER < 1800
template <typename _Iterator>
auto when_all(_Iterator _Begin, _Iterator _End)
-> decltype (details::_WhenAllImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(nullptr, _Begin, _End))
{
typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
return details::_WhenAllImpl<_ElementType, _Iterator>::_Perform(nullptr, _Begin, _End);
}
#endif
template <typename _Iterator>
#if _MSC_VER >= 1800
auto when_all(_Iterator _Begin, _Iterator _End, const task_options& _TaskOptions = task_options())
-> decltype (details::_WhenAllImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(_TaskOptions, _Begin, _End))
{
typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
return details::_WhenAllImpl<_ElementType, _Iterator>::_Perform(_TaskOptions, _Begin, _End);
}
#else
auto when_all(_Iterator _Begin, _Iterator _End, Concurrency::cancellation_token _CancellationToken)
-> decltype (details::_WhenAllImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End))
{
typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
return details::_WhenAllImpl<_ElementType, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End);
}
#endif
template<typename _ReturnType>
task<std::vector<_ReturnType>> operator&&(const task<_ReturnType> & _Lhs, const task<_ReturnType> & _Rhs)
{
task<_ReturnType> _PTasks[2] = { _Lhs, _Rhs };
return when_all(_PTasks, _PTasks + 2);
}
template<typename _ReturnType>
task<std::vector<_ReturnType>> operator&&(const task<std::vector<_ReturnType>> & _Lhs, const task<_ReturnType> & _Rhs)
{
return details::_WhenAllVectorAndValue(_Lhs, _Rhs, true);
}
template<typename _ReturnType>
task<std::vector<_ReturnType>> operator&&(const task<_ReturnType> & _Lhs, const task<std::vector<_ReturnType>> & _Rhs)
{
return details::_WhenAllVectorAndValue(_Rhs, _Lhs, false);
}
template<typename _ReturnType>
task<std::vector<_ReturnType>> operator&&(const task<std::vector<_ReturnType>> & _Lhs, const task<std::vector<_ReturnType>> & _Rhs)
{
task<std::vector<_ReturnType>> _PTasks[2] = { _Lhs, _Rhs };
return when_all(_PTasks, _PTasks + 2);
}
inline task<void> operator&&(const task<void> & _Lhs, const task<void> & _Rhs)
{
task<void> _PTasks[2] = { _Lhs, _Rhs };
return when_all(_PTasks, _PTasks + 2);
}
namespace details
{
template <typename _CompletionType>
struct _RunAnyParam
{
_RunAnyParam() : _M_completeCount(0), _M_numTasks(0), _M_exceptionRelatedToken(nullptr), _M_fHasExplicitToken(false)
{
}
~_RunAnyParam()
{
if (Concurrency::details::_CancellationTokenState::_IsValid(_M_exceptionRelatedToken))
_M_exceptionRelatedToken->_Release();
}
task_completion_event<_CompletionType> _M_Completed;
Concurrency::cancellation_token_source _M_cancellationSource;
Concurrency::details::_CancellationTokenState* _M_exceptionRelatedToken;
atomic_size_t _M_completeCount;
size_t _M_numTasks;
bool _M_fHasExplicitToken;
};
template<typename _CompletionType, typename _Function, typename _TaskType>
void _WhenAnyContinuationWrapper(_RunAnyParam<_CompletionType> * _PParam, const _Function & _Func, task<_TaskType>& _Task)
{
bool _IsTokenCancled = !_PParam->_M_fHasExplicitToken && _Task._GetImpl()->_M_pTokenState != Concurrency::details::_CancellationTokenState::_None() && _Task._GetImpl()->_M_pTokenState->_IsCanceled();
if (_Task._GetImpl()->_IsCompleted() && !_IsTokenCancled)
{
_Func();
#if _MSC_VER >= 1800
if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks)
#else
if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks)
#endif
{
delete _PParam;
}
}
else
{
_CONCRT_ASSERT(_Task._GetImpl()->_IsCanceled() || _IsTokenCancled);
if (_Task._GetImpl()->_HasUserException() && !_IsTokenCancled)
{
if (_PParam->_M_Completed._StoreException(_Task._GetImpl()->_GetExceptionHolder()))
{
_PParam->_M_exceptionRelatedToken = _Task._GetImpl()->_M_pTokenState;
_CONCRT_ASSERT(_PParam->_M_exceptionRelatedToken);
if (_PParam->_M_exceptionRelatedToken != Concurrency::details::_CancellationTokenState::_None())
{
_PParam->_M_exceptionRelatedToken->_Reference();
}
}
}
#if _MSC_VER >= 1800
if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks)
#else
if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks)
#endif
{
if (!_PParam->_M_Completed._IsTriggered())
{
if (!_PParam->_M_fHasExplicitToken)
{
if (_PParam->_M_exceptionRelatedToken)
{
details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _PParam->_M_exceptionRelatedToken);
}
else
{
details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Task._GetImpl()->_M_pTokenState);
}
}
_PParam->_M_Completed._Cancel();
}
delete _PParam;
}
}
}
template<typename _ElementType, typename _Iterator>
struct _WhenAnyImpl
{
#if _MSC_VER >= 1800
static task<std::pair<_ElementType, size_t>> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End)
#else
static task<std::pair<_ElementType, size_t>> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End)
#endif
{
if (_Begin == _End)
{
throw Concurrency::invalid_operation("when_any(begin, end) cannot be called on an empty container.");
}
#if _MSC_VER >= 1800
Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
#endif
auto _PParam = new _RunAnyParam<std::pair<std::pair<_ElementType, size_t>, Concurrency::details::_CancellationTokenState *>>();
if (_PTokenState)
{
details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _PTokenState);
_PParam->_M_fHasExplicitToken = true;
}
#if _MSC_VER >= 1800
task_options _Options(_TaskOptions);
_Options.set_cancellation_token(_PParam->_M_cancellationSource.get_token());
task<std::pair<std::pair<_ElementType, size_t>, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _Options);
#else
task<std::pair<std::pair<_ElementType, size_t>, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
_Any_tasks_completed._GetImpl()->_M_fRuntimeAggregate = true;
#endif
auto _CancellationSource = _PParam->_M_cancellationSource;
_PParam->_M_numTasks = static_cast<size_t>(std::distance(_Begin, _End));
size_t index = 0;
for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
{
if (_PTask->is_apartment_aware())
{
_Any_tasks_completed._SetAsync();
}
_PTask->_Then([_PParam, index](task<_ElementType> _ResultTask) -> HRESULT {
#if _MSC_VER >= 1800
auto _PParamCopy = _PParam;
auto _IndexCopy = index;
auto _Func = [&_ResultTask, _PParamCopy, _IndexCopy]() {
_PParamCopy->_M_Completed.set(std::make_pair(std::make_pair(_ResultTask._GetImpl()->_GetResult(), _IndexCopy), _ResultTask._GetImpl()->_M_pTokenState));
};
#else
auto _Func = [&_ResultTask, _PParam, index]() {
_PParam->_M_Completed.set(std::make_pair(std::make_pair(_ResultTask._GetImpl()->_GetResult(), index), _ResultTask._GetImpl()->_M_pTokenState));
};
#endif
_WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
#if _MSC_VER >= 1800
}, Concurrency::details::_CancellationTokenState::_None());
#else
}, Concurrency::details::_CancellationTokenState::_None(), false);
#endif
index++;
}
return _Any_tasks_completed._Then([=](std::pair<std::pair<_ElementType, size_t>, Concurrency::details::_CancellationTokenState *> _Result, std::pair<_ElementType, size_t>* retVal) -> HRESULT {
_CONCRT_ASSERT(_Result.second);
if (!_PTokenState)
{
details::_JoinAllTokens_Add(_CancellationSource, _Result.second);
}
*retVal = _Result.first;
return S_OK;
#if _MSC_VER >= 1800
}, nullptr);
#else
}, nullptr, true);
#endif
}
};
template<typename _Iterator>
struct _WhenAnyImpl<void, _Iterator>
{
#if _MSC_VER >= 1800
static task<size_t> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End)
#else
static task<size_t> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End)
#endif
{
if (_Begin == _End)
{
throw Concurrency::invalid_operation("when_any(begin, end) cannot be called on an empty container.");
}
#if _MSC_VER >= 1800
Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr;
#endif
auto _PParam = new _RunAnyParam<std::pair<size_t, Concurrency::details::_CancellationTokenState *>>();
if (_PTokenState)
{
details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _PTokenState);
_PParam->_M_fHasExplicitToken = true;
}
#if _MSC_VER >= 1800
task_options _Options(_TaskOptions);
_Options.set_cancellation_token(_PParam->_M_cancellationSource.get_token());
task<std::pair<size_t, _CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _Options);
#else
task<std::pair<size_t, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
#endif
auto _CancellationSource = _PParam->_M_cancellationSource;
_PParam->_M_numTasks = static_cast<size_t>(std::distance(_Begin, _End));
size_t index = 0;
for (auto _PTask = _Begin; _PTask != _End; ++_PTask)
{
if (_PTask->is_apartment_aware())
{
_Any_tasks_completed._SetAsync();
}
_PTask->_Then([_PParam, index](task<void> _ResultTask) -> HRESULT {
#if _MSC_VER >= 1800
auto _PParamCopy = _PParam;
auto _IndexCopy = index;
auto _Func = [&_ResultTask, _PParamCopy, _IndexCopy]() {
_PParamCopy->_M_Completed.set(std::make_pair(_IndexCopy, _ResultTask._GetImpl()->_M_pTokenState));
};
#else
auto _Func = [&_ResultTask, _PParam, index]() {
_PParam->_M_Completed.set(std::make_pair(index, _ResultTask._GetImpl()->_M_pTokenState));
};
#endif
_WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
#if _MSC_VER >= 1800
}, Concurrency::details::_CancellationTokenState::_None());
#else
}, Concurrency::details::_CancellationTokenState::_None(), false);
#endif
index++;
}
return _Any_tasks_completed._Then([=](std::pair<size_t, Concurrency::details::_CancellationTokenState *> _Result, size_t* retVal) -> HRESULT {
_CONCRT_ASSERT(_Result.second);
if (!_PTokenState)
{
details::_JoinAllTokens_Add(_CancellationSource, _Result.second);
}
*retVal = _Result.first;
return S_OK;
#if _MSC_VER >= 1800
}, nullptr);
#else
}, nullptr, false);
#endif
}
};
}
template<typename _Iterator>
#if _MSC_VER >= 1800
auto when_any(_Iterator _Begin, _Iterator _End, const task_options& _TaskOptions = task_options())
-> decltype (details::_WhenAnyImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(_TaskOptions, _Begin, _End))
{
typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
return details::_WhenAnyImpl<_ElementType, _Iterator>::_Perform(_TaskOptions, _Begin, _End);
}
#else
auto when_any(_Iterator _Begin, _Iterator _End)
-> decltype (details::_WhenAnyImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(nullptr, _Begin, _End))
{
typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
return details::_WhenAnyImpl<_ElementType, _Iterator>::_Perform(nullptr, _Begin, _End);
}
#endif
template<typename _Iterator>
auto when_any(_Iterator _Begin, _Iterator _End, Concurrency::cancellation_token _CancellationToken)
-> decltype (details::_WhenAnyImpl<typename std::iterator_traits<_Iterator>::value_type::result_type, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End))
{
typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType;
return details::_WhenAnyImpl<_ElementType, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End);
}
template<typename _ReturnType>
task<_ReturnType> operator||(const task<_ReturnType> & _Lhs, const task<_ReturnType> & _Rhs)
{
#if _MSC_VER >= 1800
auto _PParam = new details::_RunAnyParam<std::pair<_ReturnType, size_t>>();
task<std::pair<_ReturnType, size_t>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
auto _ReturnTask = _Any_tasks_completed._Then([=](std::pair<_ReturnType, size_t> _Ret, _ReturnType* retVal) -> HRESULT {
_CONCRT_ASSERT(_Ret.second);
details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, reinterpret_cast<Concurrency::details::_CancellationTokenState *>(_Ret.second));
*retVal = _Ret.first;
return S_OK;
}, nullptr);
#else
auto _PParam = new details::_RunAnyParam<std::pair<_ReturnType, Concurrency::details::_CancellationTokenState *>>();
task<std::pair<_ReturnType, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
auto _ReturnTask = _Any_tasks_completed._Then([=](std::pair<_ReturnType, Concurrency::details::_CancellationTokenState *> _Ret, _ReturnType* retVal) -> HRESULT {
_CONCRT_ASSERT(_Ret.second);
details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Ret.second);
*retVal = _Ret.first;
return S_OK;
}, nullptr, false);
#endif
if (_Lhs.is_apartment_aware() || _Rhs.is_apartment_aware())
{
_ReturnTask._SetAsync();
}
_PParam->_M_numTasks = 2;
auto _Continuation = [_PParam](task<_ReturnType> _ResultTask) -> HRESULT {
#if _MSC_VER >= 1800
auto _PParamCopy = _PParam;
auto _Func = [&_ResultTask, _PParamCopy]() {
_PParamCopy->_M_Completed.set(std::make_pair(_ResultTask._GetImpl()->_GetResult(), reinterpret_cast<size_t>(_ResultTask._GetImpl()->_M_pTokenState)));
};
#else
auto _Func = [&_ResultTask, _PParam]() {
_PParam->_M_Completed.set(std::make_pair(_ResultTask._GetImpl()->_GetResult(), _ResultTask._GetImpl()->_M_pTokenState));
};
#endif
_WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
};
#if _MSC_VER >= 1800
_Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None());
_Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None());
#else
_Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false);
_Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false);
#endif
return _ReturnTask;
}
template<typename _ReturnType>
task<std::vector<_ReturnType>> operator||(const task<std::vector<_ReturnType>> & _Lhs, const task<_ReturnType> & _Rhs)
{
auto _PParam = new details::_RunAnyParam<std::pair<std::vector<_ReturnType>, Concurrency::details::_CancellationTokenState *>>();
task<std::pair<std::vector<_ReturnType>, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
#if _MSC_VER < 1800
_Any_tasks_completed._GetImpl()->_M_fRuntimeAggregate = true;
#endif
auto _ReturnTask = _Any_tasks_completed._Then([=](std::pair<std::vector<_ReturnType>, Concurrency::details::_CancellationTokenState *> _Ret, std::vector<_ReturnType>* retVal) -> HRESULT {
_CONCRT_ASSERT(_Ret.second);
details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Ret.second);
*retVal = _Ret.first;
return S_OK;
}, nullptr, true);
if (_Lhs.is_apartment_aware() || _Rhs.is_apartment_aware())
{
_ReturnTask._SetAsync();
}
_PParam->_M_numTasks = 2;
_Lhs._Then([_PParam](task<std::vector<_ReturnType>> _ResultTask) -> HRESULT {
#if _MSC_VER >= 1800
auto _PParamCopy = _PParam;
auto _Func = [&_ResultTask, _PParamCopy]() {
auto _Result = _ResultTask._GetImpl()->_GetResult();
_PParamCopy->_M_Completed.set(std::make_pair(_Result, _ResultTask._GetImpl()->_M_pTokenState));
};
#else
auto _Func = [&_ResultTask, _PParam]() {
std::vector<_ReturnType> _Result = _ResultTask._GetImpl()->_GetResult();
_PParam->_M_Completed.set(std::make_pair(_Result, _ResultTask._GetImpl()->_M_pTokenState));
};
#endif
_WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
#if _MSC_VER >= 1800
}, Concurrency::details::_CancellationTokenState::_None());
#else
}, Concurrency::details::_CancellationTokenState::_None(), false);
#endif
_Rhs._Then([_PParam](task<_ReturnType> _ResultTask) -> HRESULT {
#if _MSC_VER >= 1800
typedef _ReturnType _ReturnTypeDev10;
auto _PParamCopy = _PParam;
auto _Func = [&_ResultTask, _PParamCopy]() {
auto _Result = _ResultTask._GetImpl()->_GetResult();
std::vector<_ReturnTypeDev10> _Vec;
_Vec.push_back(_Result);
_PParamCopy->_M_Completed.set(std::make_pair(_Vec, _ResultTask._GetImpl()->_M_pTokenState));
};
#else
auto _Func = [&_ResultTask, _PParam]() {
_ReturnType _Result = _ResultTask._GetImpl()->_GetResult();
std::vector<_ReturnType> _Vec;
_Vec.push_back(_Result);
_PParam->_M_Completed.set(std::make_pair(_Vec, _ResultTask._GetImpl()->_M_pTokenState));
};
#endif
_WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
#if _MSC_VER >= 1800
}, Concurrency::details::_CancellationTokenState::_None());
#else
}, Concurrency::details::_CancellationTokenState::_None(), false);
#endif
return _ReturnTask;
}
template<typename _ReturnType>
task<std::vector<_ReturnType>> operator||(const task<_ReturnType> & _Lhs, const task<std::vector<_ReturnType>> & _Rhs)
{
return _Rhs || _Lhs;
}
inline task<void> operator||(const task<void> & _Lhs, const task<void> & _Rhs)
{
auto _PParam = new details::_RunAnyParam<std::pair<details::_Unit_type, Concurrency::details::_CancellationTokenState *>>();
task<std::pair<details::_Unit_type, Concurrency::details::_CancellationTokenState *>> _Any_task_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token());
auto _ReturnTask = _Any_task_completed._Then([=](std::pair<details::_Unit_type, Concurrency::details::_CancellationTokenState *> _Ret) -> HRESULT {
_CONCRT_ASSERT(_Ret.second);
details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Ret.second);
return S_OK;
#if _MSC_VER >= 1800
}, nullptr);
#else
}, nullptr, false);
#endif
if (_Lhs.is_apartment_aware() || _Rhs.is_apartment_aware())
{
_ReturnTask._SetAsync();
}
_PParam->_M_numTasks = 2;
auto _Continuation = [_PParam](task<void> _ResultTask) mutable -> HRESULT {
auto _PParam1 = _PParam;
auto _Func = [&_ResultTask, _PParam1]() {
_PParam1->_M_Completed.set(std::make_pair(details::_Unit_type(), _ResultTask._GetImpl()->_M_pTokenState));
};
_WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask);
return S_OK;
};
#if _MSC_VER >= 1800
_Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None());
_Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None());
#else
_Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false);
_Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false);
#endif
return _ReturnTask;
}
#if _MSC_VER >= 1800
template<typename _Ty>
task<_Ty> task_from_result(_Ty _Param, const task_options& _TaskOptions = task_options())
{
task_completion_event<_Ty> _Tce;
_Tce.set(_Param);
return create_task<_Ty>(_Tce, _TaskOptions);
}
#if _MSC_VER == 1600
inline task<bool> task_from_result(bool _Param)
{
task_completion_event<bool> _Tce;
_Tce.set(_Param);
return create_task<bool>(_Tce, task_options());
}
#endif
inline task<void> task_from_result(const task_options& _TaskOptions = task_options())
{
task_completion_event<void> _Tce;
_Tce.set();
return create_task<void>(_Tce, _TaskOptions);
}
template<typename _TaskType, typename _ExType>
task<_TaskType> task_from_exception(_ExType _Exception, const task_options& _TaskOptions = task_options())
{
task_completion_event<_TaskType> _Tce;
_Tce.set_exception(_Exception);
return create_task<_TaskType>(_Tce, _TaskOptions);
}
namespace details
{
inline
task<bool> do_while(std::function<task<bool>(void)> func)
{
task<bool> first = func();
return first.then([=](bool guard, task<bool>* retVal) -> HRESULT {
if (guard)
*retVal = do_while(func);
else
*retVal = first;
return S_OK;
});
}
}
#endif
}
namespace concurrency_winrt = Concurrency_winrt;
#pragma pop_macro("new")
#pragma warning(pop)
#pragma pack(pop)
#endif
#endif