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