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