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