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 promise; 966template <class _Rp> class shared_future; 967 968// future 969 970template <class _Rp> class 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} 1876 1877template<class _Rp, class ..._ArgTypes> 1878__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() 1879{ 1880 if (__f_ == (__base*)&__buf_) 1881 __f_->destroy(); 1882 else if (__f_) 1883 __f_->destroy_deallocate(); 1884} 1885 1886template<class _Rp, class ..._ArgTypes> 1887void 1888__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT 1889{ 1890 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 1891 { 1892 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 1893 __base* __t = (__base*)&__tempbuf; 1894 __f_->__move_to(__t); 1895 __f_->destroy(); 1896 __f_ = nullptr; 1897 __f.__f_->__move_to((__base*)&__buf_); 1898 __f.__f_->destroy(); 1899 __f.__f_ = nullptr; 1900 __f_ = (__base*)&__buf_; 1901 __t->__move_to((__base*)&__f.__buf_); 1902 __t->destroy(); 1903 __f.__f_ = (__base*)&__f.__buf_; 1904 } 1905 else if (__f_ == (__base*)&__buf_) 1906 { 1907 __f_->__move_to((__base*)&__f.__buf_); 1908 __f_->destroy(); 1909 __f_ = __f.__f_; 1910 __f.__f_ = (__base*)&__f.__buf_; 1911 } 1912 else if (__f.__f_ == (__base*)&__f.__buf_) 1913 { 1914 __f.__f_->__move_to((__base*)&__buf_); 1915 __f.__f_->destroy(); 1916 __f.__f_ = __f_; 1917 __f_ = (__base*)&__buf_; 1918 } 1919 else 1920 _VSTD::swap(__f_, __f.__f_); 1921} 1922 1923template<class _Rp, class ..._ArgTypes> 1924inline _LIBCPP_INLINE_VISIBILITY 1925_Rp 1926__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const 1927{ 1928 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); 1929} 1930 1931template<class _Rp, class ..._ArgTypes> 1932class _LIBCPP_VISIBLE packaged_task<_Rp(_ArgTypes...)> 1933{ 1934public: 1935 typedef _Rp result_type; 1936 1937private: 1938 __packaged_task_function<result_type(_ArgTypes...)> __f_; 1939 promise<result_type> __p_; 1940 1941public: 1942 // construction and destruction 1943 _LIBCPP_INLINE_VISIBILITY 1944 packaged_task() _NOEXCEPT : __p_(nullptr) {} 1945 template <class _Fp> 1946 _LIBCPP_INLINE_VISIBILITY 1947 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} 1948 template <class _Fp, class _Allocator> 1949 _LIBCPP_INLINE_VISIBILITY 1950 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 1951 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), 1952 __p_(allocator_arg, __a) {} 1953 // ~packaged_task() = default; 1954 1955 // no copy 1956 packaged_task(const packaged_task&) = delete; 1957 packaged_task& operator=(const packaged_task&) = delete; 1958 1959 // move support 1960 _LIBCPP_INLINE_VISIBILITY 1961 packaged_task(packaged_task&& __other) _NOEXCEPT 1962 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 1963 _LIBCPP_INLINE_VISIBILITY 1964 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 1965 { 1966 __f_ = _VSTD::move(__other.__f_); 1967 __p_ = _VSTD::move(__other.__p_); 1968 return *this; 1969 } 1970 _LIBCPP_INLINE_VISIBILITY 1971 void swap(packaged_task& __other) _NOEXCEPT 1972 { 1973 __f_.swap(__other.__f_); 1974 __p_.swap(__other.__p_); 1975 } 1976 1977 _LIBCPP_INLINE_VISIBILITY 1978 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} 1979 1980 // result retrieval 1981 _LIBCPP_INLINE_VISIBILITY 1982 future<result_type> get_future() {return __p_.get_future();} 1983 1984 // execution 1985 void operator()(_ArgTypes... __args); 1986 void make_ready_at_thread_exit(_ArgTypes... __args); 1987 1988 void reset(); 1989}; 1990 1991template<class _Rp, class ..._ArgTypes> 1992void 1993packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) 1994{ 1995#ifndef _LIBCPP_NO_EXCEPTIONS 1996 if (__p_.__state_ == nullptr) 1997 throw future_error(make_error_code(future_errc::no_state)); 1998 if (__p_.__state_->__has_value()) 1999 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 2000 try 2001 { 2002#endif // _LIBCPP_NO_EXCEPTIONS 2003 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...)); 2004#ifndef _LIBCPP_NO_EXCEPTIONS 2005 } 2006 catch (...) 2007 { 2008 __p_.set_exception(current_exception()); 2009 } 2010#endif // _LIBCPP_NO_EXCEPTIONS 2011} 2012 2013template<class _Rp, class ..._ArgTypes> 2014void 2015packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) 2016{ 2017#ifndef _LIBCPP_NO_EXCEPTIONS 2018 if (__p_.__state_ == nullptr) 2019 throw future_error(make_error_code(future_errc::no_state)); 2020 if (__p_.__state_->__has_value()) 2021 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 2022 try 2023 { 2024#endif // _LIBCPP_NO_EXCEPTIONS 2025 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...)); 2026#ifndef _LIBCPP_NO_EXCEPTIONS 2027 } 2028 catch (...) 2029 { 2030 __p_.set_exception_at_thread_exit(current_exception()); 2031 } 2032#endif // _LIBCPP_NO_EXCEPTIONS 2033} 2034 2035template<class _Rp, class ..._ArgTypes> 2036void 2037packaged_task<_Rp(_ArgTypes...)>::reset() 2038{ 2039#ifndef _LIBCPP_NO_EXCEPTIONS 2040 if (!valid()) 2041 throw future_error(make_error_code(future_errc::no_state)); 2042#endif // _LIBCPP_NO_EXCEPTIONS 2043 __p_ = promise<result_type>(); 2044} 2045 2046template<class ..._ArgTypes> 2047class _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)> 2048{ 2049public: 2050 typedef void result_type; 2051 2052private: 2053 __packaged_task_function<result_type(_ArgTypes...)> __f_; 2054 promise<result_type> __p_; 2055 2056public: 2057 // construction and destruction 2058 _LIBCPP_INLINE_VISIBILITY 2059 packaged_task() _NOEXCEPT : __p_(nullptr) {} 2060 template <class _Fp> 2061 _LIBCPP_INLINE_VISIBILITY 2062 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} 2063 template <class _Fp, class _Allocator> 2064 _LIBCPP_INLINE_VISIBILITY 2065 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 2066 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), 2067 __p_(allocator_arg, __a) {} 2068 // ~packaged_task() = default; 2069 2070 // no copy 2071 packaged_task(const packaged_task&) = delete; 2072 packaged_task& operator=(const packaged_task&) = delete; 2073 2074 // move support 2075 _LIBCPP_INLINE_VISIBILITY 2076 packaged_task(packaged_task&& __other) _NOEXCEPT 2077 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 2078 _LIBCPP_INLINE_VISIBILITY 2079 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 2080 { 2081 __f_ = _VSTD::move(__other.__f_); 2082 __p_ = _VSTD::move(__other.__p_); 2083 return *this; 2084 } 2085 _LIBCPP_INLINE_VISIBILITY 2086 void swap(packaged_task& __other) _NOEXCEPT 2087 { 2088 __f_.swap(__other.__f_); 2089 __p_.swap(__other.__p_); 2090 } 2091 2092 _LIBCPP_INLINE_VISIBILITY 2093 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} 2094 2095 // result retrieval 2096 _LIBCPP_INLINE_VISIBILITY 2097 future<result_type> get_future() {return __p_.get_future();} 2098 2099 // execution 2100 void operator()(_ArgTypes... __args); 2101 void make_ready_at_thread_exit(_ArgTypes... __args); 2102 2103 void reset(); 2104}; 2105 2106template<class ..._ArgTypes> 2107void 2108packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) 2109{ 2110#ifndef _LIBCPP_NO_EXCEPTIONS 2111 if (__p_.__state_ == nullptr) 2112 throw future_error(make_error_code(future_errc::no_state)); 2113 if (__p_.__state_->__has_value()) 2114 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 2115 try 2116 { 2117#endif // _LIBCPP_NO_EXCEPTIONS 2118 __f_(_VSTD::forward<_ArgTypes>(__args)...); 2119 __p_.set_value(); 2120#ifndef _LIBCPP_NO_EXCEPTIONS 2121 } 2122 catch (...) 2123 { 2124 __p_.set_exception(current_exception()); 2125 } 2126#endif // _LIBCPP_NO_EXCEPTIONS 2127} 2128 2129template<class ..._ArgTypes> 2130void 2131packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) 2132{ 2133#ifndef _LIBCPP_NO_EXCEPTIONS 2134 if (__p_.__state_ == nullptr) 2135 throw future_error(make_error_code(future_errc::no_state)); 2136 if (__p_.__state_->__has_value()) 2137 throw future_error(make_error_code(future_errc::promise_already_satisfied)); 2138 try 2139 { 2140#endif // _LIBCPP_NO_EXCEPTIONS 2141 __f_(_VSTD::forward<_ArgTypes>(__args)...); 2142 __p_.set_value_at_thread_exit(); 2143#ifndef _LIBCPP_NO_EXCEPTIONS 2144 } 2145 catch (...) 2146 { 2147 __p_.set_exception_at_thread_exit(current_exception()); 2148 } 2149#endif // _LIBCPP_NO_EXCEPTIONS 2150} 2151 2152template<class ..._ArgTypes> 2153void 2154packaged_task<void(_ArgTypes...)>::reset() 2155{ 2156#ifndef _LIBCPP_NO_EXCEPTIONS 2157 if (!valid()) 2158 throw future_error(make_error_code(future_errc::no_state)); 2159#endif // _LIBCPP_NO_EXCEPTIONS 2160 __p_ = promise<result_type>(); 2161} 2162 2163template <class _Callable> 2164inline _LIBCPP_INLINE_VISIBILITY 2165void 2166swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT 2167{ 2168 __x.swap(__y); 2169} 2170 2171template <class _Callable, class _Alloc> 2172struct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc> 2173 : public true_type {}; 2174 2175template <class _Rp, class _Fp> 2176future<_Rp> 2177#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2178__make_deferred_assoc_state(_Fp&& __f) 2179#else 2180__make_deferred_assoc_state(_Fp __f) 2181#endif 2182{ 2183 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> 2184 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); 2185 return future<_Rp>(__h.get()); 2186} 2187 2188template <class _Rp, class _Fp> 2189future<_Rp> 2190#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2191__make_async_assoc_state(_Fp&& __f) 2192#else 2193__make_async_assoc_state(_Fp __f) 2194#endif 2195{ 2196 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> 2197 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); 2198 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach(); 2199 return future<_Rp>(__h.get()); 2200} 2201 2202template <class _Fp, class... _Args> 2203class __async_func 2204{ 2205 tuple<_Fp, _Args...> __f_; 2206 2207public: 2208 typedef typename __invoke_of<_Fp, _Args...>::type _Rp; 2209 2210 _LIBCPP_INLINE_VISIBILITY 2211 explicit __async_func(_Fp&& __f, _Args&&... __args) 2212 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {} 2213 2214 _LIBCPP_INLINE_VISIBILITY 2215 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {} 2216 2217 _Rp operator()() 2218 { 2219 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index; 2220 return __execute(_Index()); 2221 } 2222private: 2223 template <size_t ..._Indices> 2224 _Rp 2225 __execute(__tuple_indices<_Indices...>) 2226 { 2227 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); 2228 } 2229}; 2230 2231template <class _Fp, class... _Args> 2232future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> 2233async(launch __policy, _Fp&& __f, _Args&&... __args) 2234{ 2235 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF; 2236 typedef typename _BF::_Rp _Rp; 2237 future<_Rp> __r; 2238 if (int(__policy) & int(launch::async)) 2239 __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), 2240 __decay_copy(_VSTD::forward<_Args>(__args))...)); 2241 else if (int(__policy) & int(launch::deferred)) 2242 __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)), 2243 __decay_copy(_VSTD::forward<_Args>(__args))...)); 2244 return __r; 2245} 2246 2247template <class _Fp, class... _Args> 2248inline _LIBCPP_INLINE_VISIBILITY 2249future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> 2250async(_Fp&& __f, _Args&&... __args) 2251{ 2252 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f), 2253 _VSTD::forward<_Args>(__args)...); 2254} 2255 2256#endif // _LIBCPP_HAS_NO_VARIADICS 2257 2258// shared_future 2259 2260template <class _Rp> 2261class _LIBCPP_VISIBLE shared_future 2262{ 2263 __assoc_state<_Rp>* __state_; 2264 2265public: 2266 _LIBCPP_INLINE_VISIBILITY 2267 shared_future() _NOEXCEPT : __state_(nullptr) {} 2268 _LIBCPP_INLINE_VISIBILITY 2269 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) 2270 {if (__state_) __state_->__add_shared();} 2271#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2272 _LIBCPP_INLINE_VISIBILITY 2273 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) 2274 {__f.__state_ = nullptr;} 2275 _LIBCPP_INLINE_VISIBILITY 2276 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 2277 {__rhs.__state_ = nullptr;} 2278#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2279 ~shared_future(); 2280 shared_future& operator=(const shared_future& __rhs); 2281#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2282 _LIBCPP_INLINE_VISIBILITY 2283 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 2284 { 2285 shared_future(std::move(__rhs)).swap(*this); 2286 return *this; 2287 } 2288#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2289 2290 // retrieving the value 2291 _LIBCPP_INLINE_VISIBILITY 2292 const _Rp& get() const {return __state_->copy();} 2293 2294 _LIBCPP_INLINE_VISIBILITY 2295 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2296 2297 // functions to check state 2298 _LIBCPP_INLINE_VISIBILITY 2299 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 2300 2301 _LIBCPP_INLINE_VISIBILITY 2302 void wait() const {__state_->wait();} 2303 template <class _Rep, class _Period> 2304 _LIBCPP_INLINE_VISIBILITY 2305 future_status 2306 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 2307 {return __state_->wait_for(__rel_time);} 2308 template <class _Clock, class _Duration> 2309 _LIBCPP_INLINE_VISIBILITY 2310 future_status 2311 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 2312 {return __state_->wait_until(__abs_time);} 2313}; 2314 2315template <class _Rp> 2316shared_future<_Rp>::~shared_future() 2317{ 2318 if (__state_) 2319 __state_->__release_shared(); 2320} 2321 2322template <class _Rp> 2323shared_future<_Rp>& 2324shared_future<_Rp>::operator=(const shared_future& __rhs) 2325{ 2326 if (__rhs.__state_) 2327 __rhs.__state_->__add_shared(); 2328 if (__state_) 2329 __state_->__release_shared(); 2330 __state_ = __rhs.__state_; 2331 return *this; 2332} 2333 2334template <class _Rp> 2335class _LIBCPP_VISIBLE shared_future<_Rp&> 2336{ 2337 __assoc_state<_Rp&>* __state_; 2338 2339public: 2340 _LIBCPP_INLINE_VISIBILITY 2341 shared_future() _NOEXCEPT : __state_(nullptr) {} 2342 _LIBCPP_INLINE_VISIBILITY 2343 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) 2344 {if (__state_) __state_->__add_shared();} 2345#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2346 _LIBCPP_INLINE_VISIBILITY 2347 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) 2348 {__f.__state_ = nullptr;} 2349 _LIBCPP_INLINE_VISIBILITY 2350 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 2351 {__rhs.__state_ = nullptr;} 2352#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2353 ~shared_future(); 2354 shared_future& operator=(const shared_future& __rhs); 2355#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2356 _LIBCPP_INLINE_VISIBILITY 2357 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 2358 { 2359 shared_future(std::move(__rhs)).swap(*this); 2360 return *this; 2361 } 2362#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2363 2364 // retrieving the value 2365 _LIBCPP_INLINE_VISIBILITY 2366 _Rp& get() const {return __state_->copy();} 2367 2368 _LIBCPP_INLINE_VISIBILITY 2369 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2370 2371 // functions to check state 2372 _LIBCPP_INLINE_VISIBILITY 2373 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 2374 2375 _LIBCPP_INLINE_VISIBILITY 2376 void wait() const {__state_->wait();} 2377 template <class _Rep, class _Period> 2378 _LIBCPP_INLINE_VISIBILITY 2379 future_status 2380 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 2381 {return __state_->wait_for(__rel_time);} 2382 template <class _Clock, class _Duration> 2383 _LIBCPP_INLINE_VISIBILITY 2384 future_status 2385 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 2386 {return __state_->wait_until(__abs_time);} 2387}; 2388 2389template <class _Rp> 2390shared_future<_Rp&>::~shared_future() 2391{ 2392 if (__state_) 2393 __state_->__release_shared(); 2394} 2395 2396template <class _Rp> 2397shared_future<_Rp&>& 2398shared_future<_Rp&>::operator=(const shared_future& __rhs) 2399{ 2400 if (__rhs.__state_) 2401 __rhs.__state_->__add_shared(); 2402 if (__state_) 2403 __state_->__release_shared(); 2404 __state_ = __rhs.__state_; 2405 return *this; 2406} 2407 2408template <> 2409class _LIBCPP_VISIBLE shared_future<void> 2410{ 2411 __assoc_sub_state* __state_; 2412 2413public: 2414 _LIBCPP_INLINE_VISIBILITY 2415 shared_future() _NOEXCEPT : __state_(nullptr) {} 2416 _LIBCPP_INLINE_VISIBILITY 2417 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) 2418 {if (__state_) __state_->__add_shared();} 2419#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2420 _LIBCPP_INLINE_VISIBILITY 2421 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) 2422 {__f.__state_ = nullptr;} 2423 _LIBCPP_INLINE_VISIBILITY 2424 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) 2425 {__rhs.__state_ = nullptr;} 2426#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2427 ~shared_future(); 2428 shared_future& operator=(const shared_future& __rhs); 2429#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2430 _LIBCPP_INLINE_VISIBILITY 2431 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT 2432 { 2433 shared_future(std::move(__rhs)).swap(*this); 2434 return *this; 2435 } 2436#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2437 2438 // retrieving the value 2439 _LIBCPP_INLINE_VISIBILITY 2440 void get() const {__state_->copy();} 2441 2442 _LIBCPP_INLINE_VISIBILITY 2443 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} 2444 2445 // functions to check state 2446 _LIBCPP_INLINE_VISIBILITY 2447 bool valid() const _NOEXCEPT {return __state_ != nullptr;} 2448 2449 _LIBCPP_INLINE_VISIBILITY 2450 void wait() const {__state_->wait();} 2451 template <class _Rep, class _Period> 2452 _LIBCPP_INLINE_VISIBILITY 2453 future_status 2454 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 2455 {return __state_->wait_for(__rel_time);} 2456 template <class _Clock, class _Duration> 2457 _LIBCPP_INLINE_VISIBILITY 2458 future_status 2459 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 2460 {return __state_->wait_until(__abs_time);} 2461}; 2462 2463template <class _Rp> 2464inline _LIBCPP_INLINE_VISIBILITY 2465void 2466swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT 2467{ 2468 __x.swap(__y); 2469} 2470 2471template <class _Rp> 2472inline _LIBCPP_INLINE_VISIBILITY 2473shared_future<_Rp> 2474future<_Rp>::share() 2475{ 2476 return shared_future<_Rp>(_VSTD::move(*this)); 2477} 2478 2479template <class _Rp> 2480inline _LIBCPP_INLINE_VISIBILITY 2481shared_future<_Rp&> 2482future<_Rp&>::share() 2483{ 2484 return shared_future<_Rp&>(_VSTD::move(*this)); 2485} 2486 2487#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 2488 2489inline _LIBCPP_INLINE_VISIBILITY 2490shared_future<void> 2491future<void>::share() 2492{ 2493 return shared_future<void>(_VSTD::move(*this)); 2494} 2495 2496#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 2497 2498_LIBCPP_END_NAMESPACE_STD 2499 2500#endif // _LIBCPP_FUTURE 2501