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