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