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