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