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