1// -*- C++ -*- 2//===--------------------------- future -----------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_FUTURE 11#define _LIBCPP_FUTURE 12 13/* 14 future synopsis 15 16namespace std 17{ 18 19enum class future_errc 20{ 21 future_already_retrieved = 1, 22 promise_already_satisfied, 23 no_state, 24 broken_promise 25}; 26 27enum class launch 28{ 29 async = 1, 30 deferred = 2, 31 any = async | deferred 32}; 33 34enum class future_status 35{ 36 ready, 37 timeout, 38 deferred 39}; 40 41template <> struct is_error_code_enum<future_errc> : public true_type { }; 42error_code make_error_code(future_errc e) noexcept; 43error_condition make_error_condition(future_errc e) noexcept; 44 45const error_category& future_category() noexcept; 46 47class future_error 48 : public logic_error 49{ 50public: 51 future_error(error_code ec); // exposition only 52 explicit future_error(future_errc); // C++17 53 const error_code& code() const noexcept; 54 const char* what() const noexcept; 55}; 56 57template <class R> 58class promise 59{ 60public: 61 promise(); 62 template <class Allocator> 63 promise(allocator_arg_t, const Allocator& a); 64 promise(promise&& rhs) noexcept; 65 promise(const promise& rhs) = delete; 66 ~promise(); 67 68 // assignment 69 promise& operator=(promise&& rhs) noexcept; 70 promise& operator=(const promise& rhs) = delete; 71 void swap(promise& other) noexcept; 72 73 // retrieving the result 74 future<R> get_future(); 75 76 // setting the result 77 void set_value(const R& r); 78 void set_value(R&& r); 79 void set_exception(exception_ptr p); 80 81 // setting the result with deferred notification 82 void set_value_at_thread_exit(const R& r); 83 void set_value_at_thread_exit(R&& r); 84 void set_exception_at_thread_exit(exception_ptr p); 85}; 86 87template <class R> 88class promise<R&> 89{ 90public: 91 promise(); 92 template <class Allocator> 93 promise(allocator_arg_t, const Allocator& a); 94 promise(promise&& rhs) noexcept; 95 promise(const promise& rhs) = delete; 96 ~promise(); 97 98 // assignment 99 promise& operator=(promise&& rhs) noexcept; 100 promise& operator=(const promise& rhs) = delete; 101 void swap(promise& other) noexcept; 102 103 // retrieving the result 104 future<R&> get_future(); 105 106 // setting the result 107 void set_value(R& r); 108 void set_exception(exception_ptr p); 109 110 // setting the result with deferred notification 111 void set_value_at_thread_exit(R&); 112 void set_exception_at_thread_exit(exception_ptr p); 113}; 114 115template <> 116class promise<void> 117{ 118public: 119 promise(); 120 template <class Allocator> 121 promise(allocator_arg_t, const Allocator& a); 122 promise(promise&& rhs) noexcept; 123 promise(const promise& rhs) = delete; 124 ~promise(); 125 126 // assignment 127 promise& operator=(promise&& rhs) noexcept; 128 promise& operator=(const promise& rhs) = delete; 129 void swap(promise& other) noexcept; 130 131 // retrieving the result 132 future<void> get_future(); 133 134 // setting the result 135 void set_value(); 136 void set_exception(exception_ptr p); 137 138 // setting the result with deferred notification 139 void set_value_at_thread_exit(); 140 void set_exception_at_thread_exit(exception_ptr p); 141}; 142 143template <class R> void swap(promise<R>& x, promise<R>& y) noexcept; 144 145template <class R, class Alloc> 146 struct uses_allocator<promise<R>, Alloc> : public true_type {}; 147 148template <class R> 149class future 150{ 151public: 152 future() noexcept; 153 future(future&&) noexcept; 154 future(const future& rhs) = delete; 155 ~future(); 156 future& operator=(const future& rhs) = delete; 157 future& operator=(future&&) noexcept; 158 shared_future<R> share() noexcept; 159 160 // retrieving the value 161 R get(); 162 163 // functions to check state 164 bool valid() const noexcept; 165 166 void wait() const; 167 template <class Rep, class Period> 168 future_status 169 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 170 template <class Clock, class Duration> 171 future_status 172 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 173}; 174 175template <class R> 176class future<R&> 177{ 178public: 179 future() noexcept; 180 future(future&&) noexcept; 181 future(const future& rhs) = delete; 182 ~future(); 183 future& operator=(const future& rhs) = delete; 184 future& operator=(future&&) noexcept; 185 shared_future<R&> share() noexcept; 186 187 // retrieving the value 188 R& get(); 189 190 // functions to check state 191 bool valid() const noexcept; 192 193 void wait() const; 194 template <class Rep, class Period> 195 future_status 196 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 197 template <class Clock, class Duration> 198 future_status 199 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 200}; 201 202template <> 203class future<void> 204{ 205public: 206 future() noexcept; 207 future(future&&) noexcept; 208 future(const future& rhs) = delete; 209 ~future(); 210 future& operator=(const future& rhs) = delete; 211 future& operator=(future&&) noexcept; 212 shared_future<void> share() noexcept; 213 214 // retrieving the value 215 void get(); 216 217 // functions to check state 218 bool valid() const noexcept; 219 220 void wait() const; 221 template <class Rep, class Period> 222 future_status 223 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 224 template <class Clock, class Duration> 225 future_status 226 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 227}; 228 229template <class R> 230class shared_future 231{ 232public: 233 shared_future() noexcept; 234 shared_future(const shared_future& rhs); 235 shared_future(future<R>&&) noexcept; 236 shared_future(shared_future&& rhs) noexcept; 237 ~shared_future(); 238 shared_future& operator=(const shared_future& rhs); 239 shared_future& operator=(shared_future&& rhs) noexcept; 240 241 // retrieving the value 242 const R& get() const; 243 244 // functions to check state 245 bool valid() const noexcept; 246 247 void wait() const; 248 template <class Rep, class Period> 249 future_status 250 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 251 template <class Clock, class Duration> 252 future_status 253 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 254}; 255 256template <class R> 257class shared_future<R&> 258{ 259public: 260 shared_future() noexcept; 261 shared_future(const shared_future& rhs); 262 shared_future(future<R&>&&) noexcept; 263 shared_future(shared_future&& rhs) noexcept; 264 ~shared_future(); 265 shared_future& operator=(const shared_future& rhs); 266 shared_future& operator=(shared_future&& rhs) noexcept; 267 268 // retrieving the value 269 R& get() const; 270 271 // functions to check state 272 bool valid() const noexcept; 273 274 void wait() const; 275 template <class Rep, class Period> 276 future_status 277 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 278 template <class Clock, class Duration> 279 future_status 280 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 281}; 282 283template <> 284class shared_future<void> 285{ 286public: 287 shared_future() noexcept; 288 shared_future(const shared_future& rhs); 289 shared_future(future<void>&&) noexcept; 290 shared_future(shared_future&& rhs) noexcept; 291 ~shared_future(); 292 shared_future& operator=(const shared_future& rhs); 293 shared_future& operator=(shared_future&& rhs) noexcept; 294 295 // retrieving the value 296 void get() const; 297 298 // functions to check state 299 bool valid() const noexcept; 300 301 void wait() const; 302 template <class Rep, class Period> 303 future_status 304 wait_for(const chrono::duration<Rep, Period>& rel_time) const; 305 template <class Clock, class Duration> 306 future_status 307 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; 308}; 309 310template <class F, class... Args> 311 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 312 async(F&& f, Args&&... args); 313 314template <class F, class... Args> 315 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> 316 async(launch policy, F&& f, Args&&... args); 317 318template <class> class packaged_task; // undefined 319 320template <class R, class... ArgTypes> 321class packaged_task<R(ArgTypes...)> 322{ 323public: 324 typedef R result_type; // extension 325 326 // construction and destruction 327 packaged_task() noexcept; 328 template <class F> 329 explicit packaged_task(F&& f); 330 template <class F, class Allocator> 331 packaged_task(allocator_arg_t, const Allocator& a, F&& f); 332 ~packaged_task(); 333 334 // no copy 335 packaged_task(const packaged_task&) = delete; 336 packaged_task& operator=(const packaged_task&) = delete; 337 338 // move support 339 packaged_task(packaged_task&& other) noexcept; 340 packaged_task& operator=(packaged_task&& other) noexcept; 341 void swap(packaged_task& other) noexcept; 342 343 bool valid() const noexcept; 344 345 // result retrieval 346 future<R> get_future(); 347 348 // execution 349 void operator()(ArgTypes... ); 350 void make_ready_at_thread_exit(ArgTypes...); 351 352 void reset(); 353}; 354 355template <class R> 356 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept; 357 358template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; 359 360} // std 361 362*/ 363 364#include <__config> 365#include <system_error> 366#include <memory> 367#include <chrono> 368#include <exception> 369#include <mutex> 370#include <thread> 371 372#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 373#pragma GCC system_header 374#endif 375 376#ifdef _LIBCPP_HAS_NO_THREADS 377#error <future> is not supported on this single threaded system 378#else // !_LIBCPP_HAS_NO_THREADS 379 380_LIBCPP_BEGIN_NAMESPACE_STD 381 382//enum class future_errc 383_LIBCPP_DECLARE_STRONG_ENUM(future_errc) 384{ 385 future_already_retrieved = 1, 386 promise_already_satisfied, 387 no_state, 388 broken_promise 389}; 390_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc) 391 392template <> 393struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {}; 394 395#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS 396template <> 397struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { }; 398#endif 399 400//enum class launch 401_LIBCPP_DECLARE_STRONG_ENUM(launch) 402{ 403 async = 1, 404 deferred = 2, 405 any = async | deferred 406}; 407_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch) 408 409#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS 410 411typedef underlying_type<launch>::type __launch_underlying_type; 412 413inline _LIBCPP_INLINE_VISIBILITY 414_LIBCPP_CONSTEXPR 415launch 416operator&(launch __x, launch __y) 417{ 418 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) & 419 static_cast<__launch_underlying_type>(__y)); 420} 421 422inline _LIBCPP_INLINE_VISIBILITY 423_LIBCPP_CONSTEXPR 424launch 425operator|(launch __x, launch __y) 426{ 427 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) | 428 static_cast<__launch_underlying_type>(__y)); 429} 430 431inline _LIBCPP_INLINE_VISIBILITY 432_LIBCPP_CONSTEXPR 433launch 434operator^(launch __x, launch __y) 435{ 436 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^ 437 static_cast<__launch_underlying_type>(__y)); 438} 439 440inline _LIBCPP_INLINE_VISIBILITY 441_LIBCPP_CONSTEXPR 442launch 443operator~(launch __x) 444{ 445 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3); 446} 447 448inline _LIBCPP_INLINE_VISIBILITY 449launch& 450operator&=(launch& __x, launch __y) 451{ 452 __x = __x & __y; return __x; 453} 454 455inline _LIBCPP_INLINE_VISIBILITY 456launch& 457operator|=(launch& __x, launch __y) 458{ 459 __x = __x | __y; return __x; 460} 461 462inline _LIBCPP_INLINE_VISIBILITY 463launch& 464operator^=(launch& __x, launch __y) 465{ 466 __x = __x ^ __y; return __x; 467} 468 469#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS 470 471//enum class future_status 472_LIBCPP_DECLARE_STRONG_ENUM(future_status) 473{ 474 ready, 475 timeout, 476 deferred 477}; 478_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status) 479 480_LIBCPP_FUNC_VIS 481const error_category& future_category() _NOEXCEPT; 482 483inline _LIBCPP_INLINE_VISIBILITY 484error_code 485make_error_code(future_errc __e) _NOEXCEPT 486{ 487 return error_code(static_cast<int>(__e), future_category()); 488} 489 490inline _LIBCPP_INLINE_VISIBILITY 491error_condition 492make_error_condition(future_errc __e) _NOEXCEPT 493{ 494 return error_condition(static_cast<int>(__e), future_category()); 495} 496 497class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error 498 : public logic_error 499{ 500 error_code __ec_; 501public: 502 future_error(error_code __ec); 503#if _LIBCPP_STD_VERS > 14 504 explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {} 505#endif 506 _LIBCPP_INLINE_VISIBILITY 507 const error_code& code() const _NOEXCEPT {return __ec_;} 508 509 future_error(const future_error&) _NOEXCEPT = default; 510 virtual ~future_error() _NOEXCEPT; 511}; 512 513_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 514#ifndef _LIBCPP_NO_EXCEPTIONS 515_LIBCPP_AVAILABILITY_FUTURE_ERROR 516#endif 517void __throw_future_error(future_errc _Ev) 518{ 519#ifndef _LIBCPP_NO_EXCEPTIONS 520 throw future_error(make_error_code(_Ev)); 521#else 522 ((void)_Ev); 523 _VSTD::abort(); 524#endif 525} 526 527class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state 528 : public __shared_count 529{ 530protected: 531 exception_ptr __exception_; 532 mutable mutex __mut_; 533 mutable condition_variable __cv_; 534 unsigned __state_; 535 536 virtual void __on_zero_shared() _NOEXCEPT; 537 void __sub_wait(unique_lock<mutex>& __lk); 538public: 539 enum 540 { 541 __constructed = 1, 542 __future_attached = 2, 543 ready = 4, 544 deferred = 8 545 }; 546 547 _LIBCPP_INLINE_VISIBILITY 548 __assoc_sub_state() : __state_(0) {} 549 550 _LIBCPP_INLINE_VISIBILITY 551 bool __has_value() const 552 {return (__state_ & __constructed) || (__exception_ != nullptr);} 553 554 _LIBCPP_INLINE_VISIBILITY 555 void __attach_future() { 556 lock_guard<mutex> __lk(__mut_); 557 bool __has_future_attached = (__state_ & __future_attached) != 0; 558 if (__has_future_attached) 559 __throw_future_error(future_errc::future_already_retrieved); 560 this->__add_shared(); 561 __state_ |= __future_attached; 562 } 563 564 _LIBCPP_INLINE_VISIBILITY 565 void __set_deferred() {__state_ |= deferred;} 566 567 void __make_ready(); 568 _LIBCPP_INLINE_VISIBILITY 569 bool __is_ready() const {return (__state_ & ready) != 0;} 570 571 void set_value(); 572 void set_value_at_thread_exit(); 573 574 void set_exception(exception_ptr __p); 575 void set_exception_at_thread_exit(exception_ptr __p); 576 577 void copy(); 578 579 void wait(); 580 template <class _Rep, class _Period> 581 future_status 582 _LIBCPP_INLINE_VISIBILITY 583 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; 584 template <class _Clock, class _Duration> 585 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 586 future_status 587 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const; 588 589 virtual void __execute(); 590}; 591 592template <class _Clock, class _Duration> 593future_status 594__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const 595{ 596 unique_lock<mutex> __lk(__mut_); 597 if (__state_ & deferred) 598 return future_status::deferred; 599 while (!(__state_ & ready) && _Clock::now() < __abs_time) 600 __cv_.wait_until(__lk, __abs_time); 601 if (__state_ & ready) 602 return future_status::ready; 603 return future_status::timeout; 604} 605 606template <class _Rep, class _Period> 607inline 608future_status 609__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const 610{ 611 return wait_until(chrono::steady_clock::now() + __rel_time); 612} 613 614template <class _Rp> 615class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state 616 : public __assoc_sub_state 617{ 618 typedef __assoc_sub_state base; 619 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up; 620protected: 621 _Up __value_; 622 623 virtual void __on_zero_shared() _NOEXCEPT; 624public: 625 626 template <class _Arg> 627 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(&__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(&__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(std::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(std::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(std::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(std::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(static_cast<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(std::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(static_cast<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(std::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(static_cast<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#ifndef _LIBCPP_HAS_NO_VARIADICS 1609 1610// packaged_task 1611 1612template<class _Fp> class __packaged_task_base; 1613 1614template<class _Rp, class ..._ArgTypes> 1615class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)> 1616{ 1617 __packaged_task_base(const __packaged_task_base&); 1618 __packaged_task_base& operator=(const __packaged_task_base&); 1619public: 1620 _LIBCPP_INLINE_VISIBILITY 1621 __packaged_task_base() {} 1622 _LIBCPP_INLINE_VISIBILITY 1623 virtual ~__packaged_task_base() {} 1624 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0; 1625 virtual void destroy() = 0; 1626 virtual void destroy_deallocate() = 0; 1627 virtual _Rp operator()(_ArgTypes&& ...) = 0; 1628}; 1629 1630template<class _FD, class _Alloc, class _FB> class __packaged_task_func; 1631 1632template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1633class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> 1634 : public __packaged_task_base<_Rp(_ArgTypes...)> 1635{ 1636 __compressed_pair<_Fp, _Alloc> __f_; 1637public: 1638 _LIBCPP_INLINE_VISIBILITY 1639 explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {} 1640 _LIBCPP_INLINE_VISIBILITY 1641 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} 1642 _LIBCPP_INLINE_VISIBILITY 1643 __packaged_task_func(const _Fp& __f, const _Alloc& __a) 1644 : __f_(__f, __a) {} 1645 _LIBCPP_INLINE_VISIBILITY 1646 __packaged_task_func(_Fp&& __f, const _Alloc& __a) 1647 : __f_(_VSTD::move(__f), __a) {} 1648 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; 1649 virtual void destroy(); 1650 virtual void destroy_deallocate(); 1651 virtual _Rp operator()(_ArgTypes&& ... __args); 1652}; 1653 1654template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1655void 1656__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to( 1657 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT 1658{ 1659 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second())); 1660} 1661 1662template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1663void 1664__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() 1665{ 1666 __f_.~__compressed_pair<_Fp, _Alloc>(); 1667} 1668 1669template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1670void 1671__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() 1672{ 1673 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap; 1674 typedef allocator_traits<_Ap> _ATraits; 1675 typedef pointer_traits<typename _ATraits::pointer> _PTraits; 1676 _Ap __a(__f_.second()); 1677 __f_.~__compressed_pair<_Fp, _Alloc>(); 1678 __a.deallocate(_PTraits::pointer_to(*this), 1); 1679} 1680 1681template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 1682_Rp 1683__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) 1684{ 1685 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); 1686} 1687 1688template <class _Callable> class __packaged_task_function; 1689 1690template<class _Rp, class ..._ArgTypes> 1691class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)> 1692{ 1693 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; 1694 1695 _LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI 1696 __base* __get_buf() { return (__base*)&__buf_; } 1697 1698 typename aligned_storage<3*sizeof(void*)>::type __buf_; 1699 __base* __f_; 1700 1701public: 1702 typedef _Rp result_type; 1703 1704 // construct/copy/destroy: 1705 _LIBCPP_INLINE_VISIBILITY 1706 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {} 1707 template<class _Fp> 1708 __packaged_task_function(_Fp&& __f); 1709 template<class _Fp, class _Alloc> 1710 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); 1711 1712 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; 1713 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; 1714 1715 __packaged_task_function(const __packaged_task_function&) = delete; 1716 __packaged_task_function& operator=(const __packaged_task_function&) = delete; 1717 1718 ~__packaged_task_function(); 1719 1720 void swap(__packaged_task_function&) _NOEXCEPT; 1721 1722 _LIBCPP_INLINE_VISIBILITY 1723 _Rp operator()(_ArgTypes...) const; 1724}; 1725 1726template<class _Rp, class ..._ArgTypes> 1727__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT 1728{ 1729 if (__f.__f_ == nullptr) 1730 __f_ = nullptr; 1731 else if (__f.__f_ == __f.__get_buf()) 1732 { 1733 __f.__f_->__move_to(__get_buf()); 1734 __f_ = (__base*)&__buf_; 1735 } 1736 else 1737 { 1738 __f_ = __f.__f_; 1739 __f.__f_ = nullptr; 1740 } 1741} 1742 1743template<class _Rp, class ..._ArgTypes> 1744template <class _Fp> 1745__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) 1746 : __f_(nullptr) 1747{ 1748 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR; 1749 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; 1750 if (sizeof(_FF) <= sizeof(__buf_)) 1751 { 1752 ::new (&__buf_) _FF(_VSTD::forward<_Fp>(__f)); 1753 __f_ = (__base*)&__buf_; 1754 } 1755 else 1756 { 1757 typedef allocator<_FF> _Ap; 1758 _Ap __a; 1759 typedef __allocator_destructor<_Ap> _Dp; 1760 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1761 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a)); 1762 __f_ = __hold.release(); 1763 } 1764} 1765 1766template<class _Rp, class ..._ArgTypes> 1767template <class _Fp, class _Alloc> 1768__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function( 1769 allocator_arg_t, const _Alloc& __a0, _Fp&& __f) 1770 : __f_(nullptr) 1771{ 1772 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR; 1773 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; 1774 if (sizeof(_FF) <= sizeof(__buf_)) 1775 { 1776 __f_ = (__base*)&__buf_; 1777 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); 1778 } 1779 else 1780 { 1781 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap; 1782 _Ap __a(__a0); 1783 typedef __allocator_destructor<_Ap> _Dp; 1784 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1785 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get()))) 1786 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a)); 1787 __f_ = _VSTD::addressof(*__hold.release()); 1788 } 1789} 1790 1791template<class _Rp, class ..._ArgTypes> 1792__packaged_task_function<_Rp(_ArgTypes...)>& 1793__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT 1794{ 1795 if (__f_ == __get_buf()) 1796 __f_->destroy(); 1797 else if (__f_) 1798 __f_->destroy_deallocate(); 1799 __f_ = nullptr; 1800 if (__f.__f_ == nullptr) 1801 __f_ = nullptr; 1802 else if (__f.__f_ == __f.__get_buf()) 1803 { 1804 __f.__f_->__move_to(__get_buf()); 1805 __f_ = __get_buf(); 1806 } 1807 else 1808 { 1809 __f_ = __f.__f_; 1810 __f.__f_ = nullptr; 1811 } 1812 return *this; 1813} 1814 1815template<class _Rp, class ..._ArgTypes> 1816__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() 1817{ 1818 if (__f_ == __get_buf()) 1819 __f_->destroy(); 1820 else if (__f_) 1821 __f_->destroy_deallocate(); 1822} 1823 1824template<class _Rp, class ..._ArgTypes> 1825_LIBCPP_NO_CFI 1826void 1827__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT 1828{ 1829 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 1830 { 1831 typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 1832 __base* __t = (__base*)&__tempbuf; 1833 __f_->__move_to(__t); 1834 __f_->destroy(); 1835 __f_ = nullptr; 1836 __f.__f_->__move_to((__base*)&__buf_); 1837 __f.__f_->destroy(); 1838 __f.__f_ = nullptr; 1839 __f_ = (__base*)&__buf_; 1840 __t->__move_to((__base*)&__f.__buf_); 1841 __t->destroy(); 1842 __f.__f_ = (__base*)&__f.__buf_; 1843 } 1844 else if (__f_ == (__base*)&__buf_) 1845 { 1846 __f_->__move_to((__base*)&__f.__buf_); 1847 __f_->destroy(); 1848 __f_ = __f.__f_; 1849 __f.__f_ = (__base*)&__f.__buf_; 1850 } 1851 else if (__f.__f_ == (__base*)&__f.__buf_) 1852 { 1853 __f.__f_->__move_to((__base*)&__buf_); 1854 __f.__f_->destroy(); 1855 __f.__f_ = __f_; 1856 __f_ = (__base*)&__buf_; 1857 } 1858 else 1859 _VSTD::swap(__f_, __f.__f_); 1860} 1861 1862template<class _Rp, class ..._ArgTypes> 1863inline 1864_Rp 1865__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const 1866{ 1867 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); 1868} 1869 1870template<class _Rp, class ..._ArgTypes> 1871class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)> 1872{ 1873public: 1874 typedef _Rp result_type; // extension 1875 1876private: 1877 __packaged_task_function<result_type(_ArgTypes...)> __f_; 1878 promise<result_type> __p_; 1879 1880public: 1881 // construction and destruction 1882 _LIBCPP_INLINE_VISIBILITY 1883 packaged_task() _NOEXCEPT : __p_(nullptr) {} 1884 template <class _Fp, 1885 class = typename enable_if 1886 < 1887 !is_same< 1888 typename __uncvref<_Fp>::type, 1889 packaged_task 1890 >::value 1891 >::type 1892 > 1893 _LIBCPP_INLINE_VISIBILITY 1894 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} 1895 template <class _Fp, class _Allocator, 1896 class = typename enable_if 1897 < 1898 !is_same< 1899 typename __uncvref<_Fp>::type, 1900 packaged_task 1901 >::value 1902 >::type 1903 > 1904 _LIBCPP_INLINE_VISIBILITY 1905 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 1906 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), 1907 __p_(allocator_arg, __a) {} 1908 // ~packaged_task() = default; 1909 1910 // no copy 1911 packaged_task(const packaged_task&) = delete; 1912 packaged_task& operator=(const packaged_task&) = delete; 1913 1914 // move support 1915 _LIBCPP_INLINE_VISIBILITY 1916 packaged_task(packaged_task&& __other) _NOEXCEPT 1917 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 1918 _LIBCPP_INLINE_VISIBILITY 1919 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 1920 { 1921 __f_ = _VSTD::move(__other.__f_); 1922 __p_ = _VSTD::move(__other.__p_); 1923 return *this; 1924 } 1925 _LIBCPP_INLINE_VISIBILITY 1926 void swap(packaged_task& __other) _NOEXCEPT 1927 { 1928 __f_.swap(__other.__f_); 1929 __p_.swap(__other.__p_); 1930 } 1931 1932 _LIBCPP_INLINE_VISIBILITY 1933 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} 1934 1935 // result retrieval 1936 _LIBCPP_INLINE_VISIBILITY 1937 future<result_type> get_future() {return __p_.get_future();} 1938 1939 // execution 1940 void operator()(_ArgTypes... __args); 1941 void make_ready_at_thread_exit(_ArgTypes... __args); 1942 1943 void reset(); 1944}; 1945 1946template<class _Rp, class ..._ArgTypes> 1947void 1948packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) 1949{ 1950 if (__p_.__state_ == nullptr) 1951 __throw_future_error(future_errc::no_state); 1952 if (__p_.__state_->__has_value()) 1953 __throw_future_error(future_errc::promise_already_satisfied); 1954#ifndef _LIBCPP_NO_EXCEPTIONS 1955 try 1956 { 1957#endif // _LIBCPP_NO_EXCEPTIONS 1958 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...)); 1959#ifndef _LIBCPP_NO_EXCEPTIONS 1960 } 1961 catch (...) 1962 { 1963 __p_.set_exception(current_exception()); 1964 } 1965#endif // _LIBCPP_NO_EXCEPTIONS 1966} 1967 1968template<class _Rp, class ..._ArgTypes> 1969void 1970packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) 1971{ 1972 if (__p_.__state_ == nullptr) 1973 __throw_future_error(future_errc::no_state); 1974 if (__p_.__state_->__has_value()) 1975 __throw_future_error(future_errc::promise_already_satisfied); 1976#ifndef _LIBCPP_NO_EXCEPTIONS 1977 try 1978 { 1979#endif // _LIBCPP_NO_EXCEPTIONS 1980 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...)); 1981#ifndef _LIBCPP_NO_EXCEPTIONS 1982 } 1983 catch (...) 1984 { 1985 __p_.set_exception_at_thread_exit(current_exception()); 1986 } 1987#endif // _LIBCPP_NO_EXCEPTIONS 1988} 1989 1990template<class _Rp, class ..._ArgTypes> 1991void 1992packaged_task<_Rp(_ArgTypes...)>::reset() 1993{ 1994 if (!valid()) 1995 __throw_future_error(future_errc::no_state); 1996 __p_ = promise<result_type>(); 1997} 1998 1999template<class ..._ArgTypes> 2000class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)> 2001{ 2002public: 2003 typedef void result_type; // extension 2004 2005private: 2006 __packaged_task_function<result_type(_ArgTypes...)> __f_; 2007 promise<result_type> __p_; 2008 2009public: 2010 // construction and destruction 2011 _LIBCPP_INLINE_VISIBILITY 2012 packaged_task() _NOEXCEPT : __p_(nullptr) {} 2013 template <class _Fp, 2014 class = typename enable_if 2015 < 2016 !is_same< 2017 typename __uncvref<_Fp>::type, 2018 packaged_task 2019 >::value 2020 >::type 2021 > 2022 _LIBCPP_INLINE_VISIBILITY 2023 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {} 2024 template <class _Fp, class _Allocator, 2025 class = typename enable_if 2026 < 2027 !is_same< 2028 typename __uncvref<_Fp>::type, 2029 packaged_task 2030 >::value 2031 >::type 2032 > 2033 _LIBCPP_INLINE_VISIBILITY 2034 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) 2035 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), 2036 __p_(allocator_arg, __a) {} 2037 // ~packaged_task() = default; 2038 2039 // no copy 2040 packaged_task(const packaged_task&) = delete; 2041 packaged_task& operator=(const packaged_task&) = delete; 2042 2043 // move support 2044 _LIBCPP_INLINE_VISIBILITY 2045 packaged_task(packaged_task&& __other) _NOEXCEPT 2046 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} 2047 _LIBCPP_INLINE_VISIBILITY 2048 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT 2049 { 2050 __f_ = _VSTD::move(__other.__f_); 2051 __p_ = _VSTD::move(__other.__p_); 2052 return *this; 2053 } 2054 _LIBCPP_INLINE_VISIBILITY 2055 void swap(packaged_task& __other) _NOEXCEPT 2056 { 2057 __f_.swap(__other.__f_); 2058 __p_.swap(__other.__p_); 2059 } 2060 2061 _LIBCPP_INLINE_VISIBILITY 2062 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;} 2063 2064 // result retrieval 2065 _LIBCPP_INLINE_VISIBILITY 2066 future<result_type> get_future() {return __p_.get_future();} 2067 2068 // execution 2069 void operator()(_ArgTypes... __args); 2070 void make_ready_at_thread_exit(_ArgTypes... __args); 2071 2072 void reset(); 2073}; 2074 2075template<class ..._ArgTypes> 2076void 2077packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) 2078{ 2079 if (__p_.__state_ == nullptr) 2080 __throw_future_error(future_errc::no_state); 2081 if (__p_.__state_->__has_value()) 2082 __throw_future_error(future_errc::promise_already_satisfied); 2083#ifndef _LIBCPP_NO_EXCEPTIONS 2084 try 2085 { 2086#endif // _LIBCPP_NO_EXCEPTIONS 2087 __f_(_VSTD::forward<_ArgTypes>(__args)...); 2088 __p_.set_value(); 2089#ifndef _LIBCPP_NO_EXCEPTIONS 2090 } 2091 catch (...) 2092 { 2093 __p_.set_exception(current_exception()); 2094 } 2095#endif // _LIBCPP_NO_EXCEPTIONS 2096} 2097 2098template<class ..._ArgTypes> 2099void 2100packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) 2101{ 2102 if (__p_.__state_ == nullptr) 2103 __throw_future_error(future_errc::no_state); 2104 if (__p_.__state_->__has_value()) 2105 __throw_future_error(future_errc::promise_already_satisfied); 2106#ifndef _LIBCPP_NO_EXCEPTIONS 2107 try 2108 { 2109#endif // _LIBCPP_NO_EXCEPTIONS 2110 __f_(_VSTD::forward<_ArgTypes>(__args)...); 2111 __p_.set_value_at_thread_exit(); 2112#ifndef _LIBCPP_NO_EXCEPTIONS 2113 } 2114 catch (...) 2115 { 2116 __p_.set_exception_at_thread_exit(current_exception()); 2117 } 2118#endif // _LIBCPP_NO_EXCEPTIONS 2119} 2120 2121template<class ..._ArgTypes> 2122void 2123packaged_task<void(_ArgTypes...)>::reset() 2124{ 2125 if (!valid()) 2126 __throw_future_error(future_errc::no_state); 2127 __p_ = promise<result_type>(); 2128} 2129 2130template <class _Callable> 2131inline _LIBCPP_INLINE_VISIBILITY 2132void 2133swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT 2134{ 2135 __x.swap(__y); 2136} 2137 2138template <class _Callable, class _Alloc> 2139struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc> 2140 : public true_type {}; 2141 2142template <class _Rp, class _Fp> 2143_LIBCPP_INLINE_VISIBILITY future<_Rp> 2144__make_deferred_assoc_state(_Fp&& __f) 2145{ 2146 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> 2147 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); 2148 return future<_Rp>(__h.get()); 2149} 2150 2151template <class _Rp, class _Fp> 2152_LIBCPP_INLINE_VISIBILITY future<_Rp> 2153__make_async_assoc_state(_Fp&& __f) 2154{ 2155 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> 2156 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f))); 2157 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach(); 2158 return future<_Rp>(__h.get()); 2159} 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 __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(__decay_copy(_VSTD::forward<_Fp>(__f)), 2207 __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(__decay_copy(_VSTD::forward<_Fp>(__f)), 2215 __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 // _LIBCPP_HAS_NO_VARIADICS 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(std::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(std::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(std::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