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