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