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