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