// future C++0X header #pragma once #ifndef _FUTURE_ #define _FUTURE_ #ifndef RC_INVOKED #ifdef _M_CEE #error is not supported when compiling with /clr or /clr:pure. #endif /* _M_CEE */ #include #include #include #include #include #include #include #include #pragma pack(push,_CRT_PACKING) #pragma warning(push,3) #pragma push_macro("new") #undef new #pragma warning(disable: 4482 4521 4522) #if _HAS_CPP0X #else /* _HAS_CPP0X */ #error C++0X not fully supported #endif /* _HAS_CPP0X */ _STD_BEGIN // ENUM future_errc namespace future_errc { enum future_errc { // names for futures errors broken_promise = 1, future_already_retrieved, promise_already_satisfied, no_state }; } // namespace future_errc typedef future_errc::future_errc _Future_errc; // ENUM launch namespace launch { enum launch { // names for launch options passed to async async = 0x1, deferred = 0x2, any = async | deferred, // retained sync = deferred }; inline launch operator&(launch _Left, launch _Right) { return (static_cast(static_cast(_Left) & static_cast(_Right))); } inline launch operator|(launch _Left, launch _Right) { return (static_cast(static_cast(_Left) | static_cast(_Right))); } inline launch operator^(launch _Left, launch _Right) { return (static_cast(static_cast(_Left) ^ static_cast(_Right))); } inline launch operator~(launch _Left) { return (static_cast(~static_cast(_Left))); } inline launch& operator&=(launch& _Left, launch _Right) { _Left = _Left & _Right; return (_Left); } inline launch& operator|=(launch& _Left, launch _Right) { _Left = _Left | _Right; return (_Left); } inline launch& operator^=(launch& _Left, launch _Right) { _Left = _Left ^ _Right; return (_Left); } } // namespace launch typedef launch::launch _Launch_type; // ENUM future_status namespace future_status { enum future_status { // names for timed wait function returns ready, timeout, deferred }; } // namespace future_status typedef future_status::future_status _Future_status; // HELPER FUNCTIONS _CRTIMP2_PURE _NO_RETURN(__CLRCALL_PURE_OR_CDECL _Throw_future_error( const error_code& _Code)); _CRTIMP2_PURE _NO_RETURN(__CLRCALL_PURE_OR_CDECL _Rethrow_future_exception( _XSTD exception_ptr _Ptr)); // TEMPLATE CLASS SPECIALIZATION is_error_code_enum template<> struct is_error_code_enum<_Future_errc> : public true_type { // tests for error_code enumeration }; const error_category& future_category() _NOEXCEPT; inline error_code make_error_code(_Future_errc _Errno) _NOEXCEPT { // make an error_code object return (error_code(static_cast(_Errno), future_category())); } inline error_condition make_error_condition(_Future_errc _Errno) _NOEXCEPT { // make an error_condition object return (error_condition(static_cast(_Errno), future_category())); } // CLASS future_error _CRTIMP2_PURE const char *__CLRCALL_PURE_OR_CDECL _Get_future_error_what(int) _THROW0(); class future_error : public logic_error { // future exception public: explicit future_error(error_code _Errcode, const string& _Message = "") : logic_error(_Message), _Mycode(_Errcode) { // construct from error code and message string } future_error(error_code _Errcode, const char *_Message) : logic_error(_Message), _Mycode(_Errcode) { // construct from error code and message string } future_error(int _Errval, const error_category& _Errcat, const string& _Message = "") : logic_error(_Message), _Mycode(_Errval, _Errcat) { // construct from error code components and message string } future_error(int _Errval, const error_category& _Errcat, const char *_Message) : logic_error(_Message), _Mycode(_Errval, _Errcat) { // construct from error code components and message string } const error_code& code() const _THROW0() { // return stored error code return (_Mycode); } const char *__CLR_OR_THIS_CALL what() const _THROW0() { // get message string return (_Get_future_error_what(_Mycode.value())); } #if _HAS_EXCEPTIONS #else /* _HAS_EXCEPTIONS */ protected: virtual void _Doraise() const { // perform class-specific exception handling _RAISE(*this); } #endif /* _HAS_EXCEPTIONS */ private: error_code _Mycode; // the stored error code }; _CRTIMP2_PURE const char *__CLRCALL_PURE_OR_CDECL _Future_error_map(int); // CLASS _Future_error_category class _Future_error_category : public _Generic_error_category { // categorize a future error public: _Future_error_category() { // default constructor } virtual const char *name() const _NOEXCEPT { // get name of category return ("future"); } virtual string message(int _Errcode) const { // convert to name of error const char *_Name = _Future_error_map(_Errcode); if (_Name != 0) return (_Name); else return (_Generic_error_category::message(_Errcode)); } }; template struct _Future_error_object { // reports a future error _Future_error_object() { // default constructor } static _Future_error_category _Future_object; }; template _Future_error_category _Future_error_object<_Cat>::_Future_object; inline const error_category& future_category() _NOEXCEPT { // return error_category object for future return (_Future_error_object::_Future_object); } // TEMPLATE STRUCT _State_deleter template class _Associated_state; template struct _State_deleter; template void _Delete_state(_Alloc _Al, _Associated_state<_Ty> *_State, _State_deleter<_Ty, _Alloc> *); template struct _Deleter_base { // abstract base class for managing deletion of state objects virtual void _Delete(_Associated_state<_Ty> *) = 0; virtual ~_Deleter_base() _NOEXCEPT { } }; template struct _State_deleter : _Deleter_base<_Ty> { // manage allocator and deletion state objects _State_deleter(_Alloc _Al) : _My_alloc(_Al) { // construct with allocator } _State_deleter(const _State_deleter& _Other) : _My_alloc(_Other._My_alloc) { // copy from _Other } template _State_deleter(const _State_deleter<_Ty, _Alloc2>& _Other) : _My_alloc(_Other._My_alloc) { // copy from _Other } void _Delete(_Associated_state<_Ty> *_State) { // delete _State using stored allocator _Delete_state(_My_alloc, _State, this); } _Alloc _My_alloc; }; // TEMPLATE CLASS _Associated_state template class _Associated_state { // class for managing associated synchronous state public: typedef _Ty _State_type; _Associated_state(_Deleter_base<_Ty> *_Dp = 0) : _Exception(), _Retrieved(false), _Running(false), _Ready(false), _Ready_at_thread_exit(false), _Has_stored_result(false), _Deleter(_Dp) { // construct // TODO: _Associated_state ctor assumes _Ty is default constructible _Init_refs(); } virtual ~_Associated_state() _NOEXCEPT { // destroy if (_Has_stored_result && !_Ready) { // registered for release at thread exit _Cond._Unregister(_Mtx); } _Destroy_refs(); } void _Retain() { // increment reference count _MT_INCR(_Mtx0, _Refs); } void _Release() { // decrement reference count and destroy when zero if (_MT_DECR(_Mtx0, _Refs) == 0) _Delete_this(); } private: _Atomic_counter_t _Refs; public: void _Init_refs() { // initialize reference count _Init_atomic_counter(_Refs, 1); } void _Destroy_refs() { // destroy reference count } virtual void _Wait() { // wait for signal unique_lock _Lock(_Mtx); _Maybe_run_deferred_function(_Lock); while (!_Ready) _Cond.wait(_Lock); } struct _Test_ready { // wraps _Associated_state _Test_ready(const _Associated_state *_St) : _State(_St) { // construct from associated state } bool operator()() const { // test state return (_State->_Ready != 0); } const _Associated_state *_State; }; template _Future_status _Wait_for( const chrono::duration<_Rep, _Per>& _Rel_time) { // wait for duration _Future_status _Res = _Future_status::ready; unique_lock _Lock(_Mtx); if (!_Running) _Res = _Future_status::deferred; else { // do the wait bool _Cv_state = _Cond.wait_for(_Lock, _Rel_time, _Test_ready(this)); if (!_Cv_state) _Res = _Future_status::timeout; } return (_Res); } template _Future_status _Wait_until( const chrono::time_point<_Clock, _Dur>& _Abs_time) { // wait until time point _Future_status _Res = _Future_status::ready; unique_lock _Lock(_Mtx); if (!_Running) _Res = _Future_status::deferred; else { // do the wait bool _Cv_state = _Cond.wait_until(_Lock, _Abs_time, _Test_ready(this)); if (!_Cv_state) _Res = _Future_status::timeout; } return (_Res); } virtual _Ty& _Get_value(bool _Get_only_once) { // return the stored result or throw stored exception unique_lock _Lock(_Mtx); if (_Get_only_once && _Retrieved) _Throw_future_error( make_error_code(future_errc::future_already_retrieved)); if (_Exception) _Rethrow_future_exception(_Exception); _Retrieved = true; _Maybe_run_deferred_function(_Lock); while (!_Ready) _Cond.wait(_Lock); if (_Exception) _Rethrow_future_exception(_Exception); return (_Result); } void _Set_value(const _Ty& _Val, bool _At_thread_exit) { // store a result unique_lock _Lock(_Mtx); _Set_value_raw(_Val, &_Lock, _At_thread_exit); } void _Set_value_raw(const _Ty& _Val, unique_lock *_Lock, bool _At_thread_exit) { // store a result while inside a locked block if (_Has_stored_result) _Throw_future_error( make_error_code(future_errc::promise_already_satisfied)); _Result = _Val; _Do_notify(_Lock, _At_thread_exit); } void _Set_value(_Ty&& _Val, bool _At_thread_exit) { // store a result unique_lock _Lock(_Mtx); _Set_value_raw(_STD forward<_Ty>(_Val), &_Lock, _At_thread_exit); } void _Set_value_raw(_Ty&& _Val, unique_lock *_Lock, bool _At_thread_exit) { // store a result while inside a locked block if (_Has_stored_result) _Throw_future_error( make_error_code(future_errc::promise_already_satisfied)); _Result = _STD forward<_Ty>(_Val); _Do_notify(_Lock, _At_thread_exit); } void _Set_value(bool _At_thread_exit) { // store a (void) result unique_lock _Lock(_Mtx); _Set_value_raw(&_Lock, _At_thread_exit); } void _Set_value_raw(unique_lock *_Lock, bool _At_thread_exit) { // store a (void) result while inside a locked block if (_Has_stored_result) _Throw_future_error( make_error_code(future_errc::promise_already_satisfied)); _Do_notify(_Lock, _At_thread_exit); } void _Set_exception(_XSTD exception_ptr _Exc, bool _At_thread_exit) { // store a result unique_lock _Lock(_Mtx); _Set_exception_raw(_Exc, &_Lock, _At_thread_exit); } struct _Anon { // anonymous type }; void _Set_exception_raw(_XSTD exception_ptr _Exc, unique_lock *_Lock, bool _At_thread_exit) { // store a result while inside a locked block if (_Has_stored_result) _Throw_future_error( make_error_code(future_errc::promise_already_satisfied)); _Exception = _Exc; if (!_Exc) { // make a non-null exception_ptr _Exception = make_exception_ptr(_Anon()); } _Do_notify(_Lock, _At_thread_exit); } bool _Is_ready() const { // return ready status return (_Ready != 0); } bool _Already_retrieved() const { // return retrieved status return (_Retrieved); } protected: void _Make_ready_at_thread_exit() { // set ready status at thread exit if (_Ready_at_thread_exit) _Ready = true; } void _Maybe_run_deferred_function(unique_lock& _Lock) { // run a deferred function if not already done if (!_Running) { // run the function _Running = true; _Run_deferred_function(_Lock); } } _Ty _Result; _XSTD exception_ptr _Exception; mutex _Mtx; condition_variable _Cond; bool _Retrieved; int _Ready; bool _Ready_at_thread_exit; bool _Has_stored_result; bool _Running; private: virtual void _Run_deferred_function(unique_lock&) { // do nothing } virtual void _Do_notify(unique_lock *_Lock, bool _At_thread_exit) { // notify waiting threads _Has_stored_result = true; if (_At_thread_exit) { // notify at thread exit _Cond._Register(*_Lock, &_Ready); } else { // notify immediately _Ready = true; _Cond.notify_all(); } } void _Delete_this() { // delete this object if (_Deleter) _Deleter->_Delete(this); else delete this; } _Deleter_base<_Ty> *_Deleter; _Associated_state(const _Associated_state&); // not defined _Associated_state& operator=( const _Associated_state&) const; // not defined }; // TEMPLATE FUNCTION _Delete_state template inline void _Delete_state(_Alloc _Al, _Associated_state<_Ty> *_State, _State_deleter<_Ty, _Alloc> *_Deleter) { // delete _State and _Deleter using allocator _Al typedef typename _Alloc::template rebind<_Associated_state<_Ty> > ::other _State_allocator; _State_allocator _St_alloc(_Al); _St_alloc.destroy(_State); _St_alloc.deallocate(_State, 1); typedef typename _Alloc::template rebind<_State_deleter<_Ty, _Alloc> > ::other _Deleter_allocator; _Deleter_allocator _Del_alloc(_Al); _Del_alloc.destroy(_Deleter); _Del_alloc.deallocate(_Deleter, 1); } // TEMPLATE CLASS _Packaged_state template class _Packaged_state; #define _CLASS_PACKAGED_STATE( \ TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \ template \ class _Packaged_state<_Ret(LIST(_TYPE))> \ : public _Associated_state<_Ret> \ { /* manages associated asynchronous state for packaged_task */ \ public: \ template \ _Packaged_state(const _Fty2& _Fnarg) \ : _Fn(_Fnarg) \ { /* construct from function object */ \ } \ template \ _Packaged_state(const _Fty2& _Fnarg, const _Alloc& _Al, \ _Deleter_base<_Ret> *_Dp) \ : _Associated_state<_Ret>(_Dp), _Fn(_Fnarg, _Al) \ { /* construct from function object and allocator */ \ } \ template \ _Packaged_state(_Fty2&& _Fnarg) \ : _Fn(_STD forward<_Fty2>(_Fnarg)) \ { /* construct from rvalue function object */ \ } \ template \ _Packaged_state(_Fty2&& _Fnarg, const _Alloc& _Al, \ _Deleter_base<_Ret> *_Dp) \ : _Associated_state<_Ret>(_Dp), \ _Fn(_STD forward<_Fty2>(_Fnarg), _Al) \ { /* construct from rvalue function object and allocator */ \ } \ _Packaged_state(const function<_Ret(LIST(_TYPE))>& _NewFn, \ bool) \ : _Fn(_NewFn) \ { /* construct from our own stored function type */ \ } \ void _Call_deferred(LIST(_TYPE_ARG)) \ { /* set deferred call */ \ _TRY_BEGIN \ /* call function object and catch exceptions */ \ this->_Set_value(_Fn(LIST(_FORWARD_ARG)), true); \ _CATCH_ALL \ /* function object threw exception; record result */ \ this->_Set_exception(_XSTD current_exception(), true); \ _CATCH_END \ } \ void _Call_immediate(LIST(_TYPE_ARG)) \ { /* call function object */ \ _TRY_BEGIN \ /* call function object and catch exceptions */ \ this->_Set_value(_Fn(LIST(_FORWARD_ARG)), false); \ _CATCH_ALL \ /* function object threw exception; record result */ \ this->_Set_exception(_XSTD current_exception(), false); \ _CATCH_END \ } \ const function<_Ret(LIST(_TYPE))>& _Get_fn() \ { /* return stored function object */ \ return (_Fn); \ } \ private: \ function<_Ret(LIST(_TYPE))> _Fn; \ }; _VARIADIC_EXPAND_0X(_CLASS_PACKAGED_STATE, , , , ) #undef _CLASS_PACKAGED_STATE #define _CLASS_PACKAGED_STATE_REF( \ TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \ template \ class _Packaged_state<_Ret&(LIST(_TYPE))> \ : public _Associated_state<_Ret *> \ { /* manages associated asynchronous state for packaged_task */ \ public: \ template \ _Packaged_state(const _Fty2& _Fnarg) \ : _Fn(_Fnarg) \ { /* construct from function object */ \ } \ template \ _Packaged_state(const _Fty2& _Fnarg, const _Alloc& _Al, \ _Deleter_base<_Ret> *_Dp) \ : _Associated_state<_Ret *>(_Dp), _Fn(_Fnarg, _Al) \ { /* construct from function object and allocator */ \ } \ template \ _Packaged_state(_Fty2&& _Fnarg) \ : _Fn(_STD forward<_Fty2>(_Fnarg)) \ { /* construct from rvalue function object */ \ } \ template \ _Packaged_state(_Fty2&& _Fnarg, const _Alloc& _Al, \ _Deleter_base<_Ret> *_Dp) \ : _Associated_state<_Ret *>(_Dp), \ _Fn(_STD forward<_Fty2>(_Fnarg), _Al) \ { /* construct from rvalue function object and allocator */ \ } \ _Packaged_state(const function<_Ret&(LIST(_TYPE))>& _NewFn, \ bool) \ : _Fn(_NewFn) \ { /* construct from our own stored function type */ \ } \ void _Call_deferred(LIST(_TYPE_ARG)) \ { /* set deferred call */ \ _TRY_BEGIN \ /* call function object and catch exceptions */ \ this->_Set_value(&_Fn(LIST(_FORWARD_ARG)), true); \ _CATCH_ALL \ /* function object threw exception; record result */ \ this->_Set_exception(_XSTD current_exception(), true); \ _CATCH_END \ } \ void _Call_immediate(LIST(_TYPE_ARG)) \ { /* call function object */ \ _TRY_BEGIN \ /* call function object and catch exceptions */ \ this->_Set_value(&_Fn(LIST(_FORWARD_ARG)), false); \ _CATCH_ALL \ /* function object threw exception; record result */ \ this->_Set_exception(_XSTD current_exception(), false); \ _CATCH_END \ } \ const function<_Ret&(LIST(_TYPE))>& _Get_fn() \ { /* return stored function object */ \ return (_Fn); \ } \ private: \ function<_Ret&(LIST(_TYPE))> _Fn; \ }; _VARIADIC_EXPAND_0X(_CLASS_PACKAGED_STATE_REF, , , , ) #undef _CLASS_PACKAGED_STATE_REF #define _CLASS_PACKAGED_STATE_VOID( \ TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \ template \ class _Packaged_state \ : public _Associated_state \ { /* manages associated asynchronous state for packaged_task */ \ public: \ template \ _Packaged_state(const _Fty2& _Fnarg) \ : _Fn(_Fnarg) \ { /* construct from function object */ \ } \ template \ _Packaged_state(const _Fty2& _Fnarg, const _Alloc& _Al, \ _Deleter_base *_Dp) \ : _Associated_state(_Dp), _Fn(_Fnarg, _Al) \ { /* construct from function object and allocator */ \ } \ template \ _Packaged_state(_Fty2&& _Fnarg) \ : _Fn(_STD forward<_Fty2>(_Fnarg)) \ { /* construct from rvalue function object */ \ } \ template \ _Packaged_state(_Fty2&& _Fnarg, const _Alloc& _Al, \ _Deleter_base *_Dp) \ : _Associated_state(_Dp), \ _Fn(_STD forward<_Fty2>(_Fnarg), _Al) \ { /* construct from rvalue function object and allocator */ \ } \ _Packaged_state(const function& _NewFn, \ bool) \ : _Fn(_NewFn) \ { /* construct from our own stored function type */ \ } \ void _Call_deferred(LIST(_TYPE_ARG)) \ { /* set deferred call */ \ _TRY_BEGIN \ /* call function object and catch exceptions */ \ _Fn(LIST(_FORWARD_ARG)); \ this->_Set_value(1, true); \ _CATCH_ALL \ /* function object threw exception; record result */ \ this->_Set_exception(_XSTD current_exception(), true); \ _CATCH_END \ } \ void _Call_immediate(LIST(_TYPE_ARG)) \ { /* call function object */ \ _TRY_BEGIN \ /* call function object and catch exceptions */ \ _Fn(LIST(_FORWARD_ARG)); \ this->_Set_value(1, false); \ _CATCH_ALL \ /* function object threw exception; record result */ \ this->_Set_exception(_XSTD current_exception(), false); \ _CATCH_END \ } \ const function& _Get_fn() \ { /* return stored function object */ \ return (_Fn); \ } \ private: \ function _Fn; \ }; _VARIADIC_EXPAND_0X(_CLASS_PACKAGED_STATE_VOID, , , , ) #undef _CLASS_PACKAGED_STATE_VOID template inline _Associated_state<_Ty> *_Make_associated_state(_Allocx _Al) { // construct an _Associated_state object with an allocator typedef _Wrap_alloc<_Allocx> _Alloc; typedef typename _Alloc::template rebind<_Associated_state<_Ty> > ::other _State_allocator; _State_allocator _St_alloc(_Al); typedef typename _Alloc::template rebind<_State_deleter<_Ty, _Alloc> > ::other _Deleter_allocator; _Deleter_allocator _Del_alloc(_Al); _State_deleter<_Ty, _Alloc> *_Del = _Del_alloc.allocate(1); _Del_alloc.construct(_Del, _St_alloc); _Associated_state<_Ty> *_Res = _St_alloc.allocate(1); _St_alloc.construct(_Res, _Del); return (_Res); } template inline _Associated_state<_Ty> *_Make_packaged_state(const _Fty& _Fn, const _Allocx& _Al) { // construct a _Packaged_state object with an allocator typedef _Wrap_alloc<_Allocx> _Alloc; typedef typename _Alloc::template rebind<_Packaged_state<_Fty> > ::other _State_allocator; _State_allocator _St_alloc(_Al); typedef typename _Alloc::template rebind<_State_deleter<_Fty, _Alloc> > ::other _Deleter_allocator; _Deleter_allocator _Del_alloc(_Al); _State_deleter<_Fty, _Alloc> *_Del = _Del_alloc.allocate(1); _Del_alloc.construct(_Del, _St_alloc); _Packaged_state<_Fty> *_Res = _St_alloc.allocate(1); _St_alloc.construct(_Res, _Fn, _Del); return (_Res); } template inline _Associated_state<_Ty> *_Make_packaged_state(_Fty&& _Fn, const _Alloc& _Al) { // construct a _Packaged_state object with an allocator from // an rvalue function object typedef typename _Alloc::template rebind<_Packaged_state<_Fty> > ::other _State_allocator; _State_allocator _St_alloc(_Al); typedef typename _Alloc::template rebind<_State_deleter<_Fty, _Alloc> > ::other _Deleter_allocator; _Deleter_allocator _Del_alloc(_Al); _State_deleter<_Fty, _Alloc> *_Del = _Del_alloc.allocate(1); _Del_alloc.construct(_Del, _St_alloc); _Packaged_state<_Fty> *_Res = _St_alloc.allocate(1); _St_alloc.construct(_Res, _STD forward<_Fty>(_Fn), _Del); return (_Res); } // TEMPLATE CLASS _Deferred_async_state template class _Deferred_async_state : public _Packaged_state<_Rx()> { // class for managing associated synchronous state for deferred // execution from async public: template _Deferred_async_state(const _Fty2& _Fnarg) : _Packaged_state<_Rx()>(_Fnarg) { // construct from function object } template _Deferred_async_state(_Fty2&& _Fnarg) : _Packaged_state<_Rx()>(_STD forward<_Fty2>(_Fnarg)) { // construct from rvalue function object } private: void _Run_deferred_function(unique_lock& _Lock) { // run the deferred function _Lock.unlock(); _Packaged_state<_Rx()>::_Call_immediate(); _Lock.lock(); } }; // TEMPLATE CLASS _Task_async_state template class _Task_async_state : public _Packaged_state<_Rx()> { // class for managing associated synchronous state for asynchronous // execution from async public: typedef _Packaged_state<_Rx()> _Mybase; typedef typename _Mybase::_State_type _State_type; template _Task_async_state(_Fty2&& _Fnarg) : _Mybase(_STD forward<_Fty2>(_Fnarg)) { // construct from rvalue function object this->_Retain(); // to support fire-and-forget future _Task = ::Concurrency::create_task([this]() { // do it now if (_Inline) _Call_immediate(); else { // turn on oversubscription for launch::async ::Concurrency::details::_Context::_Oversubscribe(true); _Call_immediate(); ::Concurrency::details::_Context::_Oversubscribe(false); } _Release(); }); _Running = true; } virtual void _Wait() { // wait for completion if (_Inline) _Task.wait(); else _Mybase::_Wait(); } virtual _State_type& _Get_value(bool _Get_only_once) { // return the stored result or throw stored exception if (_Inline) _Task.wait(); return (_Mybase::_Get_value(_Get_only_once)); } private: ::Concurrency::task _Task; }; // TEMPLATE CLASS _State_manager template class _State_manager { // class for managing possibly non-existent associated // asynchronous state object public: _State_manager() : _Assoc_state(0) { // construct with no associated asynchronous state object _Get_only_once = false; } _State_manager(_Associated_state<_Ty> *_New_state, bool _Get_once) : _Assoc_state(_New_state) { // construct with _New_state _Get_only_once = _Get_once; } _State_manager(const _State_manager& _Other, bool _Get_once = false) : _Assoc_state(0) { // construct from _Other _Copy_from(_Other); _Get_only_once = _Get_once; } _State_manager(_State_manager&& _Other, bool _Get_once = false) : _Assoc_state(0) { // construct from rvalue _Other _Move_from(_Other); _Get_only_once = _Get_once; } ~_State_manager() _NOEXCEPT { // destroy if (_Assoc_state != 0) _Assoc_state->_Release(); } _State_manager& operator=(const _State_manager& _Other) { // assign from _Other _Copy_from(_Other); return (*this); } _State_manager& operator=(_State_manager&& _Other) { // assign from rvalue _Other _Move_from(_Other); return (*this); } bool valid() const _NOEXCEPT { // return status return (_Assoc_state != 0 && !(_Get_only_once && _Assoc_state->_Already_retrieved())); } void wait() const { // wait for signal if (!valid()) _Throw_future_error(make_error_code(future_errc::no_state)); _Assoc_state->_Wait(); } template _Future_status wait_for( const chrono::duration<_Rep, _Per>& _Rel_time) const { // wait for duration if (!valid()) _Throw_future_error(make_error_code(future_errc::no_state)); return (_Assoc_state->_Wait_for(_Rel_time)); } template _Future_status wait_until( const chrono::time_point<_Clock, _Dur>& _Abs_time) const { // wait until time point if (!valid()) _Throw_future_error(make_error_code(future_errc::no_state)); return (_Assoc_state->_Wait_until(_Abs_time)); } _Ty& _Get_value() const { // return the stored result or throw stored exception if (!valid()) _Throw_future_error( make_error_code(future_errc::no_state)); return (_Assoc_state->_Get_value(_Get_only_once)); } void _Set_value(const _Ty& _Val, bool _Defer) { // store a result if (!valid()) _Throw_future_error( make_error_code(future_errc::no_state)); _Assoc_state->_Set_value(_Val, _Defer); } void _Set_value(_Ty&& _Val, bool _Defer) { // store a result if (!valid()) _Throw_future_error( make_error_code(future_errc::no_state)); _Assoc_state->_Set_value(_STD forward<_Ty>(_Val), _Defer); } void _Set_exception(_XSTD exception_ptr _Exc, bool _Defer) { // store a result if (!valid()) _Throw_future_error( make_error_code(future_errc::no_state)); _Assoc_state->_Set_exception(_Exc, _Defer); } void _Swap(_State_manager& _Other) { // exchange with _Other _STD swap(_Assoc_state, _Other._Assoc_state); } _Associated_state<_Ty> *_Ptr() const { // return pointer to stored associated asynchronous state object return (_Assoc_state); } void _Copy_from(const _State_manager& _Other) { // copy stored associated asynchronous state object from _Other if (this != &_Other) { // different, copy if (_Assoc_state) _Assoc_state->_Release(); if (_Other._Assoc_state == 0) _Assoc_state = 0; else { // do the copy _Other._Assoc_state->_Retain(); _Assoc_state = _Other._Assoc_state; _Get_only_once = _Other._Get_only_once; } } } void _Move_from(_State_manager& _Other) { // move stored associated asynchronous state object from _Other if (this != &_Other) { // different, move if (_Assoc_state) _Assoc_state->_Release(); _Assoc_state = _Other._Assoc_state; _Other._Assoc_state = 0; _Get_only_once = _Other._Get_only_once; } } bool _Is_ready() const { // return status return (_Assoc_state && _Assoc_state->_Is_ready()); } private: _Associated_state<_Ty> *_Assoc_state; bool _Get_only_once; }; // TEMPLATE CLASS future template class shared_future; template class future : public _State_manager<_Ty> { // class that defines a non-copyable asynchronous return object // that holds a value typedef _State_manager<_Ty> _Mybase; public: future() _NOEXCEPT { // construct } future(future&& _Other) _NOEXCEPT : _Mybase(_STD forward(_Other), true) { // construct from rvalue future object } future& operator=(future&& _Right) _NOEXCEPT { // assign from rvalue future object _Mybase::operator=(_STD forward(_Right)); return (*this); } future(const _Mybase& _State) : _Mybase(_State, true) { // construct from associated asynchronous state object } ~future() _NOEXCEPT { // destroy } _Ty get() { // block until ready then return the stored result or // throw the stored exception return (_STD move(this->_Get_value())); } shared_future<_Ty> share() { // return state as shared_future return (shared_future<_Ty>(_STD move(*this))); } private: future(const future& _Other); future& operator=(const future& _Right); }; template class future<_Ty&> : public _State_manager<_Ty *> { // class that defines a non-copyable asynchronous return object // that holds a reference typedef _State_manager<_Ty *> _Mybase; public: future() _NOEXCEPT { // construct } future(future&& _Other) _NOEXCEPT : _Mybase(_STD forward(_Other), true) { // construct from rvalue future object } future& operator=(future&& _Right) _NOEXCEPT { // assign from rvalue future object _Mybase::operator=(_STD forward(_Right)); return (*this); } future(const _Mybase& _State) : _Mybase(_State, true) { // construct from associated asynchronous state object } ~future() _NOEXCEPT { // destroy } _Ty& get() { // block until ready then return the stored result or // throw the stored exception return (*this->_Get_value()); } shared_future<_Ty&> share() { // return state as shared_future return (shared_future<_Ty&>(_STD move(*this))); } private: future(const future& _Other); future& operator=(const future& _Right); }; template<> class future : public _State_manager { // class that defines a non-copyable asynchronous return object // that does not hold a value typedef _State_manager _Mybase; public: future() _NOEXCEPT { // construct } future(future&& _Other) _NOEXCEPT : _Mybase(_STD forward(_Other), true) { // construct from rvalue future object } future& operator=(future&& _Right) _NOEXCEPT { // assign from rvalue future object _Mybase::operator=(_STD forward(_Right)); return (*this); } future(const _Mybase& _State) : _Mybase(_State, true) { // construct from associated asynchronous state object } ~future() _NOEXCEPT { // destroy } void get() { // block until ready then return or // throw the stored exception this->_Get_value(); } shared_future share(); private: future(const future& _Other); future& operator=(const future& _Right); }; // TEMPLATE CLASS shared_future template class shared_future : public _State_manager<_Ty> { // class that defines a copyable asynchronous return object // that holds a value typedef _State_manager<_Ty> _Mybase; public: shared_future() _NOEXCEPT { // construct } shared_future(const shared_future& _Other) : _Mybase(_Other) { // construct from shared_future object } shared_future& operator=(const shared_future& _Right) { // assign from shared_future object _Mybase::operator=(_Right); return (*this); } shared_future(future<_Ty>&& _Other) _NOEXCEPT : _Mybase(_STD forward<_Mybase>(_Other)) { // construct from rvalue future object } shared_future(shared_future&& _Other) _NOEXCEPT : _Mybase(_STD forward(_Other)) { // construct from rvalue shared_future object } shared_future& operator=(shared_future&& _Right) _NOEXCEPT { // assign from shared_future rvalue object _Mybase::operator=(_STD forward(_Right)); return (*this); } ~shared_future() _NOEXCEPT { // destroy } const _Ty& get() const { // block until ready then return the stored result or // throw the stored exception return (this->_Get_value()); } }; template class shared_future<_Ty&> : public _State_manager<_Ty *> { // class that defines a copyable asynchronous return object // that holds a reference typedef _State_manager<_Ty *> _Mybase; public: shared_future() _NOEXCEPT { // construct } shared_future(const future<_Ty&>& _Other) : _Mybase(_Other) { // construct from rvalue future object } shared_future(const shared_future& _Other) : _Mybase(_Other) { // construct from shared_future object } shared_future& operator=(const shared_future& _Right) { // assign from shared_future object _Mybase::operator=(_Right); return (*this); } shared_future(future<_Ty&>&& _Other) _NOEXCEPT : _Mybase(_STD forward<_Mybase>(_Other)) { // construct from rvalue future object } shared_future(shared_future&& _Other) _NOEXCEPT : _Mybase(_STD forward(_Other)) { // construct from rvalue shared_future object } shared_future& operator=(shared_future&& _Right) _NOEXCEPT { // assign from rvalue shared_future object _Mybase::operator=(_STD forward(_Right)); return (*this); } ~shared_future() _NOEXCEPT { // destroy } _Ty& get() const { // block until ready then return the stored result or // throw the stored exception return (*this->_Get_value()); } }; template<> class shared_future : public _State_manager { // class that defines a copyable asynchronous return object // that does not hold a value typedef _State_manager _Mybase; public: shared_future() _NOEXCEPT { // construct } shared_future(const shared_future& _Other) : _Mybase(_Other) { // construct from shared_future object } shared_future(const future& _Other) : _Mybase(_Other) { // construct from rvalue future object } shared_future& operator=(const shared_future& _Right) { // assign from shared_future object _Mybase::operator=(_Right); return (*this); } shared_future(shared_future&& _Other) _NOEXCEPT : _Mybase(_STD forward(_Other)) { // construct from rvalue shared_future object } shared_future(future&& _Other) _NOEXCEPT : _Mybase(_STD forward<_Mybase>(_Other)) { // construct from rvalue future object } shared_future& operator=(shared_future&& _Right) { // assign from rvalue shared_future object _Mybase::operator=(_STD forward(_Right)); return (*this); } ~shared_future() _NOEXCEPT { // destroy } void get() const { // block until ready then return or // throw the stored exception this->_Get_value(); } }; // DEFINITION OF future::share() inline shared_future future::share() { // return state as shared_future return (shared_future(_STD move(*this))); } // TEMPLATE CLASS _Promise template class _Promise { // class that implements core of promise public: _Promise(_Associated_state<_Ty> *_State_ptr) : _State(_State_ptr, false), _Future_retrieved(false) { // construct from associated asynchronous state object } _Promise(_Promise&& _Other) : _State(_STD forward<_State_manager<_Ty> >(_Other._State)), _Future_retrieved(_Other._Future_retrieved) { // construct from rvalue _Promise object } _Promise& operator=(_Promise&& _Other) { // assign from rvalue _Promise object _State = _STD move(_Other._State); _Future_retrieved = _Other._Future_retrieved; return (*this); } ~_Promise() _NOEXCEPT { // destroy } void _Swap(_Promise& _Other) { // exchange with _Other _State._Swap(_Other._State); _STD swap(_Future_retrieved, _Other._Future_retrieved); } const _State_manager<_Ty>& _Get_state() const { // return reference to associated asynchronous state object return (_State); } _State_manager<_Ty>& _Get_state() { // return reference to associated asynchronous state object return (_State); } _State_manager<_Ty>& _Get_state_for_set() { // return reference to associated asynchronous state object, or // throw exception if not valid for setting state if (!_State.valid()) _Throw_future_error( make_error_code(future_errc::no_state)); return (_State); } _State_manager<_Ty>& _Get_state_for_future() { // return reference to associated asynchronous state object, or // throw exception if not valid for retrieving future if (!_State.valid()) _Throw_future_error( make_error_code(future_errc::no_state)); if (_Future_retrieved) _Throw_future_error( make_error_code(future_errc::future_already_retrieved)); _Future_retrieved = true; return (_State); } bool _Is_valid() const { // return status return (_State.valid()); } bool _Is_ready() const { // return status return (_State._Is_ready()); } private: _State_manager<_Ty> _State; bool _Future_retrieved; _Promise(const _Promise&); // not defined _Promise& operator=(const _Promise&); // not defined }; // TEMPLATE CLASS promise template class promise { // class that defines an asynchronous provider that holds a value public: promise() : _MyPromise(new _Associated_state<_Ty>) { // construct } template promise(allocator_arg_t, const _Alloc& _Al) : _MyPromise(_Make_associated_state<_Ty>(_Al)) { // construct with allocator } promise(promise&& _Other) _NOEXCEPT : _MyPromise(_STD forward<_Promise<_Ty> >(_Other._MyPromise)) { // construct from rvalue promise object } promise& operator=(promise&& _Other) _NOEXCEPT { // assign from rvalue promise object _MyPromise = _STD forward<_Promise<_Ty> >(_Other._MyPromise); return (*this); } ~promise() _NOEXCEPT { // destroy if (_MyPromise._Is_valid() && !_MyPromise._Is_ready()) { // exception if destroyed before function object returns future_error _Fut(make_error_code(future_errc::broken_promise)); _MyPromise._Get_state() ._Set_exception(_XSTD make_exception_ptr(_Fut), false); } } void swap(promise& _Other) _NOEXCEPT { // exchange with _Other _MyPromise._Swap(_Other._MyPromise); } future<_Ty> get_future() { // return a future object that shares the associated // asynchronous state return (future<_Ty>(_MyPromise._Get_state_for_future())); } void set_value(const _Ty& _Val) { // store result _MyPromise._Get_state_for_set()._Set_value(_Val, false); } void set_value_at_thread_exit(const _Ty& _Val) { // store result and block until thread exit _MyPromise._Get_state_for_set()._Set_value(_Val, true); } void set_value(_Ty&& _Val) { // store result _MyPromise._Get_state_for_set()._Set_value(_STD forward<_Ty>(_Val), false); } void set_value_at_thread_exit(_Ty&& _Val) { // store result and block until thread exit _MyPromise._Get_state_for_set()._Set_value(_STD forward<_Ty>(_Val), true); } void set_exception(_XSTD exception_ptr _Exc) { // store result _MyPromise._Get_state_for_set()._Set_exception(_Exc, false); } void set_exception_at_thread_exit(_XSTD exception_ptr _Exc) { // store result and block until thread exit _MyPromise._Get_state_for_set()._Set_exception(_Exc, true); } private: _Promise<_Ty> _MyPromise; promise(const promise&); // not defined promise& operator=(const promise&); // not defined }; template class promise<_Ty&> { // class that defines an asynchronous provider that holds a reference public: promise() : _MyPromise(new _Associated_state<_Ty *>) { // construct } template promise(allocator_arg_t, const _Alloc& _Al) : _MyPromise(_Make_associated_state<_Ty *>(_Al)) { // construct with allocator } promise(promise&& _Other) _NOEXCEPT : _MyPromise(_STD forward<_Promise<_Ty *> >(_Other._MyPromise)) { // construct from rvalue promise object } promise& operator=(promise&& _Other) _NOEXCEPT { // assign from rvalue promise object _MyPromise = _STD forward<_Promise<_Ty *> >(_Other._MyPromise); return (*this); } ~promise() _NOEXCEPT { // destroy } void swap(promise& _Other) _NOEXCEPT { // exchange with _Other _MyPromise._Swap(_Other._MyPromise); } future<_Ty&> get_future() { // return a future object that shares the associated // asynchronous state return (future<_Ty&>(_MyPromise._Get_state_for_future())); } void set_value(_Ty& _Val) { // store result _MyPromise._Get_state_for_set()._Set_value(&_Val, false); } void set_value_at_thread_exit(_Ty& _Val) { // store result and block until thread exit _MyPromise._Get_state_for_set()._Set_value(&_Val, true); } void set_exception(_XSTD exception_ptr _Exc) { // store result _MyPromise._Get_state_for_set()._Set_exception(_Exc, false); } void set_exception_at_thread_exit(_XSTD exception_ptr _Exc) { // store result and block until thread exit _MyPromise._Get_state_for_set()._Set_exception(_Exc, true); } private: _Promise<_Ty *> _MyPromise; }; template<> class promise { // defines an asynchronous provider that does not hold a value public: promise() : _MyPromise(new _Associated_state) { // construct } template promise(allocator_arg_t, const _Alloc& _Al) : _MyPromise(_Make_associated_state(_Al)) { // construct with allocator } promise(promise&& _Other) _NOEXCEPT : _MyPromise(_STD forward<_Promise >(_Other._MyPromise)) { // construct from rvalue promise object } promise& operator=(promise&& _Other) _NOEXCEPT { // assign from rvalue promise object _MyPromise = _STD forward<_Promise >(_Other._MyPromise); return (*this); } ~promise() _NOEXCEPT { // destroy } void swap(promise& _Other) _NOEXCEPT { // exchange with _Other _MyPromise._Swap(_Other._MyPromise); } future get_future() { // return a future object that shares the associated // asynchronous state future _Fut(_MyPromise._Get_state_for_future()); return (_Fut); } void set_value() { // store a (void) result _MyPromise._Get_state_for_set()._Set_value(1, false); } void set_value_at_thread_exit() { // store result and block until thread exit _MyPromise._Get_state_for_set()._Set_value(1, true); } void set_exception(_XSTD exception_ptr _Exc) { // store a result _MyPromise._Get_state_for_set()._Set_exception(_Exc, false); } void set_exception_at_thread_exit(_XSTD exception_ptr _Exc) { // store result and block until thread exit _MyPromise._Get_state_for_set()._Set_exception(_Exc, true); } private: _Promise _MyPromise; }; template inline void swap(promise<_Ty>& _Left, promise<_Ty>& _Right) _NOEXCEPT { // exchange _Left and _Right _Left.swap(_Right); } // TEMPLATE CLASS packaged_task template struct _P_arg_type { // type for function typedef _Fret type; }; template struct _P_arg_type<_Fret&> { // type for ref to function typedef _Fret *type; }; template <> struct _P_arg_type { // type for void function typedef int type; }; template class packaged_task; // not defined #define _PACKAGED_TASK_FUNCTION_DELETES \ private: \ packaged_task(const packaged_task&); /* not defined */ \ packaged_task& operator=(const packaged_task&); /* not defined */ #define _CLASS_PACKAGED_TASK( \ TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \ template \ class packaged_task<_Ret(LIST(_TYPE))> \ { /* class that defines an asynchronous provider that returns the */ \ /* result of a call to a function object */ \ typedef packaged_task<_Ret(LIST(_TYPE))> _Myt; \ typedef typename _P_arg_type<_Ret>::type _Ptype; \ typedef _Promise<_Ptype> _MyPromiseType; \ typedef _State_manager<_Ptype> _MyStateManagerType; \ typedef _Packaged_state<_Ret(LIST(_TYPE))> _MyStateType; \ public: \ packaged_task() _NOEXCEPT \ : _MyPromise(0) \ { /* construct */ \ } \ template \ explicit packaged_task(_Fty2&& _Fnarg) \ : _MyPromise(new _MyStateType(_STD forward<_Fty2>(_Fnarg))) \ { /* construct from rvalue function object */ \ } \ template \ explicit packaged_task(const _Fty2& _Fnarg) \ : _MyPromise(new _MyStateType(_Fnarg)) \ { /* construct from rvalue function object */ \ } \ packaged_task(packaged_task&& _Other) _NOEXCEPT \ : _MyPromise(_STD forward<_Promise<_Ret> >(_Other._MyPromise)) \ { /* construct from rvalue packaged_task object */ \ } \ packaged_task& operator=(packaged_task&& _Other) _NOEXCEPT \ { /* assign from rvalue packaged_task object */ \ _MyPromise = _STD forward<_MyPromiseType>(_Other._MyPromise); \ return (*this); \ } \ template \ explicit packaged_task(allocator_arg_t, const _Alloc& _Al, \ _Fty2&& _Fnarg) \ : _MyPromise(_Make_packaged_state<_Ret(LIST(_TYPE))>( \ _STD forward<_Fty2>(_Fnarg)), _Al) \ { /* construct from rvalue function object and allocator */ \ } \ ~packaged_task() _NOEXCEPT \ { /* destroy */ \ } \ void swap(packaged_task& _Other) _NOEXCEPT \ { /* exchange with _Other */ \ _STD swap(_MyPromise, _Other._MyPromise); \ } \ _TYPEDEF_BOOL_TYPE; \ _OPERATOR_BOOL() const _NOEXCEPT /* retained */ \ { /* return status */ \ return (_MyPromise._Is_valid() ? _CONVERTIBLE_TO_TRUE : 0); \ } \ bool valid() const \ { /* return status */ \ return (_MyPromise._Is_valid()); \ } \ future<_Ret> get_future() \ { /* return a future object that shares the associated */ \ /* asynchronous state */ \ return (future<_Ret>(_MyPromise._Get_state_for_future())); \ } \ void operator()(LIST(_TYPE_ARG)) \ { /* call the function object */ \ if (_MyPromise._Is_ready()) \ _Throw_future_error( \ make_error_code(future_errc::promise_already_satisfied)); \ _MyStateManagerType& _State = _MyPromise._Get_state_for_set(); \ _MyStateType *_Ptr = static_cast<_MyStateType *>(_State._Ptr()); \ _Ptr->_Call_immediate(LIST(_FORWARD_ARG)); \ } \ void make_ready_at_thread_exit(LIST(_TYPE_ARG)) \ { /* call the function object and block until thread exit */ \ if (_MyPromise._Is_ready()) \ _Throw_future_error( \ make_error_code(future_errc::promise_already_satisfied)); \ _MyStateManagerType& _State = _MyPromise._Get_state_for_set(); \ _MyStateType *_Ptr = static_cast<_MyStateType *>(_State._Ptr()); \ _Ptr->_Call_deferred(LIST(_FORWARD_ARG)); \ } \ void reset() \ { /* reset to newly constructed state */ \ _MyStateManagerType& _State = _MyPromise._Get_state(); \ _MyStateType *_MyState = \ static_cast<_MyStateType *>(_State._Ptr()); \ function<_Ret(LIST(_TYPE))> _Fnarg = _MyState->_Get_fn(); \ _MyPromiseType _New_promise(new _MyStateType(_Fnarg, true)); \ _MyPromise._Swap(_New_promise); \ } \ _PACKAGED_TASK_FUNCTION_DELETES \ private: \ _MyPromiseType _MyPromise; \ }; _VARIADIC_EXPAND_0X(_CLASS_PACKAGED_TASK, , , , ) #undef _PACKAGED_TASK_FUNCTION_DELETES #undef _CLASS_PACKAGED_TASK template inline void swap(packaged_task<_Ty>& _Left, packaged_task<_Ty>& _Right) _NOEXCEPT { // exchange _Left and _Right _Left.swap(_Right); } // HELPERS FOR async template struct _Is_launch_type : false_type { // tests for _Launch_type argument }; template<> struct _Is_launch_type<_Launch_type> : true_type { // tests for _Launch_type argument }; template inline _Associated_state::type> *_Get_associated_state(_Launch_type _Psync, _Fty&& _Fnarg) { // construct associated asynchronous state object for the launch type switch (_Psync) { case launch::async: return (new _Task_async_state<_Ret, false>(_STD forward<_Fty >(_Fnarg))); case launch::deferred: return (new _Deferred_async_state<_Ret>(_STD forward<_Fty >(_Fnarg))); default: return (new _Task_async_state<_Ret, true>(_STD forward<_Fty >(_Fnarg))); } } // TEMPLATE FUNCTIONS _Async AND async #define _ASYNC_FUN( \ TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \ template inline \ future::type> \ _Async(_Launch_type _Policy, _Fty&& _Fnarg \ COMMA LIST(_TYPE_REFREF_ARG)) \ { /* return a future object that manages a function object */ \ typedef typename result_of<_Fty(LIST(_TYPE))>::type _Ret; \ typedef typename _P_arg_type<_Ret>::type _Ptype; \ _Promise<_Ptype> _Pr(_Get_associated_state<_Ret>(_Policy, \ _STD bind(_STD forward<_Fty>(_Fnarg) \ COMMA LIST(_DECAY_COPY_FORWARD_ARG)))); \ return (_Pr._Get_state_for_future()); \ } \ template inline \ future::type>::value, _Fty> \ ::type(LIST(_TYPE))>::type> \ async(_Fty&& _Fnarg COMMA LIST(_TYPE_REFREF_ARG)) \ { /* return a future object that manages a function object */ \ return (_Async(launch::any, _Decay_copy(_STD forward<_Fty>(_Fnarg)) \ COMMA LIST(_DECAY_COPY_FORWARD_ARG))); \ } \ template inline \ future::value, _Fty> \ ::type(LIST(_TYPE))>::type> \ async(_Policy_type _Policy, _Fty&& _Fnarg \ COMMA LIST(_TYPE_REFREF_ARG)) \ { /* return a future object that manages a function object */ \ return (_Async(_Policy, _Decay_copy(_STD forward<_Fty>(_Fnarg)) \ COMMA LIST(_DECAY_COPY_FORWARD_ARG))); \ } _VARIADIC_EXPAND_0X(_ASYNC_FUN, , , , ) #undef _ASYNC_FUN _STD_END namespace std { template struct uses_allocator, _Alloc> : true_type { // asserts that promise<_Ty> can use an allocator }; template struct uses_allocator, _Alloc> : true_type { // asserts that packaged_task<_Ty> can use an allocator }; } // namespace std #pragma pop_macro("new") #pragma warning(pop) #pragma pack(pop) #endif /* RC_INVOKED */ #endif /* _FUTURE_ */ /* * Copyright (c) 1992-2012 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V6.00:0009 */