libstdc++
|
00001 // <future> -*- C++ -*- 00002 00003 // Copyright (C) 2009-2014 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file include/future 00026 * This is a Standard C++ Library header. 00027 */ 00028 00029 #ifndef _GLIBCXX_FUTURE 00030 #define _GLIBCXX_FUTURE 1 00031 00032 #pragma GCC system_header 00033 00034 #if __cplusplus < 201103L 00035 # include <bits/c++0x_warning.h> 00036 #else 00037 00038 #include <functional> 00039 #include <mutex> 00040 #include <thread> 00041 #include <condition_variable> 00042 #include <system_error> 00043 #include <atomic> 00044 #include <bits/functexcept.h> 00045 #include <bits/unique_ptr.h> 00046 #include <bits/shared_ptr.h> 00047 #include <bits/uses_allocator.h> 00048 #include <bits/alloc_traits.h> 00049 #include <ext/aligned_buffer.h> 00050 00051 namespace std _GLIBCXX_VISIBILITY(default) 00052 { 00053 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00054 00055 /** 00056 * @defgroup futures Futures 00057 * @ingroup concurrency 00058 * 00059 * Classes for futures support. 00060 * @{ 00061 */ 00062 00063 /// Error code for futures 00064 enum class future_errc 00065 { 00066 future_already_retrieved = 1, 00067 promise_already_satisfied, 00068 no_state, 00069 broken_promise 00070 }; 00071 00072 /// Specialization. 00073 template<> 00074 struct is_error_code_enum<future_errc> : public true_type { }; 00075 00076 /// Points to a statically-allocated object derived from error_category. 00077 const error_category& 00078 future_category() noexcept; 00079 00080 /// Overload for make_error_code. 00081 inline error_code 00082 make_error_code(future_errc __errc) noexcept 00083 { return error_code(static_cast<int>(__errc), future_category()); } 00084 00085 /// Overload for make_error_condition. 00086 inline error_condition 00087 make_error_condition(future_errc __errc) noexcept 00088 { return error_condition(static_cast<int>(__errc), future_category()); } 00089 00090 /** 00091 * @brief Exception type thrown by futures. 00092 * @ingroup exceptions 00093 */ 00094 class future_error : public logic_error 00095 { 00096 error_code _M_code; 00097 00098 public: 00099 explicit future_error(error_code __ec) 00100 : logic_error("std::future_error"), _M_code(__ec) 00101 { } 00102 00103 virtual ~future_error() noexcept; 00104 00105 virtual const char* 00106 what() const noexcept; 00107 00108 const error_code& 00109 code() const noexcept { return _M_code; } 00110 }; 00111 00112 // Forward declarations. 00113 template<typename _Res> 00114 class future; 00115 00116 template<typename _Res> 00117 class shared_future; 00118 00119 template<typename _Signature> 00120 class packaged_task; 00121 00122 template<typename _Res> 00123 class promise; 00124 00125 /// Launch code for futures 00126 enum class launch 00127 { 00128 async = 1, 00129 deferred = 2 00130 }; 00131 00132 constexpr launch operator&(launch __x, launch __y) 00133 { 00134 return static_cast<launch>( 00135 static_cast<int>(__x) & static_cast<int>(__y)); 00136 } 00137 00138 constexpr launch operator|(launch __x, launch __y) 00139 { 00140 return static_cast<launch>( 00141 static_cast<int>(__x) | static_cast<int>(__y)); 00142 } 00143 00144 constexpr launch operator^(launch __x, launch __y) 00145 { 00146 return static_cast<launch>( 00147 static_cast<int>(__x) ^ static_cast<int>(__y)); 00148 } 00149 00150 constexpr launch operator~(launch __x) 00151 { return static_cast<launch>(~static_cast<int>(__x)); } 00152 00153 inline launch& operator&=(launch& __x, launch __y) 00154 { return __x = __x & __y; } 00155 00156 inline launch& operator|=(launch& __x, launch __y) 00157 { return __x = __x | __y; } 00158 00159 inline launch& operator^=(launch& __x, launch __y) 00160 { return __x = __x ^ __y; } 00161 00162 /// Status code for futures 00163 enum class future_status 00164 { 00165 ready, 00166 timeout, 00167 deferred 00168 }; 00169 00170 template<typename _Fn, typename... _Args> 00171 future<typename result_of<_Fn(_Args...)>::type> 00172 async(launch __policy, _Fn&& __fn, _Args&&... __args); 00173 00174 template<typename _Fn, typename... _Args> 00175 future<typename result_of<_Fn(_Args...)>::type> 00176 async(_Fn&& __fn, _Args&&... __args); 00177 00178 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \ 00179 && (ATOMIC_INT_LOCK_FREE > 1) 00180 00181 /// Base class and enclosing scope. 00182 struct __future_base 00183 { 00184 /// Base class for results. 00185 struct _Result_base 00186 { 00187 exception_ptr _M_error; 00188 00189 _Result_base(const _Result_base&) = delete; 00190 _Result_base& operator=(const _Result_base&) = delete; 00191 00192 // _M_destroy() allows derived classes to control deallocation 00193 virtual void _M_destroy() = 0; 00194 00195 struct _Deleter 00196 { 00197 void operator()(_Result_base* __fr) const { __fr->_M_destroy(); } 00198 }; 00199 00200 protected: 00201 _Result_base(); 00202 virtual ~_Result_base(); 00203 }; 00204 00205 /// Result. 00206 template<typename _Res> 00207 struct _Result : _Result_base 00208 { 00209 private: 00210 __gnu_cxx::__aligned_buffer<_Res> _M_storage; 00211 bool _M_initialized; 00212 00213 public: 00214 typedef _Res result_type; 00215 00216 _Result() noexcept : _M_initialized() { } 00217 00218 ~_Result() 00219 { 00220 if (_M_initialized) 00221 _M_value().~_Res(); 00222 } 00223 00224 // Return lvalue, future will add const or rvalue-reference 00225 _Res& 00226 _M_value() noexcept { return *_M_storage._M_ptr(); } 00227 00228 void 00229 _M_set(const _Res& __res) 00230 { 00231 ::new (_M_storage._M_addr()) _Res(__res); 00232 _M_initialized = true; 00233 } 00234 00235 void 00236 _M_set(_Res&& __res) 00237 { 00238 ::new (_M_storage._M_addr()) _Res(std::move(__res)); 00239 _M_initialized = true; 00240 } 00241 00242 private: 00243 void _M_destroy() { delete this; } 00244 }; 00245 00246 /// A unique_ptr based on the instantiating type. 00247 template<typename _Res> 00248 using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>; 00249 00250 /// Result_alloc. 00251 template<typename _Res, typename _Alloc> 00252 struct _Result_alloc final : _Result<_Res>, _Alloc 00253 { 00254 typedef typename allocator_traits<_Alloc>::template 00255 rebind_alloc<_Result_alloc> __allocator_type; 00256 00257 explicit 00258 _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a) 00259 { } 00260 00261 private: 00262 void _M_destroy() 00263 { 00264 typedef allocator_traits<__allocator_type> __traits; 00265 __allocator_type __a(*this); 00266 __traits::destroy(__a, this); 00267 __traits::deallocate(__a, this, 1); 00268 } 00269 }; 00270 00271 template<typename _Res, typename _Allocator> 00272 static _Ptr<_Result_alloc<_Res, _Allocator>> 00273 _S_allocate_result(const _Allocator& __a) 00274 { 00275 typedef _Result_alloc<_Res, _Allocator> __result_type; 00276 typedef allocator_traits<typename __result_type::__allocator_type> 00277 __traits; 00278 typename __traits::allocator_type __a2(__a); 00279 __result_type* __p = __traits::allocate(__a2, 1); 00280 __try 00281 { 00282 __traits::construct(__a2, __p, __a); 00283 } 00284 __catch(...) 00285 { 00286 __traits::deallocate(__a2, __p, 1); 00287 __throw_exception_again; 00288 } 00289 return _Ptr<__result_type>(__p); 00290 } 00291 00292 template<typename _Res, typename _Tp> 00293 static _Ptr<_Result<_Res>> 00294 _S_allocate_result(const std::allocator<_Tp>& __a) 00295 { 00296 return _Ptr<_Result<_Res>>(new _Result<_Res>); 00297 } 00298 00299 /// Base class for state between a promise and one or more 00300 /// associated futures. 00301 class _State_baseV2 00302 { 00303 typedef _Ptr<_Result_base> _Ptr_type; 00304 00305 _Ptr_type _M_result; 00306 mutex _M_mutex; 00307 condition_variable _M_cond; 00308 atomic_flag _M_retrieved; 00309 once_flag _M_once; 00310 00311 public: 00312 _State_baseV2() noexcept : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) 00313 { } 00314 _State_baseV2(const _State_baseV2&) = delete; 00315 _State_baseV2& operator=(const _State_baseV2&) = delete; 00316 virtual ~_State_baseV2() = default; 00317 00318 _Result_base& 00319 wait() 00320 { 00321 _M_complete_async(); 00322 unique_lock<mutex> __lock(_M_mutex); 00323 _M_cond.wait(__lock, [&] { return _M_ready(); }); 00324 return *_M_result; 00325 } 00326 00327 template<typename _Rep, typename _Period> 00328 future_status 00329 wait_for(const chrono::duration<_Rep, _Period>& __rel) 00330 { 00331 unique_lock<mutex> __lock(_M_mutex); 00332 if (_M_ready()) 00333 return future_status::ready; 00334 if (_M_has_deferred()) 00335 return future_status::deferred; 00336 if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready(); })) 00337 { 00338 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00339 // 2100. timed waiting functions must also join 00340 _M_complete_async(); 00341 return future_status::ready; 00342 } 00343 return future_status::timeout; 00344 } 00345 00346 template<typename _Clock, typename _Duration> 00347 future_status 00348 wait_until(const chrono::time_point<_Clock, _Duration>& __abs) 00349 { 00350 unique_lock<mutex> __lock(_M_mutex); 00351 if (_M_ready()) 00352 return future_status::ready; 00353 if (_M_has_deferred()) 00354 return future_status::deferred; 00355 if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready(); })) 00356 { 00357 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00358 // 2100. timed waiting functions must also join 00359 _M_complete_async(); 00360 return future_status::ready; 00361 } 00362 return future_status::timeout; 00363 } 00364 00365 void 00366 _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false) 00367 { 00368 bool __set = false; 00369 // all calls to this function are serialized, 00370 // side-effects of invoking __res only happen once 00371 call_once(_M_once, &_State_baseV2::_M_do_set, this, ref(__res), 00372 ref(__set)); 00373 if (__set) 00374 _M_cond.notify_all(); 00375 else if (!__ignore_failure) 00376 __throw_future_error(int(future_errc::promise_already_satisfied)); 00377 } 00378 00379 void 00380 _M_break_promise(_Ptr_type __res) 00381 { 00382 if (static_cast<bool>(__res)) 00383 { 00384 error_code __ec(make_error_code(future_errc::broken_promise)); 00385 __res->_M_error = make_exception_ptr(future_error(__ec)); 00386 { 00387 lock_guard<mutex> __lock(_M_mutex); 00388 _M_result.swap(__res); 00389 } 00390 _M_cond.notify_all(); 00391 } 00392 } 00393 00394 // Called when this object is passed to a future. 00395 void 00396 _M_set_retrieved_flag() 00397 { 00398 if (_M_retrieved.test_and_set()) 00399 __throw_future_error(int(future_errc::future_already_retrieved)); 00400 } 00401 00402 template<typename _Res, typename _Arg> 00403 struct _Setter; 00404 00405 // set lvalues 00406 template<typename _Res, typename _Arg> 00407 struct _Setter<_Res, _Arg&> 00408 { 00409 // check this is only used by promise<R>::set_value(const R&) 00410 // or promise<R>::set_value(R&) 00411 static_assert(is_same<_Res, _Arg&>::value // promise<R&> 00412 || is_same<const _Res, _Arg>::value, // promise<R> 00413 "Invalid specialisation"); 00414 00415 typename promise<_Res>::_Ptr_type operator()() 00416 { 00417 _State_baseV2::_S_check(_M_promise->_M_future); 00418 _M_promise->_M_storage->_M_set(_M_arg); 00419 return std::move(_M_promise->_M_storage); 00420 } 00421 promise<_Res>* _M_promise; 00422 _Arg& _M_arg; 00423 }; 00424 00425 // set rvalues 00426 template<typename _Res> 00427 struct _Setter<_Res, _Res&&> 00428 { 00429 typename promise<_Res>::_Ptr_type operator()() 00430 { 00431 _State_baseV2::_S_check(_M_promise->_M_future); 00432 _M_promise->_M_storage->_M_set(std::move(_M_arg)); 00433 return std::move(_M_promise->_M_storage); 00434 } 00435 promise<_Res>* _M_promise; 00436 _Res& _M_arg; 00437 }; 00438 00439 struct __exception_ptr_tag { }; 00440 00441 // set exceptions 00442 template<typename _Res> 00443 struct _Setter<_Res, __exception_ptr_tag> 00444 { 00445 typename promise<_Res>::_Ptr_type operator()() 00446 { 00447 _State_baseV2::_S_check(_M_promise->_M_future); 00448 _M_promise->_M_storage->_M_error = _M_ex; 00449 return std::move(_M_promise->_M_storage); 00450 } 00451 00452 promise<_Res>* _M_promise; 00453 exception_ptr& _M_ex; 00454 }; 00455 00456 template<typename _Res, typename _Arg> 00457 static _Setter<_Res, _Arg&&> 00458 __setter(promise<_Res>* __prom, _Arg&& __arg) 00459 { 00460 return _Setter<_Res, _Arg&&>{ __prom, __arg }; 00461 } 00462 00463 template<typename _Res> 00464 static _Setter<_Res, __exception_ptr_tag> 00465 __setter(exception_ptr& __ex, promise<_Res>* __prom) 00466 { 00467 return _Setter<_Res, __exception_ptr_tag>{ __prom, __ex }; 00468 } 00469 00470 static _Setter<void, void> 00471 __setter(promise<void>* __prom); 00472 00473 template<typename _Tp> 00474 static void 00475 _S_check(const shared_ptr<_Tp>& __p) 00476 { 00477 if (!static_cast<bool>(__p)) 00478 __throw_future_error((int)future_errc::no_state); 00479 } 00480 00481 private: 00482 void 00483 _M_do_set(function<_Ptr_type()>& __f, bool& __set) 00484 { 00485 _Ptr_type __res = __f(); 00486 { 00487 lock_guard<mutex> __lock(_M_mutex); 00488 _M_result.swap(__res); 00489 } 00490 __set = true; 00491 } 00492 00493 bool _M_ready() const noexcept { return static_cast<bool>(_M_result); } 00494 00495 // Wait for completion of async function. 00496 virtual void _M_complete_async() { } 00497 00498 // Return true if state contains a deferred function. 00499 // Caller must own _M_mutex. 00500 virtual bool _M_has_deferred() const { return false; } 00501 }; 00502 00503 #ifdef _GLIBCXX_ASYNC_ABI_COMPAT 00504 class _State_base; 00505 class _Async_state_common; 00506 #else 00507 using _State_base = _State_baseV2; 00508 class _Async_state_commonV2; 00509 #endif 00510 00511 template<typename _BoundFn, typename = typename _BoundFn::result_type> 00512 class _Deferred_state; 00513 00514 template<typename _BoundFn, typename = typename _BoundFn::result_type> 00515 class _Async_state_impl; 00516 00517 template<typename _Signature> 00518 class _Task_state_base; 00519 00520 template<typename _Fn, typename _Alloc, typename _Signature> 00521 class _Task_state; 00522 00523 template<typename _BoundFn> 00524 static std::shared_ptr<_State_base> 00525 _S_make_deferred_state(_BoundFn&& __fn); 00526 00527 template<typename _BoundFn> 00528 static std::shared_ptr<_State_base> 00529 _S_make_async_state(_BoundFn&& __fn); 00530 00531 template<typename _Res_ptr, 00532 typename _Res = typename _Res_ptr::element_type::result_type> 00533 struct _Task_setter; 00534 00535 template<typename _Res_ptr, typename _BoundFn> 00536 static _Task_setter<_Res_ptr> 00537 _S_task_setter(_Res_ptr& __ptr, _BoundFn&& __call) 00538 { 00539 return _Task_setter<_Res_ptr>{ __ptr, std::ref(__call) }; 00540 } 00541 }; 00542 00543 /// Partial specialization for reference types. 00544 template<typename _Res> 00545 struct __future_base::_Result<_Res&> : __future_base::_Result_base 00546 { 00547 typedef _Res& result_type; 00548 00549 _Result() noexcept : _M_value_ptr() { } 00550 00551 void _M_set(_Res& __res) noexcept { _M_value_ptr = &__res; } 00552 00553 _Res& _M_get() noexcept { return *_M_value_ptr; } 00554 00555 private: 00556 _Res* _M_value_ptr; 00557 00558 void _M_destroy() { delete this; } 00559 }; 00560 00561 /// Explicit specialization for void. 00562 template<> 00563 struct __future_base::_Result<void> : __future_base::_Result_base 00564 { 00565 typedef void result_type; 00566 00567 private: 00568 void _M_destroy() { delete this; } 00569 }; 00570 00571 #ifndef _GLIBCXX_ASYNC_ABI_COMPAT 00572 00573 /// Common implementation for future and shared_future. 00574 template<typename _Res> 00575 class __basic_future : public __future_base 00576 { 00577 protected: 00578 typedef shared_ptr<_State_base> __state_type; 00579 typedef __future_base::_Result<_Res>& __result_type; 00580 00581 private: 00582 __state_type _M_state; 00583 00584 public: 00585 // Disable copying. 00586 __basic_future(const __basic_future&) = delete; 00587 __basic_future& operator=(const __basic_future&) = delete; 00588 00589 bool 00590 valid() const noexcept { return static_cast<bool>(_M_state); } 00591 00592 void 00593 wait() const 00594 { 00595 _State_base::_S_check(_M_state); 00596 _M_state->wait(); 00597 } 00598 00599 template<typename _Rep, typename _Period> 00600 future_status 00601 wait_for(const chrono::duration<_Rep, _Period>& __rel) const 00602 { 00603 _State_base::_S_check(_M_state); 00604 return _M_state->wait_for(__rel); 00605 } 00606 00607 template<typename _Clock, typename _Duration> 00608 future_status 00609 wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const 00610 { 00611 _State_base::_S_check(_M_state); 00612 return _M_state->wait_until(__abs); 00613 } 00614 00615 protected: 00616 /// Wait for the state to be ready and rethrow any stored exception 00617 __result_type 00618 _M_get_result() const 00619 { 00620 _State_base::_S_check(_M_state); 00621 _Result_base& __res = _M_state->wait(); 00622 if (!(__res._M_error == 0)) 00623 rethrow_exception(__res._M_error); 00624 return static_cast<__result_type>(__res); 00625 } 00626 00627 void _M_swap(__basic_future& __that) noexcept 00628 { 00629 _M_state.swap(__that._M_state); 00630 } 00631 00632 // Construction of a future by promise::get_future() 00633 explicit 00634 __basic_future(const __state_type& __state) : _M_state(__state) 00635 { 00636 _State_base::_S_check(_M_state); 00637 _M_state->_M_set_retrieved_flag(); 00638 } 00639 00640 // Copy construction from a shared_future 00641 explicit 00642 __basic_future(const shared_future<_Res>&) noexcept; 00643 00644 // Move construction from a shared_future 00645 explicit 00646 __basic_future(shared_future<_Res>&&) noexcept; 00647 00648 // Move construction from a future 00649 explicit 00650 __basic_future(future<_Res>&&) noexcept; 00651 00652 constexpr __basic_future() noexcept : _M_state() { } 00653 00654 struct _Reset 00655 { 00656 explicit _Reset(__basic_future& __fut) noexcept : _M_fut(__fut) { } 00657 ~_Reset() { _M_fut._M_state.reset(); } 00658 __basic_future& _M_fut; 00659 }; 00660 }; 00661 00662 00663 /// Primary template for future. 00664 template<typename _Res> 00665 class future : public __basic_future<_Res> 00666 { 00667 friend class promise<_Res>; 00668 template<typename> friend class packaged_task; 00669 template<typename _Fn, typename... _Args> 00670 friend future<typename result_of<_Fn(_Args...)>::type> 00671 async(launch, _Fn&&, _Args&&...); 00672 00673 typedef __basic_future<_Res> _Base_type; 00674 typedef typename _Base_type::__state_type __state_type; 00675 00676 explicit 00677 future(const __state_type& __state) : _Base_type(__state) { } 00678 00679 public: 00680 constexpr future() noexcept : _Base_type() { } 00681 00682 /// Move constructor 00683 future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } 00684 00685 // Disable copying 00686 future(const future&) = delete; 00687 future& operator=(const future&) = delete; 00688 00689 future& operator=(future&& __fut) noexcept 00690 { 00691 future(std::move(__fut))._M_swap(*this); 00692 return *this; 00693 } 00694 00695 /// Retrieving the value 00696 _Res 00697 get() 00698 { 00699 typename _Base_type::_Reset __reset(*this); 00700 return std::move(this->_M_get_result()._M_value()); 00701 } 00702 00703 shared_future<_Res> share(); 00704 }; 00705 00706 /// Partial specialization for future<R&> 00707 template<typename _Res> 00708 class future<_Res&> : public __basic_future<_Res&> 00709 { 00710 friend class promise<_Res&>; 00711 template<typename> friend class packaged_task; 00712 template<typename _Fn, typename... _Args> 00713 friend future<typename result_of<_Fn(_Args...)>::type> 00714 async(launch, _Fn&&, _Args&&...); 00715 00716 typedef __basic_future<_Res&> _Base_type; 00717 typedef typename _Base_type::__state_type __state_type; 00718 00719 explicit 00720 future(const __state_type& __state) : _Base_type(__state) { } 00721 00722 public: 00723 constexpr future() noexcept : _Base_type() { } 00724 00725 /// Move constructor 00726 future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } 00727 00728 // Disable copying 00729 future(const future&) = delete; 00730 future& operator=(const future&) = delete; 00731 00732 future& operator=(future&& __fut) noexcept 00733 { 00734 future(std::move(__fut))._M_swap(*this); 00735 return *this; 00736 } 00737 00738 /// Retrieving the value 00739 _Res& 00740 get() 00741 { 00742 typename _Base_type::_Reset __reset(*this); 00743 return this->_M_get_result()._M_get(); 00744 } 00745 00746 shared_future<_Res&> share(); 00747 }; 00748 00749 /// Explicit specialization for future<void> 00750 template<> 00751 class future<void> : public __basic_future<void> 00752 { 00753 friend class promise<void>; 00754 template<typename> friend class packaged_task; 00755 template<typename _Fn, typename... _Args> 00756 friend future<typename result_of<_Fn(_Args...)>::type> 00757 async(launch, _Fn&&, _Args&&...); 00758 00759 typedef __basic_future<void> _Base_type; 00760 typedef typename _Base_type::__state_type __state_type; 00761 00762 explicit 00763 future(const __state_type& __state) : _Base_type(__state) { } 00764 00765 public: 00766 constexpr future() noexcept : _Base_type() { } 00767 00768 /// Move constructor 00769 future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } 00770 00771 // Disable copying 00772 future(const future&) = delete; 00773 future& operator=(const future&) = delete; 00774 00775 future& operator=(future&& __fut) noexcept 00776 { 00777 future(std::move(__fut))._M_swap(*this); 00778 return *this; 00779 } 00780 00781 /// Retrieving the value 00782 void 00783 get() 00784 { 00785 typename _Base_type::_Reset __reset(*this); 00786 this->_M_get_result(); 00787 } 00788 00789 shared_future<void> share(); 00790 }; 00791 00792 00793 /// Primary template for shared_future. 00794 template<typename _Res> 00795 class shared_future : public __basic_future<_Res> 00796 { 00797 typedef __basic_future<_Res> _Base_type; 00798 00799 public: 00800 constexpr shared_future() noexcept : _Base_type() { } 00801 00802 /// Copy constructor 00803 shared_future(const shared_future& __sf) : _Base_type(__sf) { } 00804 00805 /// Construct from a future rvalue 00806 shared_future(future<_Res>&& __uf) noexcept 00807 : _Base_type(std::move(__uf)) 00808 { } 00809 00810 /// Construct from a shared_future rvalue 00811 shared_future(shared_future&& __sf) noexcept 00812 : _Base_type(std::move(__sf)) 00813 { } 00814 00815 shared_future& operator=(const shared_future& __sf) 00816 { 00817 shared_future(__sf)._M_swap(*this); 00818 return *this; 00819 } 00820 00821 shared_future& operator=(shared_future&& __sf) noexcept 00822 { 00823 shared_future(std::move(__sf))._M_swap(*this); 00824 return *this; 00825 } 00826 00827 /// Retrieving the value 00828 const _Res& 00829 get() const { return this->_M_get_result()._M_value(); } 00830 }; 00831 00832 /// Partial specialization for shared_future<R&> 00833 template<typename _Res> 00834 class shared_future<_Res&> : public __basic_future<_Res&> 00835 { 00836 typedef __basic_future<_Res&> _Base_type; 00837 00838 public: 00839 constexpr shared_future() noexcept : _Base_type() { } 00840 00841 /// Copy constructor 00842 shared_future(const shared_future& __sf) : _Base_type(__sf) { } 00843 00844 /// Construct from a future rvalue 00845 shared_future(future<_Res&>&& __uf) noexcept 00846 : _Base_type(std::move(__uf)) 00847 { } 00848 00849 /// Construct from a shared_future rvalue 00850 shared_future(shared_future&& __sf) noexcept 00851 : _Base_type(std::move(__sf)) 00852 { } 00853 00854 shared_future& operator=(const shared_future& __sf) 00855 { 00856 shared_future(__sf)._M_swap(*this); 00857 return *this; 00858 } 00859 00860 shared_future& operator=(shared_future&& __sf) noexcept 00861 { 00862 shared_future(std::move(__sf))._M_swap(*this); 00863 return *this; 00864 } 00865 00866 /// Retrieving the value 00867 _Res& 00868 get() const { return this->_M_get_result()._M_get(); } 00869 }; 00870 00871 /// Explicit specialization for shared_future<void> 00872 template<> 00873 class shared_future<void> : public __basic_future<void> 00874 { 00875 typedef __basic_future<void> _Base_type; 00876 00877 public: 00878 constexpr shared_future() noexcept : _Base_type() { } 00879 00880 /// Copy constructor 00881 shared_future(const shared_future& __sf) : _Base_type(__sf) { } 00882 00883 /// Construct from a future rvalue 00884 shared_future(future<void>&& __uf) noexcept 00885 : _Base_type(std::move(__uf)) 00886 { } 00887 00888 /// Construct from a shared_future rvalue 00889 shared_future(shared_future&& __sf) noexcept 00890 : _Base_type(std::move(__sf)) 00891 { } 00892 00893 shared_future& operator=(const shared_future& __sf) 00894 { 00895 shared_future(__sf)._M_swap(*this); 00896 return *this; 00897 } 00898 00899 shared_future& operator=(shared_future&& __sf) noexcept 00900 { 00901 shared_future(std::move(__sf))._M_swap(*this); 00902 return *this; 00903 } 00904 00905 // Retrieving the value 00906 void 00907 get() const { this->_M_get_result(); } 00908 }; 00909 00910 // Now we can define the protected __basic_future constructors. 00911 template<typename _Res> 00912 inline __basic_future<_Res>:: 00913 __basic_future(const shared_future<_Res>& __sf) noexcept 00914 : _M_state(__sf._M_state) 00915 { } 00916 00917 template<typename _Res> 00918 inline __basic_future<_Res>:: 00919 __basic_future(shared_future<_Res>&& __sf) noexcept 00920 : _M_state(std::move(__sf._M_state)) 00921 { } 00922 00923 template<typename _Res> 00924 inline __basic_future<_Res>:: 00925 __basic_future(future<_Res>&& __uf) noexcept 00926 : _M_state(std::move(__uf._M_state)) 00927 { } 00928 00929 template<typename _Res> 00930 inline shared_future<_Res> 00931 future<_Res>::share() 00932 { return shared_future<_Res>(std::move(*this)); } 00933 00934 template<typename _Res> 00935 inline shared_future<_Res&> 00936 future<_Res&>::share() 00937 { return shared_future<_Res&>(std::move(*this)); } 00938 00939 inline shared_future<void> 00940 future<void>::share() 00941 { return shared_future<void>(std::move(*this)); } 00942 00943 /// Primary template for promise 00944 template<typename _Res> 00945 class promise 00946 { 00947 typedef __future_base::_State_base _State; 00948 typedef __future_base::_Result<_Res> _Res_type; 00949 typedef __future_base::_Ptr<_Res_type> _Ptr_type; 00950 template<typename, typename> friend class _State::_Setter; 00951 00952 shared_ptr<_State> _M_future; 00953 _Ptr_type _M_storage; 00954 00955 public: 00956 promise() 00957 : _M_future(std::make_shared<_State>()), 00958 _M_storage(new _Res_type()) 00959 { } 00960 00961 promise(promise&& __rhs) noexcept 00962 : _M_future(std::move(__rhs._M_future)), 00963 _M_storage(std::move(__rhs._M_storage)) 00964 { } 00965 00966 template<typename _Allocator> 00967 promise(allocator_arg_t, const _Allocator& __a) 00968 : _M_future(std::allocate_shared<_State>(__a)), 00969 _M_storage(__future_base::_S_allocate_result<_Res>(__a)) 00970 { } 00971 00972 template<typename _Allocator> 00973 promise(allocator_arg_t, const _Allocator&, promise&& __rhs) 00974 : _M_future(std::move(__rhs._M_future)), 00975 _M_storage(std::move(__rhs._M_storage)) 00976 { } 00977 00978 promise(const promise&) = delete; 00979 00980 ~promise() 00981 { 00982 if (static_cast<bool>(_M_future) && !_M_future.unique()) 00983 _M_future->_M_break_promise(std::move(_M_storage)); 00984 } 00985 00986 // Assignment 00987 promise& 00988 operator=(promise&& __rhs) noexcept 00989 { 00990 promise(std::move(__rhs)).swap(*this); 00991 return *this; 00992 } 00993 00994 promise& operator=(const promise&) = delete; 00995 00996 void 00997 swap(promise& __rhs) noexcept 00998 { 00999 _M_future.swap(__rhs._M_future); 01000 _M_storage.swap(__rhs._M_storage); 01001 } 01002 01003 // Retrieving the result 01004 future<_Res> 01005 get_future() 01006 { return future<_Res>(_M_future); } 01007 01008 // Setting the result 01009 void 01010 set_value(const _Res& __r) 01011 { 01012 auto __future = _M_future; 01013 auto __setter = _State::__setter(this, __r); 01014 __future->_M_set_result(std::move(__setter)); 01015 } 01016 01017 void 01018 set_value(_Res&& __r) 01019 { 01020 auto __future = _M_future; 01021 auto __setter = _State::__setter(this, std::move(__r)); 01022 __future->_M_set_result(std::move(__setter)); 01023 } 01024 01025 void 01026 set_exception(exception_ptr __p) 01027 { 01028 auto __future = _M_future; 01029 auto __setter = _State::__setter(__p, this); 01030 __future->_M_set_result(std::move(__setter)); 01031 } 01032 }; 01033 01034 template<typename _Res> 01035 inline void 01036 swap(promise<_Res>& __x, promise<_Res>& __y) noexcept 01037 { __x.swap(__y); } 01038 01039 template<typename _Res, typename _Alloc> 01040 struct uses_allocator<promise<_Res>, _Alloc> 01041 : public true_type { }; 01042 01043 01044 /// Partial specialization for promise<R&> 01045 template<typename _Res> 01046 class promise<_Res&> 01047 { 01048 typedef __future_base::_State_base _State; 01049 typedef __future_base::_Result<_Res&> _Res_type; 01050 typedef __future_base::_Ptr<_Res_type> _Ptr_type; 01051 template<typename, typename> friend class _State::_Setter; 01052 01053 shared_ptr<_State> _M_future; 01054 _Ptr_type _M_storage; 01055 01056 public: 01057 promise() 01058 : _M_future(std::make_shared<_State>()), 01059 _M_storage(new _Res_type()) 01060 { } 01061 01062 promise(promise&& __rhs) noexcept 01063 : _M_future(std::move(__rhs._M_future)), 01064 _M_storage(std::move(__rhs._M_storage)) 01065 { } 01066 01067 template<typename _Allocator> 01068 promise(allocator_arg_t, const _Allocator& __a) 01069 : _M_future(std::allocate_shared<_State>(__a)), 01070 _M_storage(__future_base::_S_allocate_result<_Res&>(__a)) 01071 { } 01072 01073 template<typename _Allocator> 01074 promise(allocator_arg_t, const _Allocator&, promise&& __rhs) 01075 : _M_future(std::move(__rhs._M_future)), 01076 _M_storage(std::move(__rhs._M_storage)) 01077 { } 01078 01079 promise(const promise&) = delete; 01080 01081 ~promise() 01082 { 01083 if (static_cast<bool>(_M_future) && !_M_future.unique()) 01084 _M_future->_M_break_promise(std::move(_M_storage)); 01085 } 01086 01087 // Assignment 01088 promise& 01089 operator=(promise&& __rhs) noexcept 01090 { 01091 promise(std::move(__rhs)).swap(*this); 01092 return *this; 01093 } 01094 01095 promise& operator=(const promise&) = delete; 01096 01097 void 01098 swap(promise& __rhs) noexcept 01099 { 01100 _M_future.swap(__rhs._M_future); 01101 _M_storage.swap(__rhs._M_storage); 01102 } 01103 01104 // Retrieving the result 01105 future<_Res&> 01106 get_future() 01107 { return future<_Res&>(_M_future); } 01108 01109 // Setting the result 01110 void 01111 set_value(_Res& __r) 01112 { 01113 auto __future = _M_future; 01114 auto __setter = _State::__setter(this, __r); 01115 __future->_M_set_result(std::move(__setter)); 01116 } 01117 01118 void 01119 set_exception(exception_ptr __p) 01120 { 01121 auto __future = _M_future; 01122 auto __setter = _State::__setter(__p, this); 01123 __future->_M_set_result(std::move(__setter)); 01124 } 01125 }; 01126 01127 /// Explicit specialization for promise<void> 01128 template<> 01129 class promise<void> 01130 { 01131 typedef __future_base::_State_base _State; 01132 typedef __future_base::_Result<void> _Res_type; 01133 typedef __future_base::_Ptr<_Res_type> _Ptr_type; 01134 template<typename, typename> friend class _State::_Setter; 01135 01136 shared_ptr<_State> _M_future; 01137 _Ptr_type _M_storage; 01138 01139 public: 01140 promise() 01141 : _M_future(std::make_shared<_State>()), 01142 _M_storage(new _Res_type()) 01143 { } 01144 01145 promise(promise&& __rhs) noexcept 01146 : _M_future(std::move(__rhs._M_future)), 01147 _M_storage(std::move(__rhs._M_storage)) 01148 { } 01149 01150 template<typename _Allocator> 01151 promise(allocator_arg_t, const _Allocator& __a) 01152 : _M_future(std::allocate_shared<_State>(__a)), 01153 _M_storage(__future_base::_S_allocate_result<void>(__a)) 01154 { } 01155 01156 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01157 // 2095. missing constructors needed for uses-allocator construction 01158 template<typename _Allocator> 01159 promise(allocator_arg_t, const _Allocator&, promise&& __rhs) 01160 : _M_future(std::move(__rhs._M_future)), 01161 _M_storage(std::move(__rhs._M_storage)) 01162 { } 01163 01164 promise(const promise&) = delete; 01165 01166 ~promise() 01167 { 01168 if (static_cast<bool>(_M_future) && !_M_future.unique()) 01169 _M_future->_M_break_promise(std::move(_M_storage)); 01170 } 01171 01172 // Assignment 01173 promise& 01174 operator=(promise&& __rhs) noexcept 01175 { 01176 promise(std::move(__rhs)).swap(*this); 01177 return *this; 01178 } 01179 01180 promise& operator=(const promise&) = delete; 01181 01182 void 01183 swap(promise& __rhs) noexcept 01184 { 01185 _M_future.swap(__rhs._M_future); 01186 _M_storage.swap(__rhs._M_storage); 01187 } 01188 01189 // Retrieving the result 01190 future<void> 01191 get_future() 01192 { return future<void>(_M_future); } 01193 01194 // Setting the result 01195 void set_value(); 01196 01197 void 01198 set_exception(exception_ptr __p) 01199 { 01200 auto __future = _M_future; 01201 auto __setter = _State::__setter(__p, this); 01202 __future->_M_set_result(std::move(__setter)); 01203 } 01204 }; 01205 01206 // set void 01207 template<> 01208 struct __future_base::_State_base::_Setter<void, void> 01209 { 01210 promise<void>::_Ptr_type operator()() 01211 { 01212 _State_base::_S_check(_M_promise->_M_future); 01213 return std::move(_M_promise->_M_storage); 01214 } 01215 01216 promise<void>* _M_promise; 01217 }; 01218 01219 inline __future_base::_State_base::_Setter<void, void> 01220 __future_base::_State_base::__setter(promise<void>* __prom) 01221 { 01222 return _Setter<void, void>{ __prom }; 01223 } 01224 01225 inline void 01226 promise<void>::set_value() 01227 { 01228 auto __future = _M_future; 01229 auto __setter = _State::__setter(this); 01230 __future->_M_set_result(std::move(__setter)); 01231 } 01232 01233 01234 template<typename _Ptr_type, typename _Res> 01235 struct __future_base::_Task_setter 01236 { 01237 _Ptr_type operator()() 01238 { 01239 __try 01240 { 01241 _M_result->_M_set(_M_fn()); 01242 } 01243 __catch(const __cxxabiv1::__forced_unwind&) 01244 { 01245 __throw_exception_again; // will cause broken_promise 01246 } 01247 __catch(...) 01248 { 01249 _M_result->_M_error = current_exception(); 01250 } 01251 return std::move(_M_result); 01252 } 01253 _Ptr_type& _M_result; 01254 std::function<_Res()> _M_fn; 01255 }; 01256 01257 template<typename _Ptr_type> 01258 struct __future_base::_Task_setter<_Ptr_type, void> 01259 { 01260 _Ptr_type operator()() 01261 { 01262 __try 01263 { 01264 _M_fn(); 01265 } 01266 __catch(const __cxxabiv1::__forced_unwind&) 01267 { 01268 __throw_exception_again; // will cause broken_promise 01269 } 01270 __catch(...) 01271 { 01272 _M_result->_M_error = current_exception(); 01273 } 01274 return std::move(_M_result); 01275 } 01276 _Ptr_type& _M_result; 01277 std::function<void()> _M_fn; 01278 }; 01279 01280 template<typename _Res, typename... _Args> 01281 struct __future_base::_Task_state_base<_Res(_Args...)> 01282 : __future_base::_State_base 01283 { 01284 typedef _Res _Res_type; 01285 01286 template<typename _Alloc> 01287 _Task_state_base(const _Alloc& __a) 01288 : _M_result(_S_allocate_result<_Res>(__a)) 01289 { } 01290 01291 virtual void 01292 _M_run(_Args... __args) = 0; 01293 01294 virtual shared_ptr<_Task_state_base> 01295 _M_reset() = 0; 01296 01297 typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; 01298 _Ptr_type _M_result; 01299 }; 01300 01301 template<typename _Fn, typename _Alloc, typename _Res, typename... _Args> 01302 struct __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)> final 01303 : __future_base::_Task_state_base<_Res(_Args...)> 01304 { 01305 template<typename _Fn2> 01306 _Task_state(_Fn2&& __fn, const _Alloc& __a) 01307 : _Task_state_base<_Res(_Args...)>(__a), 01308 _M_impl(std::forward<_Fn2>(__fn), __a) 01309 { } 01310 01311 private: 01312 virtual void 01313 _M_run(_Args... __args) 01314 { 01315 // bound arguments decay so wrap lvalue references 01316 auto __boundfn = std::__bind_simple(std::ref(_M_impl._M_fn), 01317 _S_maybe_wrap_ref(std::forward<_Args>(__args))...); 01318 auto __setter = _S_task_setter(this->_M_result, std::move(__boundfn)); 01319 this->_M_set_result(std::move(__setter)); 01320 } 01321 01322 virtual shared_ptr<_Task_state_base<_Res(_Args...)>> 01323 _M_reset(); 01324 01325 template<typename _Tp> 01326 static reference_wrapper<_Tp> 01327 _S_maybe_wrap_ref(_Tp& __t) 01328 { return std::ref(__t); } 01329 01330 template<typename _Tp> 01331 static 01332 typename enable_if<!is_lvalue_reference<_Tp>::value, _Tp>::type&& 01333 _S_maybe_wrap_ref(_Tp&& __t) 01334 { return std::forward<_Tp>(__t); } 01335 01336 struct _Impl : _Alloc 01337 { 01338 template<typename _Fn2> 01339 _Impl(_Fn2&& __fn, const _Alloc& __a) 01340 : _Alloc(__a), _M_fn(std::forward<_Fn2>(__fn)) { } 01341 _Fn _M_fn; 01342 } _M_impl; 01343 }; 01344 01345 template<typename _Signature, typename _Fn, typename _Alloc> 01346 static shared_ptr<__future_base::_Task_state_base<_Signature>> 01347 __create_task_state(_Fn&& __fn, const _Alloc& __a) 01348 { 01349 typedef typename decay<_Fn>::type _Fn2; 01350 typedef __future_base::_Task_state<_Fn2, _Alloc, _Signature> _State; 01351 return std::allocate_shared<_State>(__a, std::forward<_Fn>(__fn), __a); 01352 } 01353 01354 template<typename _Fn, typename _Alloc, typename _Res, typename... _Args> 01355 shared_ptr<__future_base::_Task_state_base<_Res(_Args...)>> 01356 __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)>::_M_reset() 01357 { 01358 return __create_task_state<_Res(_Args...)>(std::move(_M_impl._M_fn), 01359 static_cast<_Alloc&>(_M_impl)); 01360 } 01361 01362 template<typename _Task, typename _Fn, bool 01363 = is_same<_Task, typename decay<_Fn>::type>::value> 01364 struct __constrain_pkgdtask 01365 { typedef void __type; }; 01366 01367 template<typename _Task, typename _Fn> 01368 struct __constrain_pkgdtask<_Task, _Fn, true> 01369 { }; 01370 01371 /// packaged_task 01372 template<typename _Res, typename... _ArgTypes> 01373 class packaged_task<_Res(_ArgTypes...)> 01374 { 01375 typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type; 01376 shared_ptr<_State_type> _M_state; 01377 01378 public: 01379 // Construction and destruction 01380 packaged_task() noexcept { } 01381 01382 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01383 // 2095. missing constructors needed for uses-allocator construction 01384 template<typename _Allocator> 01385 packaged_task(allocator_arg_t, const _Allocator& __a) noexcept 01386 { } 01387 01388 template<typename _Fn, typename = typename 01389 __constrain_pkgdtask<packaged_task, _Fn>::__type> 01390 explicit 01391 packaged_task(_Fn&& __fn) 01392 : packaged_task(allocator_arg, std::allocator<int>(), 01393 std::forward<_Fn>(__fn)) 01394 { } 01395 01396 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01397 // 2097. packaged_task constructors should be constrained 01398 template<typename _Fn, typename _Alloc, typename = typename 01399 __constrain_pkgdtask<packaged_task, _Fn>::__type> 01400 explicit 01401 packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn) 01402 : _M_state(__create_task_state<_Res(_ArgTypes...)>( 01403 std::forward<_Fn>(__fn), __a)) 01404 { } 01405 01406 ~packaged_task() 01407 { 01408 if (static_cast<bool>(_M_state) && !_M_state.unique()) 01409 _M_state->_M_break_promise(std::move(_M_state->_M_result)); 01410 } 01411 01412 // No copy 01413 packaged_task(const packaged_task&) = delete; 01414 packaged_task& operator=(const packaged_task&) = delete; 01415 01416 template<typename _Allocator> 01417 packaged_task(allocator_arg_t, const _Allocator&, 01418 const packaged_task&) = delete; 01419 01420 // Move support 01421 packaged_task(packaged_task&& __other) noexcept 01422 { this->swap(__other); } 01423 01424 template<typename _Allocator> 01425 packaged_task(allocator_arg_t, const _Allocator&, 01426 packaged_task&& __other) noexcept 01427 { this->swap(__other); } 01428 01429 packaged_task& operator=(packaged_task&& __other) noexcept 01430 { 01431 packaged_task(std::move(__other)).swap(*this); 01432 return *this; 01433 } 01434 01435 void 01436 swap(packaged_task& __other) noexcept 01437 { _M_state.swap(__other._M_state); } 01438 01439 bool 01440 valid() const noexcept 01441 { return static_cast<bool>(_M_state); } 01442 01443 // Result retrieval 01444 future<_Res> 01445 get_future() 01446 { return future<_Res>(_M_state); } 01447 01448 // Execution 01449 void 01450 operator()(_ArgTypes... __args) 01451 { 01452 __future_base::_State_base::_S_check(_M_state); 01453 _M_state->_M_run(std::forward<_ArgTypes>(__args)...); 01454 } 01455 01456 void 01457 reset() 01458 { 01459 __future_base::_State_base::_S_check(_M_state); 01460 packaged_task __tmp; 01461 __tmp._M_state = _M_state; 01462 _M_state = _M_state->_M_reset(); 01463 } 01464 }; 01465 01466 /// swap 01467 template<typename _Res, typename... _ArgTypes> 01468 inline void 01469 swap(packaged_task<_Res(_ArgTypes...)>& __x, 01470 packaged_task<_Res(_ArgTypes...)>& __y) noexcept 01471 { __x.swap(__y); } 01472 01473 template<typename _Res, typename _Alloc> 01474 struct uses_allocator<packaged_task<_Res>, _Alloc> 01475 : public true_type { }; 01476 01477 01478 template<typename _BoundFn, typename _Res> 01479 class __future_base::_Deferred_state final 01480 : public __future_base::_State_base 01481 { 01482 public: 01483 explicit 01484 _Deferred_state(_BoundFn&& __fn) 01485 : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)) 01486 { } 01487 01488 private: 01489 typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; 01490 _Ptr_type _M_result; 01491 _BoundFn _M_fn; 01492 01493 // Run the deferred function. 01494 virtual void 01495 _M_complete_async() 01496 { 01497 // safe to call multiple times so ignore failure 01498 _M_set_result(_S_task_setter(_M_result, _M_fn), true); 01499 } 01500 01501 virtual bool 01502 _M_has_deferred() const { return static_cast<bool>(_M_result); } 01503 }; 01504 01505 class __future_base::_Async_state_commonV2 01506 : public __future_base::_State_base 01507 { 01508 protected: 01509 ~_Async_state_commonV2() = default; 01510 01511 // Make waiting functions block until the thread completes, as if joined. 01512 virtual void _M_complete_async() { _M_join(); } 01513 01514 void _M_join() { std::call_once(_M_once, &thread::join, ref(_M_thread)); } 01515 01516 thread _M_thread; 01517 once_flag _M_once; 01518 }; 01519 01520 template<typename _BoundFn, typename _Res> 01521 class __future_base::_Async_state_impl final 01522 : public __future_base::_Async_state_commonV2 01523 { 01524 public: 01525 explicit 01526 _Async_state_impl(_BoundFn&& __fn) 01527 : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)) 01528 { 01529 _M_thread = std::thread{ [this] { 01530 __try 01531 { 01532 _M_set_result(_S_task_setter(_M_result, _M_fn)); 01533 } 01534 __catch (const __cxxabiv1::__forced_unwind&) 01535 { 01536 // make the shared state ready on thread cancellation 01537 if (static_cast<bool>(_M_result)) 01538 this->_M_break_promise(std::move(_M_result)); 01539 __throw_exception_again; 01540 } 01541 } }; 01542 } 01543 01544 ~_Async_state_impl() { _M_join(); } 01545 01546 private: 01547 typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; 01548 _Ptr_type _M_result; 01549 _BoundFn _M_fn; 01550 }; 01551 01552 template<typename _BoundFn> 01553 inline std::shared_ptr<__future_base::_State_base> 01554 __future_base::_S_make_deferred_state(_BoundFn&& __fn) 01555 { 01556 typedef typename remove_reference<_BoundFn>::type __fn_type; 01557 typedef _Deferred_state<__fn_type> __state_type; 01558 return std::make_shared<__state_type>(std::move(__fn)); 01559 } 01560 01561 template<typename _BoundFn> 01562 inline std::shared_ptr<__future_base::_State_base> 01563 __future_base::_S_make_async_state(_BoundFn&& __fn) 01564 { 01565 typedef typename remove_reference<_BoundFn>::type __fn_type; 01566 typedef _Async_state_impl<__fn_type> __state_type; 01567 return std::make_shared<__state_type>(std::move(__fn)); 01568 } 01569 01570 01571 /// async 01572 template<typename _Fn, typename... _Args> 01573 future<typename result_of<_Fn(_Args...)>::type> 01574 async(launch __policy, _Fn&& __fn, _Args&&... __args) 01575 { 01576 typedef typename result_of<_Fn(_Args...)>::type result_type; 01577 std::shared_ptr<__future_base::_State_base> __state; 01578 if ((__policy & (launch::async|launch::deferred)) == launch::async) 01579 { 01580 __state = __future_base::_S_make_async_state(std::__bind_simple( 01581 std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)); 01582 } 01583 else 01584 { 01585 __state = __future_base::_S_make_deferred_state(std::__bind_simple( 01586 std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)); 01587 } 01588 return future<result_type>(__state); 01589 } 01590 01591 /// async, potential overload 01592 template<typename _Fn, typename... _Args> 01593 inline future<typename result_of<_Fn(_Args...)>::type> 01594 async(_Fn&& __fn, _Args&&... __args) 01595 { 01596 return async(launch::async|launch::deferred, std::forward<_Fn>(__fn), 01597 std::forward<_Args>(__args)...); 01598 } 01599 01600 #endif // _GLIBCXX_ASYNC_ABI_COMPAT 01601 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 01602 // && ATOMIC_INT_LOCK_FREE 01603 01604 // @} group futures 01605 _GLIBCXX_END_NAMESPACE_VERSION 01606 } // namespace 01607 01608 #endif // C++11 01609 01610 #endif // _GLIBCXX_FUTURE