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