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