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