// -*- C++ -*- // Copyright (C) 2009, 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file future * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_FUTURE #define _GLIBCXX_FUTURE 1 #pragma GCC system_header #ifndef __GXX_EXPERIMENTAL_CXX0X__ # include #else #include #include #include #include #include #include #include #include #include namespace std { /** * @defgroup futures Futures * @ingroup concurrency * * Classes for futures support. * @{ */ /// Error code for futures enum class future_errc { broken_promise, future_already_retrieved, promise_already_satisfied, no_state }; template<> struct is_error_code_enum : public true_type { }; /// Points to a statically-allocated object derived from error_category. extern const error_category* const future_category; // TODO: requires constexpr inline error_code make_error_code(future_errc __errc) { return error_code(static_cast(__errc), *future_category); } // TODO: requires constexpr inline error_condition make_error_condition(future_errc __errc) { return error_condition(static_cast(__errc), *future_category); } /** * @brief Exception type thrown by futures. * @ingroup exceptions */ class future_error : public logic_error { error_code _M_code; public: explicit future_error(error_code __ec) : logic_error("std::future_error"), _M_code(__ec) { } virtual ~future_error() throw(); virtual const char* what() const throw(); const error_code& code() const throw() { return _M_code; } }; // Forward declarations. template class future; template class shared_future; template class atomic_future; template class packaged_task; template class promise; enum class launch { any, async, sync }; template future::type> async(launch __policy, _Fn&& __fn, _Args&&... __args); template typename enable_if::type, launch>::value, future()(std::declval<_Args>()...))> >::type async(_Fn&& __fn, _Args&&... __args); #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \ && defined(_GLIBCXX_ATOMIC_BUILTINS_4) /// Base class and enclosing scope. struct __future_base { /// Base class for results. struct _Result_base { exception_ptr _M_error; _Result_base() = default; _Result_base(const _Result_base&) = delete; _Result_base& operator=(const _Result_base&) = delete; // _M_destroy() allows derived classes to control deallocation virtual void _M_destroy() = 0; struct _Deleter { void operator()(_Result_base* __fr) const { __fr->_M_destroy(); } }; protected: ~_Result_base(); }; /// Result. template struct _Result : _Result_base { private: typedef alignment_of<_Res> __a_of; typedef aligned_storage __align_storage; typedef typename __align_storage::type __align_type; __align_type _M_storage; bool _M_initialized; public: _Result() : _M_initialized() { } ~_Result() { if (_M_initialized) _M_value().~_Res(); } // Return lvalue, future will add const or rvalue-reference _Res& _M_value() { return *static_cast<_Res*>(_M_addr()); } void _M_set(const _Res& __res) { ::new (_M_addr()) _Res(__res); _M_initialized = true; } void _M_set(_Res&& __res) { ::new (_M_addr()) _Res(std::move(__res)); _M_initialized = true; } private: void _M_destroy() { delete this; } void* _M_addr() { return static_cast(&_M_storage); } }; // TODO: use template alias when available /* template using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>; */ /// A unique_ptr based on the instantiating type. template struct _Ptr { typedef unique_ptr<_Res, _Result_base::_Deleter> type; }; /// Result_alloc. template struct _Result_alloc : _Result<_Res> { typedef typename _Alloc::template rebind<_Result_alloc>::other __allocator_type; explicit _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _M_alloc(__a) { } private: void _M_destroy() { __allocator_type __a(_M_alloc); __a.destroy(this); __a.deallocate(this, 1); } __allocator_type _M_alloc; }; template static typename _Ptr<_Result_alloc<_Res, _Allocator>>::type _S_allocate_result(const _Allocator& __a) { typedef _Result_alloc<_Res, _Allocator> __result_type; typename __result_type::__allocator_type __a2(__a); __result_type* __p = __a2.allocate(1); __try { __a2.construct(__p, __a); } __catch(...) { __a2.deallocate(__p, 1); __throw_exception_again; } return typename _Ptr<__result_type>::type(__p); } /// Shared state between a promise and one or more associated futures. class _State { typedef _Ptr<_Result_base>::type _Ptr_type; _Ptr_type _M_result; mutex _M_mutex; condition_variable _M_cond; atomic_flag _M_retrieved; once_flag _M_once; public: _State() : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { } _State(const _State&) = delete; _State& operator=(const _State&) = delete; _Result_base& wait() { _M_run_deferred(); unique_lock __lock(_M_mutex); if (!_M_ready()) _M_cond.wait(__lock, std::bind(&_State::_M_ready, this)); return *_M_result; } template bool wait_for(const chrono::duration<_Rep, _Period>& __rel) { unique_lock __lock(_M_mutex); auto __bound = std::bind(&_State::_M_ready, this); return _M_ready() || _M_cond.wait_for(__lock, __rel, __bound); } template bool wait_until(const chrono::time_point<_Clock, _Duration>& __abs) { unique_lock __lock(_M_mutex); auto __bound = std::bind(&_State::_M_ready, this); return _M_ready() || _M_cond.wait_until(__lock, __abs, __bound); } void _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false) { bool __set = __ignore_failure; // all calls to this function are serialized, // side-effects of invoking __res only happen once call_once(_M_once, &_State::_M_do_set, this, ref(__res), ref(__set)); if (!__set) __throw_future_error(int(future_errc::promise_already_satisfied)); } void _M_break_promise(_Ptr_type __res) { if (static_cast(__res)) { error_code __ec(make_error_code(future_errc::broken_promise)); __res->_M_error = copy_exception(future_error(__ec)); { lock_guard __lock(_M_mutex); _M_result.swap(__res); } _M_cond.notify_all(); } } // Called when this object is passed to a future. void _M_set_retrieved_flag() { if (_M_retrieved.test_and_set()) __throw_future_error(int(future_errc::future_already_retrieved)); } template struct _Setter; // set lvalues template struct _Setter<_Res, _Arg&> { // check this is only used by promise::set_value(const R&) // or promise::set_value(R&) static_assert(is_same<_Res, _Arg&>::value // promise || is_same::value, // promise "Invalid specialisation"); typename promise<_Res>::_Ptr_type operator()() { _State::_S_check(_M_promise->_M_future); _M_promise->_M_storage->_M_set(_M_arg); return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; _Arg& _M_arg; }; // set rvalues template struct _Setter<_Res, _Res&&> { typename promise<_Res>::_Ptr_type operator()() { _State::_S_check(_M_promise->_M_future); _M_promise->_M_storage->_M_set(std::move(_M_arg)); return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; _Res& _M_arg; }; struct __exception_ptr_tag { }; // set exceptions template struct _Setter<_Res, __exception_ptr_tag> { typename promise<_Res>::_Ptr_type operator()() { _State::_S_check(_M_promise->_M_future); _M_promise->_M_storage->_M_error = _M_ex; return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; exception_ptr& _M_ex; }; template static _Setter<_Res, _Arg&&> __setter(promise<_Res>* __prom, _Arg&& __arg) { return _Setter<_Res, _Arg&&>{ __prom, __arg }; } template static _Setter<_Res, __exception_ptr_tag> __setter(exception_ptr& __ex, promise<_Res>* __prom) { return _Setter<_Res, __exception_ptr_tag>{ __prom, __ex }; } static _Setter __setter(promise* __prom); template static bool _S_check(const shared_ptr<_Tp>& __p) { if (!static_cast(__p)) __throw_future_error((int)future_errc::no_state); } private: void _M_do_set(function<_Ptr_type()>& __f, bool& __set) { _Ptr_type __res = __f(); { lock_guard __lock(_M_mutex); _M_result.swap(__res); } _M_cond.notify_all(); __set = true; } bool _M_ready() const { return static_cast(_M_result); } virtual void _M_run_deferred() { } }; template class _Deferred_state; template class _Async_state; template class _Task_state; template struct _Task_setter; }; inline __future_base::_Result_base::~_Result_base() = default; /// Partial specialization for reference types. template struct __future_base::_Result<_Res&> : __future_base::_Result_base { _Result() : _M_value_ptr() { } void _M_set(_Res& __res) { _M_value_ptr = &__res; } _Res& _M_get() { return *_M_value_ptr; } private: _Res* _M_value_ptr; void _M_destroy() { delete this; } }; /// Explicit specialization for void. template<> struct __future_base::_Result : __future_base::_Result_base { private: void _M_destroy() { delete this; } }; /// Common implementation for future and shared_future. template class __basic_future : public __future_base { protected: typedef shared_ptr<_State> __state_type; typedef __future_base::_Result<_Res>& __result_type; private: __state_type _M_state; public: // Disable copying. __basic_future(const __basic_future&) = delete; __basic_future& operator=(const __basic_future&) = delete; bool valid() const { return static_cast(_M_state); } void wait() const { _M_state->wait(); } template bool wait_for(const chrono::duration<_Rep, _Period>& __rel) const { return _M_state->wait_for(__rel); } template bool wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const { return _M_state->wait_until(__abs); } protected: /// Wait for the state to be ready and rethrow any stored exception __result_type _M_get_result() { _Result_base& __res = _M_state->wait(); if (!(__res._M_error == 0)) rethrow_exception(__res._M_error); return static_cast<__result_type>(__res); } void _M_swap(__basic_future& __that) { _M_state.swap(__that._M_state); } // Construction of a future by promise::get_future() explicit __basic_future(const __state_type& __state) : _M_state(__state) { _State::_S_check(_M_state); _M_state->_M_set_retrieved_flag(); } // Copy construction from a shared_future explicit __basic_future(const shared_future<_Res>&); // Move construction from a shared_future explicit __basic_future(shared_future<_Res>&&); // Move construction from a future explicit __basic_future(future<_Res>&&); __basic_future() { } struct _Reset { explicit _Reset(__basic_future& __fut) : _M_fut(__fut) { } ~_Reset() { _M_fut._M_state.reset(); } __basic_future& _M_fut; }; }; /// Primary template for future. template class future : public __basic_future<_Res> { friend class promise<_Res>; template friend class packaged_task; template friend future::type> async(launch, _Fn&&, _Args&&...); typedef __basic_future<_Res> _Base_type; typedef typename _Base_type::__state_type __state_type; explicit future(const __state_type& __state) : _Base_type(__state) { } public: future() : _Base_type() { } /// Move constructor future(future&& __uf) : _Base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value _Res get() { typename _Base_type::_Reset __reset(*this); return std::move(this->_M_get_result()._M_value()); } }; /// Partial specialization for future template class future<_Res&> : public __basic_future<_Res&> { friend class promise<_Res&>; template friend class packaged_task; template friend future::type> async(launch, _Fn&&, _Args&&...); typedef __basic_future<_Res&> _Base_type; typedef typename _Base_type::__state_type __state_type; explicit future(const __state_type& __state) : _Base_type(__state) { } public: future() : _Base_type() { } /// Move constructor future(future&& __uf) : _Base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value _Res& get() { typename _Base_type::_Reset __reset(*this); return this->_M_get_result()._M_get(); } }; /// Explicit specialization for future template<> class future : public __basic_future { friend class promise; template friend class packaged_task; template friend future::type> async(launch, _Fn&&, _Args&&...); typedef __basic_future _Base_type; typedef typename _Base_type::__state_type __state_type; explicit future(const __state_type& __state) : _Base_type(__state) { } public: future() : _Base_type() { } /// Move constructor future(future&& __uf) : _Base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value void get() { typename _Base_type::_Reset __reset(*this); this->_M_get_result(); } }; /// Primary template for shared_future. template class shared_future : public __basic_future<_Res> { typedef __basic_future<_Res> _Base_type; public: shared_future() : _Base_type() { } /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } /// Construct from a future rvalue shared_future(future<_Res>&& __uf) : _Base_type(std::move(__uf)) { } /// Construct from a shared_future rvalue shared_future(shared_future&& __sf) : _Base_type(std::move(__sf)) { } shared_future& operator=(const shared_future& __sf) { shared_future(__sf)._M_swap(*this); return *this; } shared_future& operator=(shared_future&& __sf) { shared_future(std::move(__sf))._M_swap(*this); return *this; } /// Retrieving the value const _Res& get() { typename _Base_type::__result_type __r = this->_M_get_result(); _Res& __rs(__r._M_value()); return __rs; } }; /// Partial specialization for shared_future template class shared_future<_Res&> : public __basic_future<_Res&> { typedef __basic_future<_Res&> _Base_type; public: shared_future() : _Base_type() { } /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } /// Construct from a future rvalue shared_future(future<_Res&>&& __uf) : _Base_type(std::move(__uf)) { } /// Construct from a shared_future rvalue shared_future(shared_future&& __sf) : _Base_type(std::move(__sf)) { } shared_future& operator=(const shared_future& __sf) { shared_future(__sf)._M_swap(*this); return *this; } shared_future& operator=(shared_future&& __sf) { shared_future(std::move(__sf))._M_swap(*this); return *this; } /// Retrieving the value _Res& get() { return this->_M_get_result()._M_get(); } }; /// Explicit specialization for shared_future template<> class shared_future : public __basic_future { typedef __basic_future _Base_type; public: shared_future() : _Base_type() { } /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } /// Construct from a future rvalue shared_future(future&& __uf) : _Base_type(std::move(__uf)) { } /// Construct from a shared_future rvalue shared_future(shared_future&& __sf) : _Base_type(std::move(__sf)) { } shared_future& operator=(const shared_future& __sf) { shared_future(__sf)._M_swap(*this); return *this; } shared_future& operator=(shared_future&& __sf) { shared_future(std::move(__sf))._M_swap(*this); return *this; } // Retrieving the value void get() { this->_M_get_result(); } }; // Now we can define the protected __basic_future constructors. template inline __basic_future<_Res>:: __basic_future(const shared_future<_Res>& __sf) : _M_state(__sf._M_state) { } template inline __basic_future<_Res>:: __basic_future(shared_future<_Res>&& __sf) : _M_state(std::move(__sf._M_state)) { } template inline __basic_future<_Res>:: __basic_future(future<_Res>&& __uf) : _M_state(std::move(__uf._M_state)) { } /// Primary template for promise template class promise { typedef __future_base::_State _State; typedef __future_base::_Result<_Res> _Res_type; typedef typename __future_base::_Ptr<_Res_type>::type _Ptr_type; template friend class _State::_Setter; shared_ptr<_State> _M_future; _Ptr_type _M_storage; public: promise() : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } template promise(allocator_arg_t, const _Allocator& __a) : _M_future(std::allocate_shared<_State>(__a)), _M_storage(__future_base::_S_allocate_result<_Res>(__a)) { } promise(const promise&) = delete; ~promise() { if (static_cast(_M_future) && !_M_future.unique()) _M_future->_M_break_promise(std::move(_M_storage)); } // Assignment promise& operator=(promise&& __rhs) { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise&) = delete; void swap(promise& __rhs) { _M_future.swap(__rhs._M_future); _M_storage.swap(__rhs._M_storage); } // Retrieving the result future<_Res> get_future() { return future<_Res>(_M_future); } // Setting the result void set_value(const _Res& __r) { auto __setter = _State::__setter(this, __r); _M_future->_M_set_result(std::move(__setter)); } void set_value(_Res&& __r) { auto __setter = _State::__setter(this, std::move(__r)); _M_future->_M_set_result(std::move(__setter)); } void set_exception(exception_ptr __p) { auto __setter = _State::__setter(__p, this); _M_future->_M_set_result(std::move(__setter)); } }; template inline void swap(promise<_Res>& __x, promise<_Res>& __y) { __x.swap(__y); } /// Partial specialization for promise template class promise<_Res&> { typedef __future_base::_State _State; typedef __future_base::_Result<_Res&> _Res_type; typedef typename __future_base::_Ptr<_Res_type>::type _Ptr_type; template friend class _State::_Setter; shared_ptr<_State> _M_future; _Ptr_type _M_storage; public: promise() : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } template promise(allocator_arg_t, const _Allocator& __a) : _M_future(std::allocate_shared<_State>(__a)), _M_storage(__future_base::_S_allocate_result<_Res&>(__a)) { } promise(const promise&) = delete; ~promise() { if (static_cast(_M_future) && !_M_future.unique()) _M_future->_M_break_promise(std::move(_M_storage)); } // Assignment promise& operator=(promise&& __rhs) { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise&) = delete; void swap(promise& __rhs) { _M_future.swap(__rhs._M_future); _M_storage.swap(__rhs._M_storage); } // Retrieving the result future<_Res&> get_future() { return future<_Res&>(_M_future); } // Setting the result void set_value(_Res& __r) { auto __setter = _State::__setter(this, __r); _M_future->_M_set_result(std::move(__setter)); } void set_exception(exception_ptr __p) { auto __setter = _State::__setter(__p, this); _M_future->_M_set_result(std::move(__setter)); } }; /// Explicit specialization for promise template<> class promise { typedef __future_base::_State _State; typedef __future_base::_Result _Res_type; typedef typename __future_base::_Ptr<_Res_type>::type _Ptr_type; template friend class _State::_Setter; shared_ptr<_State> _M_future; _Ptr_type _M_storage; public: promise() : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } template promise(allocator_arg_t, const _Allocator& __a) : _M_future(std::allocate_shared<_State>(__a)), _M_storage(__future_base::_S_allocate_result(__a)) { } promise(const promise&) = delete; ~promise() { if (static_cast(_M_future) && !_M_future.unique()) _M_future->_M_break_promise(std::move(_M_storage)); } // Assignment promise& operator=(promise&& __rhs) { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise&) = delete; void swap(promise& __rhs) { _M_future.swap(__rhs._M_future); _M_storage.swap(__rhs._M_storage); } // Retrieving the result future get_future() { return future(_M_future); } // Setting the result void set_value(); void set_exception(exception_ptr __p) { auto __setter = _State::__setter(__p, this); _M_future->_M_set_result(std::move(__setter)); } }; // set void template<> struct __future_base::_State::_Setter { promise::_Ptr_type operator()() { _State::_S_check(_M_promise->_M_future); return std::move(_M_promise->_M_storage); } promise* _M_promise; }; inline __future_base::_State::_Setter __future_base::_State::__setter(promise* __prom) { return _Setter{ __prom }; } inline void promise::set_value() { auto __setter = _State::__setter(this); _M_future->_M_set_result(std::move(__setter)); } template struct uses_allocator, Alloc> : true_type { }; template struct __future_base::_Task_setter { typename _StateT::_Ptr_type operator()() { __try { _M_state->_M_result->_M_set(_M_fn()); } __catch(...) { _M_state->_M_result->_M_error = current_exception(); } return std::move(_M_state->_M_result); } _StateT* _M_state; std::function<_Res()> _M_fn; }; template struct __future_base::_Task_setter<_StateT, void> { typename _StateT::_Ptr_type operator()() { __try { _M_fn(); } __catch(...) { _M_state->_M_result->_M_error = current_exception(); } return std::move(_M_state->_M_result); } _StateT* _M_state; std::function _M_fn; }; template struct __future_base::_Task_state<_Res(_Args...)> : __future_base::_State { typedef _Res _Res_type; _Task_state(std::function<_Res(_Args...)> __task) : _M_result(new _Result<_Res>()), _M_task(std::move(__task)) { } template _Task_state(_Func&& __task, const _Alloc& __a) : _M_result(_S_allocate_result<_Res>(__a)) , _M_task(allocator_arg, __a, std::move(__task)) { } void _M_run(_Args... __args) { // bound arguments decay so wrap lvalue references auto __bound = std::bind<_Res>(std::ref(_M_task), _S_maybe_wrap_ref(std::forward<_Args>(__args))...); _Task_setter<_Task_state> __setter{ this, std::move(__bound) }; _M_set_result(std::move(__setter)); } template friend class _Task_setter; typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type; _Ptr_type _M_result; std::function<_Res(_Args...)> _M_task; template static reference_wrapper<_Tp> _S_maybe_wrap_ref(_Tp& __t) { return std::ref(__t); } template static typename enable_if::value, _Tp>::type&& _S_maybe_wrap_ref(_Tp&& __t) { return std::forward<_Tp>(__t); } }; /// packaged_task template class packaged_task<_Res(_ArgTypes...)> { typedef __future_base::_Task_state<_Res(_ArgTypes...)> _State_type; shared_ptr<_State_type> _M_state; public: typedef _Res result_type; // Construction and destruction packaged_task() { } template explicit packaged_task(const _Fn& __fn) : _M_state(std::make_shared<_State_type>(__fn)) { } template explicit packaged_task(_Fn&& __fn) : _M_state(std::make_shared<_State_type>(std::move(__fn))) { } explicit packaged_task(_Res(*__fn)(_ArgTypes...)) : _M_state(std::make_shared<_State_type>(__fn)) { } template explicit packaged_task(allocator_arg_t __tag, const _Allocator& __a, _Fn __fn) : _M_state(std::allocate_shared<_State_type>(__a, std::move(__fn))) { } ~packaged_task() { if (static_cast(_M_state) && !_M_state.unique()) _M_state->_M_break_promise(std::move(_M_state->_M_result)); } // No copy packaged_task(packaged_task&) = delete; packaged_task& operator=(packaged_task&) = delete; // Move support packaged_task(packaged_task&& __other) { this->swap(__other); } packaged_task& operator=(packaged_task&& __other) { packaged_task(std::move(__other)).swap(*this); return *this; } void swap(packaged_task& __other) { _M_state.swap(__other._M_state); } explicit operator bool() const { return static_cast(_M_state); } // Result retrieval future<_Res> get_future() { return future<_Res>(_M_state); } // Execution void operator()(_ArgTypes... __args) { __future_base::_State::_S_check(_M_state); _M_state->_M_run(std::forward<_ArgTypes>(__args)...); } void reset() { __future_base::_State::_S_check(_M_state); packaged_task(std::move(_M_state->_M_task)).swap(*this); } }; template inline void swap(packaged_task<_Res(_ArgTypes...)>& __x, packaged_task<_Res(_ArgTypes...)>& __y) { __x.swap(__y); } template class __future_base::_Deferred_state : public __future_base::_State { public: typedef _Res _Res_type; explicit _Deferred_state(std::function<_Res()>&& __fn) : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)) { } private: template friend class _Task_setter; typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type; _Ptr_type _M_result; std::function<_Res()> _M_fn; virtual void _M_run_deferred() { _Task_setter<_Deferred_state> __setter{ this, _M_fn }; // safe to call multiple times so ignore failure _M_set_result(std::move(__setter), true); } }; template class __future_base::_Async_state : public __future_base::_State { public: typedef _Res _Res_type; explicit _Async_state(std::function<_Res()>&& __fn) : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)), _M_thread(mem_fn(&_Async_state::_M_do_run), this) { } ~_Async_state() { _M_thread.join(); } private: void _M_do_run() { _Task_setter<_Async_state> __setter{ this, std::move(_M_fn) }; _M_set_result(std::move(__setter)); } template friend class _Task_setter; typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type; _Ptr_type _M_result; std::function<_Res()> _M_fn; thread _M_thread; }; template future::type> async(launch __policy, _Fn&& __fn, _Args&&... __args) { typedef typename result_of<_Fn(_Args...)>::type result_type; std::shared_ptr<__future_base::_State> __state; if (__policy == launch::async) { typedef typename __future_base::_Async_state _State; __state = std::make_shared<_State>(std::bind( std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)); } else { typedef typename __future_base::_Deferred_state _State; __state = std::make_shared<_State>(std::bind( std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)); } return future(__state); } template inline typename enable_if::type, launch>::value, future()(std::declval<_Args>()...))> >::type async(_Fn&& __fn, _Args&&... __args) { return async(launch::any, std::forward<_Fn>(__fn), std::forward<_Args>(__args)...); } #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 // && _GLIBCXX_ATOMIC_BUILTINS_4 // @} group futures } #endif // __GXX_EXPERIMENTAL_CXX0X__ #endif // _GLIBCXX_FUTURE