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