The C and C++ Include Header Files
/usr/include/c++/11/future
$ cat -n /usr/include/c++/11/future 1 //
-*- C++ -*- 2 3 // Copyright (C) 2009-2021 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 //
. 24 25 /** @file include/future 26 * This is a Standard C++ Library header. 27 */ 28 29 #ifndef _GLIBCXX_FUTURE 30 #define _GLIBCXX_FUTURE 1 31 32 #pragma GCC system_header 33 34 #if __cplusplus < 201103L 35 # include
36 #else 37 38 #include
// call_once 39 #include
// __at_thread_exit_elt 40 #include
41 #include
42 #include
43 #include
44 #include
45 #include
46 #include
47 #include
48 #include
49 #include
50 #include
51 52 namespace std _GLIBCXX_VISIBILITY(default) 53 { 54 _GLIBCXX_BEGIN_NAMESPACE_VERSION 55 56 /** 57 * @defgroup futures Futures 58 * @ingroup concurrency 59 * 60 * Classes for futures support. 61 * @{ 62 */ 63 64 /// Error code for futures 65 enum class future_errc 66 { 67 future_already_retrieved = 1, 68 promise_already_satisfied, 69 no_state, 70 broken_promise 71 }; 72 73 /// Specialization. 74 template<> 75 struct is_error_code_enum
: public true_type { }; 76 77 /// Points to a statically-allocated object derived from error_category. 78 const error_category& 79 future_category() noexcept; 80 81 /// Overload for make_error_code. 82 inline error_code 83 make_error_code(future_errc __errc) noexcept 84 { return error_code(static_cast
(__errc), future_category()); } 85 86 /// Overload for make_error_condition. 87 inline error_condition 88 make_error_condition(future_errc __errc) noexcept 89 { return error_condition(static_cast
(__errc), future_category()); } 90 91 /** 92 * @brief Exception type thrown by futures. 93 * @ingroup exceptions 94 */ 95 class future_error : public logic_error 96 { 97 public: 98 explicit 99 future_error(future_errc __errc) 100 : future_error(std::make_error_code(__errc)) 101 { } 102 103 virtual ~future_error() noexcept; 104 105 virtual const char* 106 what() const noexcept; 107 108 const error_code& 109 code() const noexcept { return _M_code; } 110 111 private: 112 explicit 113 future_error(error_code __ec) 114 : logic_error("std::future_error: " + __ec.message()), _M_code(__ec) 115 { } 116 117 friend void __throw_future_error(int); 118 119 error_code _M_code; 120 }; 121 122 // Forward declarations. 123 template
124 class future; 125 126 template
127 class shared_future; 128 129 template
130 class packaged_task; 131 132 template
133 class promise; 134 135 /// Launch code for futures 136 enum class launch 137 { 138 async = 1, 139 deferred = 2 140 }; 141 142 constexpr launch operator&(launch __x, launch __y) noexcept 143 { 144 return static_cast
( 145 static_cast
(__x) & static_cast
(__y)); 146 } 147 148 constexpr launch operator|(launch __x, launch __y) noexcept 149 { 150 return static_cast
( 151 static_cast
(__x) | static_cast
(__y)); 152 } 153 154 constexpr launch operator^(launch __x, launch __y) noexcept 155 { 156 return static_cast
( 157 static_cast
(__x) ^ static_cast
(__y)); 158 } 159 160 constexpr launch operator~(launch __x) noexcept 161 { return static_cast
(~static_cast
(__x)); } 162 163 inline launch& operator&=(launch& __x, launch __y) noexcept 164 { return __x = __x & __y; } 165 166 inline launch& operator|=(launch& __x, launch __y) noexcept 167 { return __x = __x | __y; } 168 169 inline launch& operator^=(launch& __x, launch __y) noexcept 170 { return __x = __x ^ __y; } 171 172 /// Status code for futures 173 enum class future_status 174 { 175 ready, 176 timeout, 177 deferred 178 }; 179 180 // _GLIBCXX_RESOLVE_LIB_DEFECTS 181 // 2021. Further incorrect usages of result_of 182 template
183 using __async_result_of = typename __invoke_result< 184 typename decay<_Fn>::type, typename decay<_Args>::type...>::type; 185 186 template
187 future<__async_result_of<_Fn, _Args...>> 188 async(launch __policy, _Fn&& __fn, _Args&&... __args); 189 190 template
191 future<__async_result_of<_Fn, _Args...>> 192 async(_Fn&& __fn, _Args&&... __args); 193 194 #if defined(_GLIBCXX_HAS_GTHREADS) 195 196 /// Base class and enclosing scope. 197 struct __future_base 198 { 199 /// Base class for results. 200 struct _Result_base 201 { 202 exception_ptr _M_error; 203 204 _Result_base(const _Result_base&) = delete; 205 _Result_base& operator=(const _Result_base&) = delete; 206 207 // _M_destroy() allows derived classes to control deallocation 208 virtual void _M_destroy() = 0; 209 210 struct _Deleter 211 { 212 void operator()(_Result_base* __fr) const { __fr->_M_destroy(); } 213 }; 214 215 protected: 216 _Result_base(); 217 virtual ~_Result_base(); 218 }; 219 220 /// A unique_ptr for result objects. 221 template
222 using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>; 223 224 /// A result object that has storage for an object of type _Res. 225 template
226 struct _Result : _Result_base 227 { 228 private: 229 __gnu_cxx::__aligned_buffer<_Res> _M_storage; 230 bool _M_initialized; 231 232 public: 233 typedef _Res result_type; 234 235 _Result() noexcept : _M_initialized() { } 236 237 ~_Result() 238 { 239 if (_M_initialized) 240 _M_value().~_Res(); 241 } 242 243 // Return lvalue, future will add const or rvalue-reference 244 _Res& 245 _M_value() noexcept { return *_M_storage._M_ptr(); } 246 247 void 248 _M_set(const _Res& __res) 249 { 250 ::new (_M_storage._M_addr()) _Res(__res); 251 _M_initialized = true; 252 } 253 254 void 255 _M_set(_Res&& __res) 256 { 257 ::new (_M_storage._M_addr()) _Res(std::move(__res)); 258 _M_initialized = true; 259 } 260 261 private: 262 void _M_destroy() { delete this; } 263 }; 264 265 /// A result object that uses an allocator. 266 template
267 struct _Result_alloc final : _Result<_Res>, _Alloc 268 { 269 using __allocator_type = __alloc_rebind<_Alloc, _Result_alloc>; 270 271 explicit 272 _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a) 273 { } 274 275 private: 276 void _M_destroy() 277 { 278 __allocator_type __a(*this); 279 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; 280 this->~_Result_alloc(); 281 } 282 }; 283 284 // Create a result object that uses an allocator. 285 template
286 static _Ptr<_Result_alloc<_Res, _Allocator>> 287 _S_allocate_result(const _Allocator& __a) 288 { 289 using __result_type = _Result_alloc<_Res, _Allocator>; 290 typename __result_type::__allocator_type __a2(__a); 291 auto __guard = std::__allocate_guarded(__a2); 292 __result_type* __p = ::new((void*)__guard.get()) __result_type{__a}; 293 __guard = nullptr; 294 return _Ptr<__result_type>(__p); 295 } 296 297 // Keep it simple for std::allocator. 298 template
299 static _Ptr<_Result<_Res>> 300 _S_allocate_result(const std::allocator<_Tp>& __a) 301 { 302 return _Ptr<_Result<_Res>>(new _Result<_Res>); 303 } 304 305 // Base class for various types of shared state created by an 306 // asynchronous provider (such as a std::promise) and shared with one 307 // or more associated futures. 308 class _State_baseV2 309 { 310 typedef _Ptr<_Result_base> _Ptr_type; 311 312 enum _Status : unsigned { 313 __not_ready, 314 __ready 315 }; 316 317 _Ptr_type _M_result; 318 __atomic_futex_unsigned<> _M_status; 319 atomic_flag _M_retrieved = ATOMIC_FLAG_INIT; 320 once_flag _M_once; 321 322 public: 323 _State_baseV2() noexcept : _M_result(), _M_status(_Status::__not_ready) 324 { } 325 _State_baseV2(const _State_baseV2&) = delete; 326 _State_baseV2& operator=(const _State_baseV2&) = delete; 327 virtual ~_State_baseV2() = default; 328 329 _Result_base& 330 wait() 331 { 332 // Run any deferred function or join any asynchronous thread: 333 _M_complete_async(); 334 // Acquire MO makes sure this synchronizes with the thread that made 335 // the future ready. 336 _M_status._M_load_when_equal(_Status::__ready, memory_order_acquire); 337 return *_M_result; 338 } 339 340 template
341 future_status 342 wait_for(const chrono::duration<_Rep, _Period>& __rel) 343 { 344 // First, check if the future has been made ready. Use acquire MO 345 // to synchronize with the thread that made it ready. 346 if (_M_status._M_load(memory_order_acquire) == _Status::__ready) 347 return future_status::ready; 348 349 if (_M_is_deferred_future()) 350 return future_status::deferred; 351 352 // Don't wait unless the relative time is greater than zero. 353 if (__rel > __rel.zero() 354 && _M_status._M_load_when_equal_for(_Status::__ready, 355 memory_order_acquire, 356 __rel)) 357 { 358 // _GLIBCXX_RESOLVE_LIB_DEFECTS 359 // 2100. timed waiting functions must also join 360 // This call is a no-op by default except on an async future, 361 // in which case the async thread is joined. It's also not a 362 // no-op for a deferred future, but such a future will never 363 // reach this point because it returns future_status::deferred 364 // instead of waiting for the future to become ready (see 365 // above). Async futures synchronize in this call, so we need 366 // no further synchronization here. 367 _M_complete_async(); 368 369 return future_status::ready; 370 } 371 return future_status::timeout; 372 } 373 374 template
375 future_status 376 wait_until(const chrono::time_point<_Clock, _Duration>& __abs) 377 { 378 #if __cplusplus > 201703L 379 static_assert(chrono::is_clock_v<_Clock>); 380 #endif 381 // First, check if the future has been made ready. Use acquire MO 382 // to synchronize with the thread that made it ready. 383 if (_M_status._M_load(memory_order_acquire) == _Status::__ready) 384 return future_status::ready; 385 386 if (_M_is_deferred_future()) 387 return future_status::deferred; 388 389 if (_M_status._M_load_when_equal_until(_Status::__ready, 390 memory_order_acquire, 391 __abs)) 392 { 393 // _GLIBCXX_RESOLVE_LIB_DEFECTS 394 // 2100. timed waiting functions must also join 395 // See wait_for(...) above. 396 _M_complete_async(); 397 398 return future_status::ready; 399 } 400 return future_status::timeout; 401 } 402 403 // Provide a result to the shared state and make it ready. 404 // Calls at most once: _M_result = __res(); 405 void 406 _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false) 407 { 408 bool __did_set = false; 409 // all calls to this function are serialized, 410 // side-effects of invoking __res only happen once 411 call_once(_M_once, &_State_baseV2::_M_do_set, this, 412 std::__addressof(__res), std::__addressof(__did_set)); 413 if (__did_set) 414 // Use release MO to synchronize with observers of the ready state. 415 _M_status._M_store_notify_all(_Status::__ready, 416 memory_order_release); 417 else if (!__ignore_failure) 418 __throw_future_error(int(future_errc::promise_already_satisfied)); 419 } 420 421 // Provide a result to the shared state but delay making it ready 422 // until the calling thread exits. 423 // Calls at most once: _M_result = __res(); 424 void 425 _M_set_delayed_result(function<_Ptr_type()> __res, 426 weak_ptr<_State_baseV2> __self) 427 { 428 bool __did_set = false; 429 unique_ptr<_Make_ready> __mr{new _Make_ready}; 430 // all calls to this function are serialized, 431 // side-effects of invoking __res only happen once 432 call_once(_M_once, &_State_baseV2::_M_do_set, this, 433 std::__addressof(__res), std::__addressof(__did_set)); 434 if (!__did_set) 435 __throw_future_error(int(future_errc::promise_already_satisfied)); 436 __mr->_M_shared_state = std::move(__self); 437 __mr->_M_set(); 438 __mr.release(); 439 } 440 441 // Abandon this shared state. 442 void 443 _M_break_promise(_Ptr_type __res) 444 { 445 if (static_cast
(__res)) 446 { 447 __res->_M_error = 448 make_exception_ptr(future_error(future_errc::broken_promise)); 449 // This function is only called when the last asynchronous result 450 // provider is abandoning this shared state, so noone can be 451 // trying to make the shared state ready at the same time, and 452 // we can access _M_result directly instead of through call_once. 453 _M_result.swap(__res); 454 // Use release MO to synchronize with observers of the ready state. 455 _M_status._M_store_notify_all(_Status::__ready, 456 memory_order_release); 457 } 458 } 459 460 // Called when this object is first passed to a future. 461 void 462 _M_set_retrieved_flag() 463 { 464 if (_M_retrieved.test_and_set()) 465 __throw_future_error(int(future_errc::future_already_retrieved)); 466 } 467 468 template
469 struct _Setter; 470 471 // set lvalues 472 template
473 struct _Setter<_Res, _Arg&> 474 { 475 // check this is only used by promise
::set_value(const R&) 476 // or promise
::set_value(R&) 477 static_assert(is_same<_Res, _Arg&>::value // promise
478 || is_same
::value, // promise
479 "Invalid specialisation"); 480 481 // Used by std::promise to copy construct the result. 482 typename promise<_Res>::_Ptr_type operator()() const 483 { 484 _M_promise->_M_storage->_M_set(*_M_arg); 485 return std::move(_M_promise->_M_storage); 486 } 487 promise<_Res>* _M_promise; 488 _Arg* _M_arg; 489 }; 490 491 // set rvalues 492 template
493 struct _Setter<_Res, _Res&&> 494 { 495 // Used by std::promise to move construct the result. 496 typename promise<_Res>::_Ptr_type operator()() const 497 { 498 _M_promise->_M_storage->_M_set(std::move(*_M_arg)); 499 return std::move(_M_promise->_M_storage); 500 } 501 promise<_Res>* _M_promise; 502 _Res* _M_arg; 503 }; 504 505 // set void 506 template
507 struct _Setter<_Res, void> 508 { 509 static_assert(is_void<_Res>::value, "Only used for promise
"); 510 511 typename promise<_Res>::_Ptr_type operator()() const 512 { return std::move(_M_promise->_M_storage); } 513 514 promise<_Res>* _M_promise; 515 }; 516 517 struct __exception_ptr_tag { }; 518 519 // set exceptions 520 template
521 struct _Setter<_Res, __exception_ptr_tag> 522 { 523 // Used by std::promise to store an exception as the result. 524 typename promise<_Res>::_Ptr_type operator()() const 525 { 526 _M_promise->_M_storage->_M_error = *_M_ex; 527 return std::move(_M_promise->_M_storage); 528 } 529 530 promise<_Res>* _M_promise; 531 exception_ptr* _M_ex; 532 }; 533 534 template
535 __attribute__((__always_inline__)) 536 static _Setter<_Res, _Arg&&> 537 __setter(promise<_Res>* __prom, _Arg&& __arg) noexcept 538 { 539 return _Setter<_Res, _Arg&&>{ __prom, std::__addressof(__arg) }; 540 } 541 542 template
543 __attribute__((__always_inline__)) 544 static _Setter<_Res, __exception_ptr_tag> 545 __setter(exception_ptr& __ex, promise<_Res>* __prom) noexcept 546 { 547 return _Setter<_Res, __exception_ptr_tag>{ __prom, &__ex }; 548 } 549 550 template
551 __attribute__((__always_inline__)) 552 static _Setter<_Res, void> 553 __setter(promise<_Res>* __prom) noexcept 554 { 555 return _Setter<_Res, void>{ __prom }; 556 } 557 558 template
559 static void 560 _S_check(const shared_ptr<_Tp>& __p) 561 { 562 if (!static_cast
(__p)) 563 __throw_future_error((int)future_errc::no_state); 564 } 565 566 private: 567 // The function invoked with std::call_once(_M_once, ...). 568 void 569 _M_do_set(function<_Ptr_type()>* __f, bool* __did_set) 570 { 571 _Ptr_type __res = (*__f)(); 572 // Notify the caller that we did try to set; if we do not throw an 573 // exception, the caller will be aware that it did set (e.g., see 574 // _M_set_result). 575 *__did_set = true; 576 _M_result.swap(__res); // nothrow 577 } 578 579 // Wait for completion of async function. 580 virtual void _M_complete_async() { } 581 582 // Return true if state corresponds to a deferred function. 583 virtual bool _M_is_deferred_future() const { return false; } 584 585 struct _Make_ready final : __at_thread_exit_elt 586 { 587 weak_ptr<_State_baseV2> _M_shared_state; 588 static void _S_run(void*); 589 void _M_set(); 590 }; 591 }; 592 593 #ifdef _GLIBCXX_ASYNC_ABI_COMPAT 594 class _State_base; 595 class _Async_state_common; 596 #else 597 using _State_base = _State_baseV2; 598 class _Async_state_commonV2; 599 #endif 600 601 template
()())> 603 class _Deferred_state; 604 605 template
()())> 607 class _Async_state_impl; 608 609 template
610 class _Task_state_base; 611 612 template
613 class _Task_state; 614 615 template
617 struct _Task_setter; 618 619 template
620 static _Task_setter<_Res_ptr, _BoundFn> 621 _S_task_setter(_Res_ptr& __ptr, _BoundFn& __call) 622 { 623 return { std::__addressof(__ptr), std::__addressof(__call) }; 624 } 625 }; 626 627 /// Partial specialization for reference types. 628 template
629 struct __future_base::_Result<_Res&> : __future_base::_Result_base 630 { 631 typedef _Res& result_type; 632 633 _Result() noexcept : _M_value_ptr() { } 634 635 void 636 _M_set(_Res& __res) noexcept 637 { _M_value_ptr = std::addressof(__res); } 638 639 _Res& _M_get() noexcept { return *_M_value_ptr; } 640 641 private: 642 _Res* _M_value_ptr; 643 644 void _M_destroy() { delete this; } 645 }; 646 647 /// Explicit specialization for void. 648 template<> 649 struct __future_base::_Result
: __future_base::_Result_base 650 { 651 typedef void result_type; 652 653 private: 654 void _M_destroy() { delete this; } 655 }; 656 657 #ifndef _GLIBCXX_ASYNC_ABI_COMPAT 658 659 // Allow _Setter objects to be stored locally in std::function 660 template
661 struct __is_location_invariant 662 <__future_base::_State_base::_Setter<_Res, _Arg>> 663 : true_type { }; 664 665 // Allow _Task_setter objects to be stored locally in std::function 666 template
667 struct __is_location_invariant 668 <__future_base::_Task_setter<_Res_ptr, _Fn, _Res>> 669 : true_type { }; 670 671 /// Common implementation for future and shared_future. 672 template
673 class __basic_future : public __future_base 674 { 675 protected: 676 typedef shared_ptr<_State_base> __state_type; 677 typedef __future_base::_Result<_Res>& __result_type; 678 679 private: 680 __state_type _M_state; 681 682 public: 683 // Disable copying. 684 __basic_future(const __basic_future&) = delete; 685 __basic_future& operator=(const __basic_future&) = delete; 686 687 bool 688 valid() const noexcept { return static_cast
(_M_state); } 689 690 void 691 wait() const 692 { 693 _State_base::_S_check(_M_state); 694 _M_state->wait(); 695 } 696 697 template
698 future_status 699 wait_for(const chrono::duration<_Rep, _Period>& __rel) const 700 { 701 _State_base::_S_check(_M_state); 702 return _M_state->wait_for(__rel); 703 } 704 705 template
706 future_status 707 wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const 708 { 709 _State_base::_S_check(_M_state); 710 return _M_state->wait_until(__abs); 711 } 712 713 protected: 714 /// Wait for the state to be ready and rethrow any stored exception 715 __result_type 716 _M_get_result() const 717 { 718 _State_base::_S_check(_M_state); 719 _Result_base& __res = _M_state->wait(); 720 if (!(__res._M_error == nullptr)) 721 rethrow_exception(__res._M_error); 722 return static_cast<__result_type>(__res); 723 } 724 725 void _M_swap(__basic_future& __that) noexcept 726 { 727 _M_state.swap(__that._M_state); 728 } 729 730 // Construction of a future by promise::get_future() 731 explicit 732 __basic_future(const __state_type& __state) : _M_state(__state) 733 { 734 _State_base::_S_check(_M_state); 735 _M_state->_M_set_retrieved_flag(); 736 } 737 738 // Copy construction from a shared_future 739 explicit 740 __basic_future(const shared_future<_Res>&) noexcept; 741 742 // Move construction from a shared_future 743 explicit 744 __basic_future(shared_future<_Res>&&) noexcept; 745 746 // Move construction from a future 747 explicit 748 __basic_future(future<_Res>&&) noexcept; 749 750 constexpr __basic_future() noexcept : _M_state() { } 751 752 struct _Reset 753 { 754 explicit _Reset(__basic_future& __fut) noexcept : _M_fut(__fut) { } 755 ~_Reset() { _M_fut._M_state.reset(); } 756 __basic_future& _M_fut; 757 }; 758 }; 759 760 761 /// Primary template for future. 762 template
763 class future : public __basic_future<_Res> 764 { 765 // _GLIBCXX_RESOLVE_LIB_DEFECTS 766 // 3458. Is shared_future intended to work with arrays or function types? 767 static_assert(!is_array<_Res>{}, "result type must not be an array"); 768 static_assert(!is_function<_Res>{}, "result type must not be a function"); 769 static_assert(is_destructible<_Res>{}, 770 "result type must be destructible"); 771 772 friend class promise<_Res>; 773 template
friend class packaged_task; 774 template
775 friend future<__async_result_of<_Fn, _Args...>> 776 async(launch, _Fn&&, _Args&&...); 777 778 typedef __basic_future<_Res> _Base_type; 779 typedef typename _Base_type::__state_type __state_type; 780 781 explicit 782 future(const __state_type& __state) : _Base_type(__state) { } 783 784 public: 785 constexpr future() noexcept : _Base_type() { } 786 787 /// Move constructor 788 future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } 789 790 // Disable copying 791 future(const future&) = delete; 792 future& operator=(const future&) = delete; 793 794 future& operator=(future&& __fut) noexcept 795 { 796 future(std::move(__fut))._M_swap(*this); 797 return *this; 798 } 799 800 /// Retrieving the value 801 _Res 802 get() 803 { 804 typename _Base_type::_Reset __reset(*this); 805 return std::move(this->_M_get_result()._M_value()); 806 } 807 808 shared_future<_Res> share() noexcept; 809 }; 810 811 /// Partial specialization for future
812 template
813 class future<_Res&> : public __basic_future<_Res&> 814 { 815 friend class promise<_Res&>; 816 template
friend class packaged_task; 817 template
818 friend future<__async_result_of<_Fn, _Args...>> 819 async(launch, _Fn&&, _Args&&...); 820 821 typedef __basic_future<_Res&> _Base_type; 822 typedef typename _Base_type::__state_type __state_type; 823 824 explicit 825 future(const __state_type& __state) : _Base_type(__state) { } 826 827 public: 828 constexpr future() noexcept : _Base_type() { } 829 830 /// Move constructor 831 future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } 832 833 // Disable copying 834 future(const future&) = delete; 835 future& operator=(const future&) = delete; 836 837 future& operator=(future&& __fut) noexcept 838 { 839 future(std::move(__fut))._M_swap(*this); 840 return *this; 841 } 842 843 /// Retrieving the value 844 _Res& 845 get() 846 { 847 typename _Base_type::_Reset __reset(*this); 848 return this->_M_get_result()._M_get(); 849 } 850 851 shared_future<_Res&> share() noexcept; 852 }; 853 854 /// Explicit specialization for future
855 template<> 856 class future
: public __basic_future
857 { 858 friend class promise
; 859 template
friend class packaged_task; 860 template
861 friend future<__async_result_of<_Fn, _Args...>> 862 async(launch, _Fn&&, _Args&&...); 863 864 typedef __basic_future
_Base_type; 865 typedef typename _Base_type::__state_type __state_type; 866 867 explicit 868 future(const __state_type& __state) : _Base_type(__state) { } 869 870 public: 871 constexpr future() noexcept : _Base_type() { } 872 873 /// Move constructor 874 future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } 875 876 // Disable copying 877 future(const future&) = delete; 878 future& operator=(const future&) = delete; 879 880 future& operator=(future&& __fut) noexcept 881 { 882 future(std::move(__fut))._M_swap(*this); 883 return *this; 884 } 885 886 /// Retrieving the value 887 void 888 get() 889 { 890 typename _Base_type::_Reset __reset(*this); 891 this->_M_get_result(); 892 } 893 894 shared_future
share() noexcept; 895 }; 896 897 898 /// Primary template for shared_future. 899 template
900 class shared_future : public __basic_future<_Res> 901 { 902 // _GLIBCXX_RESOLVE_LIB_DEFECTS 903 // 3458. Is shared_future intended to work with arrays or function types? 904 static_assert(!is_array<_Res>{}, "result type must not be an array"); 905 static_assert(!is_function<_Res>{}, "result type must not be a function"); 906 static_assert(is_destructible<_Res>{}, 907 "result type must be destructible"); 908 909 typedef __basic_future<_Res> _Base_type; 910 911 public: 912 constexpr shared_future() noexcept : _Base_type() { } 913 914 /// Copy constructor 915 shared_future(const shared_future& __sf) noexcept : _Base_type(__sf) { } 916 917 /// Construct from a future rvalue 918 shared_future(future<_Res>&& __uf) noexcept 919 : _Base_type(std::move(__uf)) 920 { } 921 922 /// Construct from a shared_future rvalue 923 shared_future(shared_future&& __sf) noexcept 924 : _Base_type(std::move(__sf)) 925 { } 926 927 shared_future& operator=(const shared_future& __sf) noexcept 928 { 929 shared_future(__sf)._M_swap(*this); 930 return *this; 931 } 932 933 shared_future& operator=(shared_future&& __sf) noexcept 934 { 935 shared_future(std::move(__sf))._M_swap(*this); 936 return *this; 937 } 938 939 /// Retrieving the value 940 const _Res& 941 get() const { return this->_M_get_result()._M_value(); } 942 }; 943 944 /// Partial specialization for shared_future
945 template
946 class shared_future<_Res&> : public __basic_future<_Res&> 947 { 948 typedef __basic_future<_Res&> _Base_type; 949 950 public: 951 constexpr shared_future() noexcept : _Base_type() { } 952 953 /// Copy constructor 954 shared_future(const shared_future& __sf) : _Base_type(__sf) { } 955 956 /// Construct from a future rvalue 957 shared_future(future<_Res&>&& __uf) noexcept 958 : _Base_type(std::move(__uf)) 959 { } 960 961 /// Construct from a shared_future rvalue 962 shared_future(shared_future&& __sf) noexcept 963 : _Base_type(std::move(__sf)) 964 { } 965 966 shared_future& operator=(const shared_future& __sf) 967 { 968 shared_future(__sf)._M_swap(*this); 969 return *this; 970 } 971 972 shared_future& operator=(shared_future&& __sf) noexcept 973 { 974 shared_future(std::move(__sf))._M_swap(*this); 975 return *this; 976 } 977 978 /// Retrieving the value 979 _Res& 980 get() const { return this->_M_get_result()._M_get(); } 981 }; 982 983 /// Explicit specialization for shared_future
984 template<> 985 class shared_future
: public __basic_future
986 { 987 typedef __basic_future
_Base_type; 988 989 public: 990 constexpr shared_future() noexcept : _Base_type() { } 991 992 /// Copy constructor 993 shared_future(const shared_future& __sf) : _Base_type(__sf) { } 994 995 /// Construct from a future rvalue 996 shared_future(future
&& __uf) noexcept 997 : _Base_type(std::move(__uf)) 998 { } 999 1000 /// Construct from a shared_future rvalue 1001 shared_future(shared_future&& __sf) noexcept 1002 : _Base_type(std::move(__sf)) 1003 { } 1004 1005 shared_future& operator=(const shared_future& __sf) 1006 { 1007 shared_future(__sf)._M_swap(*this); 1008 return *this; 1009 } 1010 1011 shared_future& operator=(shared_future&& __sf) noexcept 1012 { 1013 shared_future(std::move(__sf))._M_swap(*this); 1014 return *this; 1015 } 1016 1017 // Retrieving the value 1018 void 1019 get() const { this->_M_get_result(); } 1020 }; 1021 1022 // Now we can define the protected __basic_future constructors. 1023 template
1024 inline __basic_future<_Res>:: 1025 __basic_future(const shared_future<_Res>& __sf) noexcept 1026 : _M_state(__sf._M_state) 1027 { } 1028 1029 template
1030 inline __basic_future<_Res>:: 1031 __basic_future(shared_future<_Res>&& __sf) noexcept 1032 : _M_state(std::move(__sf._M_state)) 1033 { } 1034 1035 template
1036 inline __basic_future<_Res>:: 1037 __basic_future(future<_Res>&& __uf) noexcept 1038 : _M_state(std::move(__uf._M_state)) 1039 { } 1040 1041 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1042 // 2556. Wide contract for future::share() 1043 template
1044 inline shared_future<_Res> 1045 future<_Res>::share() noexcept 1046 { return shared_future<_Res>(std::move(*this)); } 1047 1048 template
1049 inline shared_future<_Res&> 1050 future<_Res&>::share() noexcept 1051 { return shared_future<_Res&>(std::move(*this)); } 1052 1053 inline shared_future
1054 future
::share() noexcept 1055 { return shared_future
(std::move(*this)); } 1056 1057 /// Primary template for promise 1058 template
1059 class promise 1060 { 1061 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1062 // 3466: Specify the requirements for promise/future/[...] consistently 1063 static_assert(!is_array<_Res>{}, "result type must not be an array"); 1064 static_assert(!is_function<_Res>{}, "result type must not be a function"); 1065 static_assert(is_destructible<_Res>{}, 1066 "result type must be destructible"); 1067 1068 typedef __future_base::_State_base _State; 1069 typedef __future_base::_Result<_Res> _Res_type; 1070 typedef __future_base::_Ptr<_Res_type> _Ptr_type; 1071 template
friend struct _State::_Setter; 1072 friend _State; 1073 1074 shared_ptr<_State> _M_future; 1075 _Ptr_type _M_storage; 1076 1077 public: 1078 promise() 1079 : _M_future(std::make_shared<_State>()), 1080 _M_storage(new _Res_type()) 1081 { } 1082 1083 promise(promise&& __rhs) noexcept 1084 : _M_future(std::move(__rhs._M_future)), 1085 _M_storage(std::move(__rhs._M_storage)) 1086 { } 1087 1088 template
1089 promise(allocator_arg_t, const _Allocator& __a) 1090 : _M_future(std::allocate_shared<_State>(__a)), 1091 _M_storage(__future_base::_S_allocate_result<_Res>(__a)) 1092 { } 1093 1094 template
1095 promise(allocator_arg_t, const _Allocator&, promise&& __rhs) 1096 : _M_future(std::move(__rhs._M_future)), 1097 _M_storage(std::move(__rhs._M_storage)) 1098 { } 1099 1100 promise(const promise&) = delete; 1101 1102 ~promise() 1103 { 1104 if (static_cast
(_M_future) && !_M_future.unique()) 1105 _M_future->_M_break_promise(std::move(_M_storage)); 1106 } 1107 1108 // Assignment 1109 promise& 1110 operator=(promise&& __rhs) noexcept 1111 { 1112 promise(std::move(__rhs)).swap(*this); 1113 return *this; 1114 } 1115 1116 promise& operator=(const promise&) = delete; 1117 1118 void 1119 swap(promise& __rhs) noexcept 1120 { 1121 _M_future.swap(__rhs._M_future); 1122 _M_storage.swap(__rhs._M_storage); 1123 } 1124 1125 // Retrieving the result 1126 future<_Res> 1127 get_future() 1128 { return future<_Res>(_M_future); } 1129 1130 // Setting the result 1131 void 1132 set_value(const _Res& __r) 1133 { _M_state()._M_set_result(_State::__setter(this, __r)); } 1134 1135 void 1136 set_value(_Res&& __r) 1137 { _M_state()._M_set_result(_State::__setter(this, std::move(__r))); } 1138 1139 void 1140 set_exception(exception_ptr __p) 1141 { _M_state()._M_set_result(_State::__setter(__p, this)); } 1142 1143 void 1144 set_value_at_thread_exit(const _Res& __r) 1145 { 1146 _M_state()._M_set_delayed_result(_State::__setter(this, __r), 1147 _M_future); 1148 } 1149 1150 void 1151 set_value_at_thread_exit(_Res&& __r) 1152 { 1153 _M_state()._M_set_delayed_result( 1154 _State::__setter(this, std::move(__r)), _M_future); 1155 } 1156 1157 void 1158 set_exception_at_thread_exit(exception_ptr __p) 1159 { 1160 _M_state()._M_set_delayed_result(_State::__setter(__p, this), 1161 _M_future); 1162 } 1163 1164 private: 1165 _State& 1166 _M_state() 1167 { 1168 __future_base::_State_base::_S_check(_M_future); 1169 return *_M_future; 1170 } 1171 }; 1172 1173 template
1174 inline void 1175 swap(promise<_Res>& __x, promise<_Res>& __y) noexcept 1176 { __x.swap(__y); } 1177 1178 template
1179 struct uses_allocator
, _Alloc> 1180 : public true_type { }; 1181 1182 1183 /// Partial specialization for promise
1184 template
1185 class promise<_Res&> 1186 { 1187 typedef __future_base::_State_base _State; 1188 typedef __future_base::_Result<_Res&> _Res_type; 1189 typedef __future_base::_Ptr<_Res_type> _Ptr_type; 1190 template
friend struct _State::_Setter; 1191 friend _State; 1192 1193 shared_ptr<_State> _M_future; 1194 _Ptr_type _M_storage; 1195 1196 public: 1197 promise() 1198 : _M_future(std::make_shared<_State>()), 1199 _M_storage(new _Res_type()) 1200 { } 1201 1202 promise(promise&& __rhs) noexcept 1203 : _M_future(std::move(__rhs._M_future)), 1204 _M_storage(std::move(__rhs._M_storage)) 1205 { } 1206 1207 template
1208 promise(allocator_arg_t, const _Allocator& __a) 1209 : _M_future(std::allocate_shared<_State>(__a)), 1210 _M_storage(__future_base::_S_allocate_result<_Res&>(__a)) 1211 { } 1212 1213 template
1214 promise(allocator_arg_t, const _Allocator&, promise&& __rhs) 1215 : _M_future(std::move(__rhs._M_future)), 1216 _M_storage(std::move(__rhs._M_storage)) 1217 { } 1218 1219 promise(const promise&) = delete; 1220 1221 ~promise() 1222 { 1223 if (static_cast
(_M_future) && !_M_future.unique()) 1224 _M_future->_M_break_promise(std::move(_M_storage)); 1225 } 1226 1227 // Assignment 1228 promise& 1229 operator=(promise&& __rhs) noexcept 1230 { 1231 promise(std::move(__rhs)).swap(*this); 1232 return *this; 1233 } 1234 1235 promise& operator=(const promise&) = delete; 1236 1237 void 1238 swap(promise& __rhs) noexcept 1239 { 1240 _M_future.swap(__rhs._M_future); 1241 _M_storage.swap(__rhs._M_storage); 1242 } 1243 1244 // Retrieving the result 1245 future<_Res&> 1246 get_future() 1247 { return future<_Res&>(_M_future); } 1248 1249 // Setting the result 1250 void 1251 set_value(_Res& __r) 1252 { _M_state()._M_set_result(_State::__setter(this, __r)); } 1253 1254 void 1255 set_exception(exception_ptr __p) 1256 { _M_state()._M_set_result(_State::__setter(__p, this)); } 1257 1258 void 1259 set_value_at_thread_exit(_Res& __r) 1260 { 1261 _M_state()._M_set_delayed_result(_State::__setter(this, __r), 1262 _M_future); 1263 } 1264 1265 void 1266 set_exception_at_thread_exit(exception_ptr __p) 1267 { 1268 _M_state()._M_set_delayed_result(_State::__setter(__p, this), 1269 _M_future); 1270 } 1271 1272 private: 1273 _State& 1274 _M_state() 1275 { 1276 __future_base::_State_base::_S_check(_M_future); 1277 return *_M_future; 1278 } 1279 }; 1280 1281 /// Explicit specialization for promise
1282 template<> 1283 class promise
1284 { 1285 typedef __future_base::_State_base _State; 1286 typedef __future_base::_Result
_Res_type; 1287 typedef __future_base::_Ptr<_Res_type> _Ptr_type; 1288 template
friend struct _State::_Setter; 1289 friend _State; 1290 1291 shared_ptr<_State> _M_future; 1292 _Ptr_type _M_storage; 1293 1294 public: 1295 promise() 1296 : _M_future(std::make_shared<_State>()), 1297 _M_storage(new _Res_type()) 1298 { } 1299 1300 promise(promise&& __rhs) noexcept 1301 : _M_future(std::move(__rhs._M_future)), 1302 _M_storage(std::move(__rhs._M_storage)) 1303 { } 1304 1305 template
1306 promise(allocator_arg_t, const _Allocator& __a) 1307 : _M_future(std::allocate_shared<_State>(__a)), 1308 _M_storage(__future_base::_S_allocate_result
(__a)) 1309 { } 1310 1311 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1312 // 2095. missing constructors needed for uses-allocator construction 1313 template
1314 promise(allocator_arg_t, const _Allocator&, promise&& __rhs) 1315 : _M_future(std::move(__rhs._M_future)), 1316 _M_storage(std::move(__rhs._M_storage)) 1317 { } 1318 1319 promise(const promise&) = delete; 1320 1321 ~promise() 1322 { 1323 if (static_cast
(_M_future) && !_M_future.unique()) 1324 _M_future->_M_break_promise(std::move(_M_storage)); 1325 } 1326 1327 // Assignment 1328 promise& 1329 operator=(promise&& __rhs) noexcept 1330 { 1331 promise(std::move(__rhs)).swap(*this); 1332 return *this; 1333 } 1334 1335 promise& operator=(const promise&) = delete; 1336 1337 void 1338 swap(promise& __rhs) noexcept 1339 { 1340 _M_future.swap(__rhs._M_future); 1341 _M_storage.swap(__rhs._M_storage); 1342 } 1343 1344 // Retrieving the result 1345 future
1346 get_future() 1347 { return future
(_M_future); } 1348 1349 // Setting the result 1350 void 1351 set_value() 1352 { _M_state()._M_set_result(_State::__setter(this)); } 1353 1354 void 1355 set_exception(exception_ptr __p) 1356 { _M_state()._M_set_result(_State::__setter(__p, this)); } 1357 1358 void 1359 set_value_at_thread_exit() 1360 { _M_state()._M_set_delayed_result(_State::__setter(this), _M_future); } 1361 1362 void 1363 set_exception_at_thread_exit(exception_ptr __p) 1364 { 1365 _M_state()._M_set_delayed_result(_State::__setter(__p, this), 1366 _M_future); 1367 } 1368 1369 private: 1370 _State& 1371 _M_state() 1372 { 1373 __future_base::_State_base::_S_check(_M_future); 1374 return *_M_future; 1375 } 1376 }; 1377 1378 template
1379 struct __future_base::_Task_setter 1380 { 1381 // Invoke the function and provide the result to the caller. 1382 _Ptr_type operator()() const 1383 { 1384 __try 1385 { 1386 (*_M_result)->_M_set((*_M_fn)()); 1387 } 1388 __catch(const __cxxabiv1::__forced_unwind&) 1389 { 1390 __throw_exception_again; // will cause broken_promise 1391 } 1392 __catch(...) 1393 { 1394 (*_M_result)->_M_error = current_exception(); 1395 } 1396 return std::move(*_M_result); 1397 } 1398 _Ptr_type* _M_result; 1399 _Fn* _M_fn; 1400 }; 1401 1402 template
1403 struct __future_base::_Task_setter<_Ptr_type, _Fn, void> 1404 { 1405 _Ptr_type operator()() const 1406 { 1407 __try 1408 { 1409 (*_M_fn)(); 1410 } 1411 __catch(const __cxxabiv1::__forced_unwind&) 1412 { 1413 __throw_exception_again; // will cause broken_promise 1414 } 1415 __catch(...) 1416 { 1417 (*_M_result)->_M_error = current_exception(); 1418 } 1419 return std::move(*_M_result); 1420 } 1421 _Ptr_type* _M_result; 1422 _Fn* _M_fn; 1423 }; 1424 1425 // Holds storage for a packaged_task's result. 1426 template
1427 struct __future_base::_Task_state_base<_Res(_Args...)> 1428 : __future_base::_State_base 1429 { 1430 typedef _Res _Res_type; 1431 1432 template
1433 _Task_state_base(const _Alloc& __a) 1434 : _M_result(_S_allocate_result<_Res>(__a)) 1435 { } 1436 1437 // Invoke the stored task and make the state ready. 1438 virtual void 1439 _M_run(_Args&&... __args) = 0; 1440 1441 // Invoke the stored task and make the state ready at thread exit. 1442 virtual void 1443 _M_run_delayed(_Args&&... __args, weak_ptr<_State_base>) = 0; 1444 1445 virtual shared_ptr<_Task_state_base> 1446 _M_reset() = 0; 1447 1448 typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; 1449 _Ptr_type _M_result; 1450 }; 1451 1452 // Holds a packaged_task's stored task. 1453 template
1454 struct __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)> final 1455 : __future_base::_Task_state_base<_Res(_Args...)> 1456 { 1457 template
1458 _Task_state(_Fn2&& __fn, const _Alloc& __a) 1459 : _Task_state_base<_Res(_Args...)>(__a), 1460 _M_impl(std::forward<_Fn2>(__fn), __a) 1461 { } 1462 1463 private: 1464 virtual void 1465 _M_run(_Args&&... __args) 1466 { 1467 auto __boundfn = [&] () -> _Res { 1468 return std::__invoke_r<_Res>(_M_impl._M_fn, 1469 std::forward<_Args>(__args)...); 1470 }; 1471 this->_M_set_result(_S_task_setter(this->_M_result, __boundfn)); 1472 } 1473 1474 virtual void 1475 _M_run_delayed(_Args&&... __args, weak_ptr<_State_base> __self) 1476 { 1477 auto __boundfn = [&] () -> _Res { 1478 return std::__invoke_r<_Res>(_M_impl._M_fn, 1479 std::forward<_Args>(__args)...); 1480 }; 1481 this->_M_set_delayed_result(_S_task_setter(this->_M_result, __boundfn), 1482 std::move(__self)); 1483 } 1484 1485 virtual shared_ptr<_Task_state_base<_Res(_Args...)>> 1486 _M_reset(); 1487 1488 struct _Impl : _Alloc 1489 { 1490 template
1491 _Impl(_Fn2&& __fn, const _Alloc& __a) 1492 : _Alloc(__a), _M_fn(std::forward<_Fn2>(__fn)) { } 1493 _Fn _M_fn; 1494 } _M_impl; 1495 }; 1496 1497 template
> 1499 static shared_ptr<__future_base::_Task_state_base<_Signature>> 1500 __create_task_state(_Fn&& __fn, const _Alloc& __a = _Alloc()) 1501 { 1502 typedef typename decay<_Fn>::type _Fn2; 1503 typedef __future_base::_Task_state<_Fn2, _Alloc, _Signature> _State; 1504 return std::allocate_shared<_State>(__a, std::forward<_Fn>(__fn), __a); 1505 } 1506 1507 template
1508 shared_ptr<__future_base::_Task_state_base<_Res(_Args...)>> 1509 __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)>::_M_reset() 1510 { 1511 return __create_task_state<_Res(_Args...)>(std::move(_M_impl._M_fn), 1512 static_cast<_Alloc&>(_M_impl)); 1513 } 1514 1515 /// packaged_task 1516 template
1517 class packaged_task<_Res(_ArgTypes...)> 1518 { 1519 typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type; 1520 shared_ptr<_State_type> _M_state; 1521 1522 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1523 // 3039. Unnecessary decay in thread and packaged_task 1524 template
> 1525 using __not_same 1526 = typename enable_if::value>::type; 1527 1528 public: 1529 // Construction and destruction 1530 packaged_task() noexcept { } 1531 1532 template
> 1533 explicit 1534 packaged_task(_Fn&& __fn) 1535 : _M_state( 1536 __create_task_state<_Res(_ArgTypes...)>(std::forward<_Fn>(__fn))) 1537 { } 1538 1539 #if __cplusplus < 201703L 1540 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1541 // 2097. packaged_task constructors should be constrained 1542 // 2407. [this constructor should not be] explicit 1543 // 2921. packaged_task and type-erased allocators 1544 template
> 1545 packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn) 1546 : _M_state(__create_task_state<_Res(_ArgTypes...)>( 1547 std::forward<_Fn>(__fn), __a)) 1548 { } 1549 1550 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1551 // 2095. missing constructors needed for uses-allocator construction 1552 template
1553 packaged_task(allocator_arg_t, const _Allocator& __a) noexcept 1554 { } 1555 1556 template
1557 packaged_task(allocator_arg_t, const _Allocator&, 1558 const packaged_task&) = delete; 1559 1560 template
1561 packaged_task(allocator_arg_t, const _Allocator&, 1562 packaged_task&& __other) noexcept 1563 { this->swap(__other); } 1564 #endif 1565 1566 ~packaged_task() 1567 { 1568 if (static_cast
(_M_state) && !_M_state.unique()) 1569 _M_state->_M_break_promise(std::move(_M_state->_M_result)); 1570 } 1571 1572 // No copy 1573 packaged_task(const packaged_task&) = delete; 1574 packaged_task& operator=(const packaged_task&) = delete; 1575 1576 // Move support 1577 packaged_task(packaged_task&& __other) noexcept 1578 { this->swap(__other); } 1579 1580 packaged_task& operator=(packaged_task&& __other) noexcept 1581 { 1582 packaged_task(std::move(__other)).swap(*this); 1583 return *this; 1584 } 1585 1586 void 1587 swap(packaged_task& __other) noexcept 1588 { _M_state.swap(__other._M_state); } 1589 1590 bool 1591 valid() const noexcept 1592 { return static_cast
(_M_state); } 1593 1594 // Result retrieval 1595 future<_Res> 1596 get_future() 1597 { return future<_Res>(_M_state); } 1598 1599 // Execution 1600 void 1601 operator()(_ArgTypes... __args) 1602 { 1603 __future_base::_State_base::_S_check(_M_state); 1604 _M_state->_M_run(std::forward<_ArgTypes>(__args)...); 1605 } 1606 1607 void 1608 make_ready_at_thread_exit(_ArgTypes... __args) 1609 { 1610 __future_base::_State_base::_S_check(_M_state); 1611 _M_state->_M_run_delayed(std::forward<_ArgTypes>(__args)..., _M_state); 1612 } 1613 1614 void 1615 reset() 1616 { 1617 __future_base::_State_base::_S_check(_M_state); 1618 packaged_task __tmp; 1619 __tmp._M_state = _M_state; 1620 _M_state = _M_state->_M_reset(); 1621 } 1622 }; 1623 1624 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1625 // 3117. Missing packaged_task deduction guides 1626 #if __cpp_deduction_guides >= 201606 1627 template
1628 packaged_task(_Res(*)(_ArgTypes...)) -> packaged_task<_Res(_ArgTypes...)>; 1629 1630 template
::type> 1632 packaged_task(_Fun) -> packaged_task<_Signature>; 1633 #endif 1634 1635 /// swap 1636 template
1637 inline void 1638 swap(packaged_task<_Res(_ArgTypes...)>& __x, 1639 packaged_task<_Res(_ArgTypes...)>& __y) noexcept 1640 { __x.swap(__y); } 1641 1642 #if __cplusplus < 201703L 1643 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1644 // 2976. Dangling uses_allocator specialization for packaged_task 1645 template
1646 struct uses_allocator
, _Alloc> 1647 : public true_type { }; 1648 #endif 1649 1650 // Shared state created by std::async(). 1651 // Holds a deferred function and storage for its result. 1652 template
1653 class __future_base::_Deferred_state final 1654 : public __future_base::_State_base 1655 { 1656 public: 1657 template
1658 explicit 1659 _Deferred_state(_Args&&... __args) 1660 : _M_result(new _Result<_Res>()), 1661 _M_fn(std::forward<_Args>(__args)...) 1662 { } 1663 1664 private: 1665 typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; 1666 _Ptr_type _M_result; 1667 _BoundFn _M_fn; 1668 1669 // Run the deferred function. 1670 virtual void 1671 _M_complete_async() 1672 { 1673 // Multiple threads can call a waiting function on the future and 1674 // reach this point at the same time. The call_once in _M_set_result 1675 // ensures only the first one run the deferred function, stores the 1676 // result in _M_result, swaps that with the base _M_result and makes 1677 // the state ready. Tell _M_set_result to ignore failure so all later 1678 // calls do nothing. 1679 _M_set_result(_S_task_setter(_M_result, _M_fn), true); 1680 } 1681 1682 // Caller should check whether the state is ready first, because this 1683 // function will return true even after the deferred function has run. 1684 virtual bool _M_is_deferred_future() const { return true; } 1685 }; 1686 1687 // Common functionality hoisted out of the _Async_state_impl template. 1688 class __future_base::_Async_state_commonV2 1689 : public __future_base::_State_base 1690 { 1691 protected: 1692 ~_Async_state_commonV2() = default; 1693 1694 // Make waiting functions block until the thread completes, as if joined. 1695 // 1696 // This function is used by wait() to satisfy the first requirement below 1697 // and by wait_for() / wait_until() to satisfy the second. 1698 // 1699 // [futures.async]: 1700 // 1701 // - a call to a waiting function on an asynchronous return object that 1702 // shares the shared state created by this async call shall block until 1703 // the associated thread has completed, as if joined, or else time out. 1704 // 1705 // - the associated thread completion synchronizes with the return from 1706 // the first function that successfully detects the ready status of the 1707 // shared state or with the return from the last function that releases 1708 // the shared state, whichever happens first. 1709 virtual void _M_complete_async() { _M_join(); } 1710 1711 void _M_join() { std::call_once(_M_once, &thread::join, &_M_thread); } 1712 1713 thread _M_thread; 1714 once_flag _M_once; 1715 }; 1716 1717 // Shared state created by std::async(). 1718 // Starts a new thread that runs a function and makes the shared state ready. 1719 template
1720 class __future_base::_Async_state_impl final 1721 : public __future_base::_Async_state_commonV2 1722 { 1723 public: 1724 template
1725 explicit 1726 _Async_state_impl(_Args&&... __args) 1727 : _M_result(new _Result<_Res>()), 1728 _M_fn(std::forward<_Args>(__args)...) 1729 { 1730 _M_thread = std::thread{&_Async_state_impl::_M_run, this}; 1731 } 1732 1733 // Must not destroy _M_result and _M_fn until the thread finishes. 1734 // Call join() directly rather than through _M_join() because no other 1735 // thread can be referring to this state if it is being destroyed. 1736 ~_Async_state_impl() 1737 { 1738 if (_M_thread.joinable()) 1739 _M_thread.join(); 1740 } 1741 1742 private: 1743 void 1744 _M_run() 1745 { 1746 __try 1747 { 1748 _M_set_result(_S_task_setter(_M_result, _M_fn)); 1749 } 1750 __catch (const __cxxabiv1::__forced_unwind&) 1751 { 1752 // make the shared state ready on thread cancellation 1753 if (static_cast
(_M_result)) 1754 this->_M_break_promise(std::move(_M_result)); 1755 __throw_exception_again; 1756 } 1757 } 1758 1759 typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; 1760 _Ptr_type _M_result; 1761 _BoundFn _M_fn; 1762 }; 1763 1764 1765 /// async 1766 template
1767 _GLIBCXX_NODISCARD future<__async_result_of<_Fn, _Args...>> 1768 async(launch __policy, _Fn&& __fn, _Args&&... __args) 1769 { 1770 using _Wr = std::thread::_Call_wrapper<_Fn, _Args...>; 1771 using _As = __future_base::_Async_state_impl<_Wr>; 1772 using _Ds = __future_base::_Deferred_state<_Wr>; 1773 1774 std::shared_ptr<__future_base::_State_base> __state; 1775 if ((__policy & launch::async) == launch::async) 1776 { 1777 __try 1778 { 1779 __state = std::make_shared<_As>(std::forward<_Fn>(__fn), 1780 std::forward<_Args>(__args)...); 1781 } 1782 #if __cpp_exceptions 1783 catch(const system_error& __e) 1784 { 1785 if (__e.code() != errc::resource_unavailable_try_again 1786 || (__policy & launch::deferred) != launch::deferred) 1787 throw; 1788 } 1789 #endif 1790 } 1791 if (!__state) 1792 { 1793 __state = std::make_shared<_Ds>(std::forward<_Fn>(__fn), 1794 std::forward<_Args>(__args)...); 1795 } 1796 return future<__async_result_of<_Fn, _Args...>>(std::move(__state)); 1797 } 1798 1799 /// async, potential overload 1800 template
1801 _GLIBCXX_NODISCARD inline future<__async_result_of<_Fn, _Args...>> 1802 async(_Fn&& __fn, _Args&&... __args) 1803 { 1804 return std::async(launch::async|launch::deferred, 1805 std::forward<_Fn>(__fn), 1806 std::forward<_Args>(__args)...); 1807 } 1808 1809 #endif // _GLIBCXX_ASYNC_ABI_COMPAT 1810 #endif // _GLIBCXX_HAS_GTHREADS 1811 1812 /// @} group futures 1813 _GLIBCXX_END_NAMESPACE_VERSION 1814 } // namespace 1815 1816 #endif // C++11 1817 1818 #endif // _GLIBCXX_FUTURE
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2024 MyWebUniversity.com ™