root / lab4 / .minix-src / include / c++ / future @ 14
History | View | Annotate | Download (70.3 KB)
1 |
// -*- C++ -*- |
---|---|
2 |
//===--------------------------- future -----------------------------------===// |
3 |
// |
4 |
// The LLVM Compiler Infrastructure |
5 |
// |
6 |
// This file is dual licensed under the MIT and the University of Illinois Open |
7 |
// Source Licenses. See LICENSE.TXT for details. |
8 |
// |
9 |
//===----------------------------------------------------------------------===// |
10 |
|
11 |
#ifndef _LIBCPP_FUTURE |
12 |
#define _LIBCPP_FUTURE |
13 |
|
14 |
/* |
15 |
future synopsis |
16 |
|
17 |
namespace std |
18 |
{ |
19 |
|
20 |
enum class future_errc |
21 |
{ |
22 |
future_already_retrieved = 1, |
23 |
promise_already_satisfied, |
24 |
no_state, |
25 |
broken_promise |
26 |
}; |
27 |
|
28 |
enum class launch |
29 |
{ |
30 |
async = 1, |
31 |
deferred = 2, |
32 |
any = async | deferred |
33 |
}; |
34 |
|
35 |
enum class future_status |
36 |
{ |
37 |
ready, |
38 |
timeout, |
39 |
deferred |
40 |
}; |
41 |
|
42 |
template <> struct is_error_code_enum<future_errc> : public true_type { }; |
43 |
error_code make_error_code(future_errc e) noexcept; |
44 |
error_condition make_error_condition(future_errc e) noexcept; |
45 |
|
46 |
const error_category& future_category() noexcept; |
47 |
|
48 |
class future_error |
49 |
: public logic_error |
50 |
{ |
51 |
public: |
52 |
future_error(error_code ec); // exposition only |
53 |
|
54 |
const error_code& code() const noexcept; |
55 |
const char* what() const noexcept; |
56 |
}; |
57 |
|
58 |
template <class R> |
59 |
class promise |
60 |
{ |
61 |
public: |
62 |
promise(); |
63 |
template <class Allocator> |
64 |
promise(allocator_arg_t, const Allocator& a); |
65 |
promise(promise&& rhs) noexcept; |
66 |
promise(const promise& rhs) = delete; |
67 |
~promise(); |
68 |
|
69 |
// assignment |
70 |
promise& operator=(promise&& rhs) noexcept; |
71 |
promise& operator=(const promise& rhs) = delete; |
72 |
void swap(promise& other) noexcept; |
73 |
|
74 |
// retrieving the result |
75 |
future<R> get_future(); |
76 |
|
77 |
// setting the result |
78 |
void set_value(const R& r); |
79 |
void set_value(R&& r); |
80 |
void set_exception(exception_ptr p); |
81 |
|
82 |
// setting the result with deferred notification |
83 |
void set_value_at_thread_exit(const R& r); |
84 |
void set_value_at_thread_exit(R&& r); |
85 |
void set_exception_at_thread_exit(exception_ptr p); |
86 |
}; |
87 |
|
88 |
template <class R> |
89 |
class promise<R&> |
90 |
{ |
91 |
public: |
92 |
promise(); |
93 |
template <class Allocator> |
94 |
promise(allocator_arg_t, const Allocator& a); |
95 |
promise(promise&& rhs) noexcept; |
96 |
promise(const promise& rhs) = delete; |
97 |
~promise(); |
98 |
|
99 |
// assignment |
100 |
promise& operator=(promise&& rhs) noexcept; |
101 |
promise& operator=(const promise& rhs) = delete; |
102 |
void swap(promise& other) noexcept; |
103 |
|
104 |
// retrieving the result |
105 |
future<R&> get_future(); |
106 |
|
107 |
// setting the result |
108 |
void set_value(R& r); |
109 |
void set_exception(exception_ptr p); |
110 |
|
111 |
// setting the result with deferred notification |
112 |
void set_value_at_thread_exit(R&); |
113 |
void set_exception_at_thread_exit(exception_ptr p); |
114 |
}; |
115 |
|
116 |
template <> |
117 |
class promise<void> |
118 |
{ |
119 |
public: |
120 |
promise(); |
121 |
template <class Allocator> |
122 |
promise(allocator_arg_t, const Allocator& a); |
123 |
promise(promise&& rhs) noexcept; |
124 |
promise(const promise& rhs) = delete; |
125 |
~promise(); |
126 |
|
127 |
// assignment |
128 |
promise& operator=(promise&& rhs) noexcept; |
129 |
promise& operator=(const promise& rhs) = delete; |
130 |
void swap(promise& other) noexcept; |
131 |
|
132 |
// retrieving the result |
133 |
future<void> get_future(); |
134 |
|
135 |
// setting the result |
136 |
void set_value(); |
137 |
void set_exception(exception_ptr p); |
138 |
|
139 |
// setting the result with deferred notification |
140 |
void set_value_at_thread_exit(); |
141 |
void set_exception_at_thread_exit(exception_ptr p); |
142 |
}; |
143 |
|
144 |
template <class R> void swap(promise<R>& x, promise<R>& y) noexcept; |
145 |
|
146 |
template <class R, class Alloc> |
147 |
struct uses_allocator<promise<R>, Alloc> : public true_type {}; |
148 |
|
149 |
template <class R> |
150 |
class future |
151 |
{ |
152 |
public: |
153 |
future() noexcept; |
154 |
future(future&&) noexcept; |
155 |
future(const future& rhs) = delete; |
156 |
~future(); |
157 |
future& operator=(const future& rhs) = delete; |
158 |
future& operator=(future&&) noexcept; |
159 |
shared_future<R> share(); |
160 |
|
161 |
// retrieving the value |
162 |
R get(); |
163 |
|
164 |
// functions to check state |
165 |
bool valid() const noexcept; |
166 |
|
167 |
void wait() const; |
168 |
template <class Rep, class Period> |
169 |
future_status |
170 |
wait_for(const chrono::duration<Rep, Period>& rel_time) const; |
171 |
template <class Clock, class Duration> |
172 |
future_status |
173 |
wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; |
174 |
}; |
175 |
|
176 |
template <class R> |
177 |
class future<R&> |
178 |
{ |
179 |
public: |
180 |
future() noexcept; |
181 |
future(future&&) noexcept; |
182 |
future(const future& rhs) = delete; |
183 |
~future(); |
184 |
future& operator=(const future& rhs) = delete; |
185 |
future& operator=(future&&) noexcept; |
186 |
shared_future<R&> share(); |
187 |
|
188 |
// retrieving the value |
189 |
R& get(); |
190 |
|
191 |
// functions to check state |
192 |
bool valid() const noexcept; |
193 |
|
194 |
void wait() const; |
195 |
template <class Rep, class Period> |
196 |
future_status |
197 |
wait_for(const chrono::duration<Rep, Period>& rel_time) const; |
198 |
template <class Clock, class Duration> |
199 |
future_status |
200 |
wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; |
201 |
}; |
202 |
|
203 |
template <> |
204 |
class future<void> |
205 |
{ |
206 |
public: |
207 |
future() noexcept; |
208 |
future(future&&) noexcept; |
209 |
future(const future& rhs) = delete; |
210 |
~future(); |
211 |
future& operator=(const future& rhs) = delete; |
212 |
future& operator=(future&&) noexcept; |
213 |
shared_future<void> share(); |
214 |
|
215 |
// retrieving the value |
216 |
void get(); |
217 |
|
218 |
// functions to check state |
219 |
bool valid() const noexcept; |
220 |
|
221 |
void wait() const; |
222 |
template <class Rep, class Period> |
223 |
future_status |
224 |
wait_for(const chrono::duration<Rep, Period>& rel_time) const; |
225 |
template <class Clock, class Duration> |
226 |
future_status |
227 |
wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; |
228 |
}; |
229 |
|
230 |
template <class R> |
231 |
class shared_future |
232 |
{ |
233 |
public: |
234 |
shared_future() noexcept; |
235 |
shared_future(const shared_future& rhs); |
236 |
shared_future(future<R>&&) noexcept; |
237 |
shared_future(shared_future&& rhs) noexcept; |
238 |
~shared_future(); |
239 |
shared_future& operator=(const shared_future& rhs); |
240 |
shared_future& operator=(shared_future&& rhs) noexcept; |
241 |
|
242 |
// retrieving the value |
243 |
const R& get() const; |
244 |
|
245 |
// functions to check state |
246 |
bool valid() const noexcept; |
247 |
|
248 |
void wait() const; |
249 |
template <class Rep, class Period> |
250 |
future_status |
251 |
wait_for(const chrono::duration<Rep, Period>& rel_time) const; |
252 |
template <class Clock, class Duration> |
253 |
future_status |
254 |
wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; |
255 |
}; |
256 |
|
257 |
template <class R> |
258 |
class shared_future<R&> |
259 |
{ |
260 |
public: |
261 |
shared_future() noexcept; |
262 |
shared_future(const shared_future& rhs); |
263 |
shared_future(future<R&>&&) noexcept; |
264 |
shared_future(shared_future&& rhs) noexcept; |
265 |
~shared_future(); |
266 |
shared_future& operator=(const shared_future& rhs); |
267 |
shared_future& operator=(shared_future&& rhs) noexcept; |
268 |
|
269 |
// retrieving the value |
270 |
R& get() const; |
271 |
|
272 |
// functions to check state |
273 |
bool valid() const noexcept; |
274 |
|
275 |
void wait() const; |
276 |
template <class Rep, class Period> |
277 |
future_status |
278 |
wait_for(const chrono::duration<Rep, Period>& rel_time) const; |
279 |
template <class Clock, class Duration> |
280 |
future_status |
281 |
wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; |
282 |
}; |
283 |
|
284 |
template <> |
285 |
class shared_future<void> |
286 |
{ |
287 |
public: |
288 |
shared_future() noexcept; |
289 |
shared_future(const shared_future& rhs); |
290 |
shared_future(future<void>&&) noexcept; |
291 |
shared_future(shared_future&& rhs) noexcept; |
292 |
~shared_future(); |
293 |
shared_future& operator=(const shared_future& rhs); |
294 |
shared_future& operator=(shared_future&& rhs) noexcept; |
295 |
|
296 |
// retrieving the value |
297 |
void get() const; |
298 |
|
299 |
// functions to check state |
300 |
bool valid() const noexcept; |
301 |
|
302 |
void wait() const; |
303 |
template <class Rep, class Period> |
304 |
future_status |
305 |
wait_for(const chrono::duration<Rep, Period>& rel_time) const; |
306 |
template <class Clock, class Duration> |
307 |
future_status |
308 |
wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; |
309 |
}; |
310 |
|
311 |
template <class F, class... Args> |
312 |
future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> |
313 |
async(F&& f, Args&&... args); |
314 |
|
315 |
template <class F, class... Args> |
316 |
future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> |
317 |
async(launch policy, F&& f, Args&&... args); |
318 |
|
319 |
template <class> class packaged_task; // undefined |
320 |
|
321 |
template <class R, class... ArgTypes> |
322 |
class packaged_task<R(ArgTypes...)> |
323 |
{ |
324 |
public: |
325 |
typedef R result_type; |
326 |
|
327 |
// construction and destruction |
328 |
packaged_task() noexcept; |
329 |
template <class F> |
330 |
explicit packaged_task(F&& f); |
331 |
template <class F, class Allocator> |
332 |
packaged_task(allocator_arg_t, const Allocator& a, F&& f); |
333 |
~packaged_task(); |
334 |
|
335 |
// no copy |
336 |
packaged_task(const packaged_task&) = delete; |
337 |
packaged_task& operator=(const packaged_task&) = delete; |
338 |
|
339 |
// move support |
340 |
packaged_task(packaged_task&& other) noexcept; |
341 |
packaged_task& operator=(packaged_task&& other) noexcept; |
342 |
void swap(packaged_task& other) noexcept; |
343 |
|
344 |
bool valid() const noexcept; |
345 |
|
346 |
// result retrieval |
347 |
future<R> get_future(); |
348 |
|
349 |
// execution |
350 |
void operator()(ArgTypes... ); |
351 |
void make_ready_at_thread_exit(ArgTypes...); |
352 |
|
353 |
void reset(); |
354 |
}; |
355 |
|
356 |
template <class R> |
357 |
void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept; |
358 |
|
359 |
template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; |
360 |
|
361 |
} // std |
362 |
|
363 |
*/ |
364 |
|
365 |
#include <__config> |
366 |
#include <system_error> |
367 |
#include <memory> |
368 |
#include <chrono> |
369 |
#include <exception> |
370 |
#include <mutex> |
371 |
#include <thread> |
372 |
|
373 |
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
374 |
#pragma GCC system_header |
375 |
#endif |
376 |
|
377 |
#ifdef _LIBCPP_HAS_NO_THREADS |
378 |
#error <future> is not supported on this single threaded system |
379 |
#else // !_LIBCPP_HAS_NO_THREADS |
380 |
|
381 |
_LIBCPP_BEGIN_NAMESPACE_STD |
382 |
|
383 |
//enum class future_errc |
384 |
_LIBCPP_DECLARE_STRONG_ENUM(future_errc) |
385 |
{ |
386 |
future_already_retrieved = 1, |
387 |
promise_already_satisfied, |
388 |
no_state, |
389 |
broken_promise |
390 |
}; |
391 |
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc) |
392 |
|
393 |
template <> |
394 |
struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {}; |
395 |
|
396 |
#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS |
397 |
template <> |
398 |
struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { }; |
399 |
#endif |
400 |
|
401 |
//enum class launch |
402 |
_LIBCPP_DECLARE_STRONG_ENUM(launch) |
403 |
{ |
404 |
async = 1, |
405 |
deferred = 2, |
406 |
any = async | deferred |
407 |
}; |
408 |
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch) |
409 |
|
410 |
#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS |
411 |
|
412 |
#ifdef _LIBCXX_UNDERLYING_TYPE |
413 |
typedef underlying_type<launch>::type __launch_underlying_type; |
414 |
#else |
415 |
typedef int __launch_underlying_type; |
416 |
#endif |
417 |
|
418 |
inline _LIBCPP_INLINE_VISIBILITY |
419 |
_LIBCPP_CONSTEXPR |
420 |
launch |
421 |
operator&(launch __x, launch __y) |
422 |
{ |
423 |
return static_cast<launch>(static_cast<__launch_underlying_type>(__x) & |
424 |
static_cast<__launch_underlying_type>(__y)); |
425 |
} |
426 |
|
427 |
inline _LIBCPP_INLINE_VISIBILITY |
428 |
_LIBCPP_CONSTEXPR |
429 |
launch |
430 |
operator|(launch __x, launch __y) |
431 |
{ |
432 |
return static_cast<launch>(static_cast<__launch_underlying_type>(__x) | |
433 |
static_cast<__launch_underlying_type>(__y)); |
434 |
} |
435 |
|
436 |
inline _LIBCPP_INLINE_VISIBILITY |
437 |
_LIBCPP_CONSTEXPR |
438 |
launch |
439 |
operator^(launch __x, launch __y) |
440 |
{ |
441 |
return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^ |
442 |
static_cast<__launch_underlying_type>(__y)); |
443 |
} |
444 |
|
445 |
inline _LIBCPP_INLINE_VISIBILITY |
446 |
_LIBCPP_CONSTEXPR |
447 |
launch |
448 |
operator~(launch __x) |
449 |
{ |
450 |
return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3); |
451 |
} |
452 |
|
453 |
inline _LIBCPP_INLINE_VISIBILITY |
454 |
launch& |
455 |
operator&=(launch& __x, launch __y) |
456 |
{ |
457 |
__x = __x & __y; return __x; |
458 |
} |
459 |
|
460 |
inline _LIBCPP_INLINE_VISIBILITY |
461 |
launch& |
462 |
operator|=(launch& __x, launch __y) |
463 |
{ |
464 |
__x = __x | __y; return __x; |
465 |
} |
466 |
|
467 |
inline _LIBCPP_INLINE_VISIBILITY |
468 |
launch& |
469 |
operator^=(launch& __x, launch __y) |
470 |
{ |
471 |
__x = __x ^ __y; return __x; |
472 |
} |
473 |
|
474 |
#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS |
475 |
|
476 |
//enum class future_status |
477 |
_LIBCPP_DECLARE_STRONG_ENUM(future_status) |
478 |
{ |
479 |
ready, |
480 |
timeout, |
481 |
deferred |
482 |
}; |
483 |
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status) |
484 |
|
485 |
_LIBCPP_FUNC_VIS |
486 |
const error_category& future_category() _NOEXCEPT; |
487 |
|
488 |
inline _LIBCPP_INLINE_VISIBILITY |
489 |
error_code |
490 |
make_error_code(future_errc __e) _NOEXCEPT |
491 |
{ |
492 |
return error_code(static_cast<int>(__e), future_category()); |
493 |
} |
494 |
|
495 |
inline _LIBCPP_INLINE_VISIBILITY |
496 |
error_condition |
497 |
make_error_condition(future_errc __e) _NOEXCEPT |
498 |
{ |
499 |
return error_condition(static_cast<int>(__e), future_category()); |
500 |
} |
501 |
|
502 |
class _LIBCPP_EXCEPTION_ABI future_error |
503 |
: public logic_error |
504 |
{ |
505 |
error_code __ec_; |
506 |
public: |
507 |
future_error(error_code __ec); |
508 |
|
509 |
_LIBCPP_INLINE_VISIBILITY |
510 |
const error_code& code() const _NOEXCEPT {return __ec_;} |
511 |
|
512 |
virtual ~future_error() _NOEXCEPT; |
513 |
}; |
514 |
|
515 |
class _LIBCPP_TYPE_VIS __assoc_sub_state |
516 |
: public __shared_count |
517 |
{ |
518 |
protected: |
519 |
exception_ptr __exception_; |
520 |
mutable mutex __mut_; |
521 |
mutable condition_variable __cv_; |
522 |
unsigned __state_; |
523 |
|
524 |
virtual void __on_zero_shared() _NOEXCEPT; |
525 |
void __sub_wait(unique_lock<mutex>& __lk); |
526 |
public: |
527 |
enum |
528 |
{ |
529 |
__constructed = 1, |
530 |
__future_attached = 2, |
531 |
ready = 4, |
532 |
deferred = 8 |
533 |
}; |
534 |
|
535 |
_LIBCPP_INLINE_VISIBILITY |
536 |
__assoc_sub_state() : __state_(0) {} |
537 |
|
538 |
_LIBCPP_INLINE_VISIBILITY |
539 |
bool __has_value() const |
540 |
{return (__state_ & __constructed) || (__exception_ != nullptr);} |
541 |
|
542 |
_LIBCPP_INLINE_VISIBILITY |
543 |
void __set_future_attached() |
544 |
{ |
545 |
lock_guard<mutex> __lk(__mut_); |
546 |
__state_ |= __future_attached; |
547 |
} |
548 |
_LIBCPP_INLINE_VISIBILITY |
549 |
bool __has_future_attached() const {return (__state_ & __future_attached) != 0;} |
550 |
|
551 |
_LIBCPP_INLINE_VISIBILITY |
552 |
void __set_deferred() {__state_ |= deferred;} |
553 |
|
554 |
void __make_ready(); |
555 |
_LIBCPP_INLINE_VISIBILITY |
556 |
bool __is_ready() const {return (__state_ & ready) != 0;} |
557 |
|
558 |
void set_value(); |
559 |
void set_value_at_thread_exit(); |
560 |
|
561 |
void set_exception(exception_ptr __p); |
562 |
void set_exception_at_thread_exit(exception_ptr __p); |
563 |
|
564 |
void copy(); |
565 |
|
566 |
void wait(); |
567 |
template <class _Rep, class _Period> |
568 |
future_status |
569 |
wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; |
570 |
template <class _Clock, class _Duration> |
571 |
future_status |
572 |
wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const; |
573 |
|
574 |
virtual void __execute(); |
575 |
}; |
576 |
|
577 |
template <class _Clock, class _Duration> |
578 |
future_status |
579 |
__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const |
580 |
{ |
581 |
unique_lock<mutex> __lk(__mut_); |
582 |
if (__state_ & deferred) |
583 |
return future_status::deferred; |
584 |
while (!(__state_ & ready) && _Clock::now() < __abs_time) |
585 |
__cv_.wait_until(__lk, __abs_time); |
586 |
if (__state_ & ready) |
587 |
return future_status::ready; |
588 |
return future_status::timeout; |
589 |
} |
590 |
|
591 |
template <class _Rep, class _Period> |
592 |
inline _LIBCPP_INLINE_VISIBILITY |
593 |
future_status |
594 |
__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const |
595 |
{ |
596 |
return wait_until(chrono::steady_clock::now() + __rel_time); |
597 |
} |
598 |
|
599 |
template <class _Rp> |
600 |
class __assoc_state |
601 |
: public __assoc_sub_state |
602 |
{ |
603 |
typedef __assoc_sub_state base; |
604 |
typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up; |
605 |
protected: |
606 |
_Up __value_; |
607 |
|
608 |
virtual void __on_zero_shared() _NOEXCEPT; |
609 |
public: |
610 |
|
611 |
template <class _Arg> |
612 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
613 |
void set_value(_Arg&& __arg); |
614 |
#else |
615 |
void set_value(_Arg& __arg); |
616 |
#endif |
617 |
|
618 |
template <class _Arg> |
619 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
620 |
void set_value_at_thread_exit(_Arg&& __arg); |
621 |
#else |
622 |
void set_value_at_thread_exit(_Arg& __arg); |
623 |
#endif |
624 |
|
625 |
_Rp move(); |
626 |
typename add_lvalue_reference<_Rp>::type copy(); |
627 |
}; |
628 |
|
629 |
template <class _Rp> |
630 |
void |
631 |
__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT |
632 |
{ |
633 |
if (this->__state_ & base::__constructed) |
634 |
reinterpret_cast<_Rp*>(&__value_)->~_Rp(); |
635 |
delete this; |
636 |
} |
637 |
|
638 |
template <class _Rp> |
639 |
template <class _Arg> |
640 |
void |
641 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
642 |
__assoc_state<_Rp>::set_value(_Arg&& __arg) |
643 |
#else |
644 |
__assoc_state<_Rp>::set_value(_Arg& __arg) |
645 |
#endif |
646 |
{ |
647 |
unique_lock<mutex> __lk(this->__mut_); |
648 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
649 |
if (this->__has_value()) |
650 |
throw future_error(make_error_code(future_errc::promise_already_satisfied)); |
651 |
#endif |
652 |
::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); |
653 |
this->__state_ |= base::__constructed | base::ready; |
654 |
__cv_.notify_all(); |
655 |
} |
656 |
|
657 |
template <class _Rp> |
658 |
template <class _Arg> |
659 |
void |
660 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
661 |
__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) |
662 |
#else |
663 |
__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg) |
664 |
#endif |
665 |
{ |
666 |
unique_lock<mutex> __lk(this->__mut_); |
667 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
668 |
if (this->__has_value()) |
669 |
throw future_error(make_error_code(future_errc::promise_already_satisfied)); |
670 |
#endif |
671 |
::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); |
672 |
this->__state_ |= base::__constructed; |
673 |
__thread_local_data()->__make_ready_at_thread_exit(this); |
674 |
} |
675 |
|
676 |
template <class _Rp> |
677 |
_Rp |
678 |
__assoc_state<_Rp>::move() |
679 |
{ |
680 |
unique_lock<mutex> __lk(this->__mut_); |
681 |
this->__sub_wait(__lk); |
682 |
if (this->__exception_ != nullptr) |
683 |
rethrow_exception(this->__exception_); |
684 |
return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_)); |
685 |
} |
686 |
|
687 |
template <class _Rp> |
688 |
typename add_lvalue_reference<_Rp>::type |
689 |
__assoc_state<_Rp>::copy() |
690 |
{ |
691 |
unique_lock<mutex> __lk(this->__mut_); |
692 |
this->__sub_wait(__lk); |
693 |
if (this->__exception_ != nullptr) |
694 |
rethrow_exception(this->__exception_); |
695 |
return *reinterpret_cast<_Rp*>(&__value_); |
696 |
} |
697 |
|
698 |
template <class _Rp> |
699 |
class __assoc_state<_Rp&> |
700 |
: public __assoc_sub_state |
701 |
{ |
702 |
typedef __assoc_sub_state base; |
703 |
typedef _Rp* _Up; |
704 |
protected: |
705 |
_Up __value_; |
706 |
|
707 |
virtual void __on_zero_shared() _NOEXCEPT; |
708 |
public: |
709 |
|
710 |
void set_value(_Rp& __arg); |
711 |
void set_value_at_thread_exit(_Rp& __arg); |
712 |
|
713 |
_Rp& copy(); |
714 |
}; |
715 |
|
716 |
template <class _Rp> |
717 |
void |
718 |
__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT |
719 |
{ |
720 |
delete this; |
721 |
} |
722 |
|
723 |
template <class _Rp> |
724 |
void |
725 |
__assoc_state<_Rp&>::set_value(_Rp& __arg) |
726 |
{ |
727 |
unique_lock<mutex> __lk(this->__mut_); |
728 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
729 |
if (this->__has_value()) |
730 |
throw future_error(make_error_code(future_errc::promise_already_satisfied)); |
731 |
#endif |
732 |
__value_ = _VSTD::addressof(__arg); |
733 |
this->__state_ |= base::__constructed | base::ready; |
734 |
__cv_.notify_all(); |
735 |
} |
736 |
|
737 |
template <class _Rp> |
738 |
void |
739 |
__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) |
740 |
{ |
741 |
unique_lock<mutex> __lk(this->__mut_); |
742 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
743 |
if (this->__has_value()) |
744 |
throw future_error(make_error_code(future_errc::promise_already_satisfied)); |
745 |
#endif |
746 |
__value_ = _VSTD::addressof(__arg); |
747 |
this->__state_ |= base::__constructed; |
748 |
__thread_local_data()->__make_ready_at_thread_exit(this); |
749 |
} |
750 |
|
751 |
template <class _Rp> |
752 |
_Rp& |
753 |
__assoc_state<_Rp&>::copy() |
754 |
{ |
755 |
unique_lock<mutex> __lk(this->__mut_); |
756 |
this->__sub_wait(__lk); |
757 |
if (this->__exception_ != nullptr) |
758 |
rethrow_exception(this->__exception_); |
759 |
return *__value_; |
760 |
} |
761 |
|
762 |
template <class _Rp, class _Alloc> |
763 |
class __assoc_state_alloc |
764 |
: public __assoc_state<_Rp> |
765 |
{ |
766 |
typedef __assoc_state<_Rp> base; |
767 |
_Alloc __alloc_; |
768 |
|
769 |
virtual void __on_zero_shared() _NOEXCEPT; |
770 |
public: |
771 |
_LIBCPP_INLINE_VISIBILITY |
772 |
explicit __assoc_state_alloc(const _Alloc& __a) |
773 |
: __alloc_(__a) {} |
774 |
}; |
775 |
|
776 |
template <class _Rp, class _Alloc> |
777 |
void |
778 |
__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT |
779 |
{ |
780 |
if (this->__state_ & base::__constructed) |
781 |
reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp(); |
782 |
typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; |
783 |
typedef allocator_traits<_Al> _ATraits; |
784 |
typedef pointer_traits<typename _ATraits::pointer> _PTraits; |
785 |
_Al __a(__alloc_); |
786 |
this->~__assoc_state_alloc(); |
787 |
__a.deallocate(_PTraits::pointer_to(*this), 1); |
788 |
} |
789 |
|
790 |
template <class _Rp, class _Alloc> |
791 |
class __assoc_state_alloc<_Rp&, _Alloc> |
792 |
: public __assoc_state<_Rp&> |
793 |
{ |
794 |
typedef __assoc_state<_Rp&> base; |
795 |
_Alloc __alloc_; |
796 |
|
797 |
virtual void __on_zero_shared() _NOEXCEPT; |
798 |
public: |
799 |
_LIBCPP_INLINE_VISIBILITY |
800 |
explicit __assoc_state_alloc(const _Alloc& __a) |
801 |
: __alloc_(__a) {} |
802 |
}; |
803 |
|
804 |
template <class _Rp, class _Alloc> |
805 |
void |
806 |
__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT |
807 |
{ |
808 |
typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; |
809 |
typedef allocator_traits<_Al> _ATraits; |
810 |
typedef pointer_traits<typename _ATraits::pointer> _PTraits; |
811 |
_Al __a(__alloc_); |
812 |
this->~__assoc_state_alloc(); |
813 |
__a.deallocate(_PTraits::pointer_to(*this), 1); |
814 |
} |
815 |
|
816 |
template <class _Alloc> |
817 |
class __assoc_sub_state_alloc |
818 |
: public __assoc_sub_state |
819 |
{ |
820 |
typedef __assoc_sub_state base; |
821 |
_Alloc __alloc_; |
822 |
|
823 |
virtual void __on_zero_shared() _NOEXCEPT; |
824 |
public: |
825 |
_LIBCPP_INLINE_VISIBILITY |
826 |
explicit __assoc_sub_state_alloc(const _Alloc& __a) |
827 |
: __alloc_(__a) {} |
828 |
}; |
829 |
|
830 |
template <class _Alloc> |
831 |
void |
832 |
__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT |
833 |
{ |
834 |
typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al; |
835 |
typedef allocator_traits<_Al> _ATraits; |
836 |
typedef pointer_traits<typename _ATraits::pointer> _PTraits; |
837 |
_Al __a(__alloc_); |
838 |
this->~__assoc_sub_state_alloc(); |
839 |
__a.deallocate(_PTraits::pointer_to(*this), 1); |
840 |
} |
841 |
|
842 |
template <class _Rp, class _Fp> |
843 |
class __deferred_assoc_state |
844 |
: public __assoc_state<_Rp> |
845 |
{ |
846 |
typedef __assoc_state<_Rp> base; |
847 |
|
848 |
_Fp __func_; |
849 |
|
850 |
public: |
851 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
852 |
explicit __deferred_assoc_state(_Fp&& __f); |
853 |
#endif |
854 |
|
855 |
virtual void __execute(); |
856 |
}; |
857 |
|
858 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
859 |
|
860 |
template <class _Rp, class _Fp> |
861 |
inline _LIBCPP_INLINE_VISIBILITY |
862 |
__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) |
863 |
: __func_(_VSTD::forward<_Fp>(__f)) |
864 |
{ |
865 |
this->__set_deferred(); |
866 |
} |
867 |
|
868 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
869 |
|
870 |
template <class _Rp, class _Fp> |
871 |
void |
872 |
__deferred_assoc_state<_Rp, _Fp>::__execute() |
873 |
{ |
874 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
875 |
try |
876 |
{ |
877 |
#endif // _LIBCPP_NO_EXCEPTIONS |
878 |
this->set_value(__func_()); |
879 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
880 |
} |
881 |
catch (...) |
882 |
{ |
883 |
this->set_exception(current_exception()); |
884 |
} |
885 |
#endif // _LIBCPP_NO_EXCEPTIONS |
886 |
} |
887 |
|
888 |
template <class _Fp> |
889 |
class __deferred_assoc_state<void, _Fp> |
890 |
: public __assoc_sub_state |
891 |
{ |
892 |
typedef __assoc_sub_state base; |
893 |
|
894 |
_Fp __func_; |
895 |
|
896 |
public: |
897 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
898 |
explicit __deferred_assoc_state(_Fp&& __f); |
899 |
#endif |
900 |
|
901 |
virtual void __execute(); |
902 |
}; |
903 |
|
904 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
905 |
|
906 |
template <class _Fp> |
907 |
inline _LIBCPP_INLINE_VISIBILITY |
908 |
__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) |
909 |
: __func_(_VSTD::forward<_Fp>(__f)) |
910 |
{ |
911 |
this->__set_deferred(); |
912 |
} |
913 |
|
914 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
915 |
|
916 |
template <class _Fp> |
917 |
void |
918 |
__deferred_assoc_state<void, _Fp>::__execute() |
919 |
{ |
920 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
921 |
try |
922 |
{ |
923 |
#endif // _LIBCPP_NO_EXCEPTIONS |
924 |
__func_(); |
925 |
this->set_value(); |
926 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
927 |
} |
928 |
catch (...) |
929 |
{ |
930 |
this->set_exception(current_exception()); |
931 |
} |
932 |
#endif // _LIBCPP_NO_EXCEPTIONS |
933 |
} |
934 |
|
935 |
template <class _Rp, class _Fp> |
936 |
class __async_assoc_state |
937 |
: public __assoc_state<_Rp> |
938 |
{ |
939 |
typedef __assoc_state<_Rp> base; |
940 |
|
941 |
_Fp __func_; |
942 |
|
943 |
virtual void __on_zero_shared() _NOEXCEPT; |
944 |
public: |
945 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
946 |
explicit __async_assoc_state(_Fp&& __f); |
947 |
#endif |
948 |
|
949 |
virtual void __execute(); |
950 |
}; |
951 |
|
952 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
953 |
|
954 |
template <class _Rp, class _Fp> |
955 |
inline _LIBCPP_INLINE_VISIBILITY |
956 |
__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) |
957 |
: __func_(_VSTD::forward<_Fp>(__f)) |
958 |
{ |
959 |
} |
960 |
|
961 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
962 |
|
963 |
template <class _Rp, class _Fp> |
964 |
void |
965 |
__async_assoc_state<_Rp, _Fp>::__execute() |
966 |
{ |
967 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
968 |
try |
969 |
{ |
970 |
#endif // _LIBCPP_NO_EXCEPTIONS |
971 |
this->set_value(__func_()); |
972 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
973 |
} |
974 |
catch (...) |
975 |
{ |
976 |
this->set_exception(current_exception()); |
977 |
} |
978 |
#endif // _LIBCPP_NO_EXCEPTIONS |
979 |
} |
980 |
|
981 |
template <class _Rp, class _Fp> |
982 |
void |
983 |
__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT |
984 |
{ |
985 |
this->wait(); |
986 |
base::__on_zero_shared(); |
987 |
} |
988 |
|
989 |
template <class _Fp> |
990 |
class __async_assoc_state<void, _Fp> |
991 |
: public __assoc_sub_state |
992 |
{ |
993 |
typedef __assoc_sub_state base; |
994 |
|
995 |
_Fp __func_; |
996 |
|
997 |
virtual void __on_zero_shared() _NOEXCEPT; |
998 |
public: |
999 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1000 |
explicit __async_assoc_state(_Fp&& __f); |
1001 |
#endif |
1002 |
|
1003 |
virtual void __execute(); |
1004 |
}; |
1005 |
|
1006 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1007 |
|
1008 |
template <class _Fp> |
1009 |
inline _LIBCPP_INLINE_VISIBILITY |
1010 |
__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) |
1011 |
: __func_(_VSTD::forward<_Fp>(__f)) |
1012 |
{ |
1013 |
} |
1014 |
|
1015 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1016 |
|
1017 |
template <class _Fp> |
1018 |
void |
1019 |
__async_assoc_state<void, _Fp>::__execute() |
1020 |
{ |
1021 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1022 |
try |
1023 |
{ |
1024 |
#endif // _LIBCPP_NO_EXCEPTIONS |
1025 |
__func_(); |
1026 |
this->set_value(); |
1027 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1028 |
} |
1029 |
catch (...) |
1030 |
{ |
1031 |
this->set_exception(current_exception()); |
1032 |
} |
1033 |
#endif // _LIBCPP_NO_EXCEPTIONS |
1034 |
} |
1035 |
|
1036 |
template <class _Fp> |
1037 |
void |
1038 |
__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT |
1039 |
{ |
1040 |
this->wait(); |
1041 |
base::__on_zero_shared(); |
1042 |
} |
1043 |
|
1044 |
template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise; |
1045 |
template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future; |
1046 |
|
1047 |
// future |
1048 |
|
1049 |
template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future; |
1050 |
|
1051 |
template <class _Rp, class _Fp> |
1052 |
future<_Rp> |
1053 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1054 |
__make_deferred_assoc_state(_Fp&& __f); |
1055 |
#else |
1056 |
__make_deferred_assoc_state(_Fp __f); |
1057 |
#endif |
1058 |
|
1059 |
template <class _Rp, class _Fp> |
1060 |
future<_Rp> |
1061 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1062 |
__make_async_assoc_state(_Fp&& __f); |
1063 |
#else |
1064 |
__make_async_assoc_state(_Fp __f); |
1065 |
#endif |
1066 |
|
1067 |
template <class _Rp> |
1068 |
class _LIBCPP_TYPE_VIS_ONLY future |
1069 |
{ |
1070 |
__assoc_state<_Rp>* __state_; |
1071 |
|
1072 |
explicit future(__assoc_state<_Rp>* __state); |
1073 |
|
1074 |
template <class> friend class promise; |
1075 |
template <class> friend class shared_future; |
1076 |
|
1077 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1078 |
template <class _R1, class _Fp> |
1079 |
friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); |
1080 |
template <class _R1, class _Fp> |
1081 |
friend future<_R1> __make_async_assoc_state(_Fp&& __f); |
1082 |
#else |
1083 |
template <class _R1, class _Fp> |
1084 |
friend future<_R1> __make_deferred_assoc_state(_Fp __f); |
1085 |
template <class _R1, class _Fp> |
1086 |
friend future<_R1> __make_async_assoc_state(_Fp __f); |
1087 |
#endif |
1088 |
|
1089 |
public: |
1090 |
_LIBCPP_INLINE_VISIBILITY |
1091 |
future() _NOEXCEPT : __state_(nullptr) {} |
1092 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1093 |
_LIBCPP_INLINE_VISIBILITY |
1094 |
future(future&& __rhs) _NOEXCEPT |
1095 |
: __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} |
1096 |
future(const future&) = delete; |
1097 |
future& operator=(const future&) = delete; |
1098 |
_LIBCPP_INLINE_VISIBILITY |
1099 |
future& operator=(future&& __rhs) _NOEXCEPT |
1100 |
{ |
1101 |
future(std::move(__rhs)).swap(*this); |
1102 |
return *this; |
1103 |
} |
1104 |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1105 |
private: |
1106 |
future(const future&); |
1107 |
future& operator=(const future&); |
1108 |
public: |
1109 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1110 |
~future(); |
1111 |
shared_future<_Rp> share(); |
1112 |
|
1113 |
// retrieving the value |
1114 |
_Rp get(); |
1115 |
|
1116 |
_LIBCPP_INLINE_VISIBILITY |
1117 |
void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
1118 |
|
1119 |
// functions to check state |
1120 |
_LIBCPP_INLINE_VISIBILITY |
1121 |
bool valid() const _NOEXCEPT {return __state_ != nullptr;} |
1122 |
|
1123 |
_LIBCPP_INLINE_VISIBILITY |
1124 |
void wait() const {__state_->wait();} |
1125 |
template <class _Rep, class _Period> |
1126 |
_LIBCPP_INLINE_VISIBILITY |
1127 |
future_status |
1128 |
wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const |
1129 |
{return __state_->wait_for(__rel_time);} |
1130 |
template <class _Clock, class _Duration> |
1131 |
_LIBCPP_INLINE_VISIBILITY |
1132 |
future_status |
1133 |
wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const |
1134 |
{return __state_->wait_until(__abs_time);} |
1135 |
}; |
1136 |
|
1137 |
template <class _Rp> |
1138 |
future<_Rp>::future(__assoc_state<_Rp>* __state) |
1139 |
: __state_(__state) |
1140 |
{ |
1141 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1142 |
if (__state_->__has_future_attached()) |
1143 |
throw future_error(make_error_code(future_errc::future_already_retrieved)); |
1144 |
#endif |
1145 |
__state_->__add_shared(); |
1146 |
__state_->__set_future_attached(); |
1147 |
} |
1148 |
|
1149 |
struct __release_shared_count |
1150 |
{ |
1151 |
void operator()(__shared_count* p) {p->__release_shared();} |
1152 |
}; |
1153 |
|
1154 |
template <class _Rp> |
1155 |
future<_Rp>::~future() |
1156 |
{ |
1157 |
if (__state_) |
1158 |
__state_->__release_shared(); |
1159 |
} |
1160 |
|
1161 |
template <class _Rp> |
1162 |
_Rp |
1163 |
future<_Rp>::get() |
1164 |
{ |
1165 |
unique_ptr<__shared_count, __release_shared_count> __(__state_); |
1166 |
__assoc_state<_Rp>* __s = __state_; |
1167 |
__state_ = nullptr; |
1168 |
return __s->move(); |
1169 |
} |
1170 |
|
1171 |
template <class _Rp> |
1172 |
class _LIBCPP_TYPE_VIS_ONLY future<_Rp&> |
1173 |
{ |
1174 |
__assoc_state<_Rp&>* __state_; |
1175 |
|
1176 |
explicit future(__assoc_state<_Rp&>* __state); |
1177 |
|
1178 |
template <class> friend class promise; |
1179 |
template <class> friend class shared_future; |
1180 |
|
1181 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1182 |
template <class _R1, class _Fp> |
1183 |
friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); |
1184 |
template <class _R1, class _Fp> |
1185 |
friend future<_R1> __make_async_assoc_state(_Fp&& __f); |
1186 |
#else |
1187 |
template <class _R1, class _Fp> |
1188 |
friend future<_R1> __make_deferred_assoc_state(_Fp __f); |
1189 |
template <class _R1, class _Fp> |
1190 |
friend future<_R1> __make_async_assoc_state(_Fp __f); |
1191 |
#endif |
1192 |
|
1193 |
public: |
1194 |
_LIBCPP_INLINE_VISIBILITY |
1195 |
future() _NOEXCEPT : __state_(nullptr) {} |
1196 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1197 |
_LIBCPP_INLINE_VISIBILITY |
1198 |
future(future&& __rhs) _NOEXCEPT |
1199 |
: __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} |
1200 |
future(const future&) = delete; |
1201 |
future& operator=(const future&) = delete; |
1202 |
_LIBCPP_INLINE_VISIBILITY |
1203 |
future& operator=(future&& __rhs) _NOEXCEPT |
1204 |
{ |
1205 |
future(std::move(__rhs)).swap(*this); |
1206 |
return *this; |
1207 |
} |
1208 |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1209 |
private: |
1210 |
future(const future&); |
1211 |
future& operator=(const future&); |
1212 |
public: |
1213 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1214 |
~future(); |
1215 |
shared_future<_Rp&> share(); |
1216 |
|
1217 |
// retrieving the value |
1218 |
_Rp& get(); |
1219 |
|
1220 |
_LIBCPP_INLINE_VISIBILITY |
1221 |
void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
1222 |
|
1223 |
// functions to check state |
1224 |
_LIBCPP_INLINE_VISIBILITY |
1225 |
bool valid() const _NOEXCEPT {return __state_ != nullptr;} |
1226 |
|
1227 |
_LIBCPP_INLINE_VISIBILITY |
1228 |
void wait() const {__state_->wait();} |
1229 |
template <class _Rep, class _Period> |
1230 |
_LIBCPP_INLINE_VISIBILITY |
1231 |
future_status |
1232 |
wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const |
1233 |
{return __state_->wait_for(__rel_time);} |
1234 |
template <class _Clock, class _Duration> |
1235 |
_LIBCPP_INLINE_VISIBILITY |
1236 |
future_status |
1237 |
wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const |
1238 |
{return __state_->wait_until(__abs_time);} |
1239 |
}; |
1240 |
|
1241 |
template <class _Rp> |
1242 |
future<_Rp&>::future(__assoc_state<_Rp&>* __state) |
1243 |
: __state_(__state) |
1244 |
{ |
1245 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1246 |
if (__state_->__has_future_attached()) |
1247 |
throw future_error(make_error_code(future_errc::future_already_retrieved)); |
1248 |
#endif |
1249 |
__state_->__add_shared(); |
1250 |
__state_->__set_future_attached(); |
1251 |
} |
1252 |
|
1253 |
template <class _Rp> |
1254 |
future<_Rp&>::~future() |
1255 |
{ |
1256 |
if (__state_) |
1257 |
__state_->__release_shared(); |
1258 |
} |
1259 |
|
1260 |
template <class _Rp> |
1261 |
_Rp& |
1262 |
future<_Rp&>::get() |
1263 |
{ |
1264 |
unique_ptr<__shared_count, __release_shared_count> __(__state_); |
1265 |
__assoc_state<_Rp&>* __s = __state_; |
1266 |
__state_ = nullptr; |
1267 |
return __s->copy(); |
1268 |
} |
1269 |
|
1270 |
template <> |
1271 |
class _LIBCPP_TYPE_VIS future<void> |
1272 |
{ |
1273 |
__assoc_sub_state* __state_; |
1274 |
|
1275 |
explicit future(__assoc_sub_state* __state); |
1276 |
|
1277 |
template <class> friend class promise; |
1278 |
template <class> friend class shared_future; |
1279 |
|
1280 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1281 |
template <class _R1, class _Fp> |
1282 |
friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); |
1283 |
template <class _R1, class _Fp> |
1284 |
friend future<_R1> __make_async_assoc_state(_Fp&& __f); |
1285 |
#else |
1286 |
template <class _R1, class _Fp> |
1287 |
friend future<_R1> __make_deferred_assoc_state(_Fp __f); |
1288 |
template <class _R1, class _Fp> |
1289 |
friend future<_R1> __make_async_assoc_state(_Fp __f); |
1290 |
#endif |
1291 |
|
1292 |
public: |
1293 |
_LIBCPP_INLINE_VISIBILITY |
1294 |
future() _NOEXCEPT : __state_(nullptr) {} |
1295 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1296 |
_LIBCPP_INLINE_VISIBILITY |
1297 |
future(future&& __rhs) _NOEXCEPT |
1298 |
: __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} |
1299 |
future(const future&) = delete; |
1300 |
future& operator=(const future&) = delete; |
1301 |
_LIBCPP_INLINE_VISIBILITY |
1302 |
future& operator=(future&& __rhs) _NOEXCEPT |
1303 |
{ |
1304 |
future(std::move(__rhs)).swap(*this); |
1305 |
return *this; |
1306 |
} |
1307 |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1308 |
private: |
1309 |
future(const future&); |
1310 |
future& operator=(const future&); |
1311 |
public: |
1312 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1313 |
~future(); |
1314 |
shared_future<void> share(); |
1315 |
|
1316 |
// retrieving the value |
1317 |
void get(); |
1318 |
|
1319 |
_LIBCPP_INLINE_VISIBILITY |
1320 |
void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
1321 |
|
1322 |
// functions to check state |
1323 |
_LIBCPP_INLINE_VISIBILITY |
1324 |
bool valid() const _NOEXCEPT {return __state_ != nullptr;} |
1325 |
|
1326 |
_LIBCPP_INLINE_VISIBILITY |
1327 |
void wait() const {__state_->wait();} |
1328 |
template <class _Rep, class _Period> |
1329 |
_LIBCPP_INLINE_VISIBILITY |
1330 |
future_status |
1331 |
wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const |
1332 |
{return __state_->wait_for(__rel_time);} |
1333 |
template <class _Clock, class _Duration> |
1334 |
_LIBCPP_INLINE_VISIBILITY |
1335 |
future_status |
1336 |
wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const |
1337 |
{return __state_->wait_until(__abs_time);} |
1338 |
}; |
1339 |
|
1340 |
template <class _Rp> |
1341 |
inline _LIBCPP_INLINE_VISIBILITY |
1342 |
void |
1343 |
swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT |
1344 |
{ |
1345 |
__x.swap(__y); |
1346 |
} |
1347 |
|
1348 |
// promise<R> |
1349 |
|
1350 |
template <class _Callable> class packaged_task; |
1351 |
|
1352 |
template <class _Rp> |
1353 |
class _LIBCPP_TYPE_VIS_ONLY promise |
1354 |
{ |
1355 |
__assoc_state<_Rp>* __state_; |
1356 |
|
1357 |
_LIBCPP_INLINE_VISIBILITY |
1358 |
explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} |
1359 |
|
1360 |
template <class> friend class packaged_task; |
1361 |
public: |
1362 |
promise(); |
1363 |
template <class _Alloc> |
1364 |
promise(allocator_arg_t, const _Alloc& __a); |
1365 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1366 |
_LIBCPP_INLINE_VISIBILITY |
1367 |
promise(promise&& __rhs) _NOEXCEPT |
1368 |
: __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} |
1369 |
promise(const promise& __rhs) = delete; |
1370 |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1371 |
private: |
1372 |
promise(const promise& __rhs); |
1373 |
public: |
1374 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1375 |
~promise(); |
1376 |
|
1377 |
// assignment |
1378 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1379 |
_LIBCPP_INLINE_VISIBILITY |
1380 |
promise& operator=(promise&& __rhs) _NOEXCEPT |
1381 |
{ |
1382 |
promise(std::move(__rhs)).swap(*this); |
1383 |
return *this; |
1384 |
} |
1385 |
promise& operator=(const promise& __rhs) = delete; |
1386 |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1387 |
private: |
1388 |
promise& operator=(const promise& __rhs); |
1389 |
public: |
1390 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1391 |
_LIBCPP_INLINE_VISIBILITY |
1392 |
void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
1393 |
|
1394 |
// retrieving the result |
1395 |
future<_Rp> get_future(); |
1396 |
|
1397 |
// setting the result |
1398 |
void set_value(const _Rp& __r); |
1399 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1400 |
void set_value(_Rp&& __r); |
1401 |
#endif |
1402 |
void set_exception(exception_ptr __p); |
1403 |
|
1404 |
// setting the result with deferred notification |
1405 |
void set_value_at_thread_exit(const _Rp& __r); |
1406 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1407 |
void set_value_at_thread_exit(_Rp&& __r); |
1408 |
#endif |
1409 |
void set_exception_at_thread_exit(exception_ptr __p); |
1410 |
}; |
1411 |
|
1412 |
template <class _Rp> |
1413 |
promise<_Rp>::promise() |
1414 |
: __state_(new __assoc_state<_Rp>) |
1415 |
{ |
1416 |
} |
1417 |
|
1418 |
template <class _Rp> |
1419 |
template <class _Alloc> |
1420 |
promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) |
1421 |
{ |
1422 |
typedef __assoc_state_alloc<_Rp, _Alloc> _State; |
1423 |
typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; |
1424 |
typedef __allocator_destructor<_A2> _D2; |
1425 |
_A2 __a(__a0); |
1426 |
unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); |
1427 |
::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0); |
1428 |
__state_ = _VSTD::addressof(*__hold.release()); |
1429 |
} |
1430 |
|
1431 |
template <class _Rp> |
1432 |
promise<_Rp>::~promise() |
1433 |
{ |
1434 |
if (__state_) |
1435 |
{ |
1436 |
if (!__state_->__has_value() && __state_->use_count() > 1) |
1437 |
__state_->set_exception(make_exception_ptr( |
1438 |
future_error(make_error_code(future_errc::broken_promise)) |
1439 |
)); |
1440 |
__state_->__release_shared(); |
1441 |
} |
1442 |
} |
1443 |
|
1444 |
template <class _Rp> |
1445 |
future<_Rp> |
1446 |
promise<_Rp>::get_future() |
1447 |
{ |
1448 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1449 |
if (__state_ == nullptr) |
1450 |
throw future_error(make_error_code(future_errc::no_state)); |
1451 |
#endif |
1452 |
return future<_Rp>(__state_); |
1453 |
} |
1454 |
|
1455 |
template <class _Rp> |
1456 |
void |
1457 |
promise<_Rp>::set_value(const _Rp& __r) |
1458 |
{ |
1459 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1460 |
if (__state_ == nullptr) |
1461 |
throw future_error(make_error_code(future_errc::no_state)); |
1462 |
#endif |
1463 |
__state_->set_value(__r); |
1464 |
} |
1465 |
|
1466 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1467 |
|
1468 |
template <class _Rp> |
1469 |
void |
1470 |
promise<_Rp>::set_value(_Rp&& __r) |
1471 |
{ |
1472 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1473 |
if (__state_ == nullptr) |
1474 |
throw future_error(make_error_code(future_errc::no_state)); |
1475 |
#endif |
1476 |
__state_->set_value(_VSTD::move(__r)); |
1477 |
} |
1478 |
|
1479 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1480 |
|
1481 |
template <class _Rp> |
1482 |
void |
1483 |
promise<_Rp>::set_exception(exception_ptr __p) |
1484 |
{ |
1485 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1486 |
if (__state_ == nullptr) |
1487 |
throw future_error(make_error_code(future_errc::no_state)); |
1488 |
#endif |
1489 |
__state_->set_exception(__p); |
1490 |
} |
1491 |
|
1492 |
template <class _Rp> |
1493 |
void |
1494 |
promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) |
1495 |
{ |
1496 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1497 |
if (__state_ == nullptr) |
1498 |
throw future_error(make_error_code(future_errc::no_state)); |
1499 |
#endif |
1500 |
__state_->set_value_at_thread_exit(__r); |
1501 |
} |
1502 |
|
1503 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1504 |
|
1505 |
template <class _Rp> |
1506 |
void |
1507 |
promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) |
1508 |
{ |
1509 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1510 |
if (__state_ == nullptr) |
1511 |
throw future_error(make_error_code(future_errc::no_state)); |
1512 |
#endif |
1513 |
__state_->set_value_at_thread_exit(_VSTD::move(__r)); |
1514 |
} |
1515 |
|
1516 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1517 |
|
1518 |
template <class _Rp> |
1519 |
void |
1520 |
promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) |
1521 |
{ |
1522 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1523 |
if (__state_ == nullptr) |
1524 |
throw future_error(make_error_code(future_errc::no_state)); |
1525 |
#endif |
1526 |
__state_->set_exception_at_thread_exit(__p); |
1527 |
} |
1528 |
|
1529 |
// promise<R&> |
1530 |
|
1531 |
template <class _Rp> |
1532 |
class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&> |
1533 |
{ |
1534 |
__assoc_state<_Rp&>* __state_; |
1535 |
|
1536 |
_LIBCPP_INLINE_VISIBILITY |
1537 |
explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} |
1538 |
|
1539 |
template <class> friend class packaged_task; |
1540 |
|
1541 |
public: |
1542 |
promise(); |
1543 |
template <class _Allocator> |
1544 |
promise(allocator_arg_t, const _Allocator& __a); |
1545 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1546 |
_LIBCPP_INLINE_VISIBILITY |
1547 |
promise(promise&& __rhs) _NOEXCEPT |
1548 |
: __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} |
1549 |
promise(const promise& __rhs) = delete; |
1550 |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1551 |
private: |
1552 |
promise(const promise& __rhs); |
1553 |
public: |
1554 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1555 |
~promise(); |
1556 |
|
1557 |
// assignment |
1558 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1559 |
_LIBCPP_INLINE_VISIBILITY |
1560 |
promise& operator=(promise&& __rhs) _NOEXCEPT |
1561 |
{ |
1562 |
promise(std::move(__rhs)).swap(*this); |
1563 |
return *this; |
1564 |
} |
1565 |
promise& operator=(const promise& __rhs) = delete; |
1566 |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1567 |
private: |
1568 |
promise& operator=(const promise& __rhs); |
1569 |
public: |
1570 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1571 |
_LIBCPP_INLINE_VISIBILITY |
1572 |
void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
1573 |
|
1574 |
// retrieving the result |
1575 |
future<_Rp&> get_future(); |
1576 |
|
1577 |
// setting the result |
1578 |
void set_value(_Rp& __r); |
1579 |
void set_exception(exception_ptr __p); |
1580 |
|
1581 |
// setting the result with deferred notification |
1582 |
void set_value_at_thread_exit(_Rp&); |
1583 |
void set_exception_at_thread_exit(exception_ptr __p); |
1584 |
}; |
1585 |
|
1586 |
template <class _Rp> |
1587 |
promise<_Rp&>::promise() |
1588 |
: __state_(new __assoc_state<_Rp&>) |
1589 |
{ |
1590 |
} |
1591 |
|
1592 |
template <class _Rp> |
1593 |
template <class _Alloc> |
1594 |
promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) |
1595 |
{ |
1596 |
typedef __assoc_state_alloc<_Rp&, _Alloc> _State; |
1597 |
typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; |
1598 |
typedef __allocator_destructor<_A2> _D2; |
1599 |
_A2 __a(__a0); |
1600 |
unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); |
1601 |
::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0); |
1602 |
__state_ = _VSTD::addressof(*__hold.release()); |
1603 |
} |
1604 |
|
1605 |
template <class _Rp> |
1606 |
promise<_Rp&>::~promise() |
1607 |
{ |
1608 |
if (__state_) |
1609 |
{ |
1610 |
if (!__state_->__has_value() && __state_->use_count() > 1) |
1611 |
__state_->set_exception(make_exception_ptr( |
1612 |
future_error(make_error_code(future_errc::broken_promise)) |
1613 |
)); |
1614 |
__state_->__release_shared(); |
1615 |
} |
1616 |
} |
1617 |
|
1618 |
template <class _Rp> |
1619 |
future<_Rp&> |
1620 |
promise<_Rp&>::get_future() |
1621 |
{ |
1622 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1623 |
if (__state_ == nullptr) |
1624 |
throw future_error(make_error_code(future_errc::no_state)); |
1625 |
#endif |
1626 |
return future<_Rp&>(__state_); |
1627 |
} |
1628 |
|
1629 |
template <class _Rp> |
1630 |
void |
1631 |
promise<_Rp&>::set_value(_Rp& __r) |
1632 |
{ |
1633 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1634 |
if (__state_ == nullptr) |
1635 |
throw future_error(make_error_code(future_errc::no_state)); |
1636 |
#endif |
1637 |
__state_->set_value(__r); |
1638 |
} |
1639 |
|
1640 |
template <class _Rp> |
1641 |
void |
1642 |
promise<_Rp&>::set_exception(exception_ptr __p) |
1643 |
{ |
1644 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1645 |
if (__state_ == nullptr) |
1646 |
throw future_error(make_error_code(future_errc::no_state)); |
1647 |
#endif |
1648 |
__state_->set_exception(__p); |
1649 |
} |
1650 |
|
1651 |
template <class _Rp> |
1652 |
void |
1653 |
promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) |
1654 |
{ |
1655 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1656 |
if (__state_ == nullptr) |
1657 |
throw future_error(make_error_code(future_errc::no_state)); |
1658 |
#endif |
1659 |
__state_->set_value_at_thread_exit(__r); |
1660 |
} |
1661 |
|
1662 |
template <class _Rp> |
1663 |
void |
1664 |
promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) |
1665 |
{ |
1666 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1667 |
if (__state_ == nullptr) |
1668 |
throw future_error(make_error_code(future_errc::no_state)); |
1669 |
#endif |
1670 |
__state_->set_exception_at_thread_exit(__p); |
1671 |
} |
1672 |
|
1673 |
// promise<void> |
1674 |
|
1675 |
template <> |
1676 |
class _LIBCPP_TYPE_VIS promise<void> |
1677 |
{ |
1678 |
__assoc_sub_state* __state_; |
1679 |
|
1680 |
_LIBCPP_INLINE_VISIBILITY |
1681 |
explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} |
1682 |
|
1683 |
template <class> friend class packaged_task; |
1684 |
|
1685 |
public: |
1686 |
promise(); |
1687 |
template <class _Allocator> |
1688 |
promise(allocator_arg_t, const _Allocator& __a); |
1689 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1690 |
_LIBCPP_INLINE_VISIBILITY |
1691 |
promise(promise&& __rhs) _NOEXCEPT |
1692 |
: __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} |
1693 |
promise(const promise& __rhs) = delete; |
1694 |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1695 |
private: |
1696 |
promise(const promise& __rhs); |
1697 |
public: |
1698 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1699 |
~promise(); |
1700 |
|
1701 |
// assignment |
1702 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1703 |
_LIBCPP_INLINE_VISIBILITY |
1704 |
promise& operator=(promise&& __rhs) _NOEXCEPT |
1705 |
{ |
1706 |
promise(std::move(__rhs)).swap(*this); |
1707 |
return *this; |
1708 |
} |
1709 |
promise& operator=(const promise& __rhs) = delete; |
1710 |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1711 |
private: |
1712 |
promise& operator=(const promise& __rhs); |
1713 |
public: |
1714 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
1715 |
_LIBCPP_INLINE_VISIBILITY |
1716 |
void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
1717 |
|
1718 |
// retrieving the result |
1719 |
future<void> get_future(); |
1720 |
|
1721 |
// setting the result |
1722 |
void set_value(); |
1723 |
void set_exception(exception_ptr __p); |
1724 |
|
1725 |
// setting the result with deferred notification |
1726 |
void set_value_at_thread_exit(); |
1727 |
void set_exception_at_thread_exit(exception_ptr __p); |
1728 |
}; |
1729 |
|
1730 |
template <class _Alloc> |
1731 |
promise<void>::promise(allocator_arg_t, const _Alloc& __a0) |
1732 |
{ |
1733 |
typedef __assoc_sub_state_alloc<_Alloc> _State; |
1734 |
typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; |
1735 |
typedef __allocator_destructor<_A2> _D2; |
1736 |
_A2 __a(__a0); |
1737 |
unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); |
1738 |
::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0); |
1739 |
__state_ = _VSTD::addressof(*__hold.release()); |
1740 |
} |
1741 |
|
1742 |
template <class _Rp> |
1743 |
inline _LIBCPP_INLINE_VISIBILITY |
1744 |
void |
1745 |
swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT |
1746 |
{ |
1747 |
__x.swap(__y); |
1748 |
} |
1749 |
|
1750 |
template <class _Rp, class _Alloc> |
1751 |
struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc> |
1752 |
: public true_type {}; |
1753 |
|
1754 |
#ifndef _LIBCPP_HAS_NO_VARIADICS |
1755 |
|
1756 |
// packaged_task |
1757 |
|
1758 |
template<class _Fp> class __packaged_task_base; |
1759 |
|
1760 |
template<class _Rp, class ..._ArgTypes> |
1761 |
class __packaged_task_base<_Rp(_ArgTypes...)> |
1762 |
{ |
1763 |
__packaged_task_base(const __packaged_task_base&); |
1764 |
__packaged_task_base& operator=(const __packaged_task_base&); |
1765 |
public: |
1766 |
_LIBCPP_INLINE_VISIBILITY |
1767 |
__packaged_task_base() {} |
1768 |
_LIBCPP_INLINE_VISIBILITY |
1769 |
virtual ~__packaged_task_base() {} |
1770 |
virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0; |
1771 |
virtual void destroy() = 0; |
1772 |
virtual void destroy_deallocate() = 0; |
1773 |
virtual _Rp operator()(_ArgTypes&& ...) = 0; |
1774 |
}; |
1775 |
|
1776 |
template<class _FD, class _Alloc, class _FB> class __packaged_task_func; |
1777 |
|
1778 |
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> |
1779 |
class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> |
1780 |
: public __packaged_task_base<_Rp(_ArgTypes...)> |
1781 |
{ |
1782 |
__compressed_pair<_Fp, _Alloc> __f_; |
1783 |
public: |
1784 |
_LIBCPP_INLINE_VISIBILITY |
1785 |
explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {} |
1786 |
_LIBCPP_INLINE_VISIBILITY |
1787 |
explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {} |
1788 |
_LIBCPP_INLINE_VISIBILITY |
1789 |
__packaged_task_func(const _Fp& __f, const _Alloc& __a) |
1790 |
: __f_(__f, __a) {} |
1791 |
_LIBCPP_INLINE_VISIBILITY |
1792 |
__packaged_task_func(_Fp&& __f, const _Alloc& __a) |
1793 |
: __f_(_VSTD::move(__f), __a) {} |
1794 |
virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; |
1795 |
virtual void destroy(); |
1796 |
virtual void destroy_deallocate(); |
1797 |
virtual _Rp operator()(_ArgTypes&& ... __args); |
1798 |
}; |
1799 |
|
1800 |
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> |
1801 |
void |
1802 |
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to( |
1803 |
__packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT |
1804 |
{ |
1805 |
::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second())); |
1806 |
} |
1807 |
|
1808 |
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> |
1809 |
void |
1810 |
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() |
1811 |
{ |
1812 |
__f_.~__compressed_pair<_Fp, _Alloc>(); |
1813 |
} |
1814 |
|
1815 |
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> |
1816 |
void |
1817 |
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() |
1818 |
{ |
1819 |
typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap; |
1820 |
typedef allocator_traits<_Ap> _ATraits; |
1821 |
typedef pointer_traits<typename _ATraits::pointer> _PTraits; |
1822 |
_Ap __a(__f_.second()); |
1823 |
__f_.~__compressed_pair<_Fp, _Alloc>(); |
1824 |
__a.deallocate(_PTraits::pointer_to(*this), 1); |
1825 |
} |
1826 |
|
1827 |
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> |
1828 |
_Rp |
1829 |
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) |
1830 |
{ |
1831 |
return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); |
1832 |
} |
1833 |
|
1834 |
template <class _Callable> class __packaged_task_function; |
1835 |
|
1836 |
template<class _Rp, class ..._ArgTypes> |
1837 |
class __packaged_task_function<_Rp(_ArgTypes...)> |
1838 |
{ |
1839 |
typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; |
1840 |
typename aligned_storage<3*sizeof(void*)>::type __buf_; |
1841 |
__base* __f_; |
1842 |
|
1843 |
public: |
1844 |
typedef _Rp result_type; |
1845 |
|
1846 |
// construct/copy/destroy: |
1847 |
_LIBCPP_INLINE_VISIBILITY |
1848 |
__packaged_task_function() _NOEXCEPT : __f_(nullptr) {} |
1849 |
template<class _Fp> |
1850 |
__packaged_task_function(_Fp&& __f); |
1851 |
template<class _Fp, class _Alloc> |
1852 |
__packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); |
1853 |
|
1854 |
__packaged_task_function(__packaged_task_function&&) _NOEXCEPT; |
1855 |
__packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; |
1856 |
|
1857 |
__packaged_task_function(const __packaged_task_function&) = delete; |
1858 |
__packaged_task_function& operator=(const __packaged_task_function&) = delete; |
1859 |
|
1860 |
~__packaged_task_function(); |
1861 |
|
1862 |
void swap(__packaged_task_function&) _NOEXCEPT; |
1863 |
|
1864 |
_Rp operator()(_ArgTypes...) const; |
1865 |
}; |
1866 |
|
1867 |
template<class _Rp, class ..._ArgTypes> |
1868 |
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT |
1869 |
{ |
1870 |
if (__f.__f_ == nullptr) |
1871 |
__f_ = nullptr; |
1872 |
else if (__f.__f_ == (__base*)&__f.__buf_) |
1873 |
{ |
1874 |
__f_ = (__base*)&__buf_; |
1875 |
__f.__f_->__move_to(__f_); |
1876 |
} |
1877 |
else |
1878 |
{ |
1879 |
__f_ = __f.__f_; |
1880 |
__f.__f_ = nullptr; |
1881 |
} |
1882 |
} |
1883 |
|
1884 |
template<class _Rp, class ..._ArgTypes> |
1885 |
template <class _Fp> |
1886 |
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) |
1887 |
: __f_(nullptr) |
1888 |
{ |
1889 |
typedef typename remove_reference<typename decay<_Fp>::type>::type _FR; |
1890 |
typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; |
1891 |
if (sizeof(_FF) <= sizeof(__buf_)) |
1892 |
{ |
1893 |
__f_ = (__base*)&__buf_; |
1894 |
::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); |
1895 |
} |
1896 |
else |
1897 |
{ |
1898 |
typedef allocator<_FF> _Ap; |
1899 |
_Ap __a; |
1900 |
typedef __allocator_destructor<_Ap> _Dp; |
1901 |
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
1902 |
::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a)); |
1903 |
__f_ = __hold.release(); |
1904 |
} |
1905 |
} |
1906 |
|
1907 |
template<class _Rp, class ..._ArgTypes> |
1908 |
template <class _Fp, class _Alloc> |
1909 |
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function( |
1910 |
allocator_arg_t, const _Alloc& __a0, _Fp&& __f) |
1911 |
: __f_(nullptr) |
1912 |
{ |
1913 |
typedef typename remove_reference<typename decay<_Fp>::type>::type _FR; |
1914 |
typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; |
1915 |
if (sizeof(_FF) <= sizeof(__buf_)) |
1916 |
{ |
1917 |
__f_ = (__base*)&__buf_; |
1918 |
::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); |
1919 |
} |
1920 |
else |
1921 |
{ |
1922 |
typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap; |
1923 |
_Ap __a(__a0); |
1924 |
typedef __allocator_destructor<_Ap> _Dp; |
1925 |
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
1926 |
::new (static_cast<void*>(_VSTD::addressof(*__hold.get()))) |
1927 |
_FF(_VSTD::forward<_Fp>(__f), _Alloc(__a)); |
1928 |
__f_ = _VSTD::addressof(*__hold.release()); |
1929 |
} |
1930 |
} |
1931 |
|
1932 |
template<class _Rp, class ..._ArgTypes> |
1933 |
__packaged_task_function<_Rp(_ArgTypes...)>& |
1934 |
__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT |
1935 |
{ |
1936 |
if (__f_ == (__base*)&__buf_) |
1937 |
__f_->destroy(); |
1938 |
else if (__f_) |
1939 |
__f_->destroy_deallocate(); |
1940 |
__f_ = nullptr; |
1941 |
if (__f.__f_ == nullptr) |
1942 |
__f_ = nullptr; |
1943 |
else if (__f.__f_ == (__base*)&__f.__buf_) |
1944 |
{ |
1945 |
__f_ = (__base*)&__buf_; |
1946 |
__f.__f_->__move_to(__f_); |
1947 |
} |
1948 |
else |
1949 |
{ |
1950 |
__f_ = __f.__f_; |
1951 |
__f.__f_ = nullptr; |
1952 |
} |
1953 |
return *this; |
1954 |
} |
1955 |
|
1956 |
template<class _Rp, class ..._ArgTypes> |
1957 |
__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() |
1958 |
{ |
1959 |
if (__f_ == (__base*)&__buf_) |
1960 |
__f_->destroy(); |
1961 |
else if (__f_) |
1962 |
__f_->destroy_deallocate(); |
1963 |
} |
1964 |
|
1965 |
template<class _Rp, class ..._ArgTypes> |
1966 |
void |
1967 |
__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT |
1968 |
{ |
1969 |
if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) |
1970 |
{ |
1971 |
typename aligned_storage<sizeof(__buf_)>::type __tempbuf; |
1972 |
__base* __t = (__base*)&__tempbuf; |
1973 |
__f_->__move_to(__t); |
1974 |
__f_->destroy(); |
1975 |
__f_ = nullptr; |
1976 |
__f.__f_->__move_to((__base*)&__buf_); |
1977 |
__f.__f_->destroy(); |
1978 |
__f.__f_ = nullptr; |
1979 |
__f_ = (__base*)&__buf_; |
1980 |
__t->__move_to((__base*)&__f.__buf_); |
1981 |
__t->destroy(); |
1982 |
__f.__f_ = (__base*)&__f.__buf_; |
1983 |
} |
1984 |
else if (__f_ == (__base*)&__buf_) |
1985 |
{ |
1986 |
__f_->__move_to((__base*)&__f.__buf_); |
1987 |
__f_->destroy(); |
1988 |
__f_ = __f.__f_; |
1989 |
__f.__f_ = (__base*)&__f.__buf_; |
1990 |
} |
1991 |
else if (__f.__f_ == (__base*)&__f.__buf_) |
1992 |
{ |
1993 |
__f.__f_->__move_to((__base*)&__buf_); |
1994 |
__f.__f_->destroy(); |
1995 |
__f.__f_ = __f_; |
1996 |
__f_ = (__base*)&__buf_; |
1997 |
} |
1998 |
else |
1999 |
_VSTD::swap(__f_, __f.__f_); |
2000 |
} |
2001 |
|
2002 |
template<class _Rp, class ..._ArgTypes> |
2003 |
inline _LIBCPP_INLINE_VISIBILITY |
2004 |
_Rp |
2005 |
__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const |
2006 |
{ |
2007 |
return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); |
2008 |
} |
2009 |
|
2010 |
template<class _Rp, class ..._ArgTypes> |
2011 |
class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)> |
2012 |
{ |
2013 |
public: |
2014 |
typedef _Rp result_type; |
2015 |
|
2016 |
private: |
2017 |
__packaged_task_function<result_type(_ArgTypes...)> __f_; |
2018 |
promise<result_type> __p_; |
2019 |
|
2020 |
public: |
2021 |
// construction and destruction |
2022 |
_LIBCPP_INLINE_VISIBILITY |
2023 |
packaged_task() _NOEXCEPT : __p_(nullptr) {} |
2024 |
template <class _Fp, |
2025 |
class = typename enable_if |
2026 |
< |
2027 |
!is_same< |
2028 |
typename decay<_Fp>::type, |
2029 |
packaged_task |
2030 |
>::value |
2031 |
>::type |
2032 |
> |
2033 |
_LIBCPP_INLINE_VISIBILITY |
2034 |
explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} |
2035 |
template <class _Fp, class _Allocator, |
2036 |
class = typename enable_if |
2037 |
< |
2038 |
!is_same< |
2039 |
typename decay<_Fp>::type, |
2040 |
packaged_task |
2041 |
>::value |
2042 |
>::type |
2043 |
> |
2044 |
_LIBCPP_INLINE_VISIBILITY |
2045 |
packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) |
2046 |
: __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), |
2047 |
__p_(allocator_arg, __a) {} |
2048 |
// ~packaged_task() = default; |
2049 |
|
2050 |
// no copy |
2051 |
packaged_task(const packaged_task&) = delete; |
2052 |
packaged_task& operator=(const packaged_task&) = delete; |
2053 |
|
2054 |
// move support |
2055 |
_LIBCPP_INLINE_VISIBILITY |
2056 |
packaged_task(packaged_task&& __other) _NOEXCEPT |
2057 |
: __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} |
2058 |
_LIBCPP_INLINE_VISIBILITY |
2059 |
packaged_task& operator=(packaged_task&& __other) _NOEXCEPT |
2060 |
{ |
2061 |
__f_ = _VSTD::move(__other.__f_); |
2062 |
__p_ = _VSTD::move(__other.__p_); |
2063 |
return *this; |
2064 |
} |
2065 |
_LIBCPP_INLINE_VISIBILITY |
2066 |
void swap(packaged_task& __other) _NOEXCEPT |
2067 |
{ |
2068 |
__f_.swap(__other.__f_); |
2069 |
__p_.swap(__other.__p_); |
2070 |
} |
2071 |
|
2072 |
_LIBCPP_INLINE_VISIBILITY |
2073 |
bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} |
2074 |
|
2075 |
// result retrieval |
2076 |
_LIBCPP_INLINE_VISIBILITY |
2077 |
future<result_type> get_future() {return __p_.get_future();} |
2078 |
|
2079 |
// execution |
2080 |
void operator()(_ArgTypes... __args); |
2081 |
void make_ready_at_thread_exit(_ArgTypes... __args); |
2082 |
|
2083 |
void reset(); |
2084 |
}; |
2085 |
|
2086 |
template<class _Rp, class ..._ArgTypes> |
2087 |
void |
2088 |
packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) |
2089 |
{ |
2090 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2091 |
if (__p_.__state_ == nullptr) |
2092 |
throw future_error(make_error_code(future_errc::no_state)); |
2093 |
if (__p_.__state_->__has_value()) |
2094 |
throw future_error(make_error_code(future_errc::promise_already_satisfied)); |
2095 |
try |
2096 |
{ |
2097 |
#endif // _LIBCPP_NO_EXCEPTIONS |
2098 |
__p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...)); |
2099 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2100 |
} |
2101 |
catch (...) |
2102 |
{ |
2103 |
__p_.set_exception(current_exception()); |
2104 |
} |
2105 |
#endif // _LIBCPP_NO_EXCEPTIONS |
2106 |
} |
2107 |
|
2108 |
template<class _Rp, class ..._ArgTypes> |
2109 |
void |
2110 |
packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) |
2111 |
{ |
2112 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2113 |
if (__p_.__state_ == nullptr) |
2114 |
throw future_error(make_error_code(future_errc::no_state)); |
2115 |
if (__p_.__state_->__has_value()) |
2116 |
throw future_error(make_error_code(future_errc::promise_already_satisfied)); |
2117 |
try |
2118 |
{ |
2119 |
#endif // _LIBCPP_NO_EXCEPTIONS |
2120 |
__p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...)); |
2121 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2122 |
} |
2123 |
catch (...) |
2124 |
{ |
2125 |
__p_.set_exception_at_thread_exit(current_exception()); |
2126 |
} |
2127 |
#endif // _LIBCPP_NO_EXCEPTIONS |
2128 |
} |
2129 |
|
2130 |
template<class _Rp, class ..._ArgTypes> |
2131 |
void |
2132 |
packaged_task<_Rp(_ArgTypes...)>::reset() |
2133 |
{ |
2134 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2135 |
if (!valid()) |
2136 |
throw future_error(make_error_code(future_errc::no_state)); |
2137 |
#endif // _LIBCPP_NO_EXCEPTIONS |
2138 |
__p_ = promise<result_type>(); |
2139 |
} |
2140 |
|
2141 |
template<class ..._ArgTypes> |
2142 |
class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)> |
2143 |
{ |
2144 |
public: |
2145 |
typedef void result_type; |
2146 |
|
2147 |
private: |
2148 |
__packaged_task_function<result_type(_ArgTypes...)> __f_; |
2149 |
promise<result_type> __p_; |
2150 |
|
2151 |
public: |
2152 |
// construction and destruction |
2153 |
_LIBCPP_INLINE_VISIBILITY |
2154 |
packaged_task() _NOEXCEPT : __p_(nullptr) {} |
2155 |
template <class _Fp, |
2156 |
class = typename enable_if |
2157 |
< |
2158 |
!is_same< |
2159 |
typename decay<_Fp>::type, |
2160 |
packaged_task |
2161 |
>::value |
2162 |
>::type |
2163 |
> |
2164 |
_LIBCPP_INLINE_VISIBILITY |
2165 |
explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} |
2166 |
template <class _Fp, class _Allocator, |
2167 |
class = typename enable_if |
2168 |
< |
2169 |
!is_same< |
2170 |
typename decay<_Fp>::type, |
2171 |
packaged_task |
2172 |
>::value |
2173 |
>::type |
2174 |
> |
2175 |
_LIBCPP_INLINE_VISIBILITY |
2176 |
packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) |
2177 |
: __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), |
2178 |
__p_(allocator_arg, __a) {} |
2179 |
// ~packaged_task() = default; |
2180 |
|
2181 |
// no copy |
2182 |
packaged_task(const packaged_task&) = delete; |
2183 |
packaged_task& operator=(const packaged_task&) = delete; |
2184 |
|
2185 |
// move support |
2186 |
_LIBCPP_INLINE_VISIBILITY |
2187 |
packaged_task(packaged_task&& __other) _NOEXCEPT |
2188 |
: __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} |
2189 |
_LIBCPP_INLINE_VISIBILITY |
2190 |
packaged_task& operator=(packaged_task&& __other) _NOEXCEPT |
2191 |
{ |
2192 |
__f_ = _VSTD::move(__other.__f_); |
2193 |
__p_ = _VSTD::move(__other.__p_); |
2194 |
return *this; |
2195 |
} |
2196 |
_LIBCPP_INLINE_VISIBILITY |
2197 |
void swap(packaged_task& __other) _NOEXCEPT |
2198 |
{ |
2199 |
__f_.swap(__other.__f_); |
2200 |
__p_.swap(__other.__p_); |
2201 |
} |
2202 |
|
2203 |
_LIBCPP_INLINE_VISIBILITY |
2204 |
bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} |
2205 |
|
2206 |
// result retrieval |
2207 |
_LIBCPP_INLINE_VISIBILITY |
2208 |
future<result_type> get_future() {return __p_.get_future();} |
2209 |
|
2210 |
// execution |
2211 |
void operator()(_ArgTypes... __args); |
2212 |
void make_ready_at_thread_exit(_ArgTypes... __args); |
2213 |
|
2214 |
void reset(); |
2215 |
}; |
2216 |
|
2217 |
template<class ..._ArgTypes> |
2218 |
void |
2219 |
packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) |
2220 |
{ |
2221 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2222 |
if (__p_.__state_ == nullptr) |
2223 |
throw future_error(make_error_code(future_errc::no_state)); |
2224 |
if (__p_.__state_->__has_value()) |
2225 |
throw future_error(make_error_code(future_errc::promise_already_satisfied)); |
2226 |
try |
2227 |
{ |
2228 |
#endif // _LIBCPP_NO_EXCEPTIONS |
2229 |
__f_(_VSTD::forward<_ArgTypes>(__args)...); |
2230 |
__p_.set_value(); |
2231 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2232 |
} |
2233 |
catch (...) |
2234 |
{ |
2235 |
__p_.set_exception(current_exception()); |
2236 |
} |
2237 |
#endif // _LIBCPP_NO_EXCEPTIONS |
2238 |
} |
2239 |
|
2240 |
template<class ..._ArgTypes> |
2241 |
void |
2242 |
packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) |
2243 |
{ |
2244 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2245 |
if (__p_.__state_ == nullptr) |
2246 |
throw future_error(make_error_code(future_errc::no_state)); |
2247 |
if (__p_.__state_->__has_value()) |
2248 |
throw future_error(make_error_code(future_errc::promise_already_satisfied)); |
2249 |
try |
2250 |
{ |
2251 |
#endif // _LIBCPP_NO_EXCEPTIONS |
2252 |
__f_(_VSTD::forward<_ArgTypes>(__args)...); |
2253 |
__p_.set_value_at_thread_exit(); |
2254 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2255 |
} |
2256 |
catch (...) |
2257 |
{ |
2258 |
__p_.set_exception_at_thread_exit(current_exception()); |
2259 |
} |
2260 |
#endif // _LIBCPP_NO_EXCEPTIONS |
2261 |
} |
2262 |
|
2263 |
template<class ..._ArgTypes> |
2264 |
void |
2265 |
packaged_task<void(_ArgTypes...)>::reset() |
2266 |
{ |
2267 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2268 |
if (!valid()) |
2269 |
throw future_error(make_error_code(future_errc::no_state)); |
2270 |
#endif // _LIBCPP_NO_EXCEPTIONS |
2271 |
__p_ = promise<result_type>(); |
2272 |
} |
2273 |
|
2274 |
template <class _Callable> |
2275 |
inline _LIBCPP_INLINE_VISIBILITY |
2276 |
void |
2277 |
swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT |
2278 |
{ |
2279 |
__x.swap(__y); |
2280 |
} |
2281 |
|
2282 |
template <class _Callable, class _Alloc> |
2283 |
struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc> |
2284 |
: public true_type {}; |
2285 |
|
2286 |
template <class _Rp, class _Fp> |
2287 |
future<_Rp> |
2288 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2289 |
__make_deferred_assoc_state(_Fp&& __f) |
2290 |
#else |
2291 |
__make_deferred_assoc_state(_Fp __f) |
2292 |
#endif |
2293 |
{ |
2294 |
unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> |
2295 |
__h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); |
2296 |
return future<_Rp>(__h.get()); |
2297 |
} |
2298 |
|
2299 |
template <class _Rp, class _Fp> |
2300 |
future<_Rp> |
2301 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2302 |
__make_async_assoc_state(_Fp&& __f) |
2303 |
#else |
2304 |
__make_async_assoc_state(_Fp __f) |
2305 |
#endif |
2306 |
{ |
2307 |
unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> |
2308 |
__h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); |
2309 |
_VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach(); |
2310 |
return future<_Rp>(__h.get()); |
2311 |
} |
2312 |
|
2313 |
template <class _Fp, class... _Args> |
2314 |
class __async_func |
2315 |
{ |
2316 |
tuple<_Fp, _Args...> __f_; |
2317 |
|
2318 |
public: |
2319 |
typedef typename __invoke_of<_Fp, _Args...>::type _Rp; |
2320 |
|
2321 |
_LIBCPP_INLINE_VISIBILITY |
2322 |
explicit __async_func(_Fp&& __f, _Args&&... __args) |
2323 |
: __f_(_VSTD::move(__f), _VSTD::move(__args)...) {} |
2324 |
|
2325 |
_LIBCPP_INLINE_VISIBILITY |
2326 |
__async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {} |
2327 |
|
2328 |
_Rp operator()() |
2329 |
{ |
2330 |
typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index; |
2331 |
return __execute(_Index()); |
2332 |
} |
2333 |
private: |
2334 |
template <size_t ..._Indices> |
2335 |
_Rp |
2336 |
__execute(__tuple_indices<_Indices...>) |
2337 |
{ |
2338 |
return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); |
2339 |
} |
2340 |
}; |
2341 |
|
2342 |
inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value ) |
2343 |
{ return (int(__policy) & int(__value)) != 0; } |
2344 |
|
2345 |
template <class _Fp, class... _Args> |
2346 |
future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> |
2347 |
async(launch __policy, _Fp&& __f, _Args&&... __args) |
2348 |
{ |
2349 |
typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF; |
2350 |
typedef typename _BF::_Rp _Rp; |
2351 |
|
2352 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2353 |
try |
2354 |
{ |
2355 |
#endif |
2356 |
if (__does_policy_contain(__policy, launch::async)) |
2357 |
return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), |
2358 |
__decay_copy(_VSTD::forward<_Args>(__args))...)); |
2359 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
2360 |
} |
2361 |
catch ( ... ) { if (__policy == launch::async) throw ; } |
2362 |
#endif |
2363 |
|
2364 |
if (__does_policy_contain(__policy, launch::deferred)) |
2365 |
return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), |
2366 |
__decay_copy(_VSTD::forward<_Args>(__args))...)); |
2367 |
return future<_Rp>{}; |
2368 |
} |
2369 |
|
2370 |
template <class _Fp, class... _Args> |
2371 |
inline _LIBCPP_INLINE_VISIBILITY |
2372 |
future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> |
2373 |
async(_Fp&& __f, _Args&&... __args) |
2374 |
{ |
2375 |
return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f), |
2376 |
_VSTD::forward<_Args>(__args)...); |
2377 |
} |
2378 |
|
2379 |
#endif // _LIBCPP_HAS_NO_VARIADICS |
2380 |
|
2381 |
// shared_future |
2382 |
|
2383 |
template <class _Rp> |
2384 |
class _LIBCPP_TYPE_VIS_ONLY shared_future |
2385 |
{ |
2386 |
__assoc_state<_Rp>* __state_; |
2387 |
|
2388 |
public: |
2389 |
_LIBCPP_INLINE_VISIBILITY |
2390 |
shared_future() _NOEXCEPT : __state_(nullptr) {} |
2391 |
_LIBCPP_INLINE_VISIBILITY |
2392 |
shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) |
2393 |
{if (__state_) __state_->__add_shared();} |
2394 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2395 |
_LIBCPP_INLINE_VISIBILITY |
2396 |
shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) |
2397 |
{__f.__state_ = nullptr;} |
2398 |
_LIBCPP_INLINE_VISIBILITY |
2399 |
shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) |
2400 |
{__rhs.__state_ = nullptr;} |
2401 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2402 |
~shared_future(); |
2403 |
shared_future& operator=(const shared_future& __rhs); |
2404 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2405 |
_LIBCPP_INLINE_VISIBILITY |
2406 |
shared_future& operator=(shared_future&& __rhs) _NOEXCEPT |
2407 |
{ |
2408 |
shared_future(std::move(__rhs)).swap(*this); |
2409 |
return *this; |
2410 |
} |
2411 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2412 |
|
2413 |
// retrieving the value |
2414 |
_LIBCPP_INLINE_VISIBILITY |
2415 |
const _Rp& get() const {return __state_->copy();} |
2416 |
|
2417 |
_LIBCPP_INLINE_VISIBILITY |
2418 |
void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
2419 |
|
2420 |
// functions to check state |
2421 |
_LIBCPP_INLINE_VISIBILITY |
2422 |
bool valid() const _NOEXCEPT {return __state_ != nullptr;} |
2423 |
|
2424 |
_LIBCPP_INLINE_VISIBILITY |
2425 |
void wait() const {__state_->wait();} |
2426 |
template <class _Rep, class _Period> |
2427 |
_LIBCPP_INLINE_VISIBILITY |
2428 |
future_status |
2429 |
wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const |
2430 |
{return __state_->wait_for(__rel_time);} |
2431 |
template <class _Clock, class _Duration> |
2432 |
_LIBCPP_INLINE_VISIBILITY |
2433 |
future_status |
2434 |
wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const |
2435 |
{return __state_->wait_until(__abs_time);} |
2436 |
}; |
2437 |
|
2438 |
template <class _Rp> |
2439 |
shared_future<_Rp>::~shared_future() |
2440 |
{ |
2441 |
if (__state_) |
2442 |
__state_->__release_shared(); |
2443 |
} |
2444 |
|
2445 |
template <class _Rp> |
2446 |
shared_future<_Rp>& |
2447 |
shared_future<_Rp>::operator=(const shared_future& __rhs) |
2448 |
{ |
2449 |
if (__rhs.__state_) |
2450 |
__rhs.__state_->__add_shared(); |
2451 |
if (__state_) |
2452 |
__state_->__release_shared(); |
2453 |
__state_ = __rhs.__state_; |
2454 |
return *this; |
2455 |
} |
2456 |
|
2457 |
template <class _Rp> |
2458 |
class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&> |
2459 |
{ |
2460 |
__assoc_state<_Rp&>* __state_; |
2461 |
|
2462 |
public: |
2463 |
_LIBCPP_INLINE_VISIBILITY |
2464 |
shared_future() _NOEXCEPT : __state_(nullptr) {} |
2465 |
_LIBCPP_INLINE_VISIBILITY |
2466 |
shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) |
2467 |
{if (__state_) __state_->__add_shared();} |
2468 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2469 |
_LIBCPP_INLINE_VISIBILITY |
2470 |
shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) |
2471 |
{__f.__state_ = nullptr;} |
2472 |
_LIBCPP_INLINE_VISIBILITY |
2473 |
shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) |
2474 |
{__rhs.__state_ = nullptr;} |
2475 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2476 |
~shared_future(); |
2477 |
shared_future& operator=(const shared_future& __rhs); |
2478 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2479 |
_LIBCPP_INLINE_VISIBILITY |
2480 |
shared_future& operator=(shared_future&& __rhs) _NOEXCEPT |
2481 |
{ |
2482 |
shared_future(std::move(__rhs)).swap(*this); |
2483 |
return *this; |
2484 |
} |
2485 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2486 |
|
2487 |
// retrieving the value |
2488 |
_LIBCPP_INLINE_VISIBILITY |
2489 |
_Rp& get() const {return __state_->copy();} |
2490 |
|
2491 |
_LIBCPP_INLINE_VISIBILITY |
2492 |
void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
2493 |
|
2494 |
// functions to check state |
2495 |
_LIBCPP_INLINE_VISIBILITY |
2496 |
bool valid() const _NOEXCEPT {return __state_ != nullptr;} |
2497 |
|
2498 |
_LIBCPP_INLINE_VISIBILITY |
2499 |
void wait() const {__state_->wait();} |
2500 |
template <class _Rep, class _Period> |
2501 |
_LIBCPP_INLINE_VISIBILITY |
2502 |
future_status |
2503 |
wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const |
2504 |
{return __state_->wait_for(__rel_time);} |
2505 |
template <class _Clock, class _Duration> |
2506 |
_LIBCPP_INLINE_VISIBILITY |
2507 |
future_status |
2508 |
wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const |
2509 |
{return __state_->wait_until(__abs_time);} |
2510 |
}; |
2511 |
|
2512 |
template <class _Rp> |
2513 |
shared_future<_Rp&>::~shared_future() |
2514 |
{ |
2515 |
if (__state_) |
2516 |
__state_->__release_shared(); |
2517 |
} |
2518 |
|
2519 |
template <class _Rp> |
2520 |
shared_future<_Rp&>& |
2521 |
shared_future<_Rp&>::operator=(const shared_future& __rhs) |
2522 |
{ |
2523 |
if (__rhs.__state_) |
2524 |
__rhs.__state_->__add_shared(); |
2525 |
if (__state_) |
2526 |
__state_->__release_shared(); |
2527 |
__state_ = __rhs.__state_; |
2528 |
return *this; |
2529 |
} |
2530 |
|
2531 |
template <> |
2532 |
class _LIBCPP_TYPE_VIS shared_future<void> |
2533 |
{ |
2534 |
__assoc_sub_state* __state_; |
2535 |
|
2536 |
public: |
2537 |
_LIBCPP_INLINE_VISIBILITY |
2538 |
shared_future() _NOEXCEPT : __state_(nullptr) {} |
2539 |
_LIBCPP_INLINE_VISIBILITY |
2540 |
shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) |
2541 |
{if (__state_) __state_->__add_shared();} |
2542 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2543 |
_LIBCPP_INLINE_VISIBILITY |
2544 |
shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) |
2545 |
{__f.__state_ = nullptr;} |
2546 |
_LIBCPP_INLINE_VISIBILITY |
2547 |
shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) |
2548 |
{__rhs.__state_ = nullptr;} |
2549 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2550 |
~shared_future(); |
2551 |
shared_future& operator=(const shared_future& __rhs); |
2552 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2553 |
_LIBCPP_INLINE_VISIBILITY |
2554 |
shared_future& operator=(shared_future&& __rhs) _NOEXCEPT |
2555 |
{ |
2556 |
shared_future(std::move(__rhs)).swap(*this); |
2557 |
return *this; |
2558 |
} |
2559 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2560 |
|
2561 |
// retrieving the value |
2562 |
_LIBCPP_INLINE_VISIBILITY |
2563 |
void get() const {__state_->copy();} |
2564 |
|
2565 |
_LIBCPP_INLINE_VISIBILITY |
2566 |
void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
2567 |
|
2568 |
// functions to check state |
2569 |
_LIBCPP_INLINE_VISIBILITY |
2570 |
bool valid() const _NOEXCEPT {return __state_ != nullptr;} |
2571 |
|
2572 |
_LIBCPP_INLINE_VISIBILITY |
2573 |
void wait() const {__state_->wait();} |
2574 |
template <class _Rep, class _Period> |
2575 |
_LIBCPP_INLINE_VISIBILITY |
2576 |
future_status |
2577 |
wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const |
2578 |
{return __state_->wait_for(__rel_time);} |
2579 |
template <class _Clock, class _Duration> |
2580 |
_LIBCPP_INLINE_VISIBILITY |
2581 |
future_status |
2582 |
wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const |
2583 |
{return __state_->wait_until(__abs_time);} |
2584 |
}; |
2585 |
|
2586 |
template <class _Rp> |
2587 |
inline _LIBCPP_INLINE_VISIBILITY |
2588 |
void |
2589 |
swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT |
2590 |
{ |
2591 |
__x.swap(__y); |
2592 |
} |
2593 |
|
2594 |
template <class _Rp> |
2595 |
inline _LIBCPP_INLINE_VISIBILITY |
2596 |
shared_future<_Rp> |
2597 |
future<_Rp>::share() |
2598 |
{ |
2599 |
return shared_future<_Rp>(_VSTD::move(*this)); |
2600 |
} |
2601 |
|
2602 |
template <class _Rp> |
2603 |
inline _LIBCPP_INLINE_VISIBILITY |
2604 |
shared_future<_Rp&> |
2605 |
future<_Rp&>::share() |
2606 |
{ |
2607 |
return shared_future<_Rp&>(_VSTD::move(*this)); |
2608 |
} |
2609 |
|
2610 |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2611 |
|
2612 |
inline _LIBCPP_INLINE_VISIBILITY |
2613 |
shared_future<void> |
2614 |
future<void>::share() |
2615 |
{ |
2616 |
return shared_future<void>(_VSTD::move(*this)); |
2617 |
} |
2618 |
|
2619 |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES |
2620 |
|
2621 |
_LIBCPP_END_NAMESPACE_STD |
2622 |
|
2623 |
#endif // !_LIBCPP_HAS_NO_THREADS |
2624 |
|
2625 |
#endif // _LIBCPP_FUTURE |