diff options
| author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-07-09 10:13:01 +0000 |
|---|---|---|
| committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-07-09 10:13:01 +0000 |
| commit | 339db54bdce71adca1d790413745f7e0d557b693 (patch) | |
| tree | 220d98d77838ae389eb4bbbfd1acdd2be8814bea /libstdc++-v3/include/std/functional | |
| parent | 3115bda06f241a032e3e5dca50556203a98767a0 (diff) | |
| download | ppe42-gcc-339db54bdce71adca1d790413745f7e0d557b693.tar.gz ppe42-gcc-339db54bdce71adca1d790413745f7e0d557b693.zip | |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@176073 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/std/functional')
| -rw-r--r-- | libstdc++-v3/include/std/functional | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 85df22017f6..df3f9ceb7b4 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -1499,6 +1499,77 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) std::forward<_BoundArgs>(__args)...); } + template<typename _Signature> + struct _Bind_simple; + + template<typename _Callable, typename... _Args> + struct _Bind_simple<_Callable(_Args...)> + { + typedef typename result_of<_Callable(_Args...)>::type result_type; + + template<typename... _Args2, typename = typename + enable_if< sizeof...(_Args) == sizeof...(_Args2)>::type> + explicit + _Bind_simple(const _Callable& __callable, _Args2&&... __args) + : _M_bound(__callable, std::forward<_Args2>(__args)...) + { } + + template<typename... _Args2, typename = typename + enable_if< sizeof...(_Args) == sizeof...(_Args2)>::type> + explicit + _Bind_simple(_Callable&& __callable, _Args2&&... __args) + : _M_bound(std::move(__callable), std::forward<_Args2>(__args)...) + { } + + _Bind_simple(const _Bind_simple&) = default; + _Bind_simple(_Bind_simple&&) = default; + + result_type + operator()() + { + typedef typename _Build_index_tuple<sizeof...(_Args)>::__type _Indices; + return _M_invoke(_Indices()); + } + + private: + + template<int... _Indices> + typename result_of<_Callable(_Args...)>::type + _M_invoke(_Index_tuple<_Indices...>) + { + // std::bind always forwards bound arguments as lvalues, + // but this type can call functions which only accept rvalues. + return std::forward<_Callable>(std::get<0>(_M_bound))( + std::forward<_Args>(std::get<_Indices+1>(_M_bound))...); + } + + std::tuple<_Callable, _Args...> _M_bound; + }; + + template<typename _Func, typename... _BoundArgs> + struct _Bind_simple_helper + { + typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type> + __maybe_type; + typedef typename __maybe_type::type __func_type; + typedef _Bind_simple<__func_type(typename decay<_BoundArgs>::type...)> + __type; + }; + + // Simplified version of std::bind for internal use, without support for + // unbound arguments, placeholders or nested bind expressions. + template<typename _Callable, typename... _Args> + typename _Bind_simple_helper<_Callable, _Args...>::__type + __bind_simple(_Callable&& __callable, _Args&&... __args) + { + typedef _Bind_simple_helper<_Callable, _Args...> __helper_type; + typedef typename __helper_type::__maybe_type __maybe_type; + typedef typename __helper_type::__type __result_type; + return __result_type( + __maybe_type::__do_wrap( std::forward<_Callable>(__callable)), + std::forward<_Args>(__args)...); + } + /** * @brief Exception class thrown when class template function's * operator() is called with an empty target. |

