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