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