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