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