aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std/future
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely.gcc@gmail.com>2011-07-09 10:13:01 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2011-07-09 11:13:01 +0100
commit4880236e3fdcec453e6f5f3ac04ea7dae3d31a8c (patch)
tree220d98d77838ae389eb4bbbfd1acdd2be8814bea /libstdc++-v3/include/std/future
parent4063e61bc63c3803f8ab2d625ebe8432ac06b3da (diff)
downloadgcc-4880236e3fdcec453e6f5f3ac04ea7dae3d31a8c.zip
gcc-4880236e3fdcec453e6f5f3ac04ea7dae3d31a8c.tar.gz
gcc-4880236e3fdcec453e6f5f3ac04ea7dae3d31a8c.tar.bz2
re PR libstdc++/49668 ([C++0x] std::thread does not forward its args as rvalues)
2011-07-09 Jonathan Wakely <jwakely.gcc@gmail.com> PR libstdc++/49668 * include/std/functional (__bind_simple): Define. * include/std/future (_Task_setter): Parameterize by type of result pointer instead of state object. (_S_task_setter): Type deduction helper. (_Task_state): Use _S_task_setter and __bind_simple. (_Deferred_state, _Async_state): Store call wrapper directly not as std::function. Use _S_task_setter and __bind_simple. (_S_make_deferred_state, _S_make_async_state): Type deduction helpers. (async): Use new functions and __bind_simple. * include/std/mutex (call_once): Use __bind_simple. * include/std/thread (thread): Likewise. Remove unused headers. * src/thread.cc: Add header. * testsuite/30_threads/async/49668.cc: New. * testsuite/30_threads/call_once/49668.cc: New. * testsuite/30_threads/thread/cons/49668.cc: New. * testsuite/30_threads/thread/cons/moveable.cc: Remove unused bool. From-SVN: r176073
Diffstat (limited to 'libstdc++-v3/include/std/future')
-rw-r--r--libstdc++-v3/include/std/future111
1 files changed, 72 insertions, 39 deletions
diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index 2b3e982..fc2d324 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -488,17 +488,42 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
virtual void _M_run_deferred() { }
};
- template<typename _Res>
+ template<typename _BoundFn, typename = typename _BoundFn::result_type>
class _Deferred_state;
- template<typename _Res>
+ template<typename _BoundFn, typename = typename _BoundFn::result_type>
class _Async_state;
template<typename _Signature>
class _Task_state;
- template<typename _StateT, typename _Res = typename _StateT::_Res_type>
+ template<typename _BoundFn>
+ static std::shared_ptr<_State_base>
+ _S_make_deferred_state(_BoundFn&& __fn);
+
+ template<typename _BoundFn>
+ static std::shared_ptr<_State_base>
+ _S_make_async_state(_BoundFn&& __fn);
+
+ template<typename _Res_ptr, typename _Res>
struct _Task_setter;
+
+ template<typename _Res_ptr, typename _BoundFn>
+ class _Task_setter_helper
+ {
+ typedef typename remove_reference<_BoundFn>::type::result_type __res;
+ public:
+ typedef _Task_setter<_Res_ptr, __res> __type;
+ };
+
+ template<typename _Res_ptr, typename _BoundFn>
+ static typename _Task_setter_helper<_Res_ptr, _BoundFn>::__type
+ _S_task_setter(_Res_ptr& __ptr, _BoundFn&& __call)
+ {
+ typedef _Task_setter_helper<_Res_ptr, _BoundFn> __helper_type;
+ typedef typename __helper_type::__type _Setter;
+ return _Setter{ __ptr, std::ref(__call) };
+ }
};
/// Partial specialization for reference types.
@@ -1165,29 +1190,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
- template<typename _StateT, typename _Res>
+ template<typename _Ptr_type, typename _Res>
struct __future_base::_Task_setter
{
- typename _StateT::_Ptr_type operator()()
+ _Ptr_type operator()()
{
__try
{
- _M_state->_M_result->_M_set(_M_fn());
+ _M_result->_M_set(_M_fn());
}
__catch(...)
{
- _M_state->_M_result->_M_error = current_exception();
+ _M_result->_M_error = current_exception();
}
- return std::move(_M_state->_M_result);
+ return std::move(_M_result);
}
- _StateT* _M_state;
+ _Ptr_type& _M_result;
std::function<_Res()> _M_fn;
};
- template<typename _StateT>
- struct __future_base::_Task_setter<_StateT, void>
+ template<typename _Ptr_type>
+ struct __future_base::_Task_setter<_Ptr_type, void>
{
- typename _StateT::_Ptr_type operator()()
+ _Ptr_type operator()()
{
__try
{
@@ -1195,11 +1220,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
__catch(...)
{
- _M_state->_M_result->_M_error = current_exception();
+ _M_result->_M_error = current_exception();
}
- return std::move(_M_state->_M_result);
+ return std::move(_M_result);
}
- _StateT* _M_state;
+ _Ptr_type& _M_result;
std::function<void()> _M_fn;
};
@@ -1223,13 +1248,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_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) };
+ auto __boundfn = std::__bind_simple(std::ref(_M_task),
+ _S_maybe_wrap_ref(std::forward<_Args>(__args))...);
+ auto __setter = _S_task_setter(_M_result, std::move(__boundfn));
_M_set_result(std::move(__setter));
}
- template<typename, typename> friend class _Task_setter;
typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type;
_Ptr_type _M_result;
std::function<_Res(_Args...)> _M_task;
@@ -1331,40 +1355,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: public true_type { };
- template<typename _Res>
+ template<typename _BoundFn, typename _Res>
class __future_base::_Deferred_state : public __future_base::_State_base
{
public:
- typedef _Res _Res_type;
-
explicit
- _Deferred_state(std::function<_Res()>&& __fn)
+ _Deferred_state(_BoundFn&& __fn)
: _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
{ }
private:
- template<typename, typename> friend class _Task_setter;
typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type;
_Ptr_type _M_result;
- std::function<_Res()> _M_fn;
+ _BoundFn _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);
+ _M_set_result(_S_task_setter(_M_result, _M_fn), true);
}
};
- template<typename _Res>
+ template<typename _BoundFn, typename _Res>
class __future_base::_Async_state : public __future_base::_State_base
{
public:
- typedef _Res _Res_type;
-
explicit
- _Async_state(std::function<_Res()>&& __fn)
+ _Async_state(_BoundFn&& __fn)
: _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)),
_M_thread(mem_fn(&_Async_state::_M_do_run), this)
{ }
@@ -1374,17 +1392,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
void _M_do_run()
{
- _Task_setter<_Async_state> __setter{ this, std::move(_M_fn) };
- _M_set_result(std::move(__setter));
+ _M_set_result(_S_task_setter(_M_result, _M_fn));
}
- template<typename, typename> friend class _Task_setter;
typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type;
_Ptr_type _M_result;
- std::function<_Res()> _M_fn;
+ _BoundFn _M_fn;
thread _M_thread;
};
+ template<typename _BoundFn>
+ inline std::shared_ptr<__future_base::_State_base>
+ __future_base::_S_make_deferred_state(_BoundFn&& __fn)
+ {
+ typedef typename remove_reference<_BoundFn>::type __fn_type;
+ typedef _Deferred_state<__fn_type> __state_type;
+ return std::make_shared<__state_type>(std::move(__fn));
+ }
+
+ template<typename _BoundFn>
+ inline std::shared_ptr<__future_base::_State_base>
+ __future_base::_S_make_async_state(_BoundFn&& __fn)
+ {
+ typedef typename remove_reference<_BoundFn>::type __fn_type;
+ typedef _Async_state<__fn_type> __state_type;
+ return std::make_shared<__state_type>(std::move(__fn));
+ }
+
+
/// async
template<typename _Fn, typename... _Args>
future<typename result_of<_Fn(_Args...)>::type>
@@ -1394,14 +1429,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::shared_ptr<__future_base::_State_base> __state;
if ((__policy & (launch::async|launch::deferred)) == launch::async)
{
- typedef typename __future_base::_Async_state<result_type> _State;
- __state = std::make_shared<_State>(std::bind<result_type>(
+ __state = __future_base::_S_make_async_state(std::__bind_simple(
std::forward<_Fn>(__fn), std::forward<_Args>(__args)...));
}
else
{
- typedef typename __future_base::_Deferred_state<result_type> _State;
- __state = std::make_shared<_State>(std::bind<result_type>(
+ __state = __future_base::_S_make_deferred_state(std::__bind_simple(
std::forward<_Fn>(__fn), std::forward<_Args>(__args)...));
}
return future<result_type>(__state);