1 | // -*- C++ -*- |
2 | //===----------------------------------------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP_FUTURE |
11 | #define _LIBCPP_FUTURE |
12 | |
13 | /* |
14 | future synopsis |
15 | |
16 | namespace std |
17 | { |
18 | |
19 | enum class future_errc |
20 | { |
21 | future_already_retrieved = 1, |
22 | promise_already_satisfied, |
23 | no_state, |
24 | broken_promise |
25 | }; |
26 | |
27 | enum class launch |
28 | { |
29 | async = 1, |
30 | deferred = 2, |
31 | any = async | deferred |
32 | }; |
33 | |
34 | enum class future_status |
35 | { |
36 | ready, |
37 | timeout, |
38 | deferred |
39 | }; |
40 | |
41 | template <> struct is_error_code_enum<future_errc> : public true_type { }; |
42 | error_code make_error_code(future_errc e) noexcept; |
43 | error_condition make_error_condition(future_errc e) noexcept; |
44 | |
45 | const error_category& future_category() noexcept; |
46 | |
47 | class future_error : public logic_error { |
48 | public: |
49 | explicit future_error(future_errc e); // since C++17 |
50 | |
51 | const error_code& code() const noexcept; |
52 | const char* what() const noexcept; |
53 | |
54 | private: |
55 | error_code ec_; // exposition only |
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() noexcept; |
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() noexcept; |
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() noexcept; |
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; // extension |
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 | |
367 | #if !defined(_LIBCPP_HAS_NO_THREADS) |
368 | |
369 | # include <__assert> |
370 | # include <__chrono/duration.h> |
371 | # include <__chrono/time_point.h> |
372 | # include <__exception/exception_ptr.h> |
373 | # include <__memory/addressof.h> |
374 | # include <__memory/allocator.h> |
375 | # include <__memory/allocator_arg_t.h> |
376 | # include <__memory/allocator_destructor.h> |
377 | # include <__memory/allocator_traits.h> |
378 | # include <__memory/compressed_pair.h> |
379 | # include <__memory/pointer_traits.h> |
380 | # include <__memory/shared_ptr.h> |
381 | # include <__memory/unique_ptr.h> |
382 | # include <__memory/uses_allocator.h> |
383 | # include <__system_error/error_category.h> |
384 | # include <__system_error/error_code.h> |
385 | # include <__system_error/error_condition.h> |
386 | # include <__type_traits/aligned_storage.h> |
387 | # include <__type_traits/strip_signature.h> |
388 | # include <__utility/auto_cast.h> |
389 | # include <__utility/forward.h> |
390 | # include <__utility/move.h> |
391 | # include <mutex> |
392 | # include <new> |
393 | # include <stdexcept> |
394 | # include <thread> |
395 | # include <version> |
396 | |
397 | # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
398 | # pragma GCC system_header |
399 | # endif |
400 | |
401 | _LIBCPP_PUSH_MACROS |
402 | # include <__undef_macros> |
403 | |
404 | _LIBCPP_BEGIN_NAMESPACE_STD |
405 | |
406 | // enum class future_errc |
407 | _LIBCPP_DECLARE_STRONG_ENUM(future_errc){ |
408 | future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise}; |
409 | _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc) |
410 | |
411 | template <> |
412 | struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {}; |
413 | |
414 | # ifdef _LIBCPP_CXX03_LANG |
415 | template <> |
416 | struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type {}; |
417 | # endif |
418 | |
419 | // enum class launch |
420 | _LIBCPP_DECLARE_STRONG_ENUM(launch){async = 1, deferred = 2, any = async | deferred}; |
421 | _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch) |
422 | |
423 | # ifndef _LIBCPP_CXX03_LANG |
424 | |
425 | typedef underlying_type<launch>::type __launch_underlying_type; |
426 | |
427 | inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator&(launch __x, launch __y) { |
428 | return static_cast<launch>(static_cast<__launch_underlying_type>(__x) & static_cast<__launch_underlying_type>(__y)); |
429 | } |
430 | |
431 | inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator|(launch __x, launch __y) { |
432 | return static_cast<launch>(static_cast<__launch_underlying_type>(__x) | static_cast<__launch_underlying_type>(__y)); |
433 | } |
434 | |
435 | inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator^(launch __x, launch __y) { |
436 | return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^ static_cast<__launch_underlying_type>(__y)); |
437 | } |
438 | |
439 | inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator~(launch __x) { |
440 | return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3); |
441 | } |
442 | |
443 | inline _LIBCPP_HIDE_FROM_ABI launch& operator&=(launch& __x, launch __y) { |
444 | __x = __x & __y; |
445 | return __x; |
446 | } |
447 | |
448 | inline _LIBCPP_HIDE_FROM_ABI launch& operator|=(launch& __x, launch __y) { |
449 | __x = __x | __y; |
450 | return __x; |
451 | } |
452 | |
453 | inline _LIBCPP_HIDE_FROM_ABI launch& operator^=(launch& __x, launch __y) { |
454 | __x = __x ^ __y; |
455 | return __x; |
456 | } |
457 | |
458 | # endif // !_LIBCPP_CXX03_LANG |
459 | |
460 | // enum class future_status |
461 | _LIBCPP_DECLARE_STRONG_ENUM(future_status){ready, timeout, deferred}; |
462 | _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status) |
463 | |
464 | _LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT; |
465 | |
466 | inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(future_errc __e) _NOEXCEPT { |
467 | return error_code(static_cast<int>(__e), future_category()); |
468 | } |
469 | |
470 | inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(future_errc __e) _NOEXCEPT { |
471 | return error_condition(static_cast<int>(__e), future_category()); |
472 | } |
473 | |
474 | _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_future_error(future_errc __ev); |
475 | |
476 | class _LIBCPP_EXPORTED_FROM_ABI future_error : public logic_error { |
477 | error_code __ec_; |
478 | |
479 | future_error(error_code); |
480 | friend void __throw_future_error(future_errc); |
481 | template <class> |
482 | friend class promise; |
483 | |
484 | public: |
485 | # if _LIBCPP_STD_VER >= 17 |
486 | _LIBCPP_HIDE_FROM_ABI explicit future_error(future_errc __ec) : future_error(std::make_error_code(__ec)) {} |
487 | # endif |
488 | |
489 | _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; } |
490 | |
491 | _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default; |
492 | ~future_error() _NOEXCEPT override; |
493 | }; |
494 | |
495 | // Declared above std::future_error |
496 | void __throw_future_error(future_errc __ev) { |
497 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
498 | throw future_error(make_error_code(__ev)); |
499 | # else |
500 | (void)__ev; |
501 | _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode" ); |
502 | # endif |
503 | } |
504 | |
505 | class _LIBCPP_EXPORTED_FROM_ABI __assoc_sub_state : public __shared_count { |
506 | protected: |
507 | exception_ptr __exception_; |
508 | mutable mutex __mut_; |
509 | mutable condition_variable __cv_; |
510 | unsigned __state_; |
511 | |
512 | void __on_zero_shared() _NOEXCEPT override; |
513 | void __sub_wait(unique_lock<mutex>& __lk); |
514 | |
515 | public: |
516 | enum { __constructed = 1, __future_attached = 2, ready = 4, deferred = 8 }; |
517 | |
518 | _LIBCPP_HIDE_FROM_ABI __assoc_sub_state() : __state_(0) {} |
519 | |
520 | _LIBCPP_HIDE_FROM_ABI bool __has_value() const { return (__state_ & __constructed) || (__exception_ != nullptr); } |
521 | |
522 | _LIBCPP_HIDE_FROM_ABI void __attach_future() { |
523 | lock_guard<mutex> __lk(__mut_); |
524 | bool __has_future_attached = (__state_ & __future_attached) != 0; |
525 | if (__has_future_attached) |
526 | __throw_future_error(future_errc::future_already_retrieved); |
527 | this->__add_shared(); |
528 | __state_ |= __future_attached; |
529 | } |
530 | |
531 | _LIBCPP_HIDE_FROM_ABI void __set_deferred() { __state_ |= deferred; } |
532 | |
533 | void __make_ready(); |
534 | _LIBCPP_HIDE_FROM_ABI bool __is_ready() const { return (__state_ & ready) != 0; } |
535 | |
536 | void set_value(); |
537 | void set_value_at_thread_exit(); |
538 | |
539 | void set_exception(exception_ptr __p); |
540 | void set_exception_at_thread_exit(exception_ptr __p); |
541 | |
542 | void copy(); |
543 | |
544 | void wait(); |
545 | template <class _Rep, class _Period> |
546 | future_status _LIBCPP_HIDE_FROM_ABI wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; |
547 | template <class _Clock, class _Duration> |
548 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS future_status |
549 | wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const; |
550 | |
551 | virtual void __execute(); |
552 | }; |
553 | |
554 | template <class _Clock, class _Duration> |
555 | future_status __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { |
556 | unique_lock<mutex> __lk(__mut_); |
557 | if (__state_ & deferred) |
558 | return future_status::deferred; |
559 | while (!(__state_ & ready) && _Clock::now() < __abs_time) |
560 | __cv_.wait_until(__lk, __abs_time); |
561 | if (__state_ & ready) |
562 | return future_status::ready; |
563 | return future_status::timeout; |
564 | } |
565 | |
566 | template <class _Rep, class _Period> |
567 | inline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { |
568 | return wait_until(chrono::steady_clock::now() + __rel_time); |
569 | } |
570 | |
571 | template <class _Rp> |
572 | class _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state { |
573 | typedef __assoc_sub_state base; |
574 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
575 | typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up; |
576 | _LIBCPP_SUPPRESS_DEPRECATED_POP |
577 | |
578 | protected: |
579 | _Up __value_; |
580 | |
581 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; |
582 | |
583 | public: |
584 | template <class _Arg> |
585 | _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg); |
586 | |
587 | template <class _Arg> |
588 | _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg); |
589 | |
590 | _LIBCPP_HIDE_FROM_ABI _Rp move(); |
591 | _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy(); |
592 | }; |
593 | |
594 | template <class _Rp> |
595 | void __assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT { |
596 | if (this->__state_ & base::__constructed) |
597 | reinterpret_cast<_Rp*>(&__value_)->~_Rp(); |
598 | delete this; |
599 | } |
600 | |
601 | template <class _Rp> |
602 | template <class _Arg> |
603 | void __assoc_state<_Rp>::set_value(_Arg&& __arg) { |
604 | unique_lock<mutex> __lk(this->__mut_); |
605 | if (this->__has_value()) |
606 | __throw_future_error(future_errc::promise_already_satisfied); |
607 | ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg)); |
608 | this->__state_ |= base::__constructed | base::ready; |
609 | __cv_.notify_all(); |
610 | } |
611 | |
612 | template <class _Rp> |
613 | template <class _Arg> |
614 | void __assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) { |
615 | unique_lock<mutex> __lk(this->__mut_); |
616 | if (this->__has_value()) |
617 | __throw_future_error(future_errc::promise_already_satisfied); |
618 | ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg)); |
619 | this->__state_ |= base::__constructed; |
620 | __thread_local_data()->__make_ready_at_thread_exit(this); |
621 | } |
622 | |
623 | template <class _Rp> |
624 | _Rp __assoc_state<_Rp>::move() { |
625 | unique_lock<mutex> __lk(this->__mut_); |
626 | this->__sub_wait(__lk); |
627 | if (this->__exception_ != nullptr) |
628 | std::rethrow_exception(this->__exception_); |
629 | return std::move(*reinterpret_cast<_Rp*>(&__value_)); |
630 | } |
631 | |
632 | template <class _Rp> |
633 | __add_lvalue_reference_t<_Rp> __assoc_state<_Rp>::copy() { |
634 | unique_lock<mutex> __lk(this->__mut_); |
635 | this->__sub_wait(__lk); |
636 | if (this->__exception_ != nullptr) |
637 | std::rethrow_exception(this->__exception_); |
638 | return *reinterpret_cast<_Rp*>(&__value_); |
639 | } |
640 | |
641 | template <class _Rp> |
642 | class __assoc_state<_Rp&> : public __assoc_sub_state { |
643 | typedef __assoc_sub_state base; |
644 | typedef _Rp* _Up; |
645 | |
646 | protected: |
647 | _Up __value_; |
648 | |
649 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; |
650 | |
651 | public: |
652 | _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg); |
653 | _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg); |
654 | |
655 | _LIBCPP_HIDE_FROM_ABI _Rp& copy(); |
656 | }; |
657 | |
658 | template <class _Rp> |
659 | void __assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT { |
660 | delete this; |
661 | } |
662 | |
663 | template <class _Rp> |
664 | void __assoc_state<_Rp&>::set_value(_Rp& __arg) { |
665 | unique_lock<mutex> __lk(this->__mut_); |
666 | if (this->__has_value()) |
667 | __throw_future_error(future_errc::promise_already_satisfied); |
668 | __value_ = std::addressof(__arg); |
669 | this->__state_ |= base::__constructed | base::ready; |
670 | __cv_.notify_all(); |
671 | } |
672 | |
673 | template <class _Rp> |
674 | void __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) { |
675 | unique_lock<mutex> __lk(this->__mut_); |
676 | if (this->__has_value()) |
677 | __throw_future_error(future_errc::promise_already_satisfied); |
678 | __value_ = std::addressof(__arg); |
679 | this->__state_ |= base::__constructed; |
680 | __thread_local_data()->__make_ready_at_thread_exit(this); |
681 | } |
682 | |
683 | template <class _Rp> |
684 | _Rp& __assoc_state<_Rp&>::copy() { |
685 | unique_lock<mutex> __lk(this->__mut_); |
686 | this->__sub_wait(__lk); |
687 | if (this->__exception_ != nullptr) |
688 | std::rethrow_exception(this->__exception_); |
689 | return *__value_; |
690 | } |
691 | |
692 | template <class _Rp, class _Alloc> |
693 | class __assoc_state_alloc : public __assoc_state<_Rp> { |
694 | typedef __assoc_state<_Rp> base; |
695 | _Alloc __alloc_; |
696 | |
697 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; |
698 | |
699 | public: |
700 | _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {} |
701 | }; |
702 | |
703 | template <class _Rp, class _Alloc> |
704 | void __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT { |
705 | if (this->__state_ & base::__constructed) |
706 | reinterpret_cast<_Rp*>(std::addressof(this->__value_))->~_Rp(); |
707 | typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; |
708 | typedef allocator_traits<_Al> _ATraits; |
709 | typedef pointer_traits<typename _ATraits::pointer> _PTraits; |
710 | _Al __a(__alloc_); |
711 | this->~__assoc_state_alloc(); |
712 | __a.deallocate(_PTraits::pointer_to(*this), 1); |
713 | } |
714 | |
715 | template <class _Rp, class _Alloc> |
716 | class __assoc_state_alloc<_Rp&, _Alloc> : public __assoc_state<_Rp&> { |
717 | typedef __assoc_state<_Rp&> base; |
718 | _Alloc __alloc_; |
719 | |
720 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; |
721 | |
722 | public: |
723 | _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {} |
724 | }; |
725 | |
726 | template <class _Rp, class _Alloc> |
727 | void __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT { |
728 | typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; |
729 | typedef allocator_traits<_Al> _ATraits; |
730 | typedef pointer_traits<typename _ATraits::pointer> _PTraits; |
731 | _Al __a(__alloc_); |
732 | this->~__assoc_state_alloc(); |
733 | __a.deallocate(_PTraits::pointer_to(*this), 1); |
734 | } |
735 | |
736 | template <class _Alloc> |
737 | class __assoc_sub_state_alloc : public __assoc_sub_state { |
738 | typedef __assoc_sub_state base; |
739 | _Alloc __alloc_; |
740 | |
741 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; |
742 | |
743 | public: |
744 | _LIBCPP_HIDE_FROM_ABI explicit __assoc_sub_state_alloc(const _Alloc& __a) : __alloc_(__a) {} |
745 | }; |
746 | |
747 | template <class _Alloc> |
748 | void __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT { |
749 | typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al; |
750 | typedef allocator_traits<_Al> _ATraits; |
751 | typedef pointer_traits<typename _ATraits::pointer> _PTraits; |
752 | _Al __a(__alloc_); |
753 | this->~__assoc_sub_state_alloc(); |
754 | __a.deallocate(_PTraits::pointer_to(*this), 1); |
755 | } |
756 | |
757 | template <class _Rp, class _Fp> |
758 | class __deferred_assoc_state : public __assoc_state<_Rp> { |
759 | typedef __assoc_state<_Rp> base; |
760 | |
761 | _Fp __func_; |
762 | |
763 | public: |
764 | _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f); |
765 | |
766 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute(); |
767 | }; |
768 | |
769 | template <class _Rp, class _Fp> |
770 | inline __deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) { |
771 | this->__set_deferred(); |
772 | } |
773 | |
774 | template <class _Rp, class _Fp> |
775 | void __deferred_assoc_state<_Rp, _Fp>::__execute() { |
776 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
777 | try { |
778 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
779 | this->set_value(__func_()); |
780 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
781 | } catch (...) { |
782 | this->set_exception(current_exception()); |
783 | } |
784 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
785 | } |
786 | |
787 | template <class _Fp> |
788 | class __deferred_assoc_state<void, _Fp> : public __assoc_sub_state { |
789 | typedef __assoc_sub_state base; |
790 | |
791 | _Fp __func_; |
792 | |
793 | public: |
794 | _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f); |
795 | |
796 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override; |
797 | }; |
798 | |
799 | template <class _Fp> |
800 | inline __deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) { |
801 | this->__set_deferred(); |
802 | } |
803 | |
804 | template <class _Fp> |
805 | void __deferred_assoc_state<void, _Fp>::__execute() { |
806 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
807 | try { |
808 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
809 | __func_(); |
810 | this->set_value(); |
811 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
812 | } catch (...) { |
813 | this->set_exception(current_exception()); |
814 | } |
815 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
816 | } |
817 | |
818 | template <class _Rp, class _Fp> |
819 | class __async_assoc_state : public __assoc_state<_Rp> { |
820 | typedef __assoc_state<_Rp> base; |
821 | |
822 | _Fp __func_; |
823 | |
824 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; |
825 | |
826 | public: |
827 | _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f); |
828 | |
829 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute(); |
830 | }; |
831 | |
832 | template <class _Rp, class _Fp> |
833 | inline __async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {} |
834 | |
835 | template <class _Rp, class _Fp> |
836 | void __async_assoc_state<_Rp, _Fp>::__execute() { |
837 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
838 | try { |
839 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
840 | this->set_value(__func_()); |
841 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
842 | } catch (...) { |
843 | this->set_exception(current_exception()); |
844 | } |
845 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
846 | } |
847 | |
848 | template <class _Rp, class _Fp> |
849 | void __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT { |
850 | this->wait(); |
851 | base::__on_zero_shared(); |
852 | } |
853 | |
854 | template <class _Fp> |
855 | class __async_assoc_state<void, _Fp> : public __assoc_sub_state { |
856 | typedef __assoc_sub_state base; |
857 | |
858 | _Fp __func_; |
859 | |
860 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; |
861 | |
862 | public: |
863 | _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f); |
864 | |
865 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override; |
866 | }; |
867 | |
868 | template <class _Fp> |
869 | inline __async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {} |
870 | |
871 | template <class _Fp> |
872 | void __async_assoc_state<void, _Fp>::__execute() { |
873 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
874 | try { |
875 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
876 | __func_(); |
877 | this->set_value(); |
878 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
879 | } catch (...) { |
880 | this->set_exception(current_exception()); |
881 | } |
882 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
883 | } |
884 | |
885 | template <class _Fp> |
886 | void __async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT { |
887 | this->wait(); |
888 | base::__on_zero_shared(); |
889 | } |
890 | |
891 | template <class _Rp> |
892 | class _LIBCPP_TEMPLATE_VIS promise; |
893 | template <class _Rp> |
894 | class _LIBCPP_TEMPLATE_VIS shared_future; |
895 | |
896 | // future |
897 | |
898 | template <class _Rp> |
899 | class _LIBCPP_TEMPLATE_VIS future; |
900 | |
901 | template <class _Rp, class _Fp> |
902 | _LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f); |
903 | |
904 | template <class _Rp, class _Fp> |
905 | _LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f); |
906 | |
907 | template <class _Rp> |
908 | class _LIBCPP_TEMPLATE_VIS future { |
909 | __assoc_state<_Rp>* __state_; |
910 | |
911 | explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state); |
912 | |
913 | template <class> |
914 | friend class promise; |
915 | template <class> |
916 | friend class shared_future; |
917 | |
918 | template <class _R1, class _Fp> |
919 | friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); |
920 | template <class _R1, class _Fp> |
921 | friend future<_R1> __make_async_assoc_state(_Fp&& __f); |
922 | |
923 | public: |
924 | _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {} |
925 | _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } |
926 | future(const future&) = delete; |
927 | future& operator=(const future&) = delete; |
928 | _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT { |
929 | future(std::move(__rhs)).swap(*this); |
930 | return *this; |
931 | } |
932 | |
933 | _LIBCPP_HIDE_FROM_ABI ~future(); |
934 | _LIBCPP_HIDE_FROM_ABI shared_future<_Rp> share() _NOEXCEPT; |
935 | |
936 | // retrieving the value |
937 | _LIBCPP_HIDE_FROM_ABI _Rp get(); |
938 | |
939 | _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } |
940 | |
941 | // functions to check state |
942 | _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } |
943 | |
944 | _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } |
945 | template <class _Rep, class _Period> |
946 | _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { |
947 | return __state_->wait_for(__rel_time); |
948 | } |
949 | template <class _Clock, class _Duration> |
950 | _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { |
951 | return __state_->wait_until(__abs_time); |
952 | } |
953 | }; |
954 | |
955 | template <class _Rp> |
956 | future<_Rp>::future(__assoc_state<_Rp>* __state) : __state_(__state) { |
957 | __state_->__attach_future(); |
958 | } |
959 | |
960 | struct __release_shared_count { |
961 | _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) { __p->__release_shared(); } |
962 | }; |
963 | |
964 | template <class _Rp> |
965 | future<_Rp>::~future() { |
966 | if (__state_) |
967 | __state_->__release_shared(); |
968 | } |
969 | |
970 | template <class _Rp> |
971 | _Rp future<_Rp>::get() { |
972 | unique_ptr<__shared_count, __release_shared_count> __guard(__state_); |
973 | __assoc_state<_Rp>* __s = __state_; |
974 | __state_ = nullptr; |
975 | return __s->move(); |
976 | } |
977 | |
978 | template <class _Rp> |
979 | class _LIBCPP_TEMPLATE_VIS future<_Rp&> { |
980 | __assoc_state<_Rp&>* __state_; |
981 | |
982 | explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state); |
983 | |
984 | template <class> |
985 | friend class promise; |
986 | template <class> |
987 | friend class shared_future; |
988 | |
989 | template <class _R1, class _Fp> |
990 | friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); |
991 | template <class _R1, class _Fp> |
992 | friend future<_R1> __make_async_assoc_state(_Fp&& __f); |
993 | |
994 | public: |
995 | _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {} |
996 | _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } |
997 | future(const future&) = delete; |
998 | future& operator=(const future&) = delete; |
999 | _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT { |
1000 | future(std::move(__rhs)).swap(*this); |
1001 | return *this; |
1002 | } |
1003 | |
1004 | _LIBCPP_HIDE_FROM_ABI ~future(); |
1005 | _LIBCPP_HIDE_FROM_ABI shared_future<_Rp&> share() _NOEXCEPT; |
1006 | |
1007 | // retrieving the value |
1008 | _LIBCPP_HIDE_FROM_ABI _Rp& get(); |
1009 | |
1010 | _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } |
1011 | |
1012 | // functions to check state |
1013 | _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } |
1014 | |
1015 | _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } |
1016 | template <class _Rep, class _Period> |
1017 | _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { |
1018 | return __state_->wait_for(__rel_time); |
1019 | } |
1020 | template <class _Clock, class _Duration> |
1021 | _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { |
1022 | return __state_->wait_until(__abs_time); |
1023 | } |
1024 | }; |
1025 | |
1026 | template <class _Rp> |
1027 | future<_Rp&>::future(__assoc_state<_Rp&>* __state) : __state_(__state) { |
1028 | __state_->__attach_future(); |
1029 | } |
1030 | |
1031 | template <class _Rp> |
1032 | future<_Rp&>::~future() { |
1033 | if (__state_) |
1034 | __state_->__release_shared(); |
1035 | } |
1036 | |
1037 | template <class _Rp> |
1038 | _Rp& future<_Rp&>::get() { |
1039 | unique_ptr<__shared_count, __release_shared_count> __guard(__state_); |
1040 | __assoc_state<_Rp&>* __s = __state_; |
1041 | __state_ = nullptr; |
1042 | return __s->copy(); |
1043 | } |
1044 | |
1045 | template <> |
1046 | class _LIBCPP_EXPORTED_FROM_ABI future<void> { |
1047 | __assoc_sub_state* __state_; |
1048 | |
1049 | explicit future(__assoc_sub_state* __state); |
1050 | |
1051 | template <class> |
1052 | friend class promise; |
1053 | template <class> |
1054 | friend class shared_future; |
1055 | |
1056 | template <class _R1, class _Fp> |
1057 | friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); |
1058 | template <class _R1, class _Fp> |
1059 | friend future<_R1> __make_async_assoc_state(_Fp&& __f); |
1060 | |
1061 | public: |
1062 | _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {} |
1063 | _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } |
1064 | future(const future&) = delete; |
1065 | future& operator=(const future&) = delete; |
1066 | _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT { |
1067 | future(std::move(__rhs)).swap(*this); |
1068 | return *this; |
1069 | } |
1070 | |
1071 | ~future(); |
1072 | _LIBCPP_HIDE_FROM_ABI shared_future<void> share() _NOEXCEPT; |
1073 | |
1074 | // retrieving the value |
1075 | void get(); |
1076 | |
1077 | _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } |
1078 | |
1079 | // functions to check state |
1080 | _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } |
1081 | |
1082 | _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } |
1083 | template <class _Rep, class _Period> |
1084 | _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { |
1085 | return __state_->wait_for(__rel_time); |
1086 | } |
1087 | template <class _Clock, class _Duration> |
1088 | _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { |
1089 | return __state_->wait_until(__abs_time); |
1090 | } |
1091 | }; |
1092 | |
1093 | template <class _Rp> |
1094 | inline _LIBCPP_HIDE_FROM_ABI void swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT { |
1095 | __x.swap(__y); |
1096 | } |
1097 | |
1098 | // promise<R> |
1099 | |
1100 | template <class _Callable> |
1101 | class packaged_task; |
1102 | |
1103 | template <class _Rp> |
1104 | class _LIBCPP_TEMPLATE_VIS promise { |
1105 | __assoc_state<_Rp>* __state_; |
1106 | |
1107 | _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} |
1108 | |
1109 | template <class> |
1110 | friend class packaged_task; |
1111 | |
1112 | public: |
1113 | _LIBCPP_HIDE_FROM_ABI promise(); |
1114 | template <class _Alloc> |
1115 | _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a); |
1116 | _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } |
1117 | promise(const promise& __rhs) = delete; |
1118 | _LIBCPP_HIDE_FROM_ABI ~promise(); |
1119 | |
1120 | // assignment |
1121 | _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT { |
1122 | promise(std::move(__rhs)).swap(*this); |
1123 | return *this; |
1124 | } |
1125 | promise& operator=(const promise& __rhs) = delete; |
1126 | |
1127 | _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } |
1128 | |
1129 | // retrieving the result |
1130 | _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future(); |
1131 | |
1132 | // setting the result |
1133 | _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r); |
1134 | _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r); |
1135 | _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p); |
1136 | |
1137 | // setting the result with deferred notification |
1138 | _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r); |
1139 | _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r); |
1140 | _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p); |
1141 | }; |
1142 | |
1143 | template <class _Rp> |
1144 | promise<_Rp>::promise() : __state_(new __assoc_state<_Rp>) {} |
1145 | |
1146 | template <class _Rp> |
1147 | template <class _Alloc> |
1148 | promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) { |
1149 | typedef __assoc_state_alloc<_Rp, _Alloc> _State; |
1150 | typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; |
1151 | typedef __allocator_destructor<_A2> _D2; |
1152 | _A2 __a(__a0); |
1153 | unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); |
1154 | ::new ((void*)std::addressof(*__hold.get())) _State(__a0); |
1155 | __state_ = std::addressof(*__hold.release()); |
1156 | } |
1157 | |
1158 | template <class _Rp> |
1159 | promise<_Rp>::~promise() { |
1160 | if (__state_) { |
1161 | if (!__state_->__has_value() && __state_->use_count() > 1) |
1162 | __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise)))); |
1163 | __state_->__release_shared(); |
1164 | } |
1165 | } |
1166 | |
1167 | template <class _Rp> |
1168 | future<_Rp> promise<_Rp>::get_future() { |
1169 | if (__state_ == nullptr) |
1170 | __throw_future_error(future_errc::no_state); |
1171 | return future<_Rp>(__state_); |
1172 | } |
1173 | |
1174 | template <class _Rp> |
1175 | void promise<_Rp>::set_value(const _Rp& __r) { |
1176 | if (__state_ == nullptr) |
1177 | __throw_future_error(future_errc::no_state); |
1178 | __state_->set_value(__r); |
1179 | } |
1180 | |
1181 | template <class _Rp> |
1182 | void promise<_Rp>::set_value(_Rp&& __r) { |
1183 | if (__state_ == nullptr) |
1184 | __throw_future_error(future_errc::no_state); |
1185 | __state_->set_value(std::move(__r)); |
1186 | } |
1187 | |
1188 | template <class _Rp> |
1189 | void promise<_Rp>::set_exception(exception_ptr __p) { |
1190 | _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr" ); |
1191 | if (__state_ == nullptr) |
1192 | __throw_future_error(future_errc::no_state); |
1193 | __state_->set_exception(__p); |
1194 | } |
1195 | |
1196 | template <class _Rp> |
1197 | void promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) { |
1198 | if (__state_ == nullptr) |
1199 | __throw_future_error(future_errc::no_state); |
1200 | __state_->set_value_at_thread_exit(__r); |
1201 | } |
1202 | |
1203 | template <class _Rp> |
1204 | void promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) { |
1205 | if (__state_ == nullptr) |
1206 | __throw_future_error(future_errc::no_state); |
1207 | __state_->set_value_at_thread_exit(std::move(__r)); |
1208 | } |
1209 | |
1210 | template <class _Rp> |
1211 | void promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) { |
1212 | _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); |
1213 | if (__state_ == nullptr) |
1214 | __throw_future_error(future_errc::no_state); |
1215 | __state_->set_exception_at_thread_exit(__p); |
1216 | } |
1217 | |
1218 | // promise<R&> |
1219 | |
1220 | template <class _Rp> |
1221 | class _LIBCPP_TEMPLATE_VIS promise<_Rp&> { |
1222 | __assoc_state<_Rp&>* __state_; |
1223 | |
1224 | _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} |
1225 | |
1226 | template <class> |
1227 | friend class packaged_task; |
1228 | |
1229 | public: |
1230 | _LIBCPP_HIDE_FROM_ABI promise(); |
1231 | template <class _Allocator> |
1232 | _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a); |
1233 | _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } |
1234 | promise(const promise& __rhs) = delete; |
1235 | _LIBCPP_HIDE_FROM_ABI ~promise(); |
1236 | |
1237 | // assignment |
1238 | _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT { |
1239 | promise(std::move(__rhs)).swap(*this); |
1240 | return *this; |
1241 | } |
1242 | promise& operator=(const promise& __rhs) = delete; |
1243 | |
1244 | _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } |
1245 | |
1246 | // retrieving the result |
1247 | _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future(); |
1248 | |
1249 | // setting the result |
1250 | _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r); |
1251 | _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p); |
1252 | |
1253 | // setting the result with deferred notification |
1254 | _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&); |
1255 | _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p); |
1256 | }; |
1257 | |
1258 | template <class _Rp> |
1259 | promise<_Rp&>::promise() : __state_(new __assoc_state<_Rp&>) {} |
1260 | |
1261 | template <class _Rp> |
1262 | template <class _Alloc> |
1263 | promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) { |
1264 | typedef __assoc_state_alloc<_Rp&, _Alloc> _State; |
1265 | typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; |
1266 | typedef __allocator_destructor<_A2> _D2; |
1267 | _A2 __a(__a0); |
1268 | unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); |
1269 | ::new ((void*)std::addressof(*__hold.get())) _State(__a0); |
1270 | __state_ = std::addressof(*__hold.release()); |
1271 | } |
1272 | |
1273 | template <class _Rp> |
1274 | promise<_Rp&>::~promise() { |
1275 | if (__state_) { |
1276 | if (!__state_->__has_value() && __state_->use_count() > 1) |
1277 | __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise)))); |
1278 | __state_->__release_shared(); |
1279 | } |
1280 | } |
1281 | |
1282 | template <class _Rp> |
1283 | future<_Rp&> promise<_Rp&>::get_future() { |
1284 | if (__state_ == nullptr) |
1285 | __throw_future_error(future_errc::no_state); |
1286 | return future<_Rp&>(__state_); |
1287 | } |
1288 | |
1289 | template <class _Rp> |
1290 | void promise<_Rp&>::set_value(_Rp& __r) { |
1291 | if (__state_ == nullptr) |
1292 | __throw_future_error(future_errc::no_state); |
1293 | __state_->set_value(__r); |
1294 | } |
1295 | |
1296 | template <class _Rp> |
1297 | void promise<_Rp&>::set_exception(exception_ptr __p) { |
1298 | _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr" ); |
1299 | if (__state_ == nullptr) |
1300 | __throw_future_error(future_errc::no_state); |
1301 | __state_->set_exception(__p); |
1302 | } |
1303 | |
1304 | template <class _Rp> |
1305 | void promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) { |
1306 | if (__state_ == nullptr) |
1307 | __throw_future_error(future_errc::no_state); |
1308 | __state_->set_value_at_thread_exit(__r); |
1309 | } |
1310 | |
1311 | template <class _Rp> |
1312 | void promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) { |
1313 | _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); |
1314 | if (__state_ == nullptr) |
1315 | __throw_future_error(future_errc::no_state); |
1316 | __state_->set_exception_at_thread_exit(__p); |
1317 | } |
1318 | |
1319 | // promise<void> |
1320 | |
1321 | template <> |
1322 | class _LIBCPP_EXPORTED_FROM_ABI promise<void> { |
1323 | __assoc_sub_state* __state_; |
1324 | |
1325 | _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} |
1326 | |
1327 | template <class> |
1328 | friend class packaged_task; |
1329 | |
1330 | public: |
1331 | promise(); |
1332 | template <class _Allocator> |
1333 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS promise(allocator_arg_t, const _Allocator& __a); |
1334 | _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } |
1335 | promise(const promise& __rhs) = delete; |
1336 | ~promise(); |
1337 | |
1338 | // assignment |
1339 | _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT { |
1340 | promise(std::move(__rhs)).swap(*this); |
1341 | return *this; |
1342 | } |
1343 | promise& operator=(const promise& __rhs) = delete; |
1344 | |
1345 | _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } |
1346 | |
1347 | // retrieving the result |
1348 | future<void> get_future(); |
1349 | |
1350 | // setting the result |
1351 | void set_value(); |
1352 | void set_exception(exception_ptr __p); |
1353 | |
1354 | // setting the result with deferred notification |
1355 | void set_value_at_thread_exit(); |
1356 | void set_exception_at_thread_exit(exception_ptr __p); |
1357 | }; |
1358 | |
1359 | template <class _Alloc> |
1360 | promise<void>::promise(allocator_arg_t, const _Alloc& __a0) { |
1361 | typedef __assoc_sub_state_alloc<_Alloc> _State; |
1362 | typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; |
1363 | typedef __allocator_destructor<_A2> _D2; |
1364 | _A2 __a(__a0); |
1365 | unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); |
1366 | ::new ((void*)std::addressof(*__hold.get())) _State(__a0); |
1367 | __state_ = std::addressof(*__hold.release()); |
1368 | } |
1369 | |
1370 | template <class _Rp> |
1371 | inline _LIBCPP_HIDE_FROM_ABI void swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT { |
1372 | __x.swap(__y); |
1373 | } |
1374 | |
1375 | template <class _Rp, class _Alloc> |
1376 | struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc> : public true_type {}; |
1377 | |
1378 | // packaged_task |
1379 | |
1380 | template <class _Fp> |
1381 | class __packaged_task_base; |
1382 | |
1383 | template <class _Rp, class... _ArgTypes> |
1384 | class __packaged_task_base<_Rp(_ArgTypes...)> { |
1385 | public: |
1386 | _LIBCPP_HIDE_FROM_ABI __packaged_task_base() {} |
1387 | __packaged_task_base(const __packaged_task_base&) = delete; |
1388 | __packaged_task_base& operator=(const __packaged_task_base&) = delete; |
1389 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL |
1390 | virtual ~__packaged_task_base() {} |
1391 | virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0; |
1392 | virtual void destroy() = 0; |
1393 | virtual void destroy_deallocate() = 0; |
1394 | virtual _Rp operator()(_ArgTypes&&...) = 0; |
1395 | }; |
1396 | |
1397 | template <class _FD, class _Alloc, class _FB> |
1398 | class __packaged_task_func; |
1399 | |
1400 | template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> |
1401 | class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __packaged_task_base<_Rp(_ArgTypes...)> { |
1402 | __compressed_pair<_Fp, _Alloc> __f_; |
1403 | |
1404 | public: |
1405 | _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {} |
1406 | _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(_Fp&& __f) : __f_(std::move(__f), __default_init_tag()) {} |
1407 | _LIBCPP_HIDE_FROM_ABI __packaged_task_func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {} |
1408 | _LIBCPP_HIDE_FROM_ABI __packaged_task_func(_Fp&& __f, const _Alloc& __a) : __f_(std::move(__f), __a) {} |
1409 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; |
1410 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy(); |
1411 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate(); |
1412 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __args); |
1413 | }; |
1414 | |
1415 | template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> |
1416 | void __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to( |
1417 | __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT { |
1418 | ::new ((void*)__p) __packaged_task_func(std::move(__f_.first()), std::move(__f_.second())); |
1419 | } |
1420 | |
1421 | template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> |
1422 | void __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() { |
1423 | __f_.~__compressed_pair<_Fp, _Alloc>(); |
1424 | } |
1425 | |
1426 | template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> |
1427 | void __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() { |
1428 | typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap; |
1429 | typedef allocator_traits<_Ap> _ATraits; |
1430 | typedef pointer_traits<typename _ATraits::pointer> _PTraits; |
1431 | _Ap __a(__f_.second()); |
1432 | __f_.~__compressed_pair<_Fp, _Alloc>(); |
1433 | __a.deallocate(_PTraits::pointer_to(*this), 1); |
1434 | } |
1435 | |
1436 | template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> |
1437 | _Rp __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) { |
1438 | return std::__invoke(__f_.first(), std::forward<_ArgTypes>(__arg)...); |
1439 | } |
1440 | |
1441 | template <class _Callable> |
1442 | class __packaged_task_function; |
1443 | |
1444 | template <class _Rp, class... _ArgTypes> |
1445 | class __packaged_task_function<_Rp(_ArgTypes...)> { |
1446 | typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; |
1447 | |
1448 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __base* __get_buf() { return (__base*)&__buf_; } |
1449 | |
1450 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
1451 | typename aligned_storage<3 * sizeof(void*)>::type __buf_; |
1452 | _LIBCPP_SUPPRESS_DEPRECATED_POP |
1453 | __base* __f_; |
1454 | |
1455 | public: |
1456 | typedef _Rp result_type; |
1457 | |
1458 | // construct/copy/destroy: |
1459 | _LIBCPP_HIDE_FROM_ABI __packaged_task_function() _NOEXCEPT : __f_(nullptr) {} |
1460 | template <class _Fp> |
1461 | _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f); |
1462 | template <class _Fp, class _Alloc> |
1463 | _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); |
1464 | |
1465 | _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; |
1466 | _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; |
1467 | |
1468 | __packaged_task_function(const __packaged_task_function&) = delete; |
1469 | __packaged_task_function& operator=(const __packaged_task_function&) = delete; |
1470 | |
1471 | _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function(); |
1472 | |
1473 | _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT; |
1474 | |
1475 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; |
1476 | }; |
1477 | |
1478 | template <class _Rp, class... _ArgTypes> |
1479 | __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT { |
1480 | if (__f.__f_ == nullptr) |
1481 | __f_ = nullptr; |
1482 | else if (__f.__f_ == __f.__get_buf()) { |
1483 | __f.__f_->__move_to(__get_buf()); |
1484 | __f_ = (__base*)&__buf_; |
1485 | } else { |
1486 | __f_ = __f.__f_; |
1487 | __f.__f_ = nullptr; |
1488 | } |
1489 | } |
1490 | |
1491 | template <class _Rp, class... _ArgTypes> |
1492 | template <class _Fp> |
1493 | __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) : __f_(nullptr) { |
1494 | typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR; |
1495 | typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; |
1496 | if (sizeof(_FF) <= sizeof(__buf_)) { |
1497 | ::new ((void*)&__buf_) _FF(std::forward<_Fp>(__f)); |
1498 | __f_ = (__base*)&__buf_; |
1499 | } else { |
1500 | typedef allocator<_FF> _Ap; |
1501 | _Ap __a; |
1502 | typedef __allocator_destructor<_Ap> _Dp; |
1503 | unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
1504 | ::new ((void*)__hold.get()) _FF(std::forward<_Fp>(__f), allocator<_FR>(__a)); |
1505 | __f_ = __hold.release(); |
1506 | } |
1507 | } |
1508 | |
1509 | template <class _Rp, class... _ArgTypes> |
1510 | template <class _Fp, class _Alloc> |
1511 | __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_arg_t, const _Alloc& __a0, _Fp&& __f) |
1512 | : __f_(nullptr) { |
1513 | typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR; |
1514 | typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; |
1515 | if (sizeof(_FF) <= sizeof(__buf_)) { |
1516 | __f_ = (__base*)&__buf_; |
1517 | ::new ((void*)__f_) _FF(std::forward<_Fp>(__f)); |
1518 | } else { |
1519 | typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap; |
1520 | _Ap __a(__a0); |
1521 | typedef __allocator_destructor<_Ap> _Dp; |
1522 | unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
1523 | ::new ((void*)std::addressof(*__hold.get())) _FF(std::forward<_Fp>(__f), _Alloc(__a)); |
1524 | __f_ = std::addressof(*__hold.release()); |
1525 | } |
1526 | } |
1527 | |
1528 | template <class _Rp, class... _ArgTypes> |
1529 | __packaged_task_function<_Rp(_ArgTypes...)>& |
1530 | __packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT { |
1531 | if (__f_ == __get_buf()) |
1532 | __f_->destroy(); |
1533 | else if (__f_) |
1534 | __f_->destroy_deallocate(); |
1535 | __f_ = nullptr; |
1536 | if (__f.__f_ == nullptr) |
1537 | __f_ = nullptr; |
1538 | else if (__f.__f_ == __f.__get_buf()) { |
1539 | __f.__f_->__move_to(__get_buf()); |
1540 | __f_ = __get_buf(); |
1541 | } else { |
1542 | __f_ = __f.__f_; |
1543 | __f.__f_ = nullptr; |
1544 | } |
1545 | return *this; |
1546 | } |
1547 | |
1548 | template <class _Rp, class... _ArgTypes> |
1549 | __packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() { |
1550 | if (__f_ == __get_buf()) |
1551 | __f_->destroy(); |
1552 | else if (__f_) |
1553 | __f_->destroy_deallocate(); |
1554 | } |
1555 | |
1556 | template <class _Rp, class... _ArgTypes> |
1557 | _LIBCPP_NO_CFI void __packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT { |
1558 | if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { |
1559 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
1560 | typename aligned_storage<sizeof(__buf_)>::type __tempbuf; |
1561 | _LIBCPP_SUPPRESS_DEPRECATED_POP |
1562 | __base* __t = (__base*)&__tempbuf; |
1563 | __f_->__move_to(__t); |
1564 | __f_->destroy(); |
1565 | __f_ = nullptr; |
1566 | __f.__f_->__move_to((__base*)&__buf_); |
1567 | __f.__f_->destroy(); |
1568 | __f.__f_ = nullptr; |
1569 | __f_ = (__base*)&__buf_; |
1570 | __t->__move_to((__base*)&__f.__buf_); |
1571 | __t->destroy(); |
1572 | __f.__f_ = (__base*)&__f.__buf_; |
1573 | } else if (__f_ == (__base*)&__buf_) { |
1574 | __f_->__move_to((__base*)&__f.__buf_); |
1575 | __f_->destroy(); |
1576 | __f_ = __f.__f_; |
1577 | __f.__f_ = (__base*)&__f.__buf_; |
1578 | } else if (__f.__f_ == (__base*)&__f.__buf_) { |
1579 | __f.__f_->__move_to((__base*)&__buf_); |
1580 | __f.__f_->destroy(); |
1581 | __f.__f_ = __f_; |
1582 | __f_ = (__base*)&__buf_; |
1583 | } else |
1584 | std::swap(__f_, __f.__f_); |
1585 | } |
1586 | |
1587 | template <class _Rp, class... _ArgTypes> |
1588 | inline _Rp __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { |
1589 | return (*__f_)(std::forward<_ArgTypes>(__arg)...); |
1590 | } |
1591 | |
1592 | template <class _Rp, class... _ArgTypes> |
1593 | class _LIBCPP_TEMPLATE_VIS packaged_task<_Rp(_ArgTypes...)> { |
1594 | public: |
1595 | typedef _Rp result_type; // extension |
1596 | |
1597 | private: |
1598 | __packaged_task_function<result_type(_ArgTypes...)> __f_; |
1599 | promise<result_type> __p_; |
1600 | |
1601 | public: |
1602 | // construction and destruction |
1603 | _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {} |
1604 | |
1605 | template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0> |
1606 | _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {} |
1607 | |
1608 | template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0> |
1609 | _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) |
1610 | : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {} |
1611 | // ~packaged_task() = default; |
1612 | |
1613 | // no copy |
1614 | packaged_task(const packaged_task&) = delete; |
1615 | packaged_task& operator=(const packaged_task&) = delete; |
1616 | |
1617 | // move support |
1618 | _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT |
1619 | : __f_(std::move(__other.__f_)), |
1620 | __p_(std::move(__other.__p_)) {} |
1621 | _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT { |
1622 | __f_ = std::move(__other.__f_); |
1623 | __p_ = std::move(__other.__p_); |
1624 | return *this; |
1625 | } |
1626 | _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT { |
1627 | __f_.swap(__other.__f_); |
1628 | __p_.swap(__other.__p_); |
1629 | } |
1630 | |
1631 | _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; } |
1632 | |
1633 | // result retrieval |
1634 | _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); } |
1635 | |
1636 | // execution |
1637 | _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args); |
1638 | _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args); |
1639 | |
1640 | _LIBCPP_HIDE_FROM_ABI void reset(); |
1641 | }; |
1642 | |
1643 | template <class _Rp, class... _ArgTypes> |
1644 | void packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) { |
1645 | if (__p_.__state_ == nullptr) |
1646 | __throw_future_error(future_errc::no_state); |
1647 | if (__p_.__state_->__has_value()) |
1648 | __throw_future_error(future_errc::promise_already_satisfied); |
1649 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
1650 | try { |
1651 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
1652 | __p_.set_value(__f_(std::forward<_ArgTypes>(__args)...)); |
1653 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
1654 | } catch (...) { |
1655 | __p_.set_exception(current_exception()); |
1656 | } |
1657 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
1658 | } |
1659 | |
1660 | template <class _Rp, class... _ArgTypes> |
1661 | void packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) { |
1662 | if (__p_.__state_ == nullptr) |
1663 | __throw_future_error(future_errc::no_state); |
1664 | if (__p_.__state_->__has_value()) |
1665 | __throw_future_error(future_errc::promise_already_satisfied); |
1666 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
1667 | try { |
1668 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
1669 | __p_.set_value_at_thread_exit(__f_(std::forward<_ArgTypes>(__args)...)); |
1670 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
1671 | } catch (...) { |
1672 | __p_.set_exception_at_thread_exit(current_exception()); |
1673 | } |
1674 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
1675 | } |
1676 | |
1677 | template <class _Rp, class... _ArgTypes> |
1678 | void packaged_task<_Rp(_ArgTypes...)>::reset() { |
1679 | if (!valid()) |
1680 | __throw_future_error(future_errc::no_state); |
1681 | __p_ = promise<result_type>(); |
1682 | } |
1683 | |
1684 | template <class... _ArgTypes> |
1685 | class _LIBCPP_TEMPLATE_VIS packaged_task<void(_ArgTypes...)> { |
1686 | public: |
1687 | typedef void result_type; // extension |
1688 | |
1689 | private: |
1690 | __packaged_task_function<result_type(_ArgTypes...)> __f_; |
1691 | promise<result_type> __p_; |
1692 | |
1693 | public: |
1694 | // construction and destruction |
1695 | _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {} |
1696 | template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0> |
1697 | _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {} |
1698 | template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0> |
1699 | _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) |
1700 | : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {} |
1701 | // ~packaged_task() = default; |
1702 | |
1703 | // no copy |
1704 | packaged_task(const packaged_task&) = delete; |
1705 | packaged_task& operator=(const packaged_task&) = delete; |
1706 | |
1707 | // move support |
1708 | _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT |
1709 | : __f_(std::move(__other.__f_)), |
1710 | __p_(std::move(__other.__p_)) {} |
1711 | _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT { |
1712 | __f_ = std::move(__other.__f_); |
1713 | __p_ = std::move(__other.__p_); |
1714 | return *this; |
1715 | } |
1716 | _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT { |
1717 | __f_.swap(__other.__f_); |
1718 | __p_.swap(__other.__p_); |
1719 | } |
1720 | |
1721 | _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; } |
1722 | |
1723 | // result retrieval |
1724 | _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); } |
1725 | |
1726 | // execution |
1727 | _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args); |
1728 | _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args); |
1729 | |
1730 | _LIBCPP_HIDE_FROM_ABI void reset(); |
1731 | }; |
1732 | |
1733 | # if _LIBCPP_STD_VER >= 17 |
1734 | |
1735 | template <class _Rp, class... _Args> |
1736 | packaged_task(_Rp (*)(_Args...)) -> packaged_task<_Rp(_Args...)>; |
1737 | |
1738 | template <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type> |
1739 | packaged_task(_Fp) -> packaged_task<_Stripped>; |
1740 | |
1741 | # endif |
1742 | |
1743 | template <class... _ArgTypes> |
1744 | void packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) { |
1745 | if (__p_.__state_ == nullptr) |
1746 | __throw_future_error(future_errc::no_state); |
1747 | if (__p_.__state_->__has_value()) |
1748 | __throw_future_error(future_errc::promise_already_satisfied); |
1749 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
1750 | try { |
1751 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
1752 | __f_(std::forward<_ArgTypes>(__args)...); |
1753 | __p_.set_value(); |
1754 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
1755 | } catch (...) { |
1756 | __p_.set_exception(current_exception()); |
1757 | } |
1758 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
1759 | } |
1760 | |
1761 | template <class... _ArgTypes> |
1762 | void packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) { |
1763 | if (__p_.__state_ == nullptr) |
1764 | __throw_future_error(future_errc::no_state); |
1765 | if (__p_.__state_->__has_value()) |
1766 | __throw_future_error(future_errc::promise_already_satisfied); |
1767 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
1768 | try { |
1769 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
1770 | __f_(std::forward<_ArgTypes>(__args)...); |
1771 | __p_.set_value_at_thread_exit(); |
1772 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
1773 | } catch (...) { |
1774 | __p_.set_exception_at_thread_exit(current_exception()); |
1775 | } |
1776 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS |
1777 | } |
1778 | |
1779 | template <class... _ArgTypes> |
1780 | void packaged_task<void(_ArgTypes...)>::reset() { |
1781 | if (!valid()) |
1782 | __throw_future_error(future_errc::no_state); |
1783 | __p_ = promise<result_type>(); |
1784 | } |
1785 | |
1786 | template <class _Rp, class... _ArgTypes> |
1787 | inline _LIBCPP_HIDE_FROM_ABI void |
1788 | swap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT { |
1789 | __x.swap(__y); |
1790 | } |
1791 | |
1792 | template <class _Callable, class _Alloc> |
1793 | struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {}; |
1794 | |
1795 | template <class _Rp, class _Fp> |
1796 | _LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f) { |
1797 | unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> __h( |
1798 | new __deferred_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f))); |
1799 | return future<_Rp>(__h.get()); |
1800 | } |
1801 | |
1802 | template <class _Rp, class _Fp> |
1803 | _LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f) { |
1804 | unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> __h( |
1805 | new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f))); |
1806 | std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach(); |
1807 | return future<_Rp>(__h.get()); |
1808 | } |
1809 | |
1810 | # ifndef _LIBCPP_CXX03_LANG |
1811 | |
1812 | template <class _Fp, class... _Args> |
1813 | class _LIBCPP_HIDDEN __async_func { |
1814 | tuple<_Fp, _Args...> __f_; |
1815 | |
1816 | public: |
1817 | typedef typename __invoke_of<_Fp, _Args...>::type _Rp; |
1818 | |
1819 | _LIBCPP_HIDE_FROM_ABI explicit __async_func(_Fp&& __f, _Args&&... __args) |
1820 | : __f_(std::move(__f), std::move(__args)...) {} |
1821 | |
1822 | _LIBCPP_HIDE_FROM_ABI __async_func(__async_func&& __f) : __f_(std::move(__f.__f_)) {} |
1823 | |
1824 | _LIBCPP_HIDE_FROM_ABI _Rp operator()() { |
1825 | typedef typename __make_tuple_indices<1 + sizeof...(_Args), 1>::type _Index; |
1826 | return __execute(_Index()); |
1827 | } |
1828 | |
1829 | private: |
1830 | template <size_t... _Indices> |
1831 | _LIBCPP_HIDE_FROM_ABI _Rp __execute(__tuple_indices<_Indices...>) { |
1832 | return std::__invoke(std::move(std::get<0>(__f_)), std::move(std::get<_Indices>(__f_))...); |
1833 | } |
1834 | }; |
1835 | |
1836 | inline _LIBCPP_HIDE_FROM_ABI bool __does_policy_contain(launch __policy, launch __value) { |
1837 | return (int(__policy) & int(__value)) != 0; |
1838 | } |
1839 | |
1840 | template <class _Fp, class... _Args> |
1841 | _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type> |
1842 | async(launch __policy, _Fp&& __f, _Args&&... __args) { |
1843 | typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF; |
1844 | typedef typename _BF::_Rp _Rp; |
1845 | |
1846 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
1847 | try { |
1848 | # endif |
1849 | if (__does_policy_contain(__policy, launch::async)) |
1850 | return std::__make_async_assoc_state<_Rp>( |
1851 | _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...)); |
1852 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
1853 | } catch (...) { |
1854 | if (__policy == launch::async) |
1855 | throw; |
1856 | } |
1857 | # endif |
1858 | |
1859 | if (__does_policy_contain(__policy, launch::deferred)) |
1860 | return std::__make_deferred_assoc_state<_Rp>( |
1861 | _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...)); |
1862 | return future<_Rp>{}; |
1863 | } |
1864 | |
1865 | template <class _Fp, class... _Args> |
1866 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type> |
1867 | async(_Fp&& __f, _Args&&... __args) { |
1868 | return std::async(launch::any, std::forward<_Fp>(__f), std::forward<_Args>(__args)...); |
1869 | } |
1870 | |
1871 | # endif // C++03 |
1872 | |
1873 | // shared_future |
1874 | |
1875 | template <class _Rp> |
1876 | class _LIBCPP_TEMPLATE_VIS shared_future { |
1877 | __assoc_state<_Rp>* __state_; |
1878 | |
1879 | public: |
1880 | _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {} |
1881 | _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { |
1882 | if (__state_) |
1883 | __state_->__add_shared(); |
1884 | } |
1885 | _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; } |
1886 | _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { |
1887 | __rhs.__state_ = nullptr; |
1888 | } |
1889 | _LIBCPP_HIDE_FROM_ABI ~shared_future(); |
1890 | _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT; |
1891 | _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT { |
1892 | shared_future(std::move(__rhs)).swap(*this); |
1893 | return *this; |
1894 | } |
1895 | |
1896 | // retrieving the value |
1897 | _LIBCPP_HIDE_FROM_ABI const _Rp& get() const { return __state_->copy(); } |
1898 | |
1899 | _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } |
1900 | |
1901 | // functions to check state |
1902 | _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } |
1903 | |
1904 | _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } |
1905 | template <class _Rep, class _Period> |
1906 | _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { |
1907 | return __state_->wait_for(__rel_time); |
1908 | } |
1909 | template <class _Clock, class _Duration> |
1910 | _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { |
1911 | return __state_->wait_until(__abs_time); |
1912 | } |
1913 | }; |
1914 | |
1915 | template <class _Rp> |
1916 | shared_future<_Rp>::~shared_future() { |
1917 | if (__state_) |
1918 | __state_->__release_shared(); |
1919 | } |
1920 | |
1921 | template <class _Rp> |
1922 | shared_future<_Rp>& shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT { |
1923 | if (__rhs.__state_) |
1924 | __rhs.__state_->__add_shared(); |
1925 | if (__state_) |
1926 | __state_->__release_shared(); |
1927 | __state_ = __rhs.__state_; |
1928 | return *this; |
1929 | } |
1930 | |
1931 | template <class _Rp> |
1932 | class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&> { |
1933 | __assoc_state<_Rp&>* __state_; |
1934 | |
1935 | public: |
1936 | _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {} |
1937 | _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) { |
1938 | if (__state_) |
1939 | __state_->__add_shared(); |
1940 | } |
1941 | _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; } |
1942 | _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { |
1943 | __rhs.__state_ = nullptr; |
1944 | } |
1945 | _LIBCPP_HIDE_FROM_ABI ~shared_future(); |
1946 | _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs); |
1947 | _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT { |
1948 | shared_future(std::move(__rhs)).swap(*this); |
1949 | return *this; |
1950 | } |
1951 | |
1952 | // retrieving the value |
1953 | _LIBCPP_HIDE_FROM_ABI _Rp& get() const { return __state_->copy(); } |
1954 | |
1955 | _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } |
1956 | |
1957 | // functions to check state |
1958 | _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } |
1959 | |
1960 | _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } |
1961 | template <class _Rep, class _Period> |
1962 | _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { |
1963 | return __state_->wait_for(__rel_time); |
1964 | } |
1965 | template <class _Clock, class _Duration> |
1966 | _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { |
1967 | return __state_->wait_until(__abs_time); |
1968 | } |
1969 | }; |
1970 | |
1971 | template <class _Rp> |
1972 | shared_future<_Rp&>::~shared_future() { |
1973 | if (__state_) |
1974 | __state_->__release_shared(); |
1975 | } |
1976 | |
1977 | template <class _Rp> |
1978 | shared_future<_Rp&>& shared_future<_Rp&>::operator=(const shared_future& __rhs) { |
1979 | if (__rhs.__state_) |
1980 | __rhs.__state_->__add_shared(); |
1981 | if (__state_) |
1982 | __state_->__release_shared(); |
1983 | __state_ = __rhs.__state_; |
1984 | return *this; |
1985 | } |
1986 | |
1987 | template <> |
1988 | class _LIBCPP_EXPORTED_FROM_ABI shared_future<void> { |
1989 | __assoc_sub_state* __state_; |
1990 | |
1991 | public: |
1992 | _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {} |
1993 | _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) { |
1994 | if (__state_) |
1995 | __state_->__add_shared(); |
1996 | } |
1997 | _LIBCPP_HIDE_FROM_ABI shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; } |
1998 | _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { |
1999 | __rhs.__state_ = nullptr; |
2000 | } |
2001 | ~shared_future(); |
2002 | shared_future& operator=(const shared_future& __rhs); |
2003 | _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT { |
2004 | shared_future(std::move(__rhs)).swap(*this); |
2005 | return *this; |
2006 | } |
2007 | |
2008 | // retrieving the value |
2009 | _LIBCPP_HIDE_FROM_ABI void get() const { __state_->copy(); } |
2010 | |
2011 | _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } |
2012 | |
2013 | // functions to check state |
2014 | _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } |
2015 | |
2016 | _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } |
2017 | template <class _Rep, class _Period> |
2018 | _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { |
2019 | return __state_->wait_for(__rel_time); |
2020 | } |
2021 | template <class _Clock, class _Duration> |
2022 | _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { |
2023 | return __state_->wait_until(__abs_time); |
2024 | } |
2025 | }; |
2026 | |
2027 | template <class _Rp> |
2028 | inline _LIBCPP_HIDE_FROM_ABI void swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT { |
2029 | __x.swap(__y); |
2030 | } |
2031 | |
2032 | template <class _Rp> |
2033 | inline shared_future<_Rp> future<_Rp>::share() _NOEXCEPT { |
2034 | return shared_future<_Rp>(std::move(*this)); |
2035 | } |
2036 | |
2037 | template <class _Rp> |
2038 | inline shared_future<_Rp&> future<_Rp&>::share() _NOEXCEPT { |
2039 | return shared_future<_Rp&>(std::move(*this)); |
2040 | } |
2041 | |
2042 | inline shared_future<void> future<void>::share() _NOEXCEPT { return shared_future<void>(std::move(*this)); } |
2043 | |
2044 | _LIBCPP_END_NAMESPACE_STD |
2045 | |
2046 | _LIBCPP_POP_MACROS |
2047 | |
2048 | #endif // !defined(_LIBCPP_HAS_NO_THREADS) |
2049 | |
2050 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17 |
2051 | # include <chrono> |
2052 | #endif |
2053 | |
2054 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
2055 | # include <atomic> |
2056 | # include <cstdlib> |
2057 | # include <exception> |
2058 | # include <iosfwd> |
2059 | # include <system_error> |
2060 | #endif |
2061 | |
2062 | #endif // _LIBCPP_FUTURE |
2063 | |