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 broken_promise, 23 future_already_retrieved, 24 promise_already_satisfied, 25 no_state 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<F(Args...)>::type> 313 async(F&& f, Args&&... args); 314 315 template <class F, class... Args> 316 future<typename result_of<F(Args...)>::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 broken_promise, 383 future_already_retrieved, 384 promise_already_satisfied, 385 no_state 386 }; 387 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc) 388 389 template <> 390 struct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {}; 391 392 #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS 393 template <> 394 struct _LIBCPP_VISIBLE 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 //enum class future_status 407 _LIBCPP_DECLARE_STRONG_ENUM(future_status) 408 { 409 ready, 410 timeout, 411 deferred 412 }; 413 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status) 414 415 _LIBCPP_VISIBLE 416 const error_category& future_category() _NOEXCEPT; 417 418 inline _LIBCPP_INLINE_VISIBILITY 419 error_code 420 make_error_code(future_errc __e) _NOEXCEPT 421 { 422 return error_code(static_cast<int>(__e), future_category()); 423 } 424 425 inline _LIBCPP_INLINE_VISIBILITY 426 error_condition 427 make_error_condition(future_errc __e) _NOEXCEPT 428 { 429 return error_condition(static_cast<int>(__e), future_category()); 430 } 431 432 class _LIBCPP_EXCEPTION_ABI future_error 433 : public logic_error 434 { 435 error_code __ec_; 436 public: 437 future_error(error_code __ec); 438 439 _LIBCPP_INLINE_VISIBILITY 440 const error_code& code() const _NOEXCEPT {return __ec_;} 441 442 virtual ~future_error() _NOEXCEPT; 443 }; 444 445 class __assoc_sub_state 446 : public __shared_count 447 { 448 protected: 449 exception_ptr __exception_; 450 mutable mutex __mut_; 451 mutable condition_variable __cv_; 452 unsigned __state_; 453 454 virtual void __on_zero_shared() _NOEXCEPT; 455 void __sub_wait(unique_lock<mutex>& __lk); 456 public: 457 enum 458 { 459 __constructed = 1, 460 __future_attached = 2, 461 ready = 4, 462 deferred = 8 463 }; 464 465 _LIBCPP_INLINE_VISIBILITY 466 __assoc_sub_state() : __state_(0) {} 467 468 _LIBCPP_INLINE_VISIBILITY 469 bool __has_value() const 470 {return (__state_ & __constructed) || (__exception_ != nullptr);} 471 472 _LIBCPP_INLINE_VISIBILITY 473 void __set_future_attached() 474 { 475 lock_guard<mutex> __lk(__mut_); 476 __state_ |= __future_attached; 477 } 478 _LIBCPP_INLINE_VISIBILITY 479 bool __has_future_attached() const {return __state_ & __future_attached;} 480 481 _LIBCPP_INLINE_VISIBILITY 482 void __set_deferred() {__state_ |= deferred;} 483 484 void __make_ready(); 485 _LIBCPP_INLINE_VISIBILITY 486 bool __is_ready() const {return __state_ & ready;} 487 488 void set_value(); 489 void set_value_at_thread_exit(); 490 491 void set_exception(exception_ptr __p); 492 void set_exception_at_thread_exit(exception_ptr __p); 493 494 void copy(); 495 496 void wait(); 497 template <class _Rep, class _Period> 498 future_status 499 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; 500 template <class _Clock, class _Duration> 501 future_status 502 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const; 503 504 virtual void __execute(); 505 }; 506 507 template <class _Clock, class _Duration> 508 future_status 509 __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 510 { 511 unique_lock<mutex> __lk(__mut_); 512 if (__state_ & deferred) 513 return future_status::deferred; 514 while (!(__state_ & ready) && _Clock::now() < __abs_time) 515 __cv_.wait_until(__lk, __abs_time); 516 if (__state_ & ready) 517 return future_status::ready; 518 return future_status::timeout; 519 } 520 521 template <class _Rep, class _Period> 522 inline _LIBCPP_INLINE_VISIBILITY 523 future_status 524 __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 525 { 526 return wait_until(chrono::steady_clock::now() + __rel_time); 527 } 528 529 template <class _Rp> 530 class __assoc_state 531 : public __assoc_sub_state 532 { 533 typedef __assoc_sub_state base; 534 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up; 535 protected: 536 _Up __value_; 537 538 virtual void __on_zero_shared() _NOEXCEPT; 539 public: 540 541 template <class _Arg> 542 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 543 void set_value(_Arg&& __arg); 544 #else 545 void set_value(_Arg& __arg); 546 #endif 547 548 template <class _Arg> 549 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 550 void set_value_at_thread_exit(_Arg&& __arg); 551 #else 552 void set_value_at_thread_exit(_Arg& __arg); 553 #endif 554 555 _Rp move(); 556 typename add_lvalue_reference<_Rp>::type copy(); 557 }; 558 559 template <class _Rp> 560 void 561 __assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT 562 { 563 if (this->__state_ & base::__constructed) 564 reinterpret_cast<_Rp*>(&__value_)->~_Rp(); 565 delete this; 566 } 567 568 template <class _Rp> 569 template <class _Arg> 570 void 571 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 572 __assoc_state<_Rp>::set_value(_Arg&& __arg) 573 #else 574 __assoc_state<_Rp>::set_value(_Arg& __arg) 575 #endif 576 { 577 unique_lock<mutex> __lk(this->__mut_); 578 #ifndef _LIBCPP_NO_EXCEPTIONS 579 if (this->__has_value()) 580 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 581 #endif 582 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); 583 this->__state_ |= base::__constructed | base::ready; 584 __lk.unlock(); 585 __cv_.notify_all(); 586 } 587 588 template <class _Rp> 589 template <class _Arg> 590 void 591 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 592 __assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) 593 #else 594 __assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg) 595 #endif 596 { 597 unique_lock<mutex> __lk(this->__mut_); 598 #ifndef _LIBCPP_NO_EXCEPTIONS 599 if (this->__has_value()) 600 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 601 #endif 602 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg)); 603 this->__state_ |= base::__constructed; 604 __thread_local_data()->__make_ready_at_thread_exit(this); 605 __lk.unlock(); 606 } 607 608 template <class _Rp> 609 _Rp 610 __assoc_state<_Rp>::move() 611 { 612 unique_lock<mutex> __lk(this->__mut_); 613 this->__sub_wait(__lk); 614 if (this->__exception_ != nullptr) 615 rethrow_exception(this->__exception_); 616 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_)); 617 } 618 619 template <class _Rp> 620 typename add_lvalue_reference<_Rp>::type 621 __assoc_state<_Rp>::copy() 622 { 623 unique_lock<mutex> __lk(this->__mut_); 624 this->__sub_wait(__lk); 625 if (this->__exception_ != nullptr) 626 rethrow_exception(this->__exception_); 627 return *reinterpret_cast<_Rp*>(&__value_); 628 } 629 630 template <class _Rp> 631 class __assoc_state<_Rp&> 632 : public __assoc_sub_state 633 { 634 typedef __assoc_sub_state base; 635 typedef _Rp* _Up; 636 protected: 637 _Up __value_; 638 639 virtual void __on_zero_shared() _NOEXCEPT; 640 public: 641 642 void set_value(_Rp& __arg); 643 void set_value_at_thread_exit(_Rp& __arg); 644 645 _Rp& copy(); 646 }; 647 648 template <class _Rp> 649 void 650 __assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT 651 { 652 delete this; 653 } 654 655 template <class _Rp> 656 void 657 __assoc_state<_Rp&>::set_value(_Rp& __arg) 658 { 659 unique_lock<mutex> __lk(this->__mut_); 660 #ifndef _LIBCPP_NO_EXCEPTIONS 661 if (this->__has_value()) 662 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 663 #endif 664 __value_ = &__arg; 665 this->__state_ |= base::__constructed | base::ready; 666 __lk.unlock(); 667 __cv_.notify_all(); 668 } 669 670 template <class _Rp> 671 void 672 __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) 673 { 674 unique_lock<mutex> __lk(this->__mut_); 675 #ifndef _LIBCPP_NO_EXCEPTIONS 676 if (this->__has_value()) 677 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 678 #endif 679 __value_ = &__arg; 680 this->__state_ |= base::__constructed; 681 __thread_local_data()->__make_ready_at_thread_exit(this); 682 __lk.unlock(); 683 } 684 685 template <class _Rp> 686 _Rp& 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 *__value_; 694 } 695 696 template <class _Rp, class _Alloc> 697 class __assoc_state_alloc 698 : public __assoc_state<_Rp> 699 { 700 typedef __assoc_state<_Rp> base; 701 _Alloc __alloc_; 702 703 virtual void __on_zero_shared() _NOEXCEPT; 704 public: 705 _LIBCPP_INLINE_VISIBILITY 706 explicit __assoc_state_alloc(const _Alloc& __a) 707 : __alloc_(__a) {} 708 }; 709 710 template <class _Rp, class _Alloc> 711 void 712 __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT 713 { 714 if (this->__state_ & base::__constructed) 715 reinterpret_cast<_Rp*>(&this->__value_)->~_Rp(); 716 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_); 717 this->~__assoc_state_alloc(); 718 __a.deallocate(this, 1); 719 } 720 721 template <class _Rp, class _Alloc> 722 class __assoc_state_alloc<_Rp&, _Alloc> 723 : public __assoc_state<_Rp&> 724 { 725 typedef __assoc_state<_Rp&> base; 726 _Alloc __alloc_; 727 728 virtual void __on_zero_shared() _NOEXCEPT; 729 public: 730 _LIBCPP_INLINE_VISIBILITY 731 explicit __assoc_state_alloc(const _Alloc& __a) 732 : __alloc_(__a) {} 733 }; 734 735 template <class _Rp, class _Alloc> 736 void 737 __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT 738 { 739 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_); 740 this->~__assoc_state_alloc(); 741 __a.deallocate(this, 1); 742 } 743 744 template <class _Alloc> 745 class __assoc_sub_state_alloc 746 : public __assoc_sub_state 747 { 748 typedef __assoc_sub_state base; 749 _Alloc __alloc_; 750 751 virtual void __on_zero_shared() _NOEXCEPT; 752 public: 753 _LIBCPP_INLINE_VISIBILITY 754 explicit __assoc_sub_state_alloc(const _Alloc& __a) 755 : __alloc_(__a) {} 756 }; 757 758 template <class _Alloc> 759 void 760 __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT 761 { 762 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_); 763 this->~__assoc_sub_state_alloc(); 764 __a.deallocate(this, 1); 765 } 766 767 template <class _Rp, class _Fp> 768 class __deferred_assoc_state 769 : public __assoc_state<_Rp> 770 { 771 typedef __assoc_state<_Rp> base; 772 773 _Fp __func_; 774 775 public: 776 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 777 explicit __deferred_assoc_state(_Fp&& __f); 778 #endif 779 780 virtual void __execute(); 781 }; 782 783 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 784 785 template <class _Rp, class _Fp> 786 inline _LIBCPP_INLINE_VISIBILITY 787 __deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) 788 : __func_(_VSTD::forward<_Fp>(__f)) 789 { 790 this->__set_deferred(); 791 } 792 793 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 794 795 template <class _Rp, class _Fp> 796 void 797 __deferred_assoc_state<_Rp, _Fp>::__execute() 798 { 799 #ifndef _LIBCPP_NO_EXCEPTIONS 800 try 801 { 802 #endif // _LIBCPP_NO_EXCEPTIONS 803 this->set_value(__func_()); 804 #ifndef _LIBCPP_NO_EXCEPTIONS 805 } 806 catch (...) 807 { 808 this->set_exception(current_exception()); 809 } 810 #endif // _LIBCPP_NO_EXCEPTIONS 811 } 812 813 template <class _Fp> 814 class __deferred_assoc_state<void, _Fp> 815 : public __assoc_sub_state 816 { 817 typedef __assoc_sub_state base; 818 819 _Fp __func_; 820 821 public: 822 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 823 explicit __deferred_assoc_state(_Fp&& __f); 824 #endif 825 826 virtual void __execute(); 827 }; 828 829 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 830 831 template <class _Fp> 832 inline _LIBCPP_INLINE_VISIBILITY 833 __deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) 834 : __func_(_VSTD::forward<_Fp>(__f)) 835 { 836 this->__set_deferred(); 837 } 838 839 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 840 841 template <class _Fp> 842 void 843 __deferred_assoc_state<void, _Fp>::__execute() 844 { 845 #ifndef _LIBCPP_NO_EXCEPTIONS 846 try 847 { 848 #endif // _LIBCPP_NO_EXCEPTIONS 849 __func_(); 850 this->set_value(); 851 #ifndef _LIBCPP_NO_EXCEPTIONS 852 } 853 catch (...) 854 { 855 this->set_exception(current_exception()); 856 } 857 #endif // _LIBCPP_NO_EXCEPTIONS 858 } 859 860 template <class _Rp, class _Fp> 861 class __async_assoc_state 862 : public __assoc_state<_Rp> 863 { 864 typedef __assoc_state<_Rp> base; 865 866 _Fp __func_; 867 868 virtual void __on_zero_shared() _NOEXCEPT; 869 public: 870 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 871 explicit __async_assoc_state(_Fp&& __f); 872 #endif 873 874 virtual void __execute(); 875 }; 876 877 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 878 879 template <class _Rp, class _Fp> 880 inline _LIBCPP_INLINE_VISIBILITY 881 __async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) 882 : __func_(_VSTD::forward<_Fp>(__f)) 883 { 884 } 885 886 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 887 888 template <class _Rp, class _Fp> 889 void 890 __async_assoc_state<_Rp, _Fp>::__execute() 891 { 892 #ifndef _LIBCPP_NO_EXCEPTIONS 893 try 894 { 895 #endif // _LIBCPP_NO_EXCEPTIONS 896 this->set_value(__func_()); 897 #ifndef _LIBCPP_NO_EXCEPTIONS 898 } 899 catch (...) 900 { 901 this->set_exception(current_exception()); 902 } 903 #endif // _LIBCPP_NO_EXCEPTIONS 904 } 905 906 template <class _Rp, class _Fp> 907 void 908 __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT 909 { 910 this->wait(); 911 base::__on_zero_shared(); 912 } 913 914 template <class _Fp> 915 class __async_assoc_state<void, _Fp> 916 : public __assoc_sub_state 917 { 918 typedef __assoc_sub_state base; 919 920 _Fp __func_; 921 922 virtual void __on_zero_shared() _NOEXCEPT; 923 public: 924 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 925 explicit __async_assoc_state(_Fp&& __f); 926 #endif 927 928 virtual void __execute(); 929 }; 930 931 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 932 933 template <class _Fp> 934 inline _LIBCPP_INLINE_VISIBILITY 935 __async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) 936 : __func_(_VSTD::forward<_Fp>(__f)) 937 { 938 } 939 940 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 941 942 template <class _Fp> 943 void 944 __async_assoc_state<void, _Fp>::__execute() 945 { 946 #ifndef _LIBCPP_NO_EXCEPTIONS 947 try 948 { 949 #endif // _LIBCPP_NO_EXCEPTIONS 950 __func_(); 951 this->set_value(); 952 #ifndef _LIBCPP_NO_EXCEPTIONS 953 } 954 catch (...) 955 { 956 this->set_exception(current_exception()); 957 } 958 #endif // _LIBCPP_NO_EXCEPTIONS 959 } 960 961 template <class _Fp> 962 void 963 __async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT 964 { 965 this->wait(); 966 base::__on_zero_shared(); 967 } 968 969 template <class _Rp> class _LIBCPP_VISIBLE promise; 970 template <class _Rp> class _LIBCPP_VISIBLE shared_future; 971 972 // future 973 974 template <class _Rp> class _LIBCPP_VISIBLE future; 975 976 template <class _Rp, class _Fp> 977 future<_Rp> 978 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 979 __make_deferred_assoc_state(_Fp&& __f); 980 #else 981 __make_deferred_assoc_state(_Fp __f); 982 #endif 983 984 template <class _Rp, class _Fp> 985 future<_Rp> 986 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 987 __make_async_assoc_state(_Fp&& __f); 988 #else 989 __make_async_assoc_state(_Fp __f); 990 #endif 991 992 template <class _Rp> 993 class _LIBCPP_VISIBLE future 994 { 995 __assoc_state<_Rp>* __state_; 996 997 explicit future(__assoc_state<_Rp>* __state); 998 999 template <class> friend class promise; 1000 template <class> friend class shared_future; 1001 1002 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1003 template <class _R1, class _Fp> 1004 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 1005 template <class _R1, class _Fp> 1006 friend future<_R1> __make_async_assoc_state(_Fp&& __f); 1007 #else 1008 template <class _R1, class _Fp> 1009 friend future<_R1> __make_deferred_assoc_state(_Fp __f); 1010 template <class _R1, class _Fp> 1011 friend future<_R1> __make_async_assoc_state(_Fp __f); 1012 #endif 1013 1014 public: 1015 _LIBCPP_INLINE_VISIBILITY 1016 future() _NOEXCEPT : __state_(nullptr) {} 1017 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1018 _LIBCPP_INLINE_VISIBILITY 1019 future(future&& __rhs) _NOEXCEPT 1020 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1021 future(const future&) = delete; 1022 future& operator=(const future&) = delete; 1023 _LIBCPP_INLINE_VISIBILITY 1024 future& operator=(future&& __rhs) _NOEXCEPT 1025 { 1026 future(std::move(__rhs)).swap(*this); 1027 return *this; 1028 } 1029 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1030 private: 1031 future(const future&); 1032 future& operator=(const future&); 1033 public: 1034 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1035 ~future(); 1036 shared_future<_Rp> share(); 1037 1038 // retrieving the value 1039 _Rp get(); 1040 1041 _LIBCPP_INLINE_VISIBILITY 1042 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1043 1044 // functions to check state 1045 _LIBCPP_INLINE_VISIBILITY 1046 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 1047 1048 _LIBCPP_INLINE_VISIBILITY 1049 void wait() const {__state_->wait();} 1050 template <class _Rep, class _Period> 1051 _LIBCPP_INLINE_VISIBILITY 1052 future_status 1053 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 1054 {return __state_->wait_for(__rel_time);} 1055 template <class _Clock, class _Duration> 1056 _LIBCPP_INLINE_VISIBILITY 1057 future_status 1058 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 1059 {return __state_->wait_until(__abs_time);} 1060 }; 1061 1062 template <class _Rp> 1063 future<_Rp>::future(__assoc_state<_Rp>* __state) 1064 : __state_(__state) 1065 { 1066 #ifndef _LIBCPP_NO_EXCEPTIONS 1067 if (__state_->__has_future_attached()) 1068 throw future_error(make_error_code(future_errc::future_already_retrieved)); 1069 #endif 1070 __state_->__add_shared(); 1071 __state_->__set_future_attached(); 1072 } 1073 1074 struct __release_shared_count 1075 { 1076 void operator()(__shared_count* p) {p->__release_shared();} 1077 }; 1078 1079 template <class _Rp> 1080 future<_Rp>::~future() 1081 { 1082 if (__state_) 1083 __state_->__release_shared(); 1084 } 1085 1086 template <class _Rp> 1087 _Rp 1088 future<_Rp>::get() 1089 { 1090 unique_ptr<__shared_count, __release_shared_count> __(__state_); 1091 __assoc_state<_Rp>* __s = __state_; 1092 __state_ = nullptr; 1093 return __s->move(); 1094 } 1095 1096 template <class _Rp> 1097 class _LIBCPP_VISIBLE future<_Rp&> 1098 { 1099 __assoc_state<_Rp&>* __state_; 1100 1101 explicit future(__assoc_state<_Rp&>* __state); 1102 1103 template <class> friend class promise; 1104 template <class> friend class shared_future; 1105 1106 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1107 template <class _R1, class _Fp> 1108 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 1109 template <class _R1, class _Fp> 1110 friend future<_R1> __make_async_assoc_state(_Fp&& __f); 1111 #else 1112 template <class _R1, class _Fp> 1113 friend future<_R1> __make_deferred_assoc_state(_Fp __f); 1114 template <class _R1, class _Fp> 1115 friend future<_R1> __make_async_assoc_state(_Fp __f); 1116 #endif 1117 1118 public: 1119 _LIBCPP_INLINE_VISIBILITY 1120 future() _NOEXCEPT : __state_(nullptr) {} 1121 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1122 _LIBCPP_INLINE_VISIBILITY 1123 future(future&& __rhs) _NOEXCEPT 1124 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1125 future(const future&) = delete; 1126 future& operator=(const future&) = delete; 1127 _LIBCPP_INLINE_VISIBILITY 1128 future& operator=(future&& __rhs) _NOEXCEPT 1129 { 1130 future(std::move(__rhs)).swap(*this); 1131 return *this; 1132 } 1133 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1134 private: 1135 future(const future&); 1136 future& operator=(const future&); 1137 public: 1138 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1139 ~future(); 1140 shared_future<_Rp&> share(); 1141 1142 // retrieving the value 1143 _Rp& get(); 1144 1145 _LIBCPP_INLINE_VISIBILITY 1146 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1147 1148 // functions to check state 1149 _LIBCPP_INLINE_VISIBILITY 1150 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 1151 1152 _LIBCPP_INLINE_VISIBILITY 1153 void wait() const {__state_->wait();} 1154 template <class _Rep, class _Period> 1155 _LIBCPP_INLINE_VISIBILITY 1156 future_status 1157 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 1158 {return __state_->wait_for(__rel_time);} 1159 template <class _Clock, class _Duration> 1160 _LIBCPP_INLINE_VISIBILITY 1161 future_status 1162 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 1163 {return __state_->wait_until(__abs_time);} 1164 }; 1165 1166 template <class _Rp> 1167 future<_Rp&>::future(__assoc_state<_Rp&>* __state) 1168 : __state_(__state) 1169 { 1170 #ifndef _LIBCPP_NO_EXCEPTIONS 1171 if (__state_->__has_future_attached()) 1172 throw future_error(make_error_code(future_errc::future_already_retrieved)); 1173 #endif 1174 __state_->__add_shared(); 1175 __state_->__set_future_attached(); 1176 } 1177 1178 template <class _Rp> 1179 future<_Rp&>::~future() 1180 { 1181 if (__state_) 1182 __state_->__release_shared(); 1183 } 1184 1185 template <class _Rp> 1186 _Rp& 1187 future<_Rp&>::get() 1188 { 1189 unique_ptr<__shared_count, __release_shared_count> __(__state_); 1190 __assoc_state<_Rp&>* __s = __state_; 1191 __state_ = nullptr; 1192 return __s->copy(); 1193 } 1194 1195 template <> 1196 class _LIBCPP_VISIBLE future<void> 1197 { 1198 __assoc_sub_state* __state_; 1199 1200 explicit future(__assoc_sub_state* __state); 1201 1202 template <class> friend class promise; 1203 template <class> friend class shared_future; 1204 1205 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1206 template <class _R1, class _Fp> 1207 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 1208 template <class _R1, class _Fp> 1209 friend future<_R1> __make_async_assoc_state(_Fp&& __f); 1210 #else 1211 template <class _R1, class _Fp> 1212 friend future<_R1> __make_deferred_assoc_state(_Fp __f); 1213 template <class _R1, class _Fp> 1214 friend future<_R1> __make_async_assoc_state(_Fp __f); 1215 #endif 1216 1217 public: 1218 _LIBCPP_INLINE_VISIBILITY 1219 future() _NOEXCEPT : __state_(nullptr) {} 1220 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1221 _LIBCPP_INLINE_VISIBILITY 1222 future(future&& __rhs) _NOEXCEPT 1223 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1224 future(const future&) = delete; 1225 future& operator=(const future&) = delete; 1226 _LIBCPP_INLINE_VISIBILITY 1227 future& operator=(future&& __rhs) _NOEXCEPT 1228 { 1229 future(std::move(__rhs)).swap(*this); 1230 return *this; 1231 } 1232 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1233 private: 1234 future(const future&); 1235 future& operator=(const future&); 1236 public: 1237 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1238 ~future(); 1239 shared_future<void> share(); 1240 1241 // retrieving the value 1242 void get(); 1243 1244 _LIBCPP_INLINE_VISIBILITY 1245 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1246 1247 // functions to check state 1248 _LIBCPP_INLINE_VISIBILITY 1249 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 1250 1251 _LIBCPP_INLINE_VISIBILITY 1252 void wait() const {__state_->wait();} 1253 template <class _Rep, class _Period> 1254 _LIBCPP_INLINE_VISIBILITY 1255 future_status 1256 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 1257 {return __state_->wait_for(__rel_time);} 1258 template <class _Clock, class _Duration> 1259 _LIBCPP_INLINE_VISIBILITY 1260 future_status 1261 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 1262 {return __state_->wait_until(__abs_time);} 1263 }; 1264 1265 template <class _Rp> 1266 inline _LIBCPP_INLINE_VISIBILITY 1267 void 1268 swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT 1269 { 1270 __x.swap(__y); 1271 } 1272 1273 // promise<R> 1274 1275 template <class _Callable> class packaged_task; 1276 1277 template <class _Rp> 1278 class _LIBCPP_VISIBLE promise 1279 { 1280 __assoc_state<_Rp>* __state_; 1281 1282 _LIBCPP_INLINE_VISIBILITY 1283 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1284 1285 template <class> friend class packaged_task; 1286 public: 1287 promise(); 1288 template <class _Alloc> 1289 promise(allocator_arg_t, const _Alloc& __a); 1290 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1291 _LIBCPP_INLINE_VISIBILITY 1292 promise(promise&& __rhs) _NOEXCEPT 1293 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1294 promise(const promise& __rhs) = delete; 1295 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1296 private: 1297 promise(const promise& __rhs); 1298 public: 1299 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1300 ~promise(); 1301 1302 // assignment 1303 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1304 _LIBCPP_INLINE_VISIBILITY 1305 promise& operator=(promise&& __rhs) _NOEXCEPT 1306 { 1307 promise(std::move(__rhs)).swap(*this); 1308 return *this; 1309 } 1310 promise& operator=(const promise& __rhs) = delete; 1311 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1312 private: 1313 promise& operator=(const promise& __rhs); 1314 public: 1315 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1316 _LIBCPP_INLINE_VISIBILITY 1317 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1318 1319 // retrieving the result 1320 future<_Rp> get_future(); 1321 1322 // setting the result 1323 void set_value(const _Rp& __r); 1324 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1325 void set_value(_Rp&& __r); 1326 #endif 1327 void set_exception(exception_ptr __p); 1328 1329 // setting the result with deferred notification 1330 void set_value_at_thread_exit(const _Rp& __r); 1331 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1332 void set_value_at_thread_exit(_Rp&& __r); 1333 #endif 1334 void set_exception_at_thread_exit(exception_ptr __p); 1335 }; 1336 1337 template <class _Rp> 1338 promise<_Rp>::promise() 1339 : __state_(new __assoc_state<_Rp>) 1340 { 1341 } 1342 1343 template <class _Rp> 1344 template <class _Alloc> 1345 promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) 1346 { 1347 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2; 1348 typedef __allocator_destructor<_A2> _D2; 1349 _A2 __a(__a0); 1350 unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1351 ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0); 1352 __state_ = __hold.release(); 1353 } 1354 1355 template <class _Rp> 1356 promise<_Rp>::~promise() 1357 { 1358 if (__state_) 1359 { 1360 if (!__state_->__has_value() && __state_->use_count() > 1) 1361 __state_->set_exception(make_exception_ptr( 1362 future_error(make_error_code(future_errc::broken_promise)) 1363 )); 1364 __state_->__release_shared(); 1365 } 1366 } 1367 1368 template <class _Rp> 1369 future<_Rp> 1370 promise<_Rp>::get_future() 1371 { 1372 #ifndef _LIBCPP_NO_EXCEPTIONS 1373 if (__state_ == nullptr) 1374 throw future_error(make_error_code(future_errc::no_state)); 1375 #endif 1376 return future<_Rp>(__state_); 1377 } 1378 1379 template <class _Rp> 1380 void 1381 promise<_Rp>::set_value(const _Rp& __r) 1382 { 1383 #ifndef _LIBCPP_NO_EXCEPTIONS 1384 if (__state_ == nullptr) 1385 throw future_error(make_error_code(future_errc::no_state)); 1386 #endif 1387 __state_->set_value(__r); 1388 } 1389 1390 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1391 1392 template <class _Rp> 1393 void 1394 promise<_Rp>::set_value(_Rp&& __r) 1395 { 1396 #ifndef _LIBCPP_NO_EXCEPTIONS 1397 if (__state_ == nullptr) 1398 throw future_error(make_error_code(future_errc::no_state)); 1399 #endif 1400 __state_->set_value(_VSTD::move(__r)); 1401 } 1402 1403 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1404 1405 template <class _Rp> 1406 void 1407 promise<_Rp>::set_exception(exception_ptr __p) 1408 { 1409 #ifndef _LIBCPP_NO_EXCEPTIONS 1410 if (__state_ == nullptr) 1411 throw future_error(make_error_code(future_errc::no_state)); 1412 #endif 1413 __state_->set_exception(__p); 1414 } 1415 1416 template <class _Rp> 1417 void 1418 promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) 1419 { 1420 #ifndef _LIBCPP_NO_EXCEPTIONS 1421 if (__state_ == nullptr) 1422 throw future_error(make_error_code(future_errc::no_state)); 1423 #endif 1424 __state_->set_value_at_thread_exit(__r); 1425 } 1426 1427 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1428 1429 template <class _Rp> 1430 void 1431 promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) 1432 { 1433 #ifndef _LIBCPP_NO_EXCEPTIONS 1434 if (__state_ == nullptr) 1435 throw future_error(make_error_code(future_errc::no_state)); 1436 #endif 1437 __state_->set_value_at_thread_exit(_VSTD::move(__r)); 1438 } 1439 1440 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1441 1442 template <class _Rp> 1443 void 1444 promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) 1445 { 1446 #ifndef _LIBCPP_NO_EXCEPTIONS 1447 if (__state_ == nullptr) 1448 throw future_error(make_error_code(future_errc::no_state)); 1449 #endif 1450 __state_->set_exception_at_thread_exit(__p); 1451 } 1452 1453 // promise<R&> 1454 1455 template <class _Rp> 1456 class _LIBCPP_VISIBLE promise<_Rp&> 1457 { 1458 __assoc_state<_Rp&>* __state_; 1459 1460 _LIBCPP_INLINE_VISIBILITY 1461 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1462 1463 template <class> friend class packaged_task; 1464 1465 public: 1466 promise(); 1467 template <class _Allocator> 1468 promise(allocator_arg_t, const _Allocator& __a); 1469 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1470 _LIBCPP_INLINE_VISIBILITY 1471 promise(promise&& __rhs) _NOEXCEPT 1472 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1473 promise(const promise& __rhs) = delete; 1474 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1475 private: 1476 promise(const promise& __rhs); 1477 public: 1478 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1479 ~promise(); 1480 1481 // assignment 1482 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1483 _LIBCPP_INLINE_VISIBILITY 1484 promise& operator=(promise&& __rhs) _NOEXCEPT 1485 { 1486 promise(std::move(__rhs)).swap(*this); 1487 return *this; 1488 } 1489 promise& operator=(const promise& __rhs) = delete; 1490 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1491 private: 1492 promise& operator=(const promise& __rhs); 1493 public: 1494 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1495 _LIBCPP_INLINE_VISIBILITY 1496 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1497 1498 // retrieving the result 1499 future<_Rp&> get_future(); 1500 1501 // setting the result 1502 void set_value(_Rp& __r); 1503 void set_exception(exception_ptr __p); 1504 1505 // setting the result with deferred notification 1506 void set_value_at_thread_exit(_Rp&); 1507 void set_exception_at_thread_exit(exception_ptr __p); 1508 }; 1509 1510 template <class _Rp> 1511 promise<_Rp&>::promise() 1512 : __state_(new __assoc_state<_Rp&>) 1513 { 1514 } 1515 1516 template <class _Rp> 1517 template <class _Alloc> 1518 promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) 1519 { 1520 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2; 1521 typedef __allocator_destructor<_A2> _D2; 1522 _A2 __a(__a0); 1523 unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1524 ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0); 1525 __state_ = __hold.release(); 1526 } 1527 1528 template <class _Rp> 1529 promise<_Rp&>::~promise() 1530 { 1531 if (__state_) 1532 { 1533 if (!__state_->__has_value() && __state_->use_count() > 1) 1534 __state_->set_exception(make_exception_ptr( 1535 future_error(make_error_code(future_errc::broken_promise)) 1536 )); 1537 __state_->__release_shared(); 1538 } 1539 } 1540 1541 template <class _Rp> 1542 future<_Rp&> 1543 promise<_Rp&>::get_future() 1544 { 1545 #ifndef _LIBCPP_NO_EXCEPTIONS 1546 if (__state_ == nullptr) 1547 throw future_error(make_error_code(future_errc::no_state)); 1548 #endif 1549 return future<_Rp&>(__state_); 1550 } 1551 1552 template <class _Rp> 1553 void 1554 promise<_Rp&>::set_value(_Rp& __r) 1555 { 1556 #ifndef _LIBCPP_NO_EXCEPTIONS 1557 if (__state_ == nullptr) 1558 throw future_error(make_error_code(future_errc::no_state)); 1559 #endif 1560 __state_->set_value(__r); 1561 } 1562 1563 template <class _Rp> 1564 void 1565 promise<_Rp&>::set_exception(exception_ptr __p) 1566 { 1567 #ifndef _LIBCPP_NO_EXCEPTIONS 1568 if (__state_ == nullptr) 1569 throw future_error(make_error_code(future_errc::no_state)); 1570 #endif 1571 __state_->set_exception(__p); 1572 } 1573 1574 template <class _Rp> 1575 void 1576 promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) 1577 { 1578 #ifndef _LIBCPP_NO_EXCEPTIONS 1579 if (__state_ == nullptr) 1580 throw future_error(make_error_code(future_errc::no_state)); 1581 #endif 1582 __state_->set_value_at_thread_exit(__r); 1583 } 1584 1585 template <class _Rp> 1586 void 1587 promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) 1588 { 1589 #ifndef _LIBCPP_NO_EXCEPTIONS 1590 if (__state_ == nullptr) 1591 throw future_error(make_error_code(future_errc::no_state)); 1592 #endif 1593 __state_->set_exception_at_thread_exit(__p); 1594 } 1595 1596 // promise<void> 1597 1598 template <> 1599 class _LIBCPP_VISIBLE promise<void> 1600 { 1601 __assoc_sub_state* __state_; 1602 1603 _LIBCPP_INLINE_VISIBILITY 1604 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1605 1606 template <class> friend class packaged_task; 1607 1608 public: 1609 promise(); 1610 template <class _Allocator> 1611 promise(allocator_arg_t, const _Allocator& __a); 1612 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1613 _LIBCPP_INLINE_VISIBILITY 1614 promise(promise&& __rhs) _NOEXCEPT 1615 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1616 promise(const promise& __rhs) = delete; 1617 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1618 private: 1619 promise(const promise& __rhs); 1620 public: 1621 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1622 ~promise(); 1623 1624 // assignment 1625 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1626 _LIBCPP_INLINE_VISIBILITY 1627 promise& operator=(promise&& __rhs) _NOEXCEPT 1628 { 1629 promise(std::move(__rhs)).swap(*this); 1630 return *this; 1631 } 1632 promise& operator=(const promise& __rhs) = delete; 1633 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1634 private: 1635 promise& operator=(const promise& __rhs); 1636 public: 1637 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1638 _LIBCPP_INLINE_VISIBILITY 1639 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1640 1641 // retrieving the result 1642 future<void> get_future(); 1643 1644 // setting the result 1645 void set_value(); 1646 void set_exception(exception_ptr __p); 1647 1648 // setting the result with deferred notification 1649 void set_value_at_thread_exit(); 1650 void set_exception_at_thread_exit(exception_ptr __p); 1651 }; 1652 1653 template <class _Alloc> 1654 promise<void>::promise(allocator_arg_t, const _Alloc& __a0) 1655 { 1656 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2; 1657 typedef __allocator_destructor<_A2> _D2; 1658 _A2 __a(__a0); 1659 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1660 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0); 1661 __state_ = __hold.release(); 1662 } 1663 1664 template <class _Rp> 1665 inline _LIBCPP_INLINE_VISIBILITY 1666 void 1667 swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT 1668 { 1669 __x.swap(__y); 1670 } 1671 1672 template <class _Rp, class _Alloc> 1673 struct _LIBCPP_VISIBLE uses_allocator<promise<_Rp>, _Alloc> 1674 : public true_type {}; 1675 1676 #ifndef _LIBCPP_HAS_NO_VARIADICS 1677 1678 // packaged_task 1679 1680 template<class _Fp> class __packaged_task_base; 1681 1682 template<class _Rp, class ..._ArgTypes> 1683 class __packaged_task_base<_Rp(_ArgTypes...)> 1684 { 1685 __packaged_task_base(const __packaged_task_base&); 1686 __packaged_task_base& operator=(const __packaged_task_base&); 1687 public: 1688 _LIBCPP_INLINE_VISIBILITY 1689 __packaged_task_base() {} 1690 _LIBCPP_INLINE_VISIBILITY 1691 virtual ~__packaged_task_base() {} 1692 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0; 1693 virtual void destroy() = 0; 1694 virtual void destroy_deallocate() = 0; 1695 virtual _Rp operator()(_ArgTypes&& ...) = 0; 1696 }; 1697 1698 template<class _FD, class _Alloc, class _FB> class __packaged_task_func; 1699 1700 template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1701 class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> 1702 : public __packaged_task_base<_Rp(_ArgTypes...)> 1703 { 1704 __compressed_pair<_Fp, _Alloc> __f_; 1705 public: 1706 _LIBCPP_INLINE_VISIBILITY 1707 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {} 1708 _LIBCPP_INLINE_VISIBILITY 1709 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {} 1710 _LIBCPP_INLINE_VISIBILITY 1711 __packaged_task_func(const _Fp& __f, const _Alloc& __a) 1712 : __f_(__f, __a) {} 1713 _LIBCPP_INLINE_VISIBILITY 1714 __packaged_task_func(_Fp&& __f, const _Alloc& __a) 1715 : __f_(_VSTD::move(__f), __a) {} 1716 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; 1717 virtual void destroy(); 1718 virtual void destroy_deallocate(); 1719 virtual _Rp operator()(_ArgTypes&& ... __args); 1720 }; 1721 1722 template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1723 void 1724 __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to( 1725 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT 1726 { 1727 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second())); 1728 } 1729 1730 template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1731 void 1732 __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() 1733 { 1734 __f_.~__compressed_pair<_Fp, _Alloc>(); 1735 } 1736 1737 template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1738 void 1739 __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() 1740 { 1741 typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap; 1742 _Ap __a(__f_.second()); 1743 __f_.~__compressed_pair<_Fp, _Alloc>(); 1744 __a.deallocate(this, 1); 1745 } 1746 1747 template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1748 _Rp 1749 __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) 1750 { 1751 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); 1752 } 1753 1754 template <class _Callable> class __packaged_task_function; 1755 1756 template<class _Rp, class ..._ArgTypes> 1757 class __packaged_task_function<_Rp(_ArgTypes...)> 1758 { 1759 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; 1760 aligned_storage<3*sizeof(void*)>::type __buf_; 1761 __base* __f_; 1762 1763 public: 1764 typedef _Rp result_type; 1765 1766 // construct/copy/destroy: 1767 _LIBCPP_INLINE_VISIBILITY 1768 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {} 1769 template<class _Fp> 1770 __packaged_task_function(_Fp&& __f); 1771 template<class _Fp, class _Alloc> 1772 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); 1773 1774 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; 1775 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; 1776 1777 __packaged_task_function(const __packaged_task_function&) = delete; 1778 __packaged_task_function& operator=(const __packaged_task_function&) = delete; 1779 1780 ~__packaged_task_function(); 1781 1782 void swap(__packaged_task_function&) _NOEXCEPT; 1783 1784 _Rp operator()(_ArgTypes...) const; 1785 }; 1786 1787 template<class _Rp, class ..._ArgTypes> 1788 __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT 1789 { 1790 if (__f.__f_ == nullptr) 1791 __f_ = nullptr; 1792 else if (__f.__f_ == (__base*)&__f.__buf_) 1793 { 1794 __f_ = (__base*)&__buf_; 1795 __f.__f_->__move_to(__f_); 1796 } 1797 else 1798 { 1799 __f_ = __f.__f_; 1800 __f.__f_ = nullptr; 1801 } 1802 } 1803 1804 template<class _Rp, class ..._ArgTypes> 1805 template <class _Fp> 1806 __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) 1807 : __f_(nullptr) 1808 { 1809 typedef typename remove_reference<_Fp>::type _FR; 1810 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; 1811 if (sizeof(_FF) <= sizeof(__buf_)) 1812 { 1813 __f_ = (__base*)&__buf_; 1814 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); 1815 } 1816 else 1817 { 1818 typedef allocator<_FF> _Ap; 1819 _Ap __a; 1820 typedef __allocator_destructor<_Ap> _Dp; 1821 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1822 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a)); 1823 __f_ = __hold.release(); 1824 } 1825 } 1826 1827 template<class _Rp, class ..._ArgTypes> 1828 template <class _Fp, class _Alloc> 1829 __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function( 1830 allocator_arg_t, const _Alloc& __a0, _Fp&& __f) 1831 : __f_(nullptr) 1832 { 1833 typedef allocator_traits<_Alloc> __alloc_traits; 1834 typedef typename remove_reference<_Fp>::type _FR; 1835 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; 1836 if (sizeof(_FF) <= sizeof(__buf_)) 1837 { 1838 __f_ = (__base*)&__buf_; 1839 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); 1840 } 1841 else 1842 { 1843 typedef typename __alloc_traits::template 1844 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES 1845 rebind_alloc<_FF> 1846 #else 1847 rebind_alloc<_FF>::other 1848 #endif 1849 _Ap; 1850 _Ap __a(__a0); 1851 typedef __allocator_destructor<_Ap> _Dp; 1852 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1853 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a)); 1854 __f_ = __hold.release(); 1855 } 1856 } 1857 1858 template<class _Rp, class ..._ArgTypes> 1859 __packaged_task_function<_Rp(_ArgTypes...)>& 1860 __packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT 1861 { 1862 if (__f_ == (__base*)&__buf_) 1863 __f_->destroy(); 1864 else if (__f_) 1865 __f_->destroy_deallocate(); 1866 __f_ = nullptr; 1867 if (__f.__f_ == nullptr) 1868 __f_ = nullptr; 1869 else if (__f.__f_ == (__base*)&__f.__buf_) 1870 { 1871 __f_ = (__base*)&__buf_; 1872 __f.__f_->__move_to(__f_); 1873 } 1874 else 1875 { 1876 __f_ = __f.__f_; 1877 __f.__f_ = nullptr; 1878 } 1879 return *this; 1880 } 1881 1882 template<class _Rp, class ..._ArgTypes> 1883 __packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() 1884 { 1885 if (__f_ == (__base*)&__buf_) 1886 __f_->destroy(); 1887 else if (__f_) 1888 __f_->destroy_deallocate(); 1889 } 1890 1891 template<class _Rp, class ..._ArgTypes> 1892 void 1893 __packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT 1894 { 1895 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 1896 { 1897 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 1898 __base* __t = (__base*)&__tempbuf; 1899 __f_->__move_to(__t); 1900 __f_->destroy(); 1901 __f_ = nullptr; 1902 __f.__f_->__move_to((__base*)&__buf_); 1903 __f.__f_->destroy(); 1904 __f.__f_ = nullptr; 1905 __f_ = (__base*)&__buf_; 1906 __t->__move_to((__base*)&__f.__buf_); 1907 __t->destroy(); 1908 __f.__f_ = (__base*)&__f.__buf_; 1909 } 1910 else if (__f_ == (__base*)&__buf_) 1911 { 1912 __f_->__move_to((__base*)&__f.__buf_); 1913 __f_->destroy(); 1914 __f_ = __f.__f_; 1915 __f.__f_ = (__base*)&__f.__buf_; 1916 } 1917 else if (__f.__f_ == (__base*)&__f.__buf_) 1918 { 1919 __f.__f_->__move_to((__base*)&__buf_); 1920 __f.__f_->destroy(); 1921 __f.__f_ = __f_; 1922 __f_ = (__base*)&__buf_; 1923 } 1924 else 1925 _VSTD::swap(__f_, __f.__f_); 1926 } 1927 1928 template<class _Rp, class ..._ArgTypes> 1929 inline _LIBCPP_INLINE_VISIBILITY 1930 _Rp 1931 __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const 1932 { 1933 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); 1934 } 1935 1936 template<class _Rp, class ..._ArgTypes> 1937 class _LIBCPP_VISIBLE packaged_task<_Rp(_ArgTypes...)> 1938 { 1939 public: 1940 typedef _Rp result_type; 1941 1942 private: 1943 __packaged_task_function<result_type(_ArgTypes...)> __f_; 1944 promise<result_type> __p_; 1945 1946 public: 1947 // construction and destruction 1948 _LIBCPP_INLINE_VISIBILITY 1949 packaged_task() _NOEXCEPT : __p_(nullptr) {} 1950 template <class _Fp> 1951 _LIBCPP_INLINE_VISIBILITY 1952 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} 1953 template <class _Fp, class _Allocator> 1954 _LIBCPP_INLINE_VISIBILITY 1955 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 1956 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), 1957 __p_(allocator_arg, __a) {} 1958 // ~packaged_task() = default; 1959 1960 // no copy 1961 packaged_task(const packaged_task&) = delete; 1962 packaged_task& operator=(const packaged_task&) = delete; 1963 1964 // move support 1965 _LIBCPP_INLINE_VISIBILITY 1966 packaged_task(packaged_task&& __other) _NOEXCEPT 1967 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 1968 _LIBCPP_INLINE_VISIBILITY 1969 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 1970 { 1971 __f_ = _VSTD::move(__other.__f_); 1972 __p_ = _VSTD::move(__other.__p_); 1973 return *this; 1974 } 1975 _LIBCPP_INLINE_VISIBILITY 1976 void swap(packaged_task& __other) _NOEXCEPT 1977 { 1978 __f_.swap(__other.__f_); 1979 __p_.swap(__other.__p_); 1980 } 1981 1982 _LIBCPP_INLINE_VISIBILITY 1983 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} 1984 1985 // result retrieval 1986 _LIBCPP_INLINE_VISIBILITY 1987 future<result_type> get_future() {return __p_.get_future();} 1988 1989 // execution 1990 void operator()(_ArgTypes... __args); 1991 void make_ready_at_thread_exit(_ArgTypes... __args); 1992 1993 void reset(); 1994 }; 1995 1996 template<class _Rp, class ..._ArgTypes> 1997 void 1998 packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) 1999 { 2000 #ifndef _LIBCPP_NO_EXCEPTIONS 2001 if (__p_.__state_ == nullptr) 2002 throw future_error(make_error_code(future_errc::no_state)); 2003 if (__p_.__state_->__has_value()) 2004 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 2005 try 2006 { 2007 #endif // _LIBCPP_NO_EXCEPTIONS 2008 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...)); 2009 #ifndef _LIBCPP_NO_EXCEPTIONS 2010 } 2011 catch (...) 2012 { 2013 __p_.set_exception(current_exception()); 2014 } 2015 #endif // _LIBCPP_NO_EXCEPTIONS 2016 } 2017 2018 template<class _Rp, class ..._ArgTypes> 2019 void 2020 packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) 2021 { 2022 #ifndef _LIBCPP_NO_EXCEPTIONS 2023 if (__p_.__state_ == nullptr) 2024 throw future_error(make_error_code(future_errc::no_state)); 2025 if (__p_.__state_->__has_value()) 2026 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 2027 try 2028 { 2029 #endif // _LIBCPP_NO_EXCEPTIONS 2030 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...)); 2031 #ifndef _LIBCPP_NO_EXCEPTIONS 2032 } 2033 catch (...) 2034 { 2035 __p_.set_exception_at_thread_exit(current_exception()); 2036 } 2037 #endif // _LIBCPP_NO_EXCEPTIONS 2038 } 2039 2040 template<class _Rp, class ..._ArgTypes> 2041 void 2042 packaged_task<_Rp(_ArgTypes...)>::reset() 2043 { 2044 #ifndef _LIBCPP_NO_EXCEPTIONS 2045 if (!valid()) 2046 throw future_error(make_error_code(future_errc::no_state)); 2047 #endif // _LIBCPP_NO_EXCEPTIONS 2048 __p_ = promise<result_type>(); 2049 } 2050 2051 template<class ..._ArgTypes> 2052 class _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)> 2053 { 2054 public: 2055 typedef void result_type; 2056 2057 private: 2058 __packaged_task_function<result_type(_ArgTypes...)> __f_; 2059 promise<result_type> __p_; 2060 2061 public: 2062 // construction and destruction 2063 _LIBCPP_INLINE_VISIBILITY 2064 packaged_task() _NOEXCEPT : __p_(nullptr) {} 2065 template <class _Fp> 2066 _LIBCPP_INLINE_VISIBILITY 2067 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} 2068 template <class _Fp, class _Allocator> 2069 _LIBCPP_INLINE_VISIBILITY 2070 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 2071 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), 2072 __p_(allocator_arg, __a) {} 2073 // ~packaged_task() = default; 2074 2075 // no copy 2076 packaged_task(const packaged_task&) = delete; 2077 packaged_task& operator=(const packaged_task&) = delete; 2078 2079 // move support 2080 _LIBCPP_INLINE_VISIBILITY 2081 packaged_task(packaged_task&& __other) _NOEXCEPT 2082 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 2083 _LIBCPP_INLINE_VISIBILITY 2084 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 2085 { 2086 __f_ = _VSTD::move(__other.__f_); 2087 __p_ = _VSTD::move(__other.__p_); 2088 return *this; 2089 } 2090 _LIBCPP_INLINE_VISIBILITY 2091 void swap(packaged_task& __other) _NOEXCEPT 2092 { 2093 __f_.swap(__other.__f_); 2094 __p_.swap(__other.__p_); 2095 } 2096 2097 _LIBCPP_INLINE_VISIBILITY 2098 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} 2099 2100 // result retrieval 2101 _LIBCPP_INLINE_VISIBILITY 2102 future<result_type> get_future() {return __p_.get_future();} 2103 2104 // execution 2105 void operator()(_ArgTypes... __args); 2106 void make_ready_at_thread_exit(_ArgTypes... __args); 2107 2108 void reset(); 2109 }; 2110 2111 template<class ..._ArgTypes> 2112 void 2113 packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) 2114 { 2115 #ifndef _LIBCPP_NO_EXCEPTIONS 2116 if (__p_.__state_ == nullptr) 2117 throw future_error(make_error_code(future_errc::no_state)); 2118 if (__p_.__state_->__has_value()) 2119 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 2120 try 2121 { 2122 #endif // _LIBCPP_NO_EXCEPTIONS 2123 __f_(_VSTD::forward<_ArgTypes>(__args)...); 2124 __p_.set_value(); 2125 #ifndef _LIBCPP_NO_EXCEPTIONS 2126 } 2127 catch (...) 2128 { 2129 __p_.set_exception(current_exception()); 2130 } 2131 #endif // _LIBCPP_NO_EXCEPTIONS 2132 } 2133 2134 template<class ..._ArgTypes> 2135 void 2136 packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) 2137 { 2138 #ifndef _LIBCPP_NO_EXCEPTIONS 2139 if (__p_.__state_ == nullptr) 2140 throw future_error(make_error_code(future_errc::no_state)); 2141 if (__p_.__state_->__has_value()) 2142 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 2143 try 2144 { 2145 #endif // _LIBCPP_NO_EXCEPTIONS 2146 __f_(_VSTD::forward<_ArgTypes>(__args)...); 2147 __p_.set_value_at_thread_exit(); 2148 #ifndef _LIBCPP_NO_EXCEPTIONS 2149 } 2150 catch (...) 2151 { 2152 __p_.set_exception_at_thread_exit(current_exception()); 2153 } 2154 #endif // _LIBCPP_NO_EXCEPTIONS 2155 } 2156 2157 template<class ..._ArgTypes> 2158 void 2159 packaged_task<void(_ArgTypes...)>::reset() 2160 { 2161 #ifndef _LIBCPP_NO_EXCEPTIONS 2162 if (!valid()) 2163 throw future_error(make_error_code(future_errc::no_state)); 2164 #endif // _LIBCPP_NO_EXCEPTIONS 2165 __p_ = promise<result_type>(); 2166 } 2167 2168 template <class _Callable> 2169 inline _LIBCPP_INLINE_VISIBILITY 2170 void 2171 swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT 2172 { 2173 __x.swap(__y); 2174 } 2175 2176 template <class _Callable, class _Alloc> 2177 struct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc> 2178 : public true_type {}; 2179 2180 template <class _Rp, class _Fp> 2181 future<_Rp> 2182 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2183 __make_deferred_assoc_state(_Fp&& __f) 2184 #else 2185 __make_deferred_assoc_state(_Fp __f) 2186 #endif 2187 { 2188 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> 2189 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); 2190 return future<_Rp>(__h.get()); 2191 } 2192 2193 template <class _Rp, class _Fp> 2194 future<_Rp> 2195 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2196 __make_async_assoc_state(_Fp&& __f) 2197 #else 2198 __make_async_assoc_state(_Fp __f) 2199 #endif 2200 { 2201 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> 2202 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); 2203 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach(); 2204 return future<_Rp>(__h.get()); 2205 } 2206 2207 template <class _Fp, class... _Args> 2208 class __async_func 2209 { 2210 tuple<_Fp, _Args...> __f_; 2211 2212 public: 2213 typedef typename __invoke_of<_Fp, _Args...>::type _Rp; 2214 2215 _LIBCPP_INLINE_VISIBILITY 2216 explicit __async_func(_Fp&& __f, _Args&&... __args) 2217 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {} 2218 2219 _LIBCPP_INLINE_VISIBILITY 2220 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {} 2221 2222 _Rp operator()() 2223 { 2224 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index; 2225 return __execute(_Index()); 2226 } 2227 private: 2228 template <size_t ..._Indices> 2229 _Rp 2230 __execute(__tuple_indices<_Indices...>) 2231 { 2232 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); 2233 } 2234 }; 2235 2236 template <class _Fp, class... _Args> 2237 future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> 2238 async(launch __policy, _Fp&& __f, _Args&&... __args) 2239 { 2240 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF; 2241 typedef typename _BF::_Rp _Rp; 2242 future<_Rp> __r; 2243 if (int(__policy) & int(launch::async)) 2244 __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), 2245 __decay_copy(_VSTD::forward<_Args>(__args))...)); 2246 else if (int(__policy) & int(launch::deferred)) 2247 __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), 2248 __decay_copy(_VSTD::forward<_Args>(__args))...)); 2249 return __r; 2250 } 2251 2252 template <class _Fp, class... _Args> 2253 inline _LIBCPP_INLINE_VISIBILITY 2254 future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> 2255 async(_Fp&& __f, _Args&&... __args) 2256 { 2257 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f), 2258 _VSTD::forward<_Args>(__args)...); 2259 } 2260 2261 #endif // _LIBCPP_HAS_NO_VARIADICS 2262 2263 // shared_future 2264 2265 template <class _Rp> 2266 class _LIBCPP_VISIBLE shared_future 2267 { 2268 __assoc_state<_Rp>* __state_; 2269 2270 public: 2271 _LIBCPP_INLINE_VISIBILITY 2272 shared_future() _NOEXCEPT : __state_(nullptr) {} 2273 _LIBCPP_INLINE_VISIBILITY 2274 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) 2275 {if (__state_) __state_->__add_shared();} 2276 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2277 _LIBCPP_INLINE_VISIBILITY 2278 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) 2279 {__f.__state_ = nullptr;} 2280 _LIBCPP_INLINE_VISIBILITY 2281 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 2282 {__rhs.__state_ = nullptr;} 2283 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2284 ~shared_future(); 2285 shared_future& operator=(const shared_future& __rhs); 2286 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2287 _LIBCPP_INLINE_VISIBILITY 2288 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 2289 { 2290 shared_future(std::move(__rhs)).swap(*this); 2291 return *this; 2292 } 2293 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2294 2295 // retrieving the value 2296 _LIBCPP_INLINE_VISIBILITY 2297 const _Rp& get() const {return __state_->copy();} 2298 2299 _LIBCPP_INLINE_VISIBILITY 2300 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2301 2302 // functions to check state 2303 _LIBCPP_INLINE_VISIBILITY 2304 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 2305 2306 _LIBCPP_INLINE_VISIBILITY 2307 void wait() const {__state_->wait();} 2308 template <class _Rep, class _Period> 2309 _LIBCPP_INLINE_VISIBILITY 2310 future_status 2311 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 2312 {return __state_->wait_for(__rel_time);} 2313 template <class _Clock, class _Duration> 2314 _LIBCPP_INLINE_VISIBILITY 2315 future_status 2316 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 2317 {return __state_->wait_until(__abs_time);} 2318 }; 2319 2320 template <class _Rp> 2321 shared_future<_Rp>::~shared_future() 2322 { 2323 if (__state_) 2324 __state_->__release_shared(); 2325 } 2326 2327 template <class _Rp> 2328 shared_future<_Rp>& 2329 shared_future<_Rp>::operator=(const shared_future& __rhs) 2330 { 2331 if (__rhs.__state_) 2332 __rhs.__state_->__add_shared(); 2333 if (__state_) 2334 __state_->__release_shared(); 2335 __state_ = __rhs.__state_; 2336 return *this; 2337 } 2338 2339 template <class _Rp> 2340 class _LIBCPP_VISIBLE shared_future<_Rp&> 2341 { 2342 __assoc_state<_Rp&>* __state_; 2343 2344 public: 2345 _LIBCPP_INLINE_VISIBILITY 2346 shared_future() _NOEXCEPT : __state_(nullptr) {} 2347 _LIBCPP_INLINE_VISIBILITY 2348 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) 2349 {if (__state_) __state_->__add_shared();} 2350 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2351 _LIBCPP_INLINE_VISIBILITY 2352 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) 2353 {__f.__state_ = nullptr;} 2354 _LIBCPP_INLINE_VISIBILITY 2355 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 2356 {__rhs.__state_ = nullptr;} 2357 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2358 ~shared_future(); 2359 shared_future& operator=(const shared_future& __rhs); 2360 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2361 _LIBCPP_INLINE_VISIBILITY 2362 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 2363 { 2364 shared_future(std::move(__rhs)).swap(*this); 2365 return *this; 2366 } 2367 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2368 2369 // retrieving the value 2370 _LIBCPP_INLINE_VISIBILITY 2371 _Rp& get() const {return __state_->copy();} 2372 2373 _LIBCPP_INLINE_VISIBILITY 2374 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2375 2376 // functions to check state 2377 _LIBCPP_INLINE_VISIBILITY 2378 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 2379 2380 _LIBCPP_INLINE_VISIBILITY 2381 void wait() const {__state_->wait();} 2382 template <class _Rep, class _Period> 2383 _LIBCPP_INLINE_VISIBILITY 2384 future_status 2385 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 2386 {return __state_->wait_for(__rel_time);} 2387 template <class _Clock, class _Duration> 2388 _LIBCPP_INLINE_VISIBILITY 2389 future_status 2390 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 2391 {return __state_->wait_until(__abs_time);} 2392 }; 2393 2394 template <class _Rp> 2395 shared_future<_Rp&>::~shared_future() 2396 { 2397 if (__state_) 2398 __state_->__release_shared(); 2399 } 2400 2401 template <class _Rp> 2402 shared_future<_Rp&>& 2403 shared_future<_Rp&>::operator=(const shared_future& __rhs) 2404 { 2405 if (__rhs.__state_) 2406 __rhs.__state_->__add_shared(); 2407 if (__state_) 2408 __state_->__release_shared(); 2409 __state_ = __rhs.__state_; 2410 return *this; 2411 } 2412 2413 template <> 2414 class _LIBCPP_VISIBLE shared_future<void> 2415 { 2416 __assoc_sub_state* __state_; 2417 2418 public: 2419 _LIBCPP_INLINE_VISIBILITY 2420 shared_future() _NOEXCEPT : __state_(nullptr) {} 2421 _LIBCPP_INLINE_VISIBILITY 2422 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) 2423 {if (__state_) __state_->__add_shared();} 2424 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2425 _LIBCPP_INLINE_VISIBILITY 2426 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) 2427 {__f.__state_ = nullptr;} 2428 _LIBCPP_INLINE_VISIBILITY 2429 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 2430 {__rhs.__state_ = nullptr;} 2431 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2432 ~shared_future(); 2433 shared_future& operator=(const shared_future& __rhs); 2434 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2435 _LIBCPP_INLINE_VISIBILITY 2436 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 2437 { 2438 shared_future(std::move(__rhs)).swap(*this); 2439 return *this; 2440 } 2441 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2442 2443 // retrieving the value 2444 _LIBCPP_INLINE_VISIBILITY 2445 void get() const {__state_->copy();} 2446 2447 _LIBCPP_INLINE_VISIBILITY 2448 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2449 2450 // functions to check state 2451 _LIBCPP_INLINE_VISIBILITY 2452 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 2453 2454 _LIBCPP_INLINE_VISIBILITY 2455 void wait() const {__state_->wait();} 2456 template <class _Rep, class _Period> 2457 _LIBCPP_INLINE_VISIBILITY 2458 future_status 2459 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 2460 {return __state_->wait_for(__rel_time);} 2461 template <class _Clock, class _Duration> 2462 _LIBCPP_INLINE_VISIBILITY 2463 future_status 2464 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 2465 {return __state_->wait_until(__abs_time);} 2466 }; 2467 2468 template <class _Rp> 2469 inline _LIBCPP_INLINE_VISIBILITY 2470 void 2471 swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT 2472 { 2473 __x.swap(__y); 2474 } 2475 2476 template <class _Rp> 2477 inline _LIBCPP_INLINE_VISIBILITY 2478 shared_future<_Rp> 2479 future<_Rp>::share() 2480 { 2481 return shared_future<_Rp>(_VSTD::move(*this)); 2482 } 2483 2484 template <class _Rp> 2485 inline _LIBCPP_INLINE_VISIBILITY 2486 shared_future<_Rp&> 2487 future<_Rp&>::share() 2488 { 2489 return shared_future<_Rp&>(_VSTD::move(*this)); 2490 } 2491 2492 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2493 2494 inline _LIBCPP_INLINE_VISIBILITY 2495 shared_future<void> 2496 future<void>::share() 2497 { 2498 return shared_future<void>(_VSTD::move(*this)); 2499 } 2500 2501 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2502 2503 _LIBCPP_END_NAMESPACE_STD 2504 2505 #endif // _LIBCPP_FUTURE 2506