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