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...)>&) noexcept; 358 359 template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; 360 361 } // std 362 363 */ 364 365 #include <__config> 366 #include <system_error> 367 #include <memory> 368 #include <chrono> 369 #include <exception> 370 #include <mutex> 371 #include <thread> 372 373 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 374 #pragma GCC system_header 375 #endif 376 377 _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) const; 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) const 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>::type _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_satisfied)); 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_satisfied)); 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_satisfied)); 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_satisfied)); 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) const 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) const 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) const 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), _D2(__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) _NOEXCEPT 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&) = delete; 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) const 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_satisfied)); 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_satisfied)); 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_satisfied)); 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_satisfied)); 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 _Index; 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, launch __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>::type...>::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::forward<_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::forward<_Fp>(__f)), 2358 __decay_copy(_VSTD::forward<_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>::type...>::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.__state_);} 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) const 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.__state_);} 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) const 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.__state_);} 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) const 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 2616