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