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