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