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 */
|
---|