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