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