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