| 1 | // future C++0X header
|
|---|
| 2 | #pragma once
|
|---|
| 3 | #ifndef _FUTURE_
|
|---|
| 4 | #define _FUTURE_
|
|---|
| 5 | #ifndef RC_INVOKED
|
|---|
| 6 |
|
|---|
| 7 | #ifdef _M_CEE
|
|---|
| 8 | #error <future> is not supported when compiling with /clr or /clr:pure.
|
|---|
| 9 | #endif /* _M_CEE */
|
|---|
| 10 |
|
|---|
| 11 | #include <functional>
|
|---|
| 12 | #include <system_error>
|
|---|
| 13 | #include <utility>
|
|---|
| 14 | #include <chrono>
|
|---|
| 15 | #include <mutex>
|
|---|
| 16 | #include <condition_variable>
|
|---|
| 17 |
|
|---|
| 18 | #include <ppltasks.h>
|
|---|
| 19 |
|
|---|
| 20 | #include <thread>
|
|---|
| 21 |
|
|---|
| 22 | #pragma pack(push,_CRT_PACKING)
|
|---|
| 23 | #pragma warning(push,3)
|
|---|
| 24 | #pragma push_macro("new")
|
|---|
| 25 | #undef new
|
|---|
| 26 |
|
|---|
| 27 | #pragma warning(disable: 4482 4521 4522)
|
|---|
| 28 |
|
|---|
| 29 | #if _HAS_CPP0X
|
|---|
| 30 |
|
|---|
| 31 | #else /* _HAS_CPP0X */
|
|---|
| 32 | #error C++0X not fully supported
|
|---|
| 33 | #endif /* _HAS_CPP0X */
|
|---|
| 34 |
|
|---|
| 35 | _STD_BEGIN
|
|---|
| 36 | // ENUM future_errc
|
|---|
| 37 |
|
|---|
| 38 | namespace future_errc {
|
|---|
| 39 | enum future_errc { // names for futures errors
|
|---|
| 40 | broken_promise = 1,
|
|---|
| 41 | future_already_retrieved,
|
|---|
| 42 | promise_already_satisfied,
|
|---|
| 43 | no_state
|
|---|
| 44 | };
|
|---|
| 45 | } // namespace future_errc
|
|---|
| 46 |
|
|---|
| 47 | typedef future_errc::future_errc _Future_errc;
|
|---|
| 48 |
|
|---|
| 49 | // ENUM launch
|
|---|
| 50 |
|
|---|
| 51 | namespace launch {
|
|---|
| 52 | enum launch { // names for launch options passed to async
|
|---|
| 53 | async = 0x1,
|
|---|
| 54 | deferred = 0x2,
|
|---|
| 55 | any = async | deferred, // retained
|
|---|
| 56 | sync = deferred
|
|---|
| 57 | };
|
|---|
| 58 |
|
|---|
| 59 | inline launch operator&(launch _Left, launch _Right)
|
|---|
| 60 | {
|
|---|
| 61 | return (static_cast<launch>(static_cast<unsigned int>(_Left)
|
|---|
| 62 | & static_cast<unsigned int>(_Right)));
|
|---|
| 63 | }
|
|---|
| 64 |
|
|---|
| 65 | inline launch operator|(launch _Left, launch _Right)
|
|---|
| 66 | {
|
|---|
| 67 | return (static_cast<launch>(static_cast<unsigned int>(_Left)
|
|---|
| 68 | | static_cast<unsigned int>(_Right)));
|
|---|
| 69 | }
|
|---|
| 70 |
|
|---|
| 71 | inline launch operator^(launch _Left, launch _Right)
|
|---|
| 72 | {
|
|---|
| 73 | return (static_cast<launch>(static_cast<unsigned int>(_Left)
|
|---|
| 74 | ^ static_cast<unsigned int>(_Right)));
|
|---|
| 75 | }
|
|---|
| 76 |
|
|---|
| 77 | inline launch operator~(launch _Left)
|
|---|
| 78 | {
|
|---|
| 79 | return (static_cast<launch>(~static_cast<unsigned int>(_Left)));
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 | inline launch& operator&=(launch& _Left, launch _Right)
|
|---|
| 83 | {
|
|---|
| 84 | _Left = _Left & _Right;
|
|---|
| 85 | return (_Left);
|
|---|
| 86 | }
|
|---|
| 87 |
|
|---|
| 88 | inline launch& operator|=(launch& _Left, launch _Right)
|
|---|
| 89 | {
|
|---|
| 90 | _Left = _Left | _Right;
|
|---|
| 91 | return (_Left);
|
|---|
| 92 | }
|
|---|
| 93 |
|
|---|
| 94 | inline launch& operator^=(launch& _Left, launch _Right)
|
|---|
| 95 | {
|
|---|
| 96 | _Left = _Left ^ _Right;
|
|---|
| 97 | return (_Left);
|
|---|
| 98 | }
|
|---|
| 99 |
|
|---|
| 100 | } // namespace launch
|
|---|
| 101 |
|
|---|
| 102 | typedef launch::launch _Launch_type;
|
|---|
| 103 |
|
|---|
| 104 | // ENUM future_status
|
|---|
| 105 |
|
|---|
| 106 | namespace future_status {
|
|---|
| 107 | enum future_status { // names for timed wait function returns
|
|---|
| 108 | ready,
|
|---|
| 109 | timeout,
|
|---|
| 110 | deferred
|
|---|
| 111 | };
|
|---|
| 112 | } // namespace future_status
|
|---|
| 113 |
|
|---|
| 114 | typedef future_status::future_status _Future_status;
|
|---|
| 115 |
|
|---|
| 116 | // HELPER FUNCTIONS
|
|---|
| 117 | _CRTIMP2_PURE _NO_RETURN(__CLRCALL_PURE_OR_CDECL _Throw_future_error(
|
|---|
| 118 | const error_code& _Code));
|
|---|
| 119 | _CRTIMP2_PURE _NO_RETURN(__CLRCALL_PURE_OR_CDECL _Rethrow_future_exception(
|
|---|
| 120 | _XSTD exception_ptr _Ptr));
|
|---|
| 121 |
|
|---|
| 122 | // TEMPLATE CLASS SPECIALIZATION is_error_code_enum
|
|---|
| 123 | template<>
|
|---|
| 124 | struct is_error_code_enum<_Future_errc>
|
|---|
| 125 | : public true_type
|
|---|
| 126 | { // tests for error_code enumeration
|
|---|
| 127 | };
|
|---|
| 128 |
|
|---|
| 129 | const error_category& future_category() _NOEXCEPT;
|
|---|
| 130 |
|
|---|
| 131 | inline error_code make_error_code(_Future_errc _Errno) _NOEXCEPT
|
|---|
| 132 | { // make an error_code object
|
|---|
| 133 | return (error_code(static_cast<int>(_Errno), future_category()));
|
|---|
| 134 | }
|
|---|
| 135 |
|
|---|
| 136 | inline error_condition make_error_condition(_Future_errc _Errno) _NOEXCEPT
|
|---|
| 137 | { // make an error_condition object
|
|---|
| 138 | return (error_condition(static_cast<int>(_Errno), future_category()));
|
|---|
| 139 | }
|
|---|
| 140 |
|
|---|
| 141 | // CLASS future_error
|
|---|
| 142 | _CRTIMP2_PURE const char *__CLRCALL_PURE_OR_CDECL _Get_future_error_what(int) _THROW0();
|
|---|
| 143 |
|
|---|
| 144 | class future_error
|
|---|
| 145 | : public logic_error
|
|---|
| 146 | { // future exception
|
|---|
| 147 | public:
|
|---|
| 148 | explicit future_error(error_code _Errcode,
|
|---|
| 149 | const string& _Message = "")
|
|---|
| 150 | : logic_error(_Message), _Mycode(_Errcode)
|
|---|
| 151 | { // construct from error code and message string
|
|---|
| 152 | }
|
|---|
| 153 |
|
|---|
| 154 | future_error(error_code _Errcode,
|
|---|
| 155 | const char *_Message)
|
|---|
| 156 | : logic_error(_Message), _Mycode(_Errcode)
|
|---|
| 157 | { // construct from error code and message string
|
|---|
| 158 | }
|
|---|
| 159 |
|
|---|
| 160 | future_error(int _Errval,
|
|---|
| 161 | const error_category& _Errcat,
|
|---|
| 162 | const string& _Message = "")
|
|---|
| 163 | : logic_error(_Message), _Mycode(_Errval, _Errcat)
|
|---|
| 164 | { // construct from error code components and message string
|
|---|
| 165 | }
|
|---|
| 166 |
|
|---|
| 167 | future_error(int _Errval,
|
|---|
| 168 | const error_category& _Errcat,
|
|---|
| 169 | const char *_Message)
|
|---|
| 170 | : logic_error(_Message), _Mycode(_Errval, _Errcat)
|
|---|
| 171 | { // construct from error code components and message string
|
|---|
| 172 | }
|
|---|
| 173 |
|
|---|
| 174 | const error_code& code() const _THROW0()
|
|---|
| 175 | { // return stored error code
|
|---|
| 176 | return (_Mycode);
|
|---|
| 177 | }
|
|---|
| 178 |
|
|---|
| 179 | const char *__CLR_OR_THIS_CALL what() const _THROW0()
|
|---|
| 180 | { // get message string
|
|---|
| 181 | return (_Get_future_error_what(_Mycode.value()));
|
|---|
| 182 | }
|
|---|
| 183 |
|
|---|
| 184 | #if _HAS_EXCEPTIONS
|
|---|
| 185 |
|
|---|
| 186 | #else /* _HAS_EXCEPTIONS */
|
|---|
| 187 | protected:
|
|---|
| 188 | virtual void _Doraise() const
|
|---|
| 189 | { // perform class-specific exception handling
|
|---|
| 190 | _RAISE(*this);
|
|---|
| 191 | }
|
|---|
| 192 | #endif /* _HAS_EXCEPTIONS */
|
|---|
| 193 |
|
|---|
| 194 | private:
|
|---|
| 195 | error_code _Mycode; // the stored error code
|
|---|
| 196 | };
|
|---|
| 197 |
|
|---|
| 198 | _CRTIMP2_PURE const char *__CLRCALL_PURE_OR_CDECL _Future_error_map(int);
|
|---|
| 199 |
|
|---|
| 200 | // CLASS _Future_error_category
|
|---|
| 201 | class _Future_error_category
|
|---|
| 202 | : public _Generic_error_category
|
|---|
| 203 | { // categorize a future error
|
|---|
| 204 | public:
|
|---|
| 205 | _Future_error_category()
|
|---|
| 206 | { // default constructor
|
|---|
| 207 | }
|
|---|
| 208 |
|
|---|
| 209 | virtual const char *name() const _NOEXCEPT
|
|---|
| 210 | { // get name of category
|
|---|
| 211 | return ("future");
|
|---|
| 212 | }
|
|---|
| 213 |
|
|---|
| 214 | virtual string message(int _Errcode) const
|
|---|
| 215 | { // convert to name of error
|
|---|
| 216 | const char *_Name = _Future_error_map(_Errcode);
|
|---|
| 217 | if (_Name != 0)
|
|---|
| 218 | return (_Name);
|
|---|
| 219 | else
|
|---|
| 220 | return (_Generic_error_category::message(_Errcode));
|
|---|
| 221 | }
|
|---|
| 222 | };
|
|---|
| 223 |
|
|---|
| 224 | template<class _Cat>
|
|---|
| 225 | struct _Future_error_object
|
|---|
| 226 | { // reports a future error
|
|---|
| 227 | _Future_error_object()
|
|---|
| 228 | { // default constructor
|
|---|
| 229 | }
|
|---|
| 230 |
|
|---|
| 231 | static _Future_error_category _Future_object;
|
|---|
| 232 | };
|
|---|
| 233 |
|
|---|
| 234 | template<class _Cat>
|
|---|
| 235 | _Future_error_category _Future_error_object<_Cat>::_Future_object;
|
|---|
| 236 |
|
|---|
| 237 | inline const error_category& future_category() _NOEXCEPT
|
|---|
| 238 | { // return error_category object for future
|
|---|
| 239 | return (_Future_error_object<int>::_Future_object);
|
|---|
| 240 | }
|
|---|
| 241 |
|
|---|
| 242 | // TEMPLATE STRUCT _State_deleter
|
|---|
| 243 | template<class _Ty>
|
|---|
| 244 | class _Associated_state;
|
|---|
| 245 |
|
|---|
| 246 | template<class _Ty,
|
|---|
| 247 | class _Alloc>
|
|---|
| 248 | struct _State_deleter;
|
|---|
| 249 |
|
|---|
| 250 | template<class _Alloc,
|
|---|
| 251 | class _Ty>
|
|---|
| 252 | void _Delete_state(_Alloc _Al, _Associated_state<_Ty> *_State,
|
|---|
| 253 | _State_deleter<_Ty, _Alloc> *);
|
|---|
| 254 |
|
|---|
| 255 | template<class _Ty>
|
|---|
| 256 | struct _Deleter_base
|
|---|
| 257 | { // abstract base class for managing deletion of state objects
|
|---|
| 258 | virtual void _Delete(_Associated_state<_Ty> *) = 0;
|
|---|
| 259 | virtual ~_Deleter_base() _NOEXCEPT {
|
|---|
| 260 | }
|
|---|
| 261 | };
|
|---|
| 262 |
|
|---|
| 263 | template<class _Ty,
|
|---|
| 264 | class _Alloc>
|
|---|
| 265 | struct _State_deleter
|
|---|
| 266 | : _Deleter_base<_Ty>
|
|---|
| 267 | { // manage allocator and deletion state objects
|
|---|
| 268 | _State_deleter(_Alloc _Al)
|
|---|
| 269 | : _My_alloc(_Al)
|
|---|
| 270 | { // construct with allocator
|
|---|
| 271 | }
|
|---|
| 272 |
|
|---|
| 273 | _State_deleter(const _State_deleter& _Other)
|
|---|
| 274 | : _My_alloc(_Other._My_alloc)
|
|---|
| 275 | { // copy from _Other
|
|---|
| 276 | }
|
|---|
| 277 |
|
|---|
| 278 | template<class _Alloc2>
|
|---|
| 279 | _State_deleter(const _State_deleter<_Ty, _Alloc2>& _Other)
|
|---|
| 280 | : _My_alloc(_Other._My_alloc)
|
|---|
| 281 | { // copy from _Other
|
|---|
| 282 | }
|
|---|
| 283 |
|
|---|
| 284 | void _Delete(_Associated_state<_Ty> *_State)
|
|---|
| 285 | { // delete _State using stored allocator
|
|---|
| 286 | _Delete_state(_My_alloc, _State, this);
|
|---|
| 287 | }
|
|---|
| 288 |
|
|---|
| 289 | _Alloc _My_alloc;
|
|---|
| 290 | };
|
|---|
| 291 |
|
|---|
| 292 | // TEMPLATE CLASS _Associated_state
|
|---|
| 293 | template<class _Ty>
|
|---|
| 294 | class _Associated_state
|
|---|
| 295 | { // class for managing associated synchronous state
|
|---|
| 296 | public:
|
|---|
| 297 | typedef _Ty _State_type;
|
|---|
| 298 |
|
|---|
| 299 | _Associated_state(_Deleter_base<_Ty> *_Dp = 0)
|
|---|
| 300 | : _Exception(),
|
|---|
| 301 | _Retrieved(false),
|
|---|
| 302 | _Running(false),
|
|---|
| 303 | _Ready(false),
|
|---|
| 304 | _Ready_at_thread_exit(false),
|
|---|
| 305 | _Has_stored_result(false),
|
|---|
| 306 | _Deleter(_Dp)
|
|---|
| 307 | { // construct
|
|---|
| 308 | // TODO: _Associated_state ctor assumes _Ty is default constructible
|
|---|
| 309 | _Init_refs();
|
|---|
| 310 | }
|
|---|
| 311 |
|
|---|
| 312 | virtual ~_Associated_state() _NOEXCEPT
|
|---|
| 313 | { // destroy
|
|---|
| 314 | if (_Has_stored_result && !_Ready)
|
|---|
| 315 | { // registered for release at thread exit
|
|---|
| 316 | _Cond._Unregister(_Mtx);
|
|---|
| 317 | }
|
|---|
| 318 | _Destroy_refs();
|
|---|
| 319 | }
|
|---|
| 320 |
|
|---|
| 321 | void _Retain()
|
|---|
| 322 | { // increment reference count
|
|---|
| 323 | _MT_INCR(_Mtx0, _Refs);
|
|---|
| 324 | }
|
|---|
| 325 |
|
|---|
| 326 | void _Release()
|
|---|
| 327 | { // decrement reference count and destroy when zero
|
|---|
| 328 | if (_MT_DECR(_Mtx0, _Refs) == 0)
|
|---|
| 329 | _Delete_this();
|
|---|
| 330 | }
|
|---|
| 331 |
|
|---|
| 332 | private:
|
|---|
| 333 | _Atomic_counter_t _Refs;
|
|---|
| 334 |
|
|---|
| 335 | public:
|
|---|
| 336 | void _Init_refs()
|
|---|
| 337 | { // initialize reference count
|
|---|
| 338 | _Init_atomic_counter(_Refs, 1);
|
|---|
| 339 | }
|
|---|
| 340 |
|
|---|
| 341 | void _Destroy_refs()
|
|---|
| 342 | { // destroy reference count
|
|---|
| 343 | }
|
|---|
| 344 |
|
|---|
| 345 | virtual void _Wait()
|
|---|
| 346 | { // wait for signal
|
|---|
| 347 | unique_lock<mutex> _Lock(_Mtx);
|
|---|
| 348 | _Maybe_run_deferred_function(_Lock);
|
|---|
| 349 | while (!_Ready)
|
|---|
| 350 | _Cond.wait(_Lock);
|
|---|
| 351 | }
|
|---|
| 352 |
|
|---|
| 353 | struct _Test_ready
|
|---|
| 354 | { // wraps _Associated_state
|
|---|
| 355 | _Test_ready(const _Associated_state *_St)
|
|---|
| 356 | : _State(_St)
|
|---|
| 357 | { // construct from associated state
|
|---|
| 358 | }
|
|---|
| 359 |
|
|---|
| 360 | bool operator()() const
|
|---|
| 361 | { // test state
|
|---|
| 362 | return (_State->_Ready != 0);
|
|---|
| 363 | }
|
|---|
| 364 | const _Associated_state *_State;
|
|---|
| 365 | };
|
|---|
| 366 |
|
|---|
| 367 | template<class _Rep,
|
|---|
| 368 | class _Per>
|
|---|
| 369 | _Future_status _Wait_for(
|
|---|
| 370 | const chrono::duration<_Rep, _Per>& _Rel_time)
|
|---|
| 371 | { // wait for duration
|
|---|
| 372 | _Future_status _Res = _Future_status::ready;
|
|---|
| 373 | unique_lock<mutex> _Lock(_Mtx);
|
|---|
| 374 |
|
|---|
| 375 | if (!_Running)
|
|---|
| 376 | _Res = _Future_status::deferred;
|
|---|
| 377 | else
|
|---|
| 378 | { // do the wait
|
|---|
| 379 | bool _Cv_state =
|
|---|
| 380 | _Cond.wait_for(_Lock, _Rel_time, _Test_ready(this));
|
|---|
| 381 | if (!_Cv_state)
|
|---|
| 382 | _Res = _Future_status::timeout;
|
|---|
| 383 | }
|
|---|
| 384 | return (_Res);
|
|---|
| 385 | }
|
|---|
| 386 |
|
|---|
| 387 | template<class _Clock,
|
|---|
| 388 | class _Dur>
|
|---|
| 389 | _Future_status _Wait_until(
|
|---|
| 390 | const chrono::time_point<_Clock, _Dur>& _Abs_time)
|
|---|
| 391 | { // wait until time point
|
|---|
| 392 | _Future_status _Res = _Future_status::ready;
|
|---|
| 393 | unique_lock<mutex> _Lock(_Mtx);
|
|---|
| 394 |
|
|---|
| 395 | if (!_Running)
|
|---|
| 396 | _Res = _Future_status::deferred;
|
|---|
| 397 | else
|
|---|
| 398 | { // do the wait
|
|---|
| 399 | bool _Cv_state =
|
|---|
| 400 | _Cond.wait_until(_Lock, _Abs_time, _Test_ready(this));
|
|---|
| 401 | if (!_Cv_state)
|
|---|
| 402 | _Res = _Future_status::timeout;
|
|---|
| 403 | }
|
|---|
| 404 | return (_Res);
|
|---|
| 405 | }
|
|---|
| 406 |
|
|---|
| 407 | virtual _Ty& _Get_value(bool _Get_only_once)
|
|---|
| 408 | { // return the stored result or throw stored exception
|
|---|
| 409 | unique_lock<mutex> _Lock(_Mtx);
|
|---|
| 410 | if (_Get_only_once && _Retrieved)
|
|---|
| 411 | _Throw_future_error(
|
|---|
| 412 | make_error_code(future_errc::future_already_retrieved));
|
|---|
| 413 | if (_Exception)
|
|---|
| 414 | _Rethrow_future_exception(_Exception);
|
|---|
| 415 | _Retrieved = true;
|
|---|
| 416 | _Maybe_run_deferred_function(_Lock);
|
|---|
| 417 | while (!_Ready)
|
|---|
| 418 | _Cond.wait(_Lock);
|
|---|
| 419 | if (_Exception)
|
|---|
| 420 | _Rethrow_future_exception(_Exception);
|
|---|
| 421 | return (_Result);
|
|---|
| 422 | }
|
|---|
| 423 |
|
|---|
| 424 | void _Set_value(const _Ty& _Val, bool _At_thread_exit)
|
|---|
| 425 | { // store a result
|
|---|
| 426 | unique_lock<mutex> _Lock(_Mtx);
|
|---|
| 427 | _Set_value_raw(_Val, &_Lock, _At_thread_exit);
|
|---|
| 428 | }
|
|---|
| 429 |
|
|---|
| 430 | void _Set_value_raw(const _Ty& _Val, unique_lock<mutex> *_Lock,
|
|---|
| 431 | bool _At_thread_exit)
|
|---|
| 432 | { // store a result while inside a locked block
|
|---|
| 433 | if (_Has_stored_result)
|
|---|
| 434 | _Throw_future_error(
|
|---|
| 435 | make_error_code(future_errc::promise_already_satisfied));
|
|---|
| 436 | _Result = _Val;
|
|---|
| 437 | _Do_notify(_Lock, _At_thread_exit);
|
|---|
| 438 | }
|
|---|
| 439 |
|
|---|
| 440 | void _Set_value(_Ty&& _Val, bool _At_thread_exit)
|
|---|
| 441 | { // store a result
|
|---|
| 442 | unique_lock<mutex> _Lock(_Mtx);
|
|---|
| 443 | _Set_value_raw(_STD forward<_Ty>(_Val), &_Lock, _At_thread_exit);
|
|---|
| 444 | }
|
|---|
| 445 |
|
|---|
| 446 | void _Set_value_raw(_Ty&& _Val, unique_lock<mutex> *_Lock,
|
|---|
| 447 | bool _At_thread_exit)
|
|---|
| 448 | { // store a result while inside a locked block
|
|---|
| 449 | if (_Has_stored_result)
|
|---|
| 450 | _Throw_future_error(
|
|---|
| 451 | make_error_code(future_errc::promise_already_satisfied));
|
|---|
| 452 | _Result = _STD forward<_Ty>(_Val);
|
|---|
| 453 | _Do_notify(_Lock, _At_thread_exit);
|
|---|
| 454 | }
|
|---|
| 455 |
|
|---|
| 456 | void _Set_value(bool _At_thread_exit)
|
|---|
| 457 | { // store a (void) result
|
|---|
| 458 | unique_lock<mutex> _Lock(_Mtx);
|
|---|
| 459 | _Set_value_raw(&_Lock, _At_thread_exit);
|
|---|
| 460 | }
|
|---|
| 461 |
|
|---|
| 462 | void _Set_value_raw(unique_lock<mutex> *_Lock, bool _At_thread_exit)
|
|---|
| 463 | { // store a (void) result while inside a locked block
|
|---|
| 464 | if (_Has_stored_result)
|
|---|
| 465 | _Throw_future_error(
|
|---|
| 466 | make_error_code(future_errc::promise_already_satisfied));
|
|---|
| 467 | _Do_notify(_Lock, _At_thread_exit);
|
|---|
| 468 | }
|
|---|
| 469 |
|
|---|
| 470 | void _Set_exception(_XSTD exception_ptr _Exc, bool _At_thread_exit)
|
|---|
| 471 | { // store a result
|
|---|
| 472 | unique_lock<mutex> _Lock(_Mtx);
|
|---|
| 473 | _Set_exception_raw(_Exc, &_Lock, _At_thread_exit);
|
|---|
| 474 | }
|
|---|
| 475 |
|
|---|
| 476 | struct _Anon
|
|---|
| 477 | { // anonymous type
|
|---|
| 478 | };
|
|---|
| 479 |
|
|---|
| 480 | void _Set_exception_raw(_XSTD exception_ptr _Exc,
|
|---|
| 481 | unique_lock<mutex> *_Lock, bool _At_thread_exit)
|
|---|
| 482 | { // store a result while inside a locked block
|
|---|
| 483 | if (_Has_stored_result)
|
|---|
| 484 | _Throw_future_error(
|
|---|
| 485 | make_error_code(future_errc::promise_already_satisfied));
|
|---|
| 486 | _Exception = _Exc;
|
|---|
| 487 | if (!_Exc)
|
|---|
| 488 |
|
|---|
| 489 | { // make a non-null exception_ptr
|
|---|
| 490 | _Exception = make_exception_ptr(_Anon());
|
|---|
| 491 | }
|
|---|
| 492 |
|
|---|
| 493 | _Do_notify(_Lock, _At_thread_exit);
|
|---|
| 494 | }
|
|---|
| 495 |
|
|---|
| 496 | bool _Is_ready() const
|
|---|
| 497 | { // return ready status
|
|---|
| 498 | return (_Ready != 0);
|
|---|
| 499 | }
|
|---|
| 500 |
|
|---|
| 501 | bool _Already_retrieved() const
|
|---|
| 502 | { // return retrieved status
|
|---|
| 503 | return (_Retrieved);
|
|---|
| 504 | }
|
|---|
| 505 |
|
|---|
| 506 | protected:
|
|---|
| 507 | void _Make_ready_at_thread_exit()
|
|---|
| 508 | { // set ready status at thread exit
|
|---|
| 509 | if (_Ready_at_thread_exit)
|
|---|
| 510 | _Ready = true;
|
|---|
| 511 | }
|
|---|
| 512 |
|
|---|
| 513 | void _Maybe_run_deferred_function(unique_lock<mutex>& _Lock)
|
|---|
| 514 | { // run a deferred function if not already done
|
|---|
| 515 | if (!_Running)
|
|---|
| 516 | { // run the function
|
|---|
| 517 | _Running = true;
|
|---|
| 518 | _Run_deferred_function(_Lock);
|
|---|
| 519 | }
|
|---|
| 520 | }
|
|---|
| 521 |
|
|---|
| 522 | _Ty _Result;
|
|---|
| 523 | _XSTD exception_ptr _Exception;
|
|---|
| 524 | mutex _Mtx;
|
|---|
| 525 | condition_variable _Cond;
|
|---|
| 526 | bool _Retrieved;
|
|---|
| 527 | int _Ready;
|
|---|
| 528 | bool _Ready_at_thread_exit;
|
|---|
| 529 | bool _Has_stored_result;
|
|---|
| 530 | bool _Running;
|
|---|
| 531 |
|
|---|
| 532 | private:
|
|---|
| 533 | virtual void _Run_deferred_function(unique_lock<mutex>&)
|
|---|
| 534 | { // do nothing
|
|---|
| 535 | }
|
|---|
| 536 |
|
|---|
| 537 | virtual void _Do_notify(unique_lock<mutex> *_Lock, bool _At_thread_exit)
|
|---|
| 538 | { // notify waiting threads
|
|---|
| 539 | _Has_stored_result = true;
|
|---|
| 540 | if (_At_thread_exit)
|
|---|
| 541 | { // notify at thread exit
|
|---|
| 542 | _Cond._Register(*_Lock, &_Ready);
|
|---|
| 543 | }
|
|---|
| 544 | else
|
|---|
| 545 | { // notify immediately
|
|---|
| 546 | _Ready = true;
|
|---|
| 547 | _Cond.notify_all();
|
|---|
| 548 | }
|
|---|
| 549 | }
|
|---|
| 550 |
|
|---|
| 551 | void _Delete_this()
|
|---|
| 552 | { // delete this object
|
|---|
| 553 | if (_Deleter)
|
|---|
| 554 | _Deleter->_Delete(this);
|
|---|
| 555 | else
|
|---|
| 556 | delete this;
|
|---|
| 557 | }
|
|---|
| 558 |
|
|---|
| 559 | _Deleter_base<_Ty> *_Deleter;
|
|---|
| 560 |
|
|---|
| 561 | _Associated_state(const _Associated_state&); // not defined
|
|---|
| 562 | _Associated_state& operator=(
|
|---|
| 563 | const _Associated_state&) const; // not defined
|
|---|
| 564 | };
|
|---|
| 565 |
|
|---|
| 566 | // TEMPLATE FUNCTION _Delete_state
|
|---|
| 567 | template<class _Alloc,
|
|---|
| 568 | class _Ty> inline
|
|---|
| 569 | void _Delete_state(_Alloc _Al, _Associated_state<_Ty> *_State,
|
|---|
| 570 | _State_deleter<_Ty, _Alloc> *_Deleter)
|
|---|
| 571 | { // delete _State and _Deleter using allocator _Al
|
|---|
| 572 | typedef typename _Alloc::template rebind<_Associated_state<_Ty> >
|
|---|
| 573 | ::other _State_allocator;
|
|---|
| 574 | _State_allocator _St_alloc(_Al);
|
|---|
| 575 | _St_alloc.destroy(_State);
|
|---|
| 576 | _St_alloc.deallocate(_State, 1);
|
|---|
| 577 |
|
|---|
| 578 | typedef typename _Alloc::template rebind<_State_deleter<_Ty, _Alloc> >
|
|---|
| 579 | ::other _Deleter_allocator;
|
|---|
| 580 | _Deleter_allocator _Del_alloc(_Al);
|
|---|
| 581 | _Del_alloc.destroy(_Deleter);
|
|---|
| 582 | _Del_alloc.deallocate(_Deleter, 1);
|
|---|
| 583 | }
|
|---|
| 584 |
|
|---|
| 585 | // TEMPLATE CLASS _Packaged_state
|
|---|
| 586 | template<class>
|
|---|
| 587 | class _Packaged_state;
|
|---|
| 588 |
|
|---|
| 589 | #define _CLASS_PACKAGED_STATE( \
|
|---|
| 590 | TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
|
|---|
| 591 | template<class _Ret COMMA LIST(_CLASS_TYPE)> \
|
|---|
| 592 | class _Packaged_state<_Ret(LIST(_TYPE))> \
|
|---|
| 593 | : public _Associated_state<_Ret> \
|
|---|
| 594 | { /* manages associated asynchronous state for packaged_task */ \
|
|---|
| 595 | public: \
|
|---|
| 596 | template<class _Fty2> \
|
|---|
| 597 | _Packaged_state(const _Fty2& _Fnarg) \
|
|---|
| 598 | : _Fn(_Fnarg) \
|
|---|
| 599 | { /* construct from function object */ \
|
|---|
| 600 | } \
|
|---|
| 601 | template<class _Fty2, \
|
|---|
| 602 | class _Alloc> \
|
|---|
| 603 | _Packaged_state(const _Fty2& _Fnarg, const _Alloc& _Al, \
|
|---|
| 604 | _Deleter_base<_Ret> *_Dp) \
|
|---|
| 605 | : _Associated_state<_Ret>(_Dp), _Fn(_Fnarg, _Al) \
|
|---|
| 606 | { /* construct from function object and allocator */ \
|
|---|
| 607 | } \
|
|---|
| 608 | template<class _Fty2> \
|
|---|
| 609 | _Packaged_state(_Fty2&& _Fnarg) \
|
|---|
| 610 | : _Fn(_STD forward<_Fty2>(_Fnarg)) \
|
|---|
| 611 | { /* construct from rvalue function object */ \
|
|---|
| 612 | } \
|
|---|
| 613 | template<class _Fty2, \
|
|---|
| 614 | class _Alloc> \
|
|---|
| 615 | _Packaged_state(_Fty2&& _Fnarg, const _Alloc& _Al, \
|
|---|
| 616 | _Deleter_base<_Ret> *_Dp) \
|
|---|
| 617 | : _Associated_state<_Ret>(_Dp), \
|
|---|
| 618 | _Fn(_STD forward<_Fty2>(_Fnarg), _Al) \
|
|---|
| 619 | { /* construct from rvalue function object and allocator */ \
|
|---|
| 620 | } \
|
|---|
| 621 | _Packaged_state(const function<_Ret(LIST(_TYPE))>& _NewFn, \
|
|---|
| 622 | bool) \
|
|---|
| 623 | : _Fn(_NewFn) \
|
|---|
| 624 | { /* construct from our own stored function type */ \
|
|---|
| 625 | } \
|
|---|
| 626 | void _Call_deferred(LIST(_TYPE_ARG)) \
|
|---|
| 627 | { /* set deferred call */ \
|
|---|
| 628 | _TRY_BEGIN \
|
|---|
| 629 | /* call function object and catch exceptions */ \
|
|---|
| 630 | this->_Set_value(_Fn(LIST(_FORWARD_ARG)), true); \
|
|---|
| 631 | _CATCH_ALL \
|
|---|
| 632 | /* function object threw exception; record result */ \
|
|---|
| 633 | this->_Set_exception(_XSTD current_exception(), true); \
|
|---|
| 634 | _CATCH_END \
|
|---|
| 635 | } \
|
|---|
| 636 | void _Call_immediate(LIST(_TYPE_ARG)) \
|
|---|
| 637 | { /* call function object */ \
|
|---|
| 638 | _TRY_BEGIN \
|
|---|
| 639 | /* call function object and catch exceptions */ \
|
|---|
| 640 | this->_Set_value(_Fn(LIST(_FORWARD_ARG)), false); \
|
|---|
| 641 | _CATCH_ALL \
|
|---|
| 642 | /* function object threw exception; record result */ \
|
|---|
| 643 | this->_Set_exception(_XSTD current_exception(), false); \
|
|---|
| 644 | _CATCH_END \
|
|---|
| 645 | } \
|
|---|
| 646 | const function<_Ret(LIST(_TYPE))>& _Get_fn() \
|
|---|
| 647 | { /* return stored function object */ \
|
|---|
| 648 | return (_Fn); \
|
|---|
| 649 | } \
|
|---|
| 650 | private: \
|
|---|
| 651 | function<_Ret(LIST(_TYPE))> _Fn; \
|
|---|
| 652 | };
|
|---|
| 653 |
|
|---|
| 654 | _VARIADIC_EXPAND_0X(_CLASS_PACKAGED_STATE, , , , )
|
|---|
| 655 | #undef _CLASS_PACKAGED_STATE
|
|---|
| 656 |
|
|---|
| 657 | #define _CLASS_PACKAGED_STATE_REF( \
|
|---|
| 658 | TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
|
|---|
| 659 | template<class _Ret COMMA LIST(_CLASS_TYPE)> \
|
|---|
| 660 | class _Packaged_state<_Ret&(LIST(_TYPE))> \
|
|---|
| 661 | : public _Associated_state<_Ret *> \
|
|---|
| 662 | { /* manages associated asynchronous state for packaged_task */ \
|
|---|
| 663 | public: \
|
|---|
| 664 | template<class _Fty2> \
|
|---|
| 665 | _Packaged_state(const _Fty2& _Fnarg) \
|
|---|
| 666 | : _Fn(_Fnarg) \
|
|---|
| 667 | { /* construct from function object */ \
|
|---|
| 668 | } \
|
|---|
| 669 | template<class _Fty2, \
|
|---|
| 670 | class _Alloc> \
|
|---|
| 671 | _Packaged_state(const _Fty2& _Fnarg, const _Alloc& _Al, \
|
|---|
| 672 | _Deleter_base<_Ret> *_Dp) \
|
|---|
| 673 | : _Associated_state<_Ret *>(_Dp), _Fn(_Fnarg, _Al) \
|
|---|
| 674 | { /* construct from function object and allocator */ \
|
|---|
| 675 | } \
|
|---|
| 676 | template<class _Fty2> \
|
|---|
| 677 | _Packaged_state(_Fty2&& _Fnarg) \
|
|---|
| 678 | : _Fn(_STD forward<_Fty2>(_Fnarg)) \
|
|---|
| 679 | { /* construct from rvalue function object */ \
|
|---|
| 680 | } \
|
|---|
| 681 | template<class _Fty2, \
|
|---|
| 682 | class _Alloc> \
|
|---|
| 683 | _Packaged_state(_Fty2&& _Fnarg, const _Alloc& _Al, \
|
|---|
| 684 | _Deleter_base<_Ret> *_Dp) \
|
|---|
| 685 | : _Associated_state<_Ret *>(_Dp), \
|
|---|
| 686 | _Fn(_STD forward<_Fty2>(_Fnarg), _Al) \
|
|---|
| 687 | { /* construct from rvalue function object and allocator */ \
|
|---|
| 688 | } \
|
|---|
| 689 | _Packaged_state(const function<_Ret&(LIST(_TYPE))>& _NewFn, \
|
|---|
| 690 | bool) \
|
|---|
| 691 | : _Fn(_NewFn) \
|
|---|
| 692 | { /* construct from our own stored function type */ \
|
|---|
| 693 | } \
|
|---|
| 694 | void _Call_deferred(LIST(_TYPE_ARG)) \
|
|---|
| 695 | { /* set deferred call */ \
|
|---|
| 696 | _TRY_BEGIN \
|
|---|
| 697 | /* call function object and catch exceptions */ \
|
|---|
| 698 | this->_Set_value(&_Fn(LIST(_FORWARD_ARG)), true); \
|
|---|
| 699 | _CATCH_ALL \
|
|---|
| 700 | /* function object threw exception; record result */ \
|
|---|
| 701 | this->_Set_exception(_XSTD current_exception(), true); \
|
|---|
| 702 | _CATCH_END \
|
|---|
| 703 | } \
|
|---|
| 704 | void _Call_immediate(LIST(_TYPE_ARG)) \
|
|---|
| 705 | { /* call function object */ \
|
|---|
| 706 | _TRY_BEGIN \
|
|---|
| 707 | /* call function object and catch exceptions */ \
|
|---|
| 708 | this->_Set_value(&_Fn(LIST(_FORWARD_ARG)), false); \
|
|---|
| 709 | _CATCH_ALL \
|
|---|
| 710 | /* function object threw exception; record result */ \
|
|---|
| 711 | this->_Set_exception(_XSTD current_exception(), false); \
|
|---|
| 712 | _CATCH_END \
|
|---|
| 713 | } \
|
|---|
| 714 | const function<_Ret&(LIST(_TYPE))>& _Get_fn() \
|
|---|
| 715 | { /* return stored function object */ \
|
|---|
| 716 | return (_Fn); \
|
|---|
| 717 | } \
|
|---|
| 718 | private: \
|
|---|
| 719 | function<_Ret&(LIST(_TYPE))> _Fn; \
|
|---|
| 720 | };
|
|---|
| 721 |
|
|---|
| 722 | _VARIADIC_EXPAND_0X(_CLASS_PACKAGED_STATE_REF, , , , )
|
|---|
| 723 | #undef _CLASS_PACKAGED_STATE_REF
|
|---|
| 724 |
|
|---|
| 725 | #define _CLASS_PACKAGED_STATE_VOID( \
|
|---|
| 726 | TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
|
|---|
| 727 | template<LIST(_CLASS_TYPE)> \
|
|---|
| 728 | class _Packaged_state<void(LIST(_TYPE))> \
|
|---|
| 729 | : public _Associated_state<int> \
|
|---|
| 730 | { /* manages associated asynchronous state for packaged_task */ \
|
|---|
| 731 | public: \
|
|---|
| 732 | template<class _Fty2> \
|
|---|
| 733 | _Packaged_state(const _Fty2& _Fnarg) \
|
|---|
| 734 | : _Fn(_Fnarg) \
|
|---|
| 735 | { /* construct from function object */ \
|
|---|
| 736 | } \
|
|---|
| 737 | template<class _Fty2, \
|
|---|
| 738 | class _Alloc> \
|
|---|
| 739 | _Packaged_state(const _Fty2& _Fnarg, const _Alloc& _Al, \
|
|---|
| 740 | _Deleter_base<int> *_Dp) \
|
|---|
| 741 | : _Associated_state<int>(_Dp), _Fn(_Fnarg, _Al) \
|
|---|
| 742 | { /* construct from function object and allocator */ \
|
|---|
| 743 | } \
|
|---|
| 744 | template<class _Fty2> \
|
|---|
| 745 | _Packaged_state(_Fty2&& _Fnarg) \
|
|---|
| 746 | : _Fn(_STD forward<_Fty2>(_Fnarg)) \
|
|---|
| 747 | { /* construct from rvalue function object */ \
|
|---|
| 748 | } \
|
|---|
| 749 | template<class _Fty2, \
|
|---|
| 750 | class _Alloc> \
|
|---|
| 751 | _Packaged_state(_Fty2&& _Fnarg, const _Alloc& _Al, \
|
|---|
| 752 | _Deleter_base<int> *_Dp) \
|
|---|
| 753 | : _Associated_state<int>(_Dp), \
|
|---|
| 754 | _Fn(_STD forward<_Fty2>(_Fnarg), _Al) \
|
|---|
| 755 | { /* construct from rvalue function object and allocator */ \
|
|---|
| 756 | } \
|
|---|
| 757 | _Packaged_state(const function<void(LIST(_TYPE))>& _NewFn, \
|
|---|
| 758 | bool) \
|
|---|
| 759 | : _Fn(_NewFn) \
|
|---|
| 760 | { /* construct from our own stored function type */ \
|
|---|
| 761 | } \
|
|---|
| 762 | void _Call_deferred(LIST(_TYPE_ARG)) \
|
|---|
| 763 | { /* set deferred call */ \
|
|---|
| 764 | _TRY_BEGIN \
|
|---|
| 765 | /* call function object and catch exceptions */ \
|
|---|
| 766 | _Fn(LIST(_FORWARD_ARG)); \
|
|---|
| 767 | this->_Set_value(1, true); \
|
|---|
| 768 | _CATCH_ALL \
|
|---|
| 769 | /* function object threw exception; record result */ \
|
|---|
| 770 | this->_Set_exception(_XSTD current_exception(), true); \
|
|---|
| 771 | _CATCH_END \
|
|---|
| 772 | } \
|
|---|
| 773 | void _Call_immediate(LIST(_TYPE_ARG)) \
|
|---|
| 774 | { /* call function object */ \
|
|---|
| 775 | _TRY_BEGIN \
|
|---|
| 776 | /* call function object and catch exceptions */ \
|
|---|
| 777 | _Fn(LIST(_FORWARD_ARG)); \
|
|---|
| 778 | this->_Set_value(1, false); \
|
|---|
| 779 | _CATCH_ALL \
|
|---|
| 780 | /* function object threw exception; record result */ \
|
|---|
| 781 | this->_Set_exception(_XSTD current_exception(), false); \
|
|---|
| 782 | _CATCH_END \
|
|---|
| 783 | } \
|
|---|
| 784 | const function<void (LIST(_TYPE))>& _Get_fn() \
|
|---|
| 785 | { /* return stored function object */ \
|
|---|
| 786 | return (_Fn); \
|
|---|
| 787 | } \
|
|---|
| 788 | private: \
|
|---|
| 789 | function<void (LIST(_TYPE))> _Fn; \
|
|---|
| 790 | };
|
|---|
| 791 |
|
|---|
| 792 | _VARIADIC_EXPAND_0X(_CLASS_PACKAGED_STATE_VOID, , , , )
|
|---|
| 793 | #undef _CLASS_PACKAGED_STATE_VOID
|
|---|
| 794 |
|
|---|
| 795 | template<class _Ty,
|
|---|
| 796 | class _Allocx> inline
|
|---|
| 797 | _Associated_state<_Ty> *_Make_associated_state(_Allocx _Al)
|
|---|
| 798 | { // construct an _Associated_state object with an allocator
|
|---|
| 799 | typedef _Wrap_alloc<_Allocx> _Alloc;
|
|---|
| 800 | typedef typename _Alloc::template rebind<_Associated_state<_Ty> >
|
|---|
| 801 | ::other _State_allocator;
|
|---|
| 802 | _State_allocator _St_alloc(_Al);
|
|---|
| 803 |
|
|---|
| 804 | typedef typename _Alloc::template rebind<_State_deleter<_Ty, _Alloc> >
|
|---|
| 805 | ::other _Deleter_allocator;
|
|---|
| 806 | _Deleter_allocator _Del_alloc(_Al);
|
|---|
| 807 | _State_deleter<_Ty, _Alloc> *_Del = _Del_alloc.allocate(1);
|
|---|
| 808 | _Del_alloc.construct(_Del, _St_alloc);
|
|---|
| 809 |
|
|---|
| 810 | _Associated_state<_Ty> *_Res = _St_alloc.allocate(1);
|
|---|
| 811 | _St_alloc.construct(_Res, _Del);
|
|---|
| 812 | return (_Res);
|
|---|
| 813 | }
|
|---|
| 814 |
|
|---|
| 815 | template<class _Fty,
|
|---|
| 816 | class _Allocx,
|
|---|
| 817 | class _Ty> inline
|
|---|
| 818 | _Associated_state<_Ty> *_Make_packaged_state(const _Fty& _Fn,
|
|---|
| 819 | const _Allocx& _Al)
|
|---|
| 820 | { // construct a _Packaged_state object with an allocator
|
|---|
| 821 | typedef _Wrap_alloc<_Allocx> _Alloc;
|
|---|
| 822 | typedef typename _Alloc::template rebind<_Packaged_state<_Fty> >
|
|---|
| 823 | ::other _State_allocator;
|
|---|
| 824 | _State_allocator _St_alloc(_Al);
|
|---|
| 825 |
|
|---|
| 826 | typedef typename _Alloc::template rebind<_State_deleter<_Fty, _Alloc> >
|
|---|
| 827 | ::other _Deleter_allocator;
|
|---|
| 828 | _Deleter_allocator _Del_alloc(_Al);
|
|---|
| 829 | _State_deleter<_Fty, _Alloc> *_Del = _Del_alloc.allocate(1);
|
|---|
| 830 | _Del_alloc.construct(_Del, _St_alloc);
|
|---|
| 831 |
|
|---|
| 832 | _Packaged_state<_Fty> *_Res = _St_alloc.allocate(1);
|
|---|
| 833 | _St_alloc.construct(_Res, _Fn, _Del);
|
|---|
| 834 | return (_Res);
|
|---|
| 835 | }
|
|---|
| 836 |
|
|---|
| 837 | template<class _Fty,
|
|---|
| 838 | class _Alloc,
|
|---|
| 839 | class _Ty> inline
|
|---|
| 840 | _Associated_state<_Ty> *_Make_packaged_state(_Fty&& _Fn,
|
|---|
| 841 | const _Alloc& _Al)
|
|---|
| 842 | { // construct a _Packaged_state object with an allocator from
|
|---|
| 843 | // an rvalue function object
|
|---|
| 844 | typedef typename _Alloc::template rebind<_Packaged_state<_Fty> >
|
|---|
| 845 | ::other _State_allocator;
|
|---|
| 846 | _State_allocator _St_alloc(_Al);
|
|---|
| 847 |
|
|---|
| 848 | typedef typename _Alloc::template rebind<_State_deleter<_Fty, _Alloc> >
|
|---|
| 849 | ::other _Deleter_allocator;
|
|---|
| 850 | _Deleter_allocator _Del_alloc(_Al);
|
|---|
| 851 | _State_deleter<_Fty, _Alloc> *_Del = _Del_alloc.allocate(1);
|
|---|
| 852 | _Del_alloc.construct(_Del, _St_alloc);
|
|---|
| 853 |
|
|---|
| 854 | _Packaged_state<_Fty> *_Res = _St_alloc.allocate(1);
|
|---|
| 855 | _St_alloc.construct(_Res, _STD forward<_Fty>(_Fn), _Del);
|
|---|
| 856 | return (_Res);
|
|---|
| 857 | }
|
|---|
| 858 |
|
|---|
| 859 | // TEMPLATE CLASS _Deferred_async_state
|
|---|
| 860 | template<class _Rx>
|
|---|
| 861 | class _Deferred_async_state
|
|---|
| 862 | : public _Packaged_state<_Rx()>
|
|---|
| 863 | { // class for managing associated synchronous state for deferred
|
|---|
| 864 | // execution from async
|
|---|
| 865 | public:
|
|---|
| 866 | template<class _Fty2>
|
|---|
| 867 | _Deferred_async_state(const _Fty2& _Fnarg)
|
|---|
| 868 | : _Packaged_state<_Rx()>(_Fnarg)
|
|---|
| 869 | { // construct from function object
|
|---|
| 870 | }
|
|---|
| 871 |
|
|---|
| 872 | template<class _Fty2>
|
|---|
| 873 | _Deferred_async_state(_Fty2&& _Fnarg)
|
|---|
| 874 | : _Packaged_state<_Rx()>(_STD forward<_Fty2>(_Fnarg))
|
|---|
| 875 | { // construct from rvalue function object
|
|---|
| 876 | }
|
|---|
| 877 |
|
|---|
| 878 | private:
|
|---|
| 879 | void _Run_deferred_function(unique_lock<mutex>& _Lock)
|
|---|
| 880 | { // run the deferred function
|
|---|
| 881 | _Lock.unlock();
|
|---|
| 882 | _Packaged_state<_Rx()>::_Call_immediate();
|
|---|
| 883 | _Lock.lock();
|
|---|
| 884 | }
|
|---|
| 885 | };
|
|---|
| 886 |
|
|---|
| 887 | // TEMPLATE CLASS _Task_async_state
|
|---|
| 888 | template<class _Rx, bool _Inline>
|
|---|
| 889 | class _Task_async_state
|
|---|
| 890 | : public _Packaged_state<_Rx()>
|
|---|
| 891 | { // class for managing associated synchronous state for asynchronous
|
|---|
| 892 | // execution from async
|
|---|
| 893 | public:
|
|---|
| 894 | typedef _Packaged_state<_Rx()> _Mybase;
|
|---|
| 895 | typedef typename _Mybase::_State_type _State_type;
|
|---|
| 896 |
|
|---|
| 897 | template<class _Fty2>
|
|---|
| 898 | _Task_async_state(_Fty2&& _Fnarg)
|
|---|
| 899 | : _Mybase(_STD forward<_Fty2>(_Fnarg))
|
|---|
| 900 | { // construct from rvalue function object
|
|---|
| 901 | this->_Retain(); // to support fire-and-forget future
|
|---|
| 902 | _Task = ::Concurrency::create_task([this]()
|
|---|
| 903 | { // do it now
|
|---|
| 904 | if (_Inline)
|
|---|
| 905 | _Call_immediate();
|
|---|
| 906 | else
|
|---|
| 907 | { // turn on oversubscription for launch::async
|
|---|
| 908 | ::Concurrency::details::_Context::_Oversubscribe(true);
|
|---|
| 909 | _Call_immediate();
|
|---|
| 910 | ::Concurrency::details::_Context::_Oversubscribe(false);
|
|---|
| 911 | }
|
|---|
| 912 | _Release();
|
|---|
| 913 | });
|
|---|
| 914 | _Running = true;
|
|---|
| 915 | }
|
|---|
| 916 |
|
|---|
| 917 | virtual void _Wait()
|
|---|
| 918 | { // wait for completion
|
|---|
| 919 | if (_Inline)
|
|---|
| 920 | _Task.wait();
|
|---|
| 921 | else
|
|---|
| 922 | _Mybase::_Wait();
|
|---|
| 923 | }
|
|---|
| 924 |
|
|---|
| 925 | virtual _State_type& _Get_value(bool _Get_only_once)
|
|---|
| 926 | { // return the stored result or throw stored exception
|
|---|
| 927 | if (_Inline)
|
|---|
| 928 | _Task.wait();
|
|---|
| 929 | return (_Mybase::_Get_value(_Get_only_once));
|
|---|
| 930 | }
|
|---|
| 931 |
|
|---|
| 932 | private:
|
|---|
| 933 | ::Concurrency::task<void> _Task;
|
|---|
| 934 | };
|
|---|
| 935 |
|
|---|
| 936 | // TEMPLATE CLASS _State_manager
|
|---|
| 937 | template<class _Ty>
|
|---|
| 938 | class _State_manager
|
|---|
| 939 | { // class for managing possibly non-existent associated
|
|---|
| 940 | // asynchronous state object
|
|---|
| 941 | public:
|
|---|
| 942 | _State_manager()
|
|---|
| 943 | : _Assoc_state(0)
|
|---|
| 944 | { // construct with no associated asynchronous state object
|
|---|
| 945 | _Get_only_once = false;
|
|---|
| 946 | }
|
|---|
| 947 |
|
|---|
| 948 | _State_manager(_Associated_state<_Ty> *_New_state, bool _Get_once)
|
|---|
| 949 | : _Assoc_state(_New_state)
|
|---|
| 950 | { // construct with _New_state
|
|---|
| 951 | _Get_only_once = _Get_once;
|
|---|
| 952 | }
|
|---|
| 953 |
|
|---|
| 954 | _State_manager(const _State_manager& _Other, bool _Get_once = false)
|
|---|
| 955 | : _Assoc_state(0)
|
|---|
| 956 | { // construct from _Other
|
|---|
| 957 | _Copy_from(_Other);
|
|---|
| 958 | _Get_only_once = _Get_once;
|
|---|
| 959 | }
|
|---|
| 960 |
|
|---|
| 961 | _State_manager(_State_manager&& _Other, bool _Get_once = false)
|
|---|
| 962 | : _Assoc_state(0)
|
|---|
| 963 | { // construct from rvalue _Other
|
|---|
| 964 | _Move_from(_Other);
|
|---|
| 965 | _Get_only_once = _Get_once;
|
|---|
| 966 | }
|
|---|
| 967 |
|
|---|
| 968 | ~_State_manager() _NOEXCEPT
|
|---|
| 969 | { // destroy
|
|---|
| 970 | if (_Assoc_state != 0)
|
|---|
| 971 | _Assoc_state->_Release();
|
|---|
| 972 | }
|
|---|
| 973 |
|
|---|
| 974 | _State_manager& operator=(const _State_manager& _Other)
|
|---|
| 975 | { // assign from _Other
|
|---|
| 976 | _Copy_from(_Other);
|
|---|
| 977 | return (*this);
|
|---|
| 978 | }
|
|---|
| 979 |
|
|---|
| 980 | _State_manager& operator=(_State_manager&& _Other)
|
|---|
| 981 | { // assign from rvalue _Other
|
|---|
| 982 | _Move_from(_Other);
|
|---|
| 983 | return (*this);
|
|---|
| 984 | }
|
|---|
| 985 |
|
|---|
| 986 | bool valid() const _NOEXCEPT
|
|---|
| 987 | { // return status
|
|---|
| 988 | return (_Assoc_state != 0
|
|---|
| 989 | && !(_Get_only_once && _Assoc_state->_Already_retrieved()));
|
|---|
| 990 | }
|
|---|
| 991 |
|
|---|
| 992 | void wait() const
|
|---|
| 993 | { // wait for signal
|
|---|
| 994 | if (!valid())
|
|---|
| 995 | _Throw_future_error(make_error_code(future_errc::no_state));
|
|---|
| 996 | _Assoc_state->_Wait();
|
|---|
| 997 | }
|
|---|
| 998 |
|
|---|
| 999 | template<class _Rep,
|
|---|
| 1000 | class _Per>
|
|---|
| 1001 | _Future_status wait_for(
|
|---|
| 1002 | const chrono::duration<_Rep, _Per>& _Rel_time) const
|
|---|
| 1003 | { // wait for duration
|
|---|
| 1004 | if (!valid())
|
|---|
| 1005 | _Throw_future_error(make_error_code(future_errc::no_state));
|
|---|
| 1006 | return (_Assoc_state->_Wait_for(_Rel_time));
|
|---|
| 1007 | }
|
|---|
| 1008 |
|
|---|
| 1009 | template<class _Clock,
|
|---|
| 1010 | class _Dur>
|
|---|
| 1011 | _Future_status wait_until(
|
|---|
| 1012 | const chrono::time_point<_Clock, _Dur>& _Abs_time) const
|
|---|
| 1013 | { // wait until time point
|
|---|
| 1014 | if (!valid())
|
|---|
| 1015 | _Throw_future_error(make_error_code(future_errc::no_state));
|
|---|
| 1016 | return (_Assoc_state->_Wait_until(_Abs_time));
|
|---|
| 1017 | }
|
|---|
| 1018 |
|
|---|
| 1019 | _Ty& _Get_value() const
|
|---|
| 1020 | { // return the stored result or throw stored exception
|
|---|
| 1021 | if (!valid())
|
|---|
| 1022 | _Throw_future_error(
|
|---|
| 1023 | make_error_code(future_errc::no_state));
|
|---|
| 1024 | return (_Assoc_state->_Get_value(_Get_only_once));
|
|---|
| 1025 | }
|
|---|
| 1026 |
|
|---|
| 1027 | void _Set_value(const _Ty& _Val, bool _Defer)
|
|---|
| 1028 | { // store a result
|
|---|
| 1029 | if (!valid())
|
|---|
| 1030 | _Throw_future_error(
|
|---|
| 1031 | make_error_code(future_errc::no_state));
|
|---|
| 1032 | _Assoc_state->_Set_value(_Val, _Defer);
|
|---|
| 1033 | }
|
|---|
| 1034 |
|
|---|
| 1035 | void _Set_value(_Ty&& _Val, bool _Defer)
|
|---|
| 1036 | { // store a result
|
|---|
| 1037 | if (!valid())
|
|---|
| 1038 | _Throw_future_error(
|
|---|
| 1039 | make_error_code(future_errc::no_state));
|
|---|
| 1040 | _Assoc_state->_Set_value(_STD forward<_Ty>(_Val), _Defer);
|
|---|
| 1041 | }
|
|---|
| 1042 |
|
|---|
| 1043 | void _Set_exception(_XSTD exception_ptr _Exc, bool _Defer)
|
|---|
| 1044 | { // store a result
|
|---|
| 1045 | if (!valid())
|
|---|
| 1046 | _Throw_future_error(
|
|---|
| 1047 | make_error_code(future_errc::no_state));
|
|---|
| 1048 | _Assoc_state->_Set_exception(_Exc, _Defer);
|
|---|
| 1049 | }
|
|---|
| 1050 |
|
|---|
| 1051 | void _Swap(_State_manager& _Other)
|
|---|
| 1052 | { // exchange with _Other
|
|---|
| 1053 | _STD swap(_Assoc_state, _Other._Assoc_state);
|
|---|
| 1054 | }
|
|---|
| 1055 |
|
|---|
| 1056 | _Associated_state<_Ty> *_Ptr() const
|
|---|
| 1057 | { // return pointer to stored associated asynchronous state object
|
|---|
| 1058 | return (_Assoc_state);
|
|---|
| 1059 | }
|
|---|
| 1060 |
|
|---|
| 1061 | void _Copy_from(const _State_manager& _Other)
|
|---|
| 1062 | { // copy stored associated asynchronous state object from _Other
|
|---|
| 1063 | if (this != &_Other)
|
|---|
| 1064 | { // different, copy
|
|---|
| 1065 | if (_Assoc_state)
|
|---|
| 1066 | _Assoc_state->_Release();
|
|---|
| 1067 | if (_Other._Assoc_state == 0)
|
|---|
| 1068 | _Assoc_state = 0;
|
|---|
| 1069 | else
|
|---|
| 1070 | { // do the copy
|
|---|
| 1071 | _Other._Assoc_state->_Retain();
|
|---|
| 1072 | _Assoc_state = _Other._Assoc_state;
|
|---|
| 1073 | _Get_only_once = _Other._Get_only_once;
|
|---|
| 1074 | }
|
|---|
| 1075 | }
|
|---|
| 1076 | }
|
|---|
| 1077 |
|
|---|
| 1078 | void _Move_from(_State_manager& _Other)
|
|---|
| 1079 | { // move stored associated asynchronous state object from _Other
|
|---|
| 1080 | if (this != &_Other)
|
|---|
| 1081 | { // different, move
|
|---|
| 1082 | if (_Assoc_state)
|
|---|
| 1083 | _Assoc_state->_Release();
|
|---|
| 1084 | _Assoc_state = _Other._Assoc_state;
|
|---|
| 1085 | _Other._Assoc_state = 0;
|
|---|
| 1086 | _Get_only_once = _Other._Get_only_once;
|
|---|
| 1087 | }
|
|---|
| 1088 | }
|
|---|
| 1089 |
|
|---|
| 1090 | bool _Is_ready() const
|
|---|
| 1091 | { // return status
|
|---|
| 1092 | return (_Assoc_state && _Assoc_state->_Is_ready());
|
|---|
| 1093 | }
|
|---|
| 1094 |
|
|---|
| 1095 | private:
|
|---|
| 1096 | _Associated_state<_Ty> *_Assoc_state;
|
|---|
| 1097 | bool _Get_only_once;
|
|---|
| 1098 | };
|
|---|
| 1099 |
|
|---|
| 1100 | // TEMPLATE CLASS future
|
|---|
| 1101 | template<class _Ty>
|
|---|
| 1102 | class shared_future;
|
|---|
| 1103 |
|
|---|
| 1104 | template<class _Ty>
|
|---|
| 1105 | class future
|
|---|
| 1106 | : public _State_manager<_Ty>
|
|---|
| 1107 | { // class that defines a non-copyable asynchronous return object
|
|---|
| 1108 | // that holds a value
|
|---|
| 1109 | typedef _State_manager<_Ty> _Mybase;
|
|---|
| 1110 | public:
|
|---|
| 1111 | future() _NOEXCEPT
|
|---|
| 1112 | { // construct
|
|---|
| 1113 | }
|
|---|
| 1114 |
|
|---|
| 1115 | future(future&& _Other) _NOEXCEPT
|
|---|
| 1116 | : _Mybase(_STD forward<future>(_Other), true)
|
|---|
| 1117 | { // construct from rvalue future object
|
|---|
| 1118 | }
|
|---|
| 1119 |
|
|---|
| 1120 | future& operator=(future&& _Right) _NOEXCEPT
|
|---|
| 1121 | { // assign from rvalue future object
|
|---|
| 1122 | _Mybase::operator=(_STD forward<future>(_Right));
|
|---|
| 1123 | return (*this);
|
|---|
| 1124 | }
|
|---|
| 1125 |
|
|---|
| 1126 | future(const _Mybase& _State)
|
|---|
| 1127 | : _Mybase(_State, true)
|
|---|
| 1128 | { // construct from associated asynchronous state object
|
|---|
| 1129 | }
|
|---|
| 1130 |
|
|---|
| 1131 | ~future() _NOEXCEPT
|
|---|
| 1132 | { // destroy
|
|---|
| 1133 | }
|
|---|
| 1134 |
|
|---|
| 1135 | _Ty get()
|
|---|
| 1136 | { // block until ready then return the stored result or
|
|---|
| 1137 | // throw the stored exception
|
|---|
| 1138 | return (_STD move(this->_Get_value()));
|
|---|
| 1139 | }
|
|---|
| 1140 |
|
|---|
| 1141 | shared_future<_Ty> share()
|
|---|
| 1142 | { // return state as shared_future
|
|---|
| 1143 | return (shared_future<_Ty>(_STD move(*this)));
|
|---|
| 1144 | }
|
|---|
| 1145 |
|
|---|
| 1146 | private:
|
|---|
| 1147 | future(const future& _Other);
|
|---|
| 1148 | future& operator=(const future& _Right);
|
|---|
| 1149 | };
|
|---|
| 1150 |
|
|---|
| 1151 | template<class _Ty>
|
|---|
| 1152 | class future<_Ty&>
|
|---|
| 1153 | : public _State_manager<_Ty *>
|
|---|
| 1154 | { // class that defines a non-copyable asynchronous return object
|
|---|
| 1155 | // that holds a reference
|
|---|
| 1156 | typedef _State_manager<_Ty *> _Mybase;
|
|---|
| 1157 | public:
|
|---|
| 1158 | future() _NOEXCEPT
|
|---|
| 1159 | { // construct
|
|---|
| 1160 | }
|
|---|
| 1161 |
|
|---|
| 1162 | future(future&& _Other) _NOEXCEPT
|
|---|
| 1163 | : _Mybase(_STD forward<future>(_Other), true)
|
|---|
| 1164 | { // construct from rvalue future object
|
|---|
| 1165 | }
|
|---|
| 1166 |
|
|---|
| 1167 | future& operator=(future&& _Right) _NOEXCEPT
|
|---|
| 1168 | { // assign from rvalue future object
|
|---|
| 1169 | _Mybase::operator=(_STD forward<future>(_Right));
|
|---|
| 1170 | return (*this);
|
|---|
| 1171 | }
|
|---|
| 1172 |
|
|---|
| 1173 | future(const _Mybase& _State)
|
|---|
| 1174 | : _Mybase(_State, true)
|
|---|
| 1175 | { // construct from associated asynchronous state object
|
|---|
| 1176 | }
|
|---|
| 1177 |
|
|---|
| 1178 | ~future() _NOEXCEPT
|
|---|
| 1179 | { // destroy
|
|---|
| 1180 | }
|
|---|
| 1181 |
|
|---|
| 1182 | _Ty& get()
|
|---|
| 1183 | { // block until ready then return the stored result or
|
|---|
| 1184 | // throw the stored exception
|
|---|
| 1185 | return (*this->_Get_value());
|
|---|
| 1186 | }
|
|---|
| 1187 |
|
|---|
| 1188 | shared_future<_Ty&> share()
|
|---|
| 1189 | { // return state as shared_future
|
|---|
| 1190 | return (shared_future<_Ty&>(_STD move(*this)));
|
|---|
| 1191 | }
|
|---|
| 1192 |
|
|---|
| 1193 | private:
|
|---|
| 1194 | future(const future& _Other);
|
|---|
| 1195 | future& operator=(const future& _Right);
|
|---|
| 1196 | };
|
|---|
| 1197 |
|
|---|
| 1198 | template<>
|
|---|
| 1199 | class future<void>
|
|---|
| 1200 | : public _State_manager<int>
|
|---|
| 1201 | { // class that defines a non-copyable asynchronous return object
|
|---|
| 1202 | // that does not hold a value
|
|---|
| 1203 | typedef _State_manager<int> _Mybase;
|
|---|
| 1204 | public:
|
|---|
| 1205 | future() _NOEXCEPT
|
|---|
| 1206 | { // construct
|
|---|
| 1207 | }
|
|---|
| 1208 |
|
|---|
| 1209 | future(future&& _Other) _NOEXCEPT
|
|---|
| 1210 | : _Mybase(_STD forward<future>(_Other), true)
|
|---|
| 1211 | { // construct from rvalue future object
|
|---|
| 1212 | }
|
|---|
| 1213 |
|
|---|
| 1214 | future& operator=(future&& _Right) _NOEXCEPT
|
|---|
| 1215 | { // assign from rvalue future object
|
|---|
| 1216 | _Mybase::operator=(_STD forward<future>(_Right));
|
|---|
| 1217 | return (*this);
|
|---|
| 1218 | }
|
|---|
| 1219 |
|
|---|
| 1220 | future(const _Mybase& _State)
|
|---|
| 1221 | : _Mybase(_State, true)
|
|---|
| 1222 | { // construct from associated asynchronous state object
|
|---|
| 1223 | }
|
|---|
| 1224 |
|
|---|
| 1225 | ~future() _NOEXCEPT
|
|---|
| 1226 | { // destroy
|
|---|
| 1227 | }
|
|---|
| 1228 |
|
|---|
| 1229 | void get()
|
|---|
| 1230 | { // block until ready then return or
|
|---|
| 1231 | // throw the stored exception
|
|---|
| 1232 | this->_Get_value();
|
|---|
| 1233 | }
|
|---|
| 1234 |
|
|---|
| 1235 | shared_future<void> share();
|
|---|
| 1236 |
|
|---|
| 1237 | private:
|
|---|
| 1238 | future(const future& _Other);
|
|---|
| 1239 | future& operator=(const future& _Right);
|
|---|
| 1240 | };
|
|---|
| 1241 |
|
|---|
| 1242 | // TEMPLATE CLASS shared_future
|
|---|
| 1243 | template<class _Ty>
|
|---|
| 1244 | class shared_future
|
|---|
| 1245 | : public _State_manager<_Ty>
|
|---|
| 1246 | { // class that defines a copyable asynchronous return object
|
|---|
| 1247 | // that holds a value
|
|---|
| 1248 | typedef _State_manager<_Ty> _Mybase;
|
|---|
| 1249 |
|
|---|
| 1250 | public:
|
|---|
| 1251 | shared_future() _NOEXCEPT
|
|---|
| 1252 | { // construct
|
|---|
| 1253 | }
|
|---|
| 1254 |
|
|---|
| 1255 | shared_future(const shared_future& _Other)
|
|---|
| 1256 | : _Mybase(_Other)
|
|---|
| 1257 | { // construct from shared_future object
|
|---|
| 1258 | }
|
|---|
| 1259 |
|
|---|
| 1260 | shared_future& operator=(const shared_future& _Right)
|
|---|
| 1261 | { // assign from shared_future object
|
|---|
| 1262 | _Mybase::operator=(_Right);
|
|---|
| 1263 | return (*this);
|
|---|
| 1264 | }
|
|---|
| 1265 |
|
|---|
| 1266 | shared_future(future<_Ty>&& _Other) _NOEXCEPT
|
|---|
| 1267 | : _Mybase(_STD forward<_Mybase>(_Other))
|
|---|
| 1268 | { // construct from rvalue future object
|
|---|
| 1269 | }
|
|---|
| 1270 |
|
|---|
| 1271 | shared_future(shared_future&& _Other) _NOEXCEPT
|
|---|
| 1272 | : _Mybase(_STD forward<shared_future>(_Other))
|
|---|
| 1273 | { // construct from rvalue shared_future object
|
|---|
| 1274 | }
|
|---|
| 1275 |
|
|---|
| 1276 | shared_future& operator=(shared_future&& _Right) _NOEXCEPT
|
|---|
| 1277 | { // assign from shared_future rvalue object
|
|---|
| 1278 | _Mybase::operator=(_STD forward<shared_future>(_Right));
|
|---|
| 1279 | return (*this);
|
|---|
| 1280 | }
|
|---|
| 1281 |
|
|---|
| 1282 | ~shared_future() _NOEXCEPT
|
|---|
| 1283 | { // destroy
|
|---|
| 1284 | }
|
|---|
| 1285 |
|
|---|
| 1286 | const _Ty& get() const
|
|---|
| 1287 | { // block until ready then return the stored result or
|
|---|
| 1288 | // throw the stored exception
|
|---|
| 1289 | return (this->_Get_value());
|
|---|
| 1290 | }
|
|---|
| 1291 | };
|
|---|
| 1292 |
|
|---|
| 1293 | template<class _Ty>
|
|---|
| 1294 | class shared_future<_Ty&>
|
|---|
| 1295 | : public _State_manager<_Ty *>
|
|---|
| 1296 | { // class that defines a copyable asynchronous return object
|
|---|
| 1297 | // that holds a reference
|
|---|
| 1298 | typedef _State_manager<_Ty *> _Mybase;
|
|---|
| 1299 |
|
|---|
| 1300 | public:
|
|---|
| 1301 | shared_future() _NOEXCEPT
|
|---|
| 1302 | { // construct
|
|---|
| 1303 | }
|
|---|
| 1304 |
|
|---|
| 1305 | shared_future(const future<_Ty&>& _Other)
|
|---|
| 1306 | : _Mybase(_Other)
|
|---|
| 1307 | { // construct from rvalue future object
|
|---|
| 1308 | }
|
|---|
| 1309 |
|
|---|
| 1310 | shared_future(const shared_future& _Other)
|
|---|
| 1311 | : _Mybase(_Other)
|
|---|
| 1312 | { // construct from shared_future object
|
|---|
| 1313 | }
|
|---|
| 1314 |
|
|---|
| 1315 | shared_future& operator=(const shared_future& _Right)
|
|---|
| 1316 | { // assign from shared_future object
|
|---|
| 1317 | _Mybase::operator=(_Right);
|
|---|
| 1318 | return (*this);
|
|---|
| 1319 | }
|
|---|
| 1320 |
|
|---|
| 1321 | shared_future(future<_Ty&>&& _Other) _NOEXCEPT
|
|---|
| 1322 | : _Mybase(_STD forward<_Mybase>(_Other))
|
|---|
| 1323 | { // construct from rvalue future object
|
|---|
| 1324 | }
|
|---|
| 1325 |
|
|---|
| 1326 | shared_future(shared_future&& _Other) _NOEXCEPT
|
|---|
| 1327 | : _Mybase(_STD forward<shared_future>(_Other))
|
|---|
| 1328 | { // construct from rvalue shared_future object
|
|---|
| 1329 | }
|
|---|
| 1330 |
|
|---|
| 1331 | shared_future& operator=(shared_future&& _Right) _NOEXCEPT
|
|---|
| 1332 | { // assign from rvalue shared_future object
|
|---|
| 1333 | _Mybase::operator=(_STD forward<shared_future>(_Right));
|
|---|
| 1334 | return (*this);
|
|---|
| 1335 | }
|
|---|
| 1336 |
|
|---|
| 1337 | ~shared_future() _NOEXCEPT
|
|---|
| 1338 | { // destroy
|
|---|
| 1339 | }
|
|---|
| 1340 |
|
|---|
| 1341 | _Ty& get() const
|
|---|
| 1342 | { // block until ready then return the stored result or
|
|---|
| 1343 | // throw the stored exception
|
|---|
| 1344 | return (*this->_Get_value());
|
|---|
| 1345 | }
|
|---|
| 1346 | };
|
|---|
| 1347 |
|
|---|
| 1348 | template<>
|
|---|
| 1349 | class shared_future<void>
|
|---|
| 1350 | : public _State_manager<int>
|
|---|
| 1351 | { // class that defines a copyable asynchronous return object
|
|---|
| 1352 | // that does not hold a value
|
|---|
| 1353 | typedef _State_manager<int> _Mybase;
|
|---|
| 1354 |
|
|---|
| 1355 | public:
|
|---|
| 1356 | shared_future() _NOEXCEPT
|
|---|
| 1357 | { // construct
|
|---|
| 1358 | }
|
|---|
| 1359 |
|
|---|
| 1360 | shared_future(const shared_future& _Other)
|
|---|
| 1361 | : _Mybase(_Other)
|
|---|
| 1362 | { // construct from shared_future object
|
|---|
| 1363 | }
|
|---|
| 1364 |
|
|---|
| 1365 | shared_future(const future<void>& _Other)
|
|---|
| 1366 | : _Mybase(_Other)
|
|---|
| 1367 | { // construct from rvalue future object
|
|---|
| 1368 | }
|
|---|
| 1369 |
|
|---|
| 1370 | shared_future& operator=(const shared_future& _Right)
|
|---|
| 1371 | { // assign from shared_future object
|
|---|
| 1372 | _Mybase::operator=(_Right);
|
|---|
| 1373 | return (*this);
|
|---|
| 1374 | }
|
|---|
| 1375 |
|
|---|
| 1376 | shared_future(shared_future&& _Other) _NOEXCEPT
|
|---|
| 1377 | : _Mybase(_STD forward<shared_future>(_Other))
|
|---|
| 1378 | { // construct from rvalue shared_future object
|
|---|
| 1379 | }
|
|---|
| 1380 |
|
|---|
| 1381 | shared_future(future<void>&& _Other) _NOEXCEPT
|
|---|
| 1382 | : _Mybase(_STD forward<_Mybase>(_Other))
|
|---|
| 1383 | { // construct from rvalue future object
|
|---|
| 1384 | }
|
|---|
| 1385 |
|
|---|
| 1386 | shared_future& operator=(shared_future&& _Right)
|
|---|
| 1387 | { // assign from rvalue shared_future object
|
|---|
| 1388 | _Mybase::operator=(_STD forward<shared_future>(_Right));
|
|---|
| 1389 | return (*this);
|
|---|
| 1390 | }
|
|---|
| 1391 |
|
|---|
| 1392 | ~shared_future() _NOEXCEPT
|
|---|
| 1393 | { // destroy
|
|---|
| 1394 | }
|
|---|
| 1395 |
|
|---|
| 1396 | void get() const
|
|---|
| 1397 | { // block until ready then return or
|
|---|
| 1398 | // throw the stored exception
|
|---|
| 1399 | this->_Get_value();
|
|---|
| 1400 | }
|
|---|
| 1401 | };
|
|---|
| 1402 |
|
|---|
| 1403 | // DEFINITION OF future<void>::share()
|
|---|
| 1404 | inline shared_future<void> future<void>::share()
|
|---|
| 1405 | { // return state as shared_future
|
|---|
| 1406 | return (shared_future<void>(_STD move(*this)));
|
|---|
| 1407 | }
|
|---|
| 1408 |
|
|---|
| 1409 | // TEMPLATE CLASS _Promise
|
|---|
| 1410 | template<class _Ty>
|
|---|
| 1411 | class _Promise
|
|---|
| 1412 | { // class that implements core of promise
|
|---|
| 1413 | public:
|
|---|
| 1414 | _Promise(_Associated_state<_Ty> *_State_ptr)
|
|---|
| 1415 | : _State(_State_ptr, false),
|
|---|
| 1416 | _Future_retrieved(false)
|
|---|
| 1417 | { // construct from associated asynchronous state object
|
|---|
| 1418 | }
|
|---|
| 1419 |
|
|---|
| 1420 | _Promise(_Promise&& _Other)
|
|---|
| 1421 | : _State(_STD forward<_State_manager<_Ty> >(_Other._State)),
|
|---|
| 1422 | _Future_retrieved(_Other._Future_retrieved)
|
|---|
| 1423 | { // construct from rvalue _Promise object
|
|---|
| 1424 | }
|
|---|
| 1425 |
|
|---|
| 1426 | _Promise& operator=(_Promise&& _Other)
|
|---|
| 1427 | { // assign from rvalue _Promise object
|
|---|
| 1428 | _State = _STD move(_Other._State);
|
|---|
| 1429 | _Future_retrieved = _Other._Future_retrieved;
|
|---|
| 1430 | return (*this);
|
|---|
| 1431 | }
|
|---|
| 1432 |
|
|---|
| 1433 | ~_Promise() _NOEXCEPT
|
|---|
| 1434 | { // destroy
|
|---|
| 1435 | }
|
|---|
| 1436 |
|
|---|
| 1437 | void _Swap(_Promise& _Other)
|
|---|
| 1438 | { // exchange with _Other
|
|---|
| 1439 | _State._Swap(_Other._State);
|
|---|
| 1440 | _STD swap(_Future_retrieved, _Other._Future_retrieved);
|
|---|
| 1441 | }
|
|---|
| 1442 |
|
|---|
| 1443 | const _State_manager<_Ty>& _Get_state() const
|
|---|
| 1444 | { // return reference to associated asynchronous state object
|
|---|
| 1445 | return (_State);
|
|---|
| 1446 | }
|
|---|
| 1447 | _State_manager<_Ty>& _Get_state()
|
|---|
| 1448 | { // return reference to associated asynchronous state object
|
|---|
| 1449 | return (_State);
|
|---|
| 1450 | }
|
|---|
| 1451 |
|
|---|
| 1452 | _State_manager<_Ty>& _Get_state_for_set()
|
|---|
| 1453 | { // return reference to associated asynchronous state object, or
|
|---|
| 1454 | // throw exception if not valid for setting state
|
|---|
| 1455 | if (!_State.valid())
|
|---|
| 1456 | _Throw_future_error(
|
|---|
| 1457 | make_error_code(future_errc::no_state));
|
|---|
| 1458 | return (_State);
|
|---|
| 1459 | }
|
|---|
| 1460 |
|
|---|
| 1461 | _State_manager<_Ty>& _Get_state_for_future()
|
|---|
| 1462 | { // return reference to associated asynchronous state object, or
|
|---|
| 1463 | // throw exception if not valid for retrieving future
|
|---|
| 1464 | if (!_State.valid())
|
|---|
| 1465 | _Throw_future_error(
|
|---|
| 1466 | make_error_code(future_errc::no_state));
|
|---|
| 1467 | if (_Future_retrieved)
|
|---|
| 1468 | _Throw_future_error(
|
|---|
| 1469 | make_error_code(future_errc::future_already_retrieved));
|
|---|
| 1470 | _Future_retrieved = true;
|
|---|
| 1471 | return (_State);
|
|---|
| 1472 | }
|
|---|
| 1473 |
|
|---|
| 1474 | bool _Is_valid() const
|
|---|
| 1475 | { // return status
|
|---|
| 1476 | return (_State.valid());
|
|---|
| 1477 | }
|
|---|
| 1478 |
|
|---|
| 1479 | bool _Is_ready() const
|
|---|
| 1480 | { // return status
|
|---|
| 1481 | return (_State._Is_ready());
|
|---|
| 1482 | }
|
|---|
| 1483 |
|
|---|
| 1484 | private:
|
|---|
| 1485 | _State_manager<_Ty> _State;
|
|---|
| 1486 | bool _Future_retrieved;
|
|---|
| 1487 |
|
|---|
| 1488 | _Promise(const _Promise&); // not defined
|
|---|
| 1489 | _Promise& operator=(const _Promise&); // not defined
|
|---|
| 1490 | };
|
|---|
| 1491 |
|
|---|
| 1492 | // TEMPLATE CLASS promise
|
|---|
| 1493 | template<class _Ty>
|
|---|
| 1494 | class promise
|
|---|
| 1495 | { // class that defines an asynchronous provider that holds a value
|
|---|
| 1496 | public:
|
|---|
| 1497 | promise()
|
|---|
| 1498 | : _MyPromise(new _Associated_state<_Ty>)
|
|---|
| 1499 | { // construct
|
|---|
| 1500 | }
|
|---|
| 1501 |
|
|---|
| 1502 | template<class _Alloc>
|
|---|
| 1503 | promise(allocator_arg_t, const _Alloc& _Al)
|
|---|
| 1504 | : _MyPromise(_Make_associated_state<_Ty>(_Al))
|
|---|
| 1505 | { // construct with allocator
|
|---|
| 1506 | }
|
|---|
| 1507 |
|
|---|
| 1508 | promise(promise&& _Other) _NOEXCEPT
|
|---|
| 1509 | : _MyPromise(_STD forward<_Promise<_Ty> >(_Other._MyPromise))
|
|---|
| 1510 | { // construct from rvalue promise object
|
|---|
| 1511 | }
|
|---|
| 1512 |
|
|---|
| 1513 | promise& operator=(promise&& _Other) _NOEXCEPT
|
|---|
| 1514 | { // assign from rvalue promise object
|
|---|
| 1515 | _MyPromise = _STD forward<_Promise<_Ty> >(_Other._MyPromise);
|
|---|
| 1516 | return (*this);
|
|---|
| 1517 | }
|
|---|
| 1518 |
|
|---|
| 1519 | ~promise() _NOEXCEPT
|
|---|
| 1520 | { // destroy
|
|---|
| 1521 | if (_MyPromise._Is_valid() && !_MyPromise._Is_ready())
|
|---|
| 1522 | { // exception if destroyed before function object returns
|
|---|
| 1523 | future_error _Fut(make_error_code(future_errc::broken_promise));
|
|---|
| 1524 | _MyPromise._Get_state()
|
|---|
| 1525 | ._Set_exception(_XSTD make_exception_ptr(_Fut), false);
|
|---|
| 1526 | }
|
|---|
| 1527 | }
|
|---|
| 1528 |
|
|---|
| 1529 | void swap(promise& _Other) _NOEXCEPT
|
|---|
| 1530 | { // exchange with _Other
|
|---|
| 1531 | _MyPromise._Swap(_Other._MyPromise);
|
|---|
| 1532 | }
|
|---|
| 1533 |
|
|---|
| 1534 | future<_Ty> get_future()
|
|---|
| 1535 | { // return a future object that shares the associated
|
|---|
| 1536 | // asynchronous state
|
|---|
| 1537 | return (future<_Ty>(_MyPromise._Get_state_for_future()));
|
|---|
| 1538 | }
|
|---|
| 1539 |
|
|---|
| 1540 | void set_value(const _Ty& _Val)
|
|---|
| 1541 | { // store result
|
|---|
| 1542 | _MyPromise._Get_state_for_set()._Set_value(_Val, false);
|
|---|
| 1543 | }
|
|---|
| 1544 |
|
|---|
| 1545 | void set_value_at_thread_exit(const _Ty& _Val)
|
|---|
| 1546 | { // store result and block until thread exit
|
|---|
| 1547 | _MyPromise._Get_state_for_set()._Set_value(_Val, true);
|
|---|
| 1548 | }
|
|---|
| 1549 |
|
|---|
| 1550 | void set_value(_Ty&& _Val)
|
|---|
| 1551 | { // store result
|
|---|
| 1552 | _MyPromise._Get_state_for_set()._Set_value(_STD forward<_Ty>(_Val), false);
|
|---|
| 1553 | }
|
|---|
| 1554 |
|
|---|
| 1555 | void set_value_at_thread_exit(_Ty&& _Val)
|
|---|
| 1556 | { // store result and block until thread exit
|
|---|
| 1557 | _MyPromise._Get_state_for_set()._Set_value(_STD forward<_Ty>(_Val), true);
|
|---|
| 1558 | }
|
|---|
| 1559 |
|
|---|
| 1560 | void set_exception(_XSTD exception_ptr _Exc)
|
|---|
| 1561 | { // store result
|
|---|
| 1562 | _MyPromise._Get_state_for_set()._Set_exception(_Exc, false);
|
|---|
| 1563 | }
|
|---|
| 1564 |
|
|---|
| 1565 | void set_exception_at_thread_exit(_XSTD exception_ptr _Exc)
|
|---|
| 1566 | { // store result and block until thread exit
|
|---|
| 1567 | _MyPromise._Get_state_for_set()._Set_exception(_Exc, true);
|
|---|
| 1568 | }
|
|---|
| 1569 |
|
|---|
| 1570 | private:
|
|---|
| 1571 | _Promise<_Ty> _MyPromise;
|
|---|
| 1572 |
|
|---|
| 1573 | promise(const promise&); // not defined
|
|---|
| 1574 | promise& operator=(const promise&); // not defined
|
|---|
| 1575 | };
|
|---|
| 1576 |
|
|---|
| 1577 | template<class _Ty>
|
|---|
| 1578 | class promise<_Ty&>
|
|---|
| 1579 | { // class that defines an asynchronous provider that holds a reference
|
|---|
| 1580 | public:
|
|---|
| 1581 | promise()
|
|---|
| 1582 | : _MyPromise(new _Associated_state<_Ty *>)
|
|---|
| 1583 | { // construct
|
|---|
| 1584 | }
|
|---|
| 1585 |
|
|---|
| 1586 | template<class _Alloc>
|
|---|
| 1587 | promise(allocator_arg_t, const _Alloc& _Al)
|
|---|
| 1588 | : _MyPromise(_Make_associated_state<_Ty *>(_Al))
|
|---|
| 1589 | { // construct with allocator
|
|---|
| 1590 | }
|
|---|
| 1591 |
|
|---|
| 1592 | promise(promise&& _Other) _NOEXCEPT
|
|---|
| 1593 | : _MyPromise(_STD forward<_Promise<_Ty *> >(_Other._MyPromise))
|
|---|
| 1594 | { // construct from rvalue promise object
|
|---|
| 1595 | }
|
|---|
| 1596 |
|
|---|
| 1597 | promise& operator=(promise&& _Other) _NOEXCEPT
|
|---|
| 1598 | { // assign from rvalue promise object
|
|---|
| 1599 | _MyPromise = _STD forward<_Promise<_Ty *> >(_Other._MyPromise);
|
|---|
| 1600 | return (*this);
|
|---|
| 1601 | }
|
|---|
| 1602 |
|
|---|
| 1603 | ~promise() _NOEXCEPT
|
|---|
| 1604 | { // destroy
|
|---|
| 1605 | }
|
|---|
| 1606 |
|
|---|
| 1607 | void swap(promise& _Other) _NOEXCEPT
|
|---|
| 1608 | { // exchange with _Other
|
|---|
| 1609 | _MyPromise._Swap(_Other._MyPromise);
|
|---|
| 1610 | }
|
|---|
| 1611 |
|
|---|
| 1612 | future<_Ty&> get_future()
|
|---|
| 1613 | { // return a future object that shares the associated
|
|---|
| 1614 | // asynchronous state
|
|---|
| 1615 | return (future<_Ty&>(_MyPromise._Get_state_for_future()));
|
|---|
| 1616 | }
|
|---|
| 1617 |
|
|---|
| 1618 | void set_value(_Ty& _Val)
|
|---|
| 1619 | { // store result
|
|---|
| 1620 | _MyPromise._Get_state_for_set()._Set_value(&_Val, false);
|
|---|
| 1621 | }
|
|---|
| 1622 |
|
|---|
| 1623 | void set_value_at_thread_exit(_Ty& _Val)
|
|---|
| 1624 | { // store result and block until thread exit
|
|---|
| 1625 | _MyPromise._Get_state_for_set()._Set_value(&_Val, true);
|
|---|
| 1626 | }
|
|---|
| 1627 |
|
|---|
| 1628 | void set_exception(_XSTD exception_ptr _Exc)
|
|---|
| 1629 | { // store result
|
|---|
| 1630 | _MyPromise._Get_state_for_set()._Set_exception(_Exc, false);
|
|---|
| 1631 | }
|
|---|
| 1632 |
|
|---|
| 1633 | void set_exception_at_thread_exit(_XSTD exception_ptr _Exc)
|
|---|
| 1634 | { // store result and block until thread exit
|
|---|
| 1635 | _MyPromise._Get_state_for_set()._Set_exception(_Exc, true);
|
|---|
| 1636 | }
|
|---|
| 1637 |
|
|---|
| 1638 | private:
|
|---|
| 1639 | _Promise<_Ty *> _MyPromise;
|
|---|
| 1640 | };
|
|---|
| 1641 |
|
|---|
| 1642 | template<>
|
|---|
| 1643 | class promise<void>
|
|---|
| 1644 | { // defines an asynchronous provider that does not hold a value
|
|---|
| 1645 | public:
|
|---|
| 1646 | promise()
|
|---|
| 1647 | : _MyPromise(new _Associated_state<int>)
|
|---|
| 1648 | { // construct
|
|---|
| 1649 | }
|
|---|
| 1650 |
|
|---|
| 1651 | template<class _Alloc>
|
|---|
| 1652 | promise(allocator_arg_t, const _Alloc& _Al)
|
|---|
| 1653 | : _MyPromise(_Make_associated_state<int>(_Al))
|
|---|
| 1654 | { // construct with allocator
|
|---|
| 1655 | }
|
|---|
| 1656 |
|
|---|
| 1657 | promise(promise&& _Other) _NOEXCEPT
|
|---|
| 1658 | : _MyPromise(_STD forward<_Promise<int> >(_Other._MyPromise))
|
|---|
| 1659 | { // construct from rvalue promise object
|
|---|
| 1660 | }
|
|---|
| 1661 |
|
|---|
| 1662 | promise& operator=(promise&& _Other) _NOEXCEPT
|
|---|
| 1663 | { // assign from rvalue promise object
|
|---|
| 1664 | _MyPromise = _STD forward<_Promise<int> >(_Other._MyPromise);
|
|---|
| 1665 | return (*this);
|
|---|
| 1666 | }
|
|---|
| 1667 |
|
|---|
| 1668 | ~promise() _NOEXCEPT
|
|---|
| 1669 | { // destroy
|
|---|
| 1670 | }
|
|---|
| 1671 |
|
|---|
| 1672 | void swap(promise& _Other) _NOEXCEPT
|
|---|
| 1673 | { // exchange with _Other
|
|---|
| 1674 | _MyPromise._Swap(_Other._MyPromise);
|
|---|
| 1675 | }
|
|---|
| 1676 |
|
|---|
| 1677 | future<void> get_future()
|
|---|
| 1678 | { // return a future object that shares the associated
|
|---|
| 1679 | // asynchronous state
|
|---|
| 1680 | future<void> _Fut(_MyPromise._Get_state_for_future());
|
|---|
| 1681 | return (_Fut);
|
|---|
| 1682 | }
|
|---|
| 1683 |
|
|---|
| 1684 | void set_value()
|
|---|
| 1685 | { // store a (void) result
|
|---|
| 1686 | _MyPromise._Get_state_for_set()._Set_value(1, false);
|
|---|
| 1687 | }
|
|---|
| 1688 |
|
|---|
| 1689 | void set_value_at_thread_exit()
|
|---|
| 1690 | { // store result and block until thread exit
|
|---|
| 1691 | _MyPromise._Get_state_for_set()._Set_value(1, true);
|
|---|
| 1692 | }
|
|---|
| 1693 |
|
|---|
| 1694 | void set_exception(_XSTD exception_ptr _Exc)
|
|---|
| 1695 | { // store a result
|
|---|
| 1696 | _MyPromise._Get_state_for_set()._Set_exception(_Exc, false);
|
|---|
| 1697 | }
|
|---|
| 1698 |
|
|---|
| 1699 | void set_exception_at_thread_exit(_XSTD exception_ptr _Exc)
|
|---|
| 1700 | { // store result and block until thread exit
|
|---|
| 1701 | _MyPromise._Get_state_for_set()._Set_exception(_Exc, true);
|
|---|
| 1702 | }
|
|---|
| 1703 |
|
|---|
| 1704 | private:
|
|---|
| 1705 | _Promise<int> _MyPromise;
|
|---|
| 1706 | };
|
|---|
| 1707 |
|
|---|
| 1708 | template<class _Ty> inline
|
|---|
| 1709 | void swap(promise<_Ty>& _Left, promise<_Ty>& _Right) _NOEXCEPT
|
|---|
| 1710 | { // exchange _Left and _Right
|
|---|
| 1711 | _Left.swap(_Right);
|
|---|
| 1712 | }
|
|---|
| 1713 |
|
|---|
| 1714 | // TEMPLATE CLASS packaged_task
|
|---|
| 1715 | template <class _Fret>
|
|---|
| 1716 | struct _P_arg_type
|
|---|
| 1717 | { // type for function
|
|---|
| 1718 | typedef _Fret type;
|
|---|
| 1719 | };
|
|---|
| 1720 |
|
|---|
| 1721 | template <class _Fret>
|
|---|
| 1722 | struct _P_arg_type<_Fret&>
|
|---|
| 1723 | { // type for ref to function
|
|---|
| 1724 | typedef _Fret *type;
|
|---|
| 1725 | };
|
|---|
| 1726 |
|
|---|
| 1727 | template <>
|
|---|
| 1728 | struct _P_arg_type<void>
|
|---|
| 1729 | { // type for void function
|
|---|
| 1730 | typedef int type;
|
|---|
| 1731 | };
|
|---|
| 1732 |
|
|---|
| 1733 | template<class>
|
|---|
| 1734 | class packaged_task; // not defined
|
|---|
| 1735 |
|
|---|
| 1736 | #define _PACKAGED_TASK_FUNCTION_DELETES \
|
|---|
| 1737 | private: \
|
|---|
| 1738 | packaged_task(const packaged_task&); /* not defined */ \
|
|---|
| 1739 | packaged_task& operator=(const packaged_task&); /* not defined */
|
|---|
| 1740 |
|
|---|
| 1741 | #define _CLASS_PACKAGED_TASK( \
|
|---|
| 1742 | TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
|
|---|
| 1743 | template<class _Ret COMMA LIST(_CLASS_TYPE)> \
|
|---|
| 1744 | class packaged_task<_Ret(LIST(_TYPE))> \
|
|---|
| 1745 | { /* class that defines an asynchronous provider that returns the */ \
|
|---|
| 1746 | /* result of a call to a function object */ \
|
|---|
| 1747 | typedef packaged_task<_Ret(LIST(_TYPE))> _Myt; \
|
|---|
| 1748 | typedef typename _P_arg_type<_Ret>::type _Ptype; \
|
|---|
| 1749 | typedef _Promise<_Ptype> _MyPromiseType; \
|
|---|
| 1750 | typedef _State_manager<_Ptype> _MyStateManagerType; \
|
|---|
| 1751 | typedef _Packaged_state<_Ret(LIST(_TYPE))> _MyStateType; \
|
|---|
| 1752 | public: \
|
|---|
| 1753 | packaged_task() _NOEXCEPT \
|
|---|
| 1754 | : _MyPromise(0) \
|
|---|
| 1755 | { /* construct */ \
|
|---|
| 1756 | } \
|
|---|
| 1757 | template<class _Fty2> \
|
|---|
| 1758 | explicit packaged_task(_Fty2&& _Fnarg) \
|
|---|
| 1759 | : _MyPromise(new _MyStateType(_STD forward<_Fty2>(_Fnarg))) \
|
|---|
| 1760 | { /* construct from rvalue function object */ \
|
|---|
| 1761 | } \
|
|---|
| 1762 | template<class _Fty2> \
|
|---|
| 1763 | explicit packaged_task(const _Fty2& _Fnarg) \
|
|---|
| 1764 | : _MyPromise(new _MyStateType(_Fnarg)) \
|
|---|
| 1765 | { /* construct from rvalue function object */ \
|
|---|
| 1766 | } \
|
|---|
| 1767 | packaged_task(packaged_task&& _Other) _NOEXCEPT \
|
|---|
| 1768 | : _MyPromise(_STD forward<_Promise<_Ret> >(_Other._MyPromise)) \
|
|---|
| 1769 | { /* construct from rvalue packaged_task object */ \
|
|---|
| 1770 | } \
|
|---|
| 1771 | packaged_task& operator=(packaged_task&& _Other) _NOEXCEPT \
|
|---|
| 1772 | { /* assign from rvalue packaged_task object */ \
|
|---|
| 1773 | _MyPromise = _STD forward<_MyPromiseType>(_Other._MyPromise); \
|
|---|
| 1774 | return (*this); \
|
|---|
| 1775 | } \
|
|---|
| 1776 | template<class _Fty2, \
|
|---|
| 1777 | class _Alloc> \
|
|---|
| 1778 | explicit packaged_task(allocator_arg_t, const _Alloc& _Al, \
|
|---|
| 1779 | _Fty2&& _Fnarg) \
|
|---|
| 1780 | : _MyPromise(_Make_packaged_state<_Ret(LIST(_TYPE))>( \
|
|---|
| 1781 | _STD forward<_Fty2>(_Fnarg)), _Al) \
|
|---|
| 1782 | { /* construct from rvalue function object and allocator */ \
|
|---|
| 1783 | } \
|
|---|
| 1784 | ~packaged_task() _NOEXCEPT \
|
|---|
| 1785 | { /* destroy */ \
|
|---|
| 1786 | } \
|
|---|
| 1787 | void swap(packaged_task& _Other) _NOEXCEPT \
|
|---|
| 1788 | { /* exchange with _Other */ \
|
|---|
| 1789 | _STD swap(_MyPromise, _Other._MyPromise); \
|
|---|
| 1790 | } \
|
|---|
| 1791 | _TYPEDEF_BOOL_TYPE; \
|
|---|
| 1792 | _OPERATOR_BOOL() const _NOEXCEPT /* retained */ \
|
|---|
| 1793 | { /* return status */ \
|
|---|
| 1794 | return (_MyPromise._Is_valid() ? _CONVERTIBLE_TO_TRUE : 0); \
|
|---|
| 1795 | } \
|
|---|
| 1796 | bool valid() const \
|
|---|
| 1797 | { /* return status */ \
|
|---|
| 1798 | return (_MyPromise._Is_valid()); \
|
|---|
| 1799 | } \
|
|---|
| 1800 | future<_Ret> get_future() \
|
|---|
| 1801 | { /* return a future object that shares the associated */ \
|
|---|
| 1802 | /* asynchronous state */ \
|
|---|
| 1803 | return (future<_Ret>(_MyPromise._Get_state_for_future())); \
|
|---|
| 1804 | } \
|
|---|
| 1805 | void operator()(LIST(_TYPE_ARG)) \
|
|---|
| 1806 | { /* call the function object */ \
|
|---|
| 1807 | if (_MyPromise._Is_ready()) \
|
|---|
| 1808 | _Throw_future_error( \
|
|---|
| 1809 | make_error_code(future_errc::promise_already_satisfied)); \
|
|---|
| 1810 | _MyStateManagerType& _State = _MyPromise._Get_state_for_set(); \
|
|---|
| 1811 | _MyStateType *_Ptr = static_cast<_MyStateType *>(_State._Ptr()); \
|
|---|
| 1812 | _Ptr->_Call_immediate(LIST(_FORWARD_ARG)); \
|
|---|
| 1813 | } \
|
|---|
| 1814 | void make_ready_at_thread_exit(LIST(_TYPE_ARG)) \
|
|---|
| 1815 | { /* call the function object and block until thread exit */ \
|
|---|
| 1816 | if (_MyPromise._Is_ready()) \
|
|---|
| 1817 | _Throw_future_error( \
|
|---|
| 1818 | make_error_code(future_errc::promise_already_satisfied)); \
|
|---|
| 1819 | _MyStateManagerType& _State = _MyPromise._Get_state_for_set(); \
|
|---|
| 1820 | _MyStateType *_Ptr = static_cast<_MyStateType *>(_State._Ptr()); \
|
|---|
| 1821 | _Ptr->_Call_deferred(LIST(_FORWARD_ARG)); \
|
|---|
| 1822 | } \
|
|---|
| 1823 | void reset() \
|
|---|
| 1824 | { /* reset to newly constructed state */ \
|
|---|
| 1825 | _MyStateManagerType& _State = _MyPromise._Get_state(); \
|
|---|
| 1826 | _MyStateType *_MyState = \
|
|---|
| 1827 | static_cast<_MyStateType *>(_State._Ptr()); \
|
|---|
| 1828 | function<_Ret(LIST(_TYPE))> _Fnarg = _MyState->_Get_fn(); \
|
|---|
| 1829 | _MyPromiseType _New_promise(new _MyStateType(_Fnarg, true)); \
|
|---|
| 1830 | _MyPromise._Swap(_New_promise); \
|
|---|
| 1831 | } \
|
|---|
| 1832 | _PACKAGED_TASK_FUNCTION_DELETES \
|
|---|
| 1833 | private: \
|
|---|
| 1834 | _MyPromiseType _MyPromise; \
|
|---|
| 1835 | };
|
|---|
| 1836 |
|
|---|
| 1837 | _VARIADIC_EXPAND_0X(_CLASS_PACKAGED_TASK, , , , )
|
|---|
| 1838 | #undef _PACKAGED_TASK_FUNCTION_DELETES
|
|---|
| 1839 | #undef _CLASS_PACKAGED_TASK
|
|---|
| 1840 |
|
|---|
| 1841 | template<class _Ty> inline
|
|---|
| 1842 | void swap(packaged_task<_Ty>& _Left,
|
|---|
| 1843 | packaged_task<_Ty>& _Right) _NOEXCEPT
|
|---|
| 1844 | { // exchange _Left and _Right
|
|---|
| 1845 | _Left.swap(_Right);
|
|---|
| 1846 | }
|
|---|
| 1847 |
|
|---|
| 1848 | // HELPERS FOR async
|
|---|
| 1849 | template<class _Fty>
|
|---|
| 1850 | struct _Is_launch_type
|
|---|
| 1851 | : false_type
|
|---|
| 1852 | { // tests for _Launch_type argument
|
|---|
| 1853 | };
|
|---|
| 1854 |
|
|---|
| 1855 | template<>
|
|---|
| 1856 | struct _Is_launch_type<_Launch_type>
|
|---|
| 1857 | : true_type
|
|---|
| 1858 | { // tests for _Launch_type argument
|
|---|
| 1859 | };
|
|---|
| 1860 |
|
|---|
| 1861 | template<class _Ret,
|
|---|
| 1862 | class _Fty> inline
|
|---|
| 1863 | _Associated_state<typename _P_arg_type<_Ret>::type>
|
|---|
| 1864 | *_Get_associated_state(_Launch_type _Psync, _Fty&& _Fnarg)
|
|---|
| 1865 | { // construct associated asynchronous state object for the launch type
|
|---|
| 1866 | switch (_Psync)
|
|---|
| 1867 | {
|
|---|
| 1868 | case launch::async:
|
|---|
| 1869 | return (new _Task_async_state<_Ret, false>(_STD forward<_Fty >(_Fnarg)));
|
|---|
| 1870 | case launch::deferred:
|
|---|
| 1871 | return (new _Deferred_async_state<_Ret>(_STD forward<_Fty >(_Fnarg)));
|
|---|
| 1872 | default:
|
|---|
| 1873 | return (new _Task_async_state<_Ret, true>(_STD forward<_Fty >(_Fnarg)));
|
|---|
| 1874 | }
|
|---|
| 1875 | }
|
|---|
| 1876 |
|
|---|
| 1877 | // TEMPLATE FUNCTIONS _Async AND async
|
|---|
| 1878 | #define _ASYNC_FUN( \
|
|---|
| 1879 | TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
|
|---|
| 1880 | template<class _Fty COMMA LIST(_CLASS_TYPE)> inline \
|
|---|
| 1881 | future<typename result_of<_Fty(LIST(_TYPE))>::type> \
|
|---|
| 1882 | _Async(_Launch_type _Policy, _Fty&& _Fnarg \
|
|---|
| 1883 | COMMA LIST(_TYPE_REFREF_ARG)) \
|
|---|
| 1884 | { /* return a future object that manages a function object */ \
|
|---|
| 1885 | typedef typename result_of<_Fty(LIST(_TYPE))>::type _Ret; \
|
|---|
| 1886 | typedef typename _P_arg_type<_Ret>::type _Ptype; \
|
|---|
| 1887 | _Promise<_Ptype> _Pr(_Get_associated_state<_Ret>(_Policy, \
|
|---|
| 1888 | _STD bind(_STD forward<_Fty>(_Fnarg) \
|
|---|
| 1889 | COMMA LIST(_DECAY_COPY_FORWARD_ARG)))); \
|
|---|
| 1890 | return (_Pr._Get_state_for_future()); \
|
|---|
| 1891 | } \
|
|---|
| 1892 | template<class _Fty COMMA LIST(_CLASS_TYPE)> inline \
|
|---|
| 1893 | future<typename result_of< \
|
|---|
| 1894 | typename enable_if<!_Is_launch_type< \
|
|---|
| 1895 | typename decay<_Fty>::type>::value, _Fty> \
|
|---|
| 1896 | ::type(LIST(_TYPE))>::type> \
|
|---|
| 1897 | async(_Fty&& _Fnarg COMMA LIST(_TYPE_REFREF_ARG)) \
|
|---|
| 1898 | { /* return a future object that manages a function object */ \
|
|---|
| 1899 | return (_Async(launch::any, _Decay_copy(_STD forward<_Fty>(_Fnarg)) \
|
|---|
| 1900 | COMMA LIST(_DECAY_COPY_FORWARD_ARG))); \
|
|---|
| 1901 | } \
|
|---|
| 1902 | template<class _Policy_type, class _Fty COMMA LIST(_CLASS_TYPE)> inline \
|
|---|
| 1903 | future<typename result_of< \
|
|---|
| 1904 | typename enable_if<_Is_launch_type< \
|
|---|
| 1905 | _Policy_type>::value, _Fty> \
|
|---|
| 1906 | ::type(LIST(_TYPE))>::type> \
|
|---|
| 1907 | async(_Policy_type _Policy, _Fty&& _Fnarg \
|
|---|
| 1908 | COMMA LIST(_TYPE_REFREF_ARG)) \
|
|---|
| 1909 | { /* return a future object that manages a function object */ \
|
|---|
| 1910 | return (_Async(_Policy, _Decay_copy(_STD forward<_Fty>(_Fnarg)) \
|
|---|
| 1911 | COMMA LIST(_DECAY_COPY_FORWARD_ARG))); \
|
|---|
| 1912 | }
|
|---|
| 1913 |
|
|---|
| 1914 | _VARIADIC_EXPAND_0X(_ASYNC_FUN, , , , )
|
|---|
| 1915 | #undef _ASYNC_FUN
|
|---|
| 1916 | _STD_END
|
|---|
| 1917 |
|
|---|
| 1918 | namespace std {
|
|---|
| 1919 | template<class _Ty,
|
|---|
| 1920 | class _Alloc>
|
|---|
| 1921 | struct uses_allocator<promise<_Ty>, _Alloc>
|
|---|
| 1922 | : true_type
|
|---|
| 1923 | { // asserts that promise<_Ty> can use an allocator
|
|---|
| 1924 | };
|
|---|
| 1925 |
|
|---|
| 1926 | template<class _Ty, class _Alloc>
|
|---|
| 1927 | struct uses_allocator<packaged_task<_Ty>, _Alloc>
|
|---|
| 1928 | : true_type
|
|---|
| 1929 | { // asserts that packaged_task<_Ty> can use an allocator
|
|---|
| 1930 | };
|
|---|
| 1931 | } // namespace std
|
|---|
| 1932 | #pragma pop_macro("new")
|
|---|
| 1933 | #pragma warning(pop)
|
|---|
| 1934 | #pragma pack(pop)
|
|---|
| 1935 | #endif /* RC_INVOKED */
|
|---|
| 1936 | #endif /* _FUTURE_ */
|
|---|
| 1937 |
|
|---|
| 1938 | /*
|
|---|
| 1939 | * Copyright (c) 1992-2012 by P.J. Plauger. ALL RIGHTS RESERVED.
|
|---|
| 1940 | * Consult your license regarding permissions and restrictions.
|
|---|
| 1941 | V6.00:0009 */
|
|---|