root / lab4 / .minix-src / include / c++ / future @ 13
History | View | Annotate | Download (70.3 KB)
1 | 13 | up20180614 | // -*- 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 |