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