Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: third_party/libcxx/include/future

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

Powered by Google App Engine
This is Rietveld 408576698