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) noexcept; 44error_condition make_error_condition(future_errc e) noexcept; 45 46const error_category& future_category() noexcept; 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 noexcept; 55 const char* what() const noexcept; 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) noexcept; 66 promise(const promise& rhs) = delete; 67 ~promise(); 68 69 // assignment 70 promise& operator=(promise&& rhs) noexcept; 71 promise& operator=(const promise& rhs) = delete; 72 void swap(promise& other) noexcept; 73 74 // retrieving the result 75 future<R> get_future(); 76 77 // setting the result 78 void set_value(const R& r); 79 void set_value(R&& r); 80 void set_exception(exception_ptr p); 81 82 // setting the result with deferred notification 83 void set_value_at_thread_exit(const R& r); 84 void set_value_at_thread_exit(R&& r); 85 void set_exception_at_thread_exit(exception_ptr p); 86}; 87 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) noexcept; 96 promise(const promise& rhs) = delete; 97 ~promise(); 98 99 // assignment 100 promise& operator=(promise&& rhs) noexcept; 101 promise& operator=(const promise& rhs) = delete; 102 void swap(promise& other) noexcept; 103 104 // retrieving the result 105 future<R&> get_future(); 106 107 // setting the result 108 void set_value(R& r); 109 void set_exception(exception_ptr p); 110 111 // setting the result with deferred notification 112 void set_value_at_thread_exit(R&); 113 void set_exception_at_thread_exit(exception_ptr p); 114}; 115 116template <> 117class promise<void> 118{ 119public: 120 promise(); 121 template <class Allocator> 122 promise(allocator_arg_t, const Allocator& a); 123 promise(promise&& rhs) noexcept; 124 promise(const promise& rhs) = delete; 125 ~promise(); 126 127 // assignment 128 promise& operator=(promise&& rhs) noexcept; 129 promise& operator=(const promise& rhs) = delete; 130 void swap(promise& other) noexcept; 131 132 // retrieving the result 133 future<void> get_future(); 134 135 // setting the result 136 void set_value(); 137 void set_exception(exception_ptr p); 138 139 // setting the result with deferred notification 140 void set_value_at_thread_exit(); 141 void set_exception_at_thread_exit(exception_ptr p); 142}; 143 144template <class R> void swap(promise<R>& x, promise<R>& y) noexcept; 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() noexcept; 154 future(future&&) noexcept; 155 future(const future& rhs) = delete; 156 ~future(); 157 future& operator=(const future& rhs) = delete; 158 future& operator=(future&&) noexcept; 159 shared_future<R> share(); 160 161 // retrieving the value 162 R get(); 163 164 // functions to check state 165 bool valid() const noexcept; 166 167 void wait() const; 168 template <class Rep, class Period> 169 future_status 170 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 171 template <class Clock, class Duration> 172 future_status 173 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 174}; 175 176template <class R> 177class future<R&> 178{ 179public: 180 future() noexcept; 181 future(future&&) noexcept; 182 future(const future& rhs) = delete; 183 ~future(); 184 future& operator=(const future& rhs) = delete; 185 future& operator=(future&&) noexcept; 186 shared_future<R&> share(); 187 188 // retrieving the value 189 R& get(); 190 191 // functions to check state 192 bool valid() const noexcept; 193 194 void wait() const; 195 template <class Rep, class Period> 196 future_status 197 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 198 template <class Clock, class Duration> 199 future_status 200 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 201}; 202 203template <> 204class future<void> 205{ 206public: 207 future() noexcept; 208 future(future&&) noexcept; 209 future(const future& rhs) = delete; 210 ~future(); 211 future& operator=(const future& rhs) = delete; 212 future& operator=(future&&) noexcept; 213 shared_future<void> share(); 214 215 // retrieving the value 216 void get(); 217 218 // functions to check state 219 bool valid() const noexcept; 220 221 void wait() const; 222 template <class Rep, class Period> 223 future_status 224 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 225 template <class Clock, class Duration> 226 future_status 227 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 228}; 229 230template <class R> 231class shared_future 232{ 233public: 234 shared_future() noexcept; 235 shared_future(const shared_future& rhs); 236 shared_future(future<R>&&) noexcept; 237 shared_future(shared_future&& rhs) noexcept; 238 ~shared_future(); 239 shared_future& operator=(const shared_future& rhs); 240 shared_future& operator=(shared_future&& rhs) noexcept; 241 242 // retrieving the value 243 const R& get() const; 244 245 // functions to check state 246 bool valid() const noexcept; 247 248 void wait() const; 249 template <class Rep, class Period> 250 future_status 251 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 252 template <class Clock, class Duration> 253 future_status 254 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 255}; 256 257template <class R> 258class shared_future<R&> 259{ 260public: 261 shared_future() noexcept; 262 shared_future(const shared_future& rhs); 263 shared_future(future<R&>&&) noexcept; 264 shared_future(shared_future&& rhs) noexcept; 265 ~shared_future(); 266 shared_future& operator=(const shared_future& rhs); 267 shared_future& operator=(shared_future&& rhs) noexcept; 268 269 // retrieving the value 270 R& get() const; 271 272 // functions to check state 273 bool valid() const noexcept; 274 275 void wait() const; 276 template <class Rep, class Period> 277 future_status 278 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 279 template <class Clock, class Duration> 280 future_status 281 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 282}; 283 284template <> 285class shared_future<void> 286{ 287public: 288 shared_future() noexcept; 289 shared_future(const shared_future& rhs); 290 shared_future(future<void>&&) noexcept; 291 shared_future(shared_future&& rhs) noexcept; 292 ~shared_future(); 293 shared_future& operator=(const shared_future& rhs); 294 shared_future& operator=(shared_future&& rhs) noexcept; 295 296 // retrieving the value 297 void get() const; 298 299 // functions to check state 300 bool valid() const noexcept; 301 302 void wait() const; 303 template <class Rep, class Period> 304 future_status 305 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 306 template <class Clock, class Duration> 307 future_status 308 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 309}; 310 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() noexcept; 329 template <class F> 330 explicit packaged_task(F&& f); 331 template <class F, class Allocator> 332 explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); 333 ~packaged_task(); 334 335 // no copy 336 packaged_task(const packaged_task&) = delete; 337 packaged_task& operator=(const packaged_task&) = delete; 338 339 // move support 340 packaged_task(packaged_task&& other) noexcept; 341 packaged_task& operator=(packaged_task&& other) noexcept; 342 void swap(packaged_task& other) noexcept; 343 344 bool valid() const noexcept; 345 346 // result retrieval 347 future<R> get_future(); 348 349 // execution 350 void operator()(ArgTypes... ); 351 void make_ready_at_thread_exit(ArgTypes...); 352 353 void reset(); 354}; 355 356template <class R> 357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept; 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() _NOEXCEPT; 417 418inline _LIBCPP_INLINE_VISIBILITY 419error_code 420make_error_code(future_errc __e) _NOEXCEPT 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) _NOEXCEPT 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 _NOEXCEPT {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 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_); 759 this->~__assoc_sub_state_alloc(); 760 __a.deallocate(this, 1); 761} 762 763template <class _Rp, class _Fp> 764class __deferred_assoc_state 765 : public __assoc_state<_Rp> 766{ 767 typedef __assoc_state<_Rp> base; 768 769 _Fp __func_; 770 771public: 772#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 773 explicit __deferred_assoc_state(_Fp&& __f); 774#endif 775 776 virtual void __execute(); 777}; 778 779#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 780 781template <class _Rp, class _Fp> 782inline _LIBCPP_INLINE_VISIBILITY 783__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) 784 : __func_(_VSTD::forward<_Fp>(__f)) 785{ 786 this->__set_deferred(); 787} 788 789#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 790 791template <class _Rp, class _Fp> 792void 793__deferred_assoc_state<_Rp, _Fp>::__execute() 794{ 795#ifndef _LIBCPP_NO_EXCEPTIONS 796 try 797 { 798#endif // _LIBCPP_NO_EXCEPTIONS 799 this->set_value(__func_()); 800#ifndef _LIBCPP_NO_EXCEPTIONS 801 } 802 catch (...) 803 { 804 this->set_exception(current_exception()); 805 } 806#endif // _LIBCPP_NO_EXCEPTIONS 807} 808 809template <class _Fp> 810class __deferred_assoc_state<void, _Fp> 811 : public __assoc_sub_state 812{ 813 typedef __assoc_sub_state base; 814 815 _Fp __func_; 816 817public: 818#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 819 explicit __deferred_assoc_state(_Fp&& __f); 820#endif 821 822 virtual void __execute(); 823}; 824 825#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 826 827template <class _Fp> 828inline _LIBCPP_INLINE_VISIBILITY 829__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) 830 : __func_(_VSTD::forward<_Fp>(__f)) 831{ 832 this->__set_deferred(); 833} 834 835#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 836 837template <class _Fp> 838void 839__deferred_assoc_state<void, _Fp>::__execute() 840{ 841#ifndef _LIBCPP_NO_EXCEPTIONS 842 try 843 { 844#endif // _LIBCPP_NO_EXCEPTIONS 845 __func_(); 846 this->set_value(); 847#ifndef _LIBCPP_NO_EXCEPTIONS 848 } 849 catch (...) 850 { 851 this->set_exception(current_exception()); 852 } 853#endif // _LIBCPP_NO_EXCEPTIONS 854} 855 856template <class _Rp, class _Fp> 857class __async_assoc_state 858 : public __assoc_state<_Rp> 859{ 860 typedef __assoc_state<_Rp> base; 861 862 _Fp __func_; 863 864 virtual void __on_zero_shared() _NOEXCEPT; 865public: 866#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 867 explicit __async_assoc_state(_Fp&& __f); 868#endif 869 870 virtual void __execute(); 871}; 872 873#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 874 875template <class _Rp, class _Fp> 876inline _LIBCPP_INLINE_VISIBILITY 877__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) 878 : __func_(_VSTD::forward<_Fp>(__f)) 879{ 880} 881 882#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 883 884template <class _Rp, class _Fp> 885void 886__async_assoc_state<_Rp, _Fp>::__execute() 887{ 888#ifndef _LIBCPP_NO_EXCEPTIONS 889 try 890 { 891#endif // _LIBCPP_NO_EXCEPTIONS 892 this->set_value(__func_()); 893#ifndef _LIBCPP_NO_EXCEPTIONS 894 } 895 catch (...) 896 { 897 this->set_exception(current_exception()); 898 } 899#endif // _LIBCPP_NO_EXCEPTIONS 900} 901 902template <class _Rp, class _Fp> 903void 904__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT 905{ 906 this->wait(); 907 base::__on_zero_shared(); 908} 909 910template <class _Fp> 911class __async_assoc_state<void, _Fp> 912 : public __assoc_sub_state 913{ 914 typedef __assoc_sub_state base; 915 916 _Fp __func_; 917 918 virtual void __on_zero_shared() _NOEXCEPT; 919public: 920#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 921 explicit __async_assoc_state(_Fp&& __f); 922#endif 923 924 virtual void __execute(); 925}; 926 927#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 928 929template <class _Fp> 930inline _LIBCPP_INLINE_VISIBILITY 931__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) 932 : __func_(_VSTD::forward<_Fp>(__f)) 933{ 934} 935 936#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 937 938template <class _Fp> 939void 940__async_assoc_state<void, _Fp>::__execute() 941{ 942#ifndef _LIBCPP_NO_EXCEPTIONS 943 try 944 { 945#endif // _LIBCPP_NO_EXCEPTIONS 946 __func_(); 947 this->set_value(); 948#ifndef _LIBCPP_NO_EXCEPTIONS 949 } 950 catch (...) 951 { 952 this->set_exception(current_exception()); 953 } 954#endif // _LIBCPP_NO_EXCEPTIONS 955} 956 957template <class _Fp> 958void 959__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT 960{ 961 this->wait(); 962 base::__on_zero_shared(); 963} 964 965template <class _Rp> class _LIBCPP_VISIBLE promise; 966template <class _Rp> class _LIBCPP_VISIBLE shared_future; 967 968// future 969 970template <class _Rp> class _LIBCPP_VISIBLE future; 971 972template <class _Rp, class _Fp> 973future<_Rp> 974#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 975__make_deferred_assoc_state(_Fp&& __f); 976#else 977__make_deferred_assoc_state(_Fp __f); 978#endif 979 980template <class _Rp, class _Fp> 981future<_Rp> 982#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 983__make_async_assoc_state(_Fp&& __f); 984#else 985__make_async_assoc_state(_Fp __f); 986#endif 987 988template <class _Rp> 989class _LIBCPP_VISIBLE future 990{ 991 __assoc_state<_Rp>* __state_; 992 993 explicit future(__assoc_state<_Rp>* __state); 994 995 template <class> friend class promise; 996 template <class> friend class shared_future; 997 998#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 999 template <class _R1, class _Fp> 1000 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 1001 template <class _R1, class _Fp> 1002 friend future<_R1> __make_async_assoc_state(_Fp&& __f); 1003#else 1004 template <class _R1, class _Fp> 1005 friend future<_R1> __make_deferred_assoc_state(_Fp __f); 1006 template <class _R1, class _Fp> 1007 friend future<_R1> __make_async_assoc_state(_Fp __f); 1008#endif 1009 1010public: 1011 _LIBCPP_INLINE_VISIBILITY 1012 future() _NOEXCEPT : __state_(nullptr) {} 1013#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1014 _LIBCPP_INLINE_VISIBILITY 1015 future(future&& __rhs) _NOEXCEPT 1016 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1017 future(const future&) = delete; 1018 future& operator=(const future&) = delete; 1019 _LIBCPP_INLINE_VISIBILITY 1020 future& operator=(future&& __rhs) _NOEXCEPT 1021 { 1022 future(std::move(__rhs)).swap(*this); 1023 return *this; 1024 } 1025#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1026private: 1027 future(const future&); 1028 future& operator=(const future&); 1029public: 1030#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1031 ~future(); 1032 shared_future<_Rp> share(); 1033 1034 // retrieving the value 1035 _Rp get(); 1036 1037 _LIBCPP_INLINE_VISIBILITY 1038 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1039 1040 // functions to check state 1041 _LIBCPP_INLINE_VISIBILITY 1042 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 1043 1044 _LIBCPP_INLINE_VISIBILITY 1045 void wait() const {__state_->wait();} 1046 template <class _Rep, class _Period> 1047 _LIBCPP_INLINE_VISIBILITY 1048 future_status 1049 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 1050 {return __state_->wait_for(__rel_time);} 1051 template <class _Clock, class _Duration> 1052 _LIBCPP_INLINE_VISIBILITY 1053 future_status 1054 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 1055 {return __state_->wait_until(__abs_time);} 1056}; 1057 1058template <class _Rp> 1059future<_Rp>::future(__assoc_state<_Rp>* __state) 1060 : __state_(__state) 1061{ 1062#ifndef _LIBCPP_NO_EXCEPTIONS 1063 if (__state_->__has_future_attached()) 1064 throw future_error(make_error_code(future_errc::future_already_retrieved)); 1065#endif 1066 __state_->__add_shared(); 1067 __state_->__set_future_attached(); 1068} 1069 1070struct __release_shared_count 1071{ 1072 void operator()(__shared_count* p) {p->__release_shared();} 1073}; 1074 1075template <class _Rp> 1076future<_Rp>::~future() 1077{ 1078 if (__state_) 1079 __state_->__release_shared(); 1080} 1081 1082template <class _Rp> 1083_Rp 1084future<_Rp>::get() 1085{ 1086 unique_ptr<__shared_count, __release_shared_count> __(__state_); 1087 __assoc_state<_Rp>* __s = __state_; 1088 __state_ = nullptr; 1089 return __s->move(); 1090} 1091 1092template <class _Rp> 1093class _LIBCPP_VISIBLE future<_Rp&> 1094{ 1095 __assoc_state<_Rp&>* __state_; 1096 1097 explicit future(__assoc_state<_Rp&>* __state); 1098 1099 template <class> friend class promise; 1100 template <class> friend class shared_future; 1101 1102#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1103 template <class _R1, class _Fp> 1104 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 1105 template <class _R1, class _Fp> 1106 friend future<_R1> __make_async_assoc_state(_Fp&& __f); 1107#else 1108 template <class _R1, class _Fp> 1109 friend future<_R1> __make_deferred_assoc_state(_Fp __f); 1110 template <class _R1, class _Fp> 1111 friend future<_R1> __make_async_assoc_state(_Fp __f); 1112#endif 1113 1114public: 1115 _LIBCPP_INLINE_VISIBILITY 1116 future() _NOEXCEPT : __state_(nullptr) {} 1117#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1118 _LIBCPP_INLINE_VISIBILITY 1119 future(future&& __rhs) _NOEXCEPT 1120 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1121 future(const future&) = delete; 1122 future& operator=(const future&) = delete; 1123 _LIBCPP_INLINE_VISIBILITY 1124 future& operator=(future&& __rhs) _NOEXCEPT 1125 { 1126 future(std::move(__rhs)).swap(*this); 1127 return *this; 1128 } 1129#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1130private: 1131 future(const future&); 1132 future& operator=(const future&); 1133public: 1134#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1135 ~future(); 1136 shared_future<_Rp&> share(); 1137 1138 // retrieving the value 1139 _Rp& get(); 1140 1141 _LIBCPP_INLINE_VISIBILITY 1142 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1143 1144 // functions to check state 1145 _LIBCPP_INLINE_VISIBILITY 1146 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 1147 1148 _LIBCPP_INLINE_VISIBILITY 1149 void wait() const {__state_->wait();} 1150 template <class _Rep, class _Period> 1151 _LIBCPP_INLINE_VISIBILITY 1152 future_status 1153 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 1154 {return __state_->wait_for(__rel_time);} 1155 template <class _Clock, class _Duration> 1156 _LIBCPP_INLINE_VISIBILITY 1157 future_status 1158 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 1159 {return __state_->wait_until(__abs_time);} 1160}; 1161 1162template <class _Rp> 1163future<_Rp&>::future(__assoc_state<_Rp&>* __state) 1164 : __state_(__state) 1165{ 1166#ifndef _LIBCPP_NO_EXCEPTIONS 1167 if (__state_->__has_future_attached()) 1168 throw future_error(make_error_code(future_errc::future_already_retrieved)); 1169#endif 1170 __state_->__add_shared(); 1171 __state_->__set_future_attached(); 1172} 1173 1174template <class _Rp> 1175future<_Rp&>::~future() 1176{ 1177 if (__state_) 1178 __state_->__release_shared(); 1179} 1180 1181template <class _Rp> 1182_Rp& 1183future<_Rp&>::get() 1184{ 1185 unique_ptr<__shared_count, __release_shared_count> __(__state_); 1186 __assoc_state<_Rp&>* __s = __state_; 1187 __state_ = nullptr; 1188 return __s->copy(); 1189} 1190 1191template <> 1192class _LIBCPP_VISIBLE future<void> 1193{ 1194 __assoc_sub_state* __state_; 1195 1196 explicit future(__assoc_sub_state* __state); 1197 1198 template <class> friend class promise; 1199 template <class> friend class shared_future; 1200 1201#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1202 template <class _R1, class _Fp> 1203 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); 1204 template <class _R1, class _Fp> 1205 friend future<_R1> __make_async_assoc_state(_Fp&& __f); 1206#else 1207 template <class _R1, class _Fp> 1208 friend future<_R1> __make_deferred_assoc_state(_Fp __f); 1209 template <class _R1, class _Fp> 1210 friend future<_R1> __make_async_assoc_state(_Fp __f); 1211#endif 1212 1213public: 1214 _LIBCPP_INLINE_VISIBILITY 1215 future() _NOEXCEPT : __state_(nullptr) {} 1216#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1217 _LIBCPP_INLINE_VISIBILITY 1218 future(future&& __rhs) _NOEXCEPT 1219 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1220 future(const future&) = delete; 1221 future& operator=(const future&) = delete; 1222 _LIBCPP_INLINE_VISIBILITY 1223 future& operator=(future&& __rhs) _NOEXCEPT 1224 { 1225 future(std::move(__rhs)).swap(*this); 1226 return *this; 1227 } 1228#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1229private: 1230 future(const future&); 1231 future& operator=(const future&); 1232public: 1233#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1234 ~future(); 1235 shared_future<void> share(); 1236 1237 // retrieving the value 1238 void get(); 1239 1240 _LIBCPP_INLINE_VISIBILITY 1241 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1242 1243 // functions to check state 1244 _LIBCPP_INLINE_VISIBILITY 1245 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 1246 1247 _LIBCPP_INLINE_VISIBILITY 1248 void wait() const {__state_->wait();} 1249 template <class _Rep, class _Period> 1250 _LIBCPP_INLINE_VISIBILITY 1251 future_status 1252 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 1253 {return __state_->wait_for(__rel_time);} 1254 template <class _Clock, class _Duration> 1255 _LIBCPP_INLINE_VISIBILITY 1256 future_status 1257 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 1258 {return __state_->wait_until(__abs_time);} 1259}; 1260 1261template <class _Rp> 1262inline _LIBCPP_INLINE_VISIBILITY 1263void 1264swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT 1265{ 1266 __x.swap(__y); 1267} 1268 1269// promise<R> 1270 1271template <class _Callable> class packaged_task; 1272 1273template <class _Rp> 1274class _LIBCPP_VISIBLE promise 1275{ 1276 __assoc_state<_Rp>* __state_; 1277 1278 _LIBCPP_INLINE_VISIBILITY 1279 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1280 1281 template <class> friend class packaged_task; 1282public: 1283 promise(); 1284 template <class _Alloc> 1285 promise(allocator_arg_t, const _Alloc& __a); 1286#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1287 _LIBCPP_INLINE_VISIBILITY 1288 promise(promise&& __rhs) _NOEXCEPT 1289 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1290 promise(const promise& __rhs) = delete; 1291#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1292private: 1293 promise(const promise& __rhs); 1294public: 1295#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1296 ~promise(); 1297 1298 // assignment 1299#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1300 _LIBCPP_INLINE_VISIBILITY 1301 promise& operator=(promise&& __rhs) _NOEXCEPT 1302 { 1303 promise(std::move(__rhs)).swap(*this); 1304 return *this; 1305 } 1306 promise& operator=(const promise& __rhs) = delete; 1307#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1308private: 1309 promise& operator=(const promise& __rhs); 1310public: 1311#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1312 _LIBCPP_INLINE_VISIBILITY 1313 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1314 1315 // retrieving the result 1316 future<_Rp> get_future(); 1317 1318 // setting the result 1319 void set_value(const _Rp& __r); 1320#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1321 void set_value(_Rp&& __r); 1322#endif 1323 void set_exception(exception_ptr __p); 1324 1325 // setting the result with deferred notification 1326 void set_value_at_thread_exit(const _Rp& __r); 1327#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1328 void set_value_at_thread_exit(_Rp&& __r); 1329#endif 1330 void set_exception_at_thread_exit(exception_ptr __p); 1331}; 1332 1333template <class _Rp> 1334promise<_Rp>::promise() 1335 : __state_(new __assoc_state<_Rp>) 1336{ 1337} 1338 1339template <class _Rp> 1340template <class _Alloc> 1341promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) 1342{ 1343 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2; 1344 typedef __allocator_destructor<_A2> _D2; 1345 _A2 __a(__a0); 1346 unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1347 ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0); 1348 __state_ = __hold.release(); 1349} 1350 1351template <class _Rp> 1352promise<_Rp>::~promise() 1353{ 1354 if (__state_) 1355 { 1356 if (!__state_->__has_value() && __state_->use_count() > 1) 1357 __state_->set_exception(make_exception_ptr( 1358 future_error(make_error_code(future_errc::broken_promise)) 1359 )); 1360 __state_->__release_shared(); 1361 } 1362} 1363 1364template <class _Rp> 1365future<_Rp> 1366promise<_Rp>::get_future() 1367{ 1368#ifndef _LIBCPP_NO_EXCEPTIONS 1369 if (__state_ == nullptr) 1370 throw future_error(make_error_code(future_errc::no_state)); 1371#endif 1372 return future<_Rp>(__state_); 1373} 1374 1375template <class _Rp> 1376void 1377promise<_Rp>::set_value(const _Rp& __r) 1378{ 1379#ifndef _LIBCPP_NO_EXCEPTIONS 1380 if (__state_ == nullptr) 1381 throw future_error(make_error_code(future_errc::no_state)); 1382#endif 1383 __state_->set_value(__r); 1384} 1385 1386#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1387 1388template <class _Rp> 1389void 1390promise<_Rp>::set_value(_Rp&& __r) 1391{ 1392#ifndef _LIBCPP_NO_EXCEPTIONS 1393 if (__state_ == nullptr) 1394 throw future_error(make_error_code(future_errc::no_state)); 1395#endif 1396 __state_->set_value(_VSTD::move(__r)); 1397} 1398 1399#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1400 1401template <class _Rp> 1402void 1403promise<_Rp>::set_exception(exception_ptr __p) 1404{ 1405#ifndef _LIBCPP_NO_EXCEPTIONS 1406 if (__state_ == nullptr) 1407 throw future_error(make_error_code(future_errc::no_state)); 1408#endif 1409 __state_->set_exception(__p); 1410} 1411 1412template <class _Rp> 1413void 1414promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) 1415{ 1416#ifndef _LIBCPP_NO_EXCEPTIONS 1417 if (__state_ == nullptr) 1418 throw future_error(make_error_code(future_errc::no_state)); 1419#endif 1420 __state_->set_value_at_thread_exit(__r); 1421} 1422 1423#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1424 1425template <class _Rp> 1426void 1427promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) 1428{ 1429#ifndef _LIBCPP_NO_EXCEPTIONS 1430 if (__state_ == nullptr) 1431 throw future_error(make_error_code(future_errc::no_state)); 1432#endif 1433 __state_->set_value_at_thread_exit(_VSTD::move(__r)); 1434} 1435 1436#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1437 1438template <class _Rp> 1439void 1440promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) 1441{ 1442#ifndef _LIBCPP_NO_EXCEPTIONS 1443 if (__state_ == nullptr) 1444 throw future_error(make_error_code(future_errc::no_state)); 1445#endif 1446 __state_->set_exception_at_thread_exit(__p); 1447} 1448 1449// promise<R&> 1450 1451template <class _Rp> 1452class _LIBCPP_VISIBLE promise<_Rp&> 1453{ 1454 __assoc_state<_Rp&>* __state_; 1455 1456 _LIBCPP_INLINE_VISIBILITY 1457 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1458 1459 template <class> friend class packaged_task; 1460 1461public: 1462 promise(); 1463 template <class _Allocator> 1464 promise(allocator_arg_t, const _Allocator& __a); 1465#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1466 _LIBCPP_INLINE_VISIBILITY 1467 promise(promise&& __rhs) _NOEXCEPT 1468 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1469 promise(const promise& __rhs) = delete; 1470#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1471private: 1472 promise(const promise& __rhs); 1473public: 1474#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1475 ~promise(); 1476 1477 // assignment 1478#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1479 _LIBCPP_INLINE_VISIBILITY 1480 promise& operator=(promise&& __rhs) _NOEXCEPT 1481 { 1482 promise(std::move(__rhs)).swap(*this); 1483 return *this; 1484 } 1485 promise& operator=(const promise& __rhs) = delete; 1486#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1487private: 1488 promise& operator=(const promise& __rhs); 1489public: 1490#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1491 _LIBCPP_INLINE_VISIBILITY 1492 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1493 1494 // retrieving the result 1495 future<_Rp&> get_future(); 1496 1497 // setting the result 1498 void set_value(_Rp& __r); 1499 void set_exception(exception_ptr __p); 1500 1501 // setting the result with deferred notification 1502 void set_value_at_thread_exit(_Rp&); 1503 void set_exception_at_thread_exit(exception_ptr __p); 1504}; 1505 1506template <class _Rp> 1507promise<_Rp&>::promise() 1508 : __state_(new __assoc_state<_Rp&>) 1509{ 1510} 1511 1512template <class _Rp> 1513template <class _Alloc> 1514promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) 1515{ 1516 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2; 1517 typedef __allocator_destructor<_A2> _D2; 1518 _A2 __a(__a0); 1519 unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1520 ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0); 1521 __state_ = __hold.release(); 1522} 1523 1524template <class _Rp> 1525promise<_Rp&>::~promise() 1526{ 1527 if (__state_) 1528 { 1529 if (!__state_->__has_value() && __state_->use_count() > 1) 1530 __state_->set_exception(make_exception_ptr( 1531 future_error(make_error_code(future_errc::broken_promise)) 1532 )); 1533 __state_->__release_shared(); 1534 } 1535} 1536 1537template <class _Rp> 1538future<_Rp&> 1539promise<_Rp&>::get_future() 1540{ 1541#ifndef _LIBCPP_NO_EXCEPTIONS 1542 if (__state_ == nullptr) 1543 throw future_error(make_error_code(future_errc::no_state)); 1544#endif 1545 return future<_Rp&>(__state_); 1546} 1547 1548template <class _Rp> 1549void 1550promise<_Rp&>::set_value(_Rp& __r) 1551{ 1552#ifndef _LIBCPP_NO_EXCEPTIONS 1553 if (__state_ == nullptr) 1554 throw future_error(make_error_code(future_errc::no_state)); 1555#endif 1556 __state_->set_value(__r); 1557} 1558 1559template <class _Rp> 1560void 1561promise<_Rp&>::set_exception(exception_ptr __p) 1562{ 1563#ifndef _LIBCPP_NO_EXCEPTIONS 1564 if (__state_ == nullptr) 1565 throw future_error(make_error_code(future_errc::no_state)); 1566#endif 1567 __state_->set_exception(__p); 1568} 1569 1570template <class _Rp> 1571void 1572promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) 1573{ 1574#ifndef _LIBCPP_NO_EXCEPTIONS 1575 if (__state_ == nullptr) 1576 throw future_error(make_error_code(future_errc::no_state)); 1577#endif 1578 __state_->set_value_at_thread_exit(__r); 1579} 1580 1581template <class _Rp> 1582void 1583promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) 1584{ 1585#ifndef _LIBCPP_NO_EXCEPTIONS 1586 if (__state_ == nullptr) 1587 throw future_error(make_error_code(future_errc::no_state)); 1588#endif 1589 __state_->set_exception_at_thread_exit(__p); 1590} 1591 1592// promise<void> 1593 1594template <> 1595class _LIBCPP_VISIBLE promise<void> 1596{ 1597 __assoc_sub_state* __state_; 1598 1599 _LIBCPP_INLINE_VISIBILITY 1600 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} 1601 1602 template <class> friend class packaged_task; 1603 1604public: 1605 promise(); 1606 template <class _Allocator> 1607 promise(allocator_arg_t, const _Allocator& __a); 1608#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1609 _LIBCPP_INLINE_VISIBILITY 1610 promise(promise&& __rhs) _NOEXCEPT 1611 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} 1612 promise(const promise& __rhs) = delete; 1613#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1614private: 1615 promise(const promise& __rhs); 1616public: 1617#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1618 ~promise(); 1619 1620 // assignment 1621#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 1622 _LIBCPP_INLINE_VISIBILITY 1623 promise& operator=(promise&& __rhs) _NOEXCEPT 1624 { 1625 promise(std::move(__rhs)).swap(*this); 1626 return *this; 1627 } 1628 promise& operator=(const promise& __rhs) = delete; 1629#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1630private: 1631 promise& operator=(const promise& __rhs); 1632public: 1633#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 1634 _LIBCPP_INLINE_VISIBILITY 1635 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 1636 1637 // retrieving the result 1638 future<void> get_future(); 1639 1640 // setting the result 1641 void set_value(); 1642 void set_exception(exception_ptr __p); 1643 1644 // setting the result with deferred notification 1645 void set_value_at_thread_exit(); 1646 void set_exception_at_thread_exit(exception_ptr __p); 1647}; 1648 1649template <class _Alloc> 1650promise<void>::promise(allocator_arg_t, const _Alloc& __a0) 1651{ 1652 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2; 1653 typedef __allocator_destructor<_A2> _D2; 1654 _A2 __a(__a0); 1655 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1)); 1656 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0); 1657 __state_ = __hold.release(); 1658} 1659 1660template <class _Rp> 1661inline _LIBCPP_INLINE_VISIBILITY 1662void 1663swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT 1664{ 1665 __x.swap(__y); 1666} 1667 1668template <class _Rp, class _Alloc> 1669 struct _LIBCPP_VISIBLE uses_allocator<promise<_Rp>, _Alloc> 1670 : public true_type {}; 1671 1672#ifndef _LIBCPP_HAS_NO_VARIADICS 1673 1674// packaged_task 1675 1676template<class _Fp> class __packaged_task_base; 1677 1678template<class _Rp, class ..._ArgTypes> 1679class __packaged_task_base<_Rp(_ArgTypes...)> 1680{ 1681 __packaged_task_base(const __packaged_task_base&); 1682 __packaged_task_base& operator=(const __packaged_task_base&); 1683public: 1684 _LIBCPP_INLINE_VISIBILITY 1685 __packaged_task_base() {} 1686 _LIBCPP_INLINE_VISIBILITY 1687 virtual ~__packaged_task_base() {} 1688 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0; 1689 virtual void destroy() = 0; 1690 virtual void destroy_deallocate() = 0; 1691 virtual _Rp operator()(_ArgTypes&& ...) = 0; 1692}; 1693 1694template<class _FD, class _Alloc, class _FB> class __packaged_task_func; 1695 1696template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1697class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> 1698 : public __packaged_task_base<_Rp(_ArgTypes...)> 1699{ 1700 __compressed_pair<_Fp, _Alloc> __f_; 1701public: 1702 _LIBCPP_INLINE_VISIBILITY 1703 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {} 1704 _LIBCPP_INLINE_VISIBILITY 1705 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {} 1706 _LIBCPP_INLINE_VISIBILITY 1707 __packaged_task_func(const _Fp& __f, const _Alloc& __a) 1708 : __f_(__f, __a) {} 1709 _LIBCPP_INLINE_VISIBILITY 1710 __packaged_task_func(_Fp&& __f, const _Alloc& __a) 1711 : __f_(_VSTD::move(__f), __a) {} 1712 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; 1713 virtual void destroy(); 1714 virtual void destroy_deallocate(); 1715 virtual _Rp operator()(_ArgTypes&& ... __args); 1716}; 1717 1718template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1719void 1720__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to( 1721 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT 1722{ 1723 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second())); 1724} 1725 1726template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1727void 1728__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() 1729{ 1730 __f_.~__compressed_pair<_Fp, _Alloc>(); 1731} 1732 1733template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1734void 1735__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() 1736{ 1737 typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap; 1738 _Ap __a(__f_.second()); 1739 __f_.~__compressed_pair<_Fp, _Alloc>(); 1740 __a.deallocate(this, 1); 1741} 1742 1743template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1744_Rp 1745__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) 1746{ 1747 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); 1748} 1749 1750template <class _Callable> class __packaged_task_function; 1751 1752template<class _Rp, class ..._ArgTypes> 1753class __packaged_task_function<_Rp(_ArgTypes...)> 1754{ 1755 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; 1756 aligned_storage<3*sizeof(void*)>::type __buf_; 1757 __base* __f_; 1758 1759public: 1760 typedef _Rp result_type; 1761 1762 // construct/copy/destroy: 1763 _LIBCPP_INLINE_VISIBILITY 1764 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {} 1765 template<class _Fp> 1766 __packaged_task_function(_Fp&& __f); 1767 template<class _Fp, class _Alloc> 1768 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); 1769 1770 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; 1771 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; 1772 1773 __packaged_task_function(const __packaged_task_function&) = delete; 1774 __packaged_task_function& operator=(const __packaged_task_function&) = delete; 1775 1776 ~__packaged_task_function(); 1777 1778 void swap(__packaged_task_function&) _NOEXCEPT; 1779 1780 _Rp operator()(_ArgTypes...) const; 1781}; 1782 1783template<class _Rp, class ..._ArgTypes> 1784__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT 1785{ 1786 if (__f.__f_ == nullptr) 1787 __f_ = nullptr; 1788 else if (__f.__f_ == (__base*)&__f.__buf_) 1789 { 1790 __f_ = (__base*)&__buf_; 1791 __f.__f_->__move_to(__f_); 1792 } 1793 else 1794 { 1795 __f_ = __f.__f_; 1796 __f.__f_ = nullptr; 1797 } 1798} 1799 1800template<class _Rp, class ..._ArgTypes> 1801template <class _Fp> 1802__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) 1803 : __f_(nullptr) 1804{ 1805 typedef typename remove_reference<_Fp>::type _FR; 1806 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; 1807 if (sizeof(_FF) <= sizeof(__buf_)) 1808 { 1809 __f_ = (__base*)&__buf_; 1810 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); 1811 } 1812 else 1813 { 1814 typedef allocator<_FF> _Ap; 1815 _Ap __a; 1816 typedef __allocator_destructor<_Ap> _Dp; 1817 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1818 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a)); 1819 __f_ = __hold.release(); 1820 } 1821} 1822 1823template<class _Rp, class ..._ArgTypes> 1824template <class _Fp, class _Alloc> 1825__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function( 1826 allocator_arg_t, const _Alloc& __a0, _Fp&& __f) 1827 : __f_(nullptr) 1828{ 1829 typedef allocator_traits<_Alloc> __alloc_traits; 1830 typedef typename remove_reference<_Fp>::type _FR; 1831 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; 1832 if (sizeof(_FF) <= sizeof(__buf_)) 1833 { 1834 __f_ = (__base*)&__buf_; 1835 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); 1836 } 1837 else 1838 { 1839 typedef typename __alloc_traits::template 1840#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES 1841 rebind_alloc<_FF> 1842#else 1843 rebind_alloc<_FF>::other 1844#endif 1845 _Ap; 1846 _Ap __a(__a0); 1847 typedef __allocator_destructor<_Ap> _Dp; 1848 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1849 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a)); 1850 __f_ = __hold.release(); 1851 } 1852} 1853 1854template<class _Rp, class ..._ArgTypes> 1855__packaged_task_function<_Rp(_ArgTypes...)>& 1856__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT 1857{ 1858 if (__f_ == (__base*)&__buf_) 1859 __f_->destroy(); 1860 else if (__f_) 1861 __f_->destroy_deallocate(); 1862 __f_ = nullptr; 1863 if (__f.__f_ == nullptr) 1864 __f_ = nullptr; 1865 else if (__f.__f_ == (__base*)&__f.__buf_) 1866 { 1867 __f_ = (__base*)&__buf_; 1868 __f.__f_->__move_to(__f_); 1869 } 1870 else 1871 { 1872 __f_ = __f.__f_; 1873 __f.__f_ = nullptr; 1874 } 1875 return *this; 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) _NOEXCEPT 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() _NOEXCEPT : __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(const packaged_task&) = delete; 1958 packaged_task& operator=(const packaged_task&) = delete; 1959 1960 // move support 1961 _LIBCPP_INLINE_VISIBILITY 1962 packaged_task(packaged_task&& __other) _NOEXCEPT 1963 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 1964 _LIBCPP_INLINE_VISIBILITY 1965 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 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) _NOEXCEPT 1973 { 1974 __f_.swap(__other.__f_); 1975 __p_.swap(__other.__p_); 1976 } 1977 1978 _LIBCPP_INLINE_VISIBILITY 1979 bool valid() const _NOEXCEPT {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() _NOEXCEPT : __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(const packaged_task&) = delete; 2073 packaged_task& operator=(const packaged_task&) = delete; 2074 2075 // move support 2076 _LIBCPP_INLINE_VISIBILITY 2077 packaged_task(packaged_task&& __other) _NOEXCEPT 2078 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 2079 _LIBCPP_INLINE_VISIBILITY 2080 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 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) _NOEXCEPT 2088 { 2089 __f_.swap(__other.__f_); 2090 __p_.swap(__other.__p_); 2091 } 2092 2093 _LIBCPP_INLINE_VISIBILITY 2094 bool valid() const _NOEXCEPT {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) _NOEXCEPT 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() _NOEXCEPT : __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) _NOEXCEPT : __state_(__f.__state_) 2275 {__f.__state_ = nullptr;} 2276 _LIBCPP_INLINE_VISIBILITY 2277 shared_future(shared_future&& __rhs) _NOEXCEPT : __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) _NOEXCEPT 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) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2297 2298 // functions to check state 2299 _LIBCPP_INLINE_VISIBILITY 2300 bool valid() const _NOEXCEPT {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() _NOEXCEPT : __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) _NOEXCEPT : __state_(__f.__state_) 2349 {__f.__state_ = nullptr;} 2350 _LIBCPP_INLINE_VISIBILITY 2351 shared_future(shared_future&& __rhs) _NOEXCEPT : __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) _NOEXCEPT 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) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2371 2372 // functions to check state 2373 _LIBCPP_INLINE_VISIBILITY 2374 bool valid() const _NOEXCEPT {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() _NOEXCEPT : __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) _NOEXCEPT : __state_(__f.__state_) 2423 {__f.__state_ = nullptr;} 2424 _LIBCPP_INLINE_VISIBILITY 2425 shared_future(shared_future&& __rhs) _NOEXCEPT : __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) _NOEXCEPT 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) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2445 2446 // functions to check state 2447 _LIBCPP_INLINE_VISIBILITY 2448 bool valid() const _NOEXCEPT {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) _NOEXCEPT 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