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