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