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