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