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