Re: [PATCH] Replace __bind_simple with std::thread::__make_invoker
On 13/10/16 13:20 +0100, Jonathan Wakely wrote: On 13/10/16 14:16 +0200, Thomas Schwinge wrote: Hi! Build failure after trunk r241093: [...]/source-gcc/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:121:12: error: ISO C++ forbids declaration of '_Bind_simple_helper' with no type [-fpermissive] template _Bind_simple_helper>::__type __bind_simple(void (thread::*&&)(), reference_wrapper&&); ^~~ [...]/source-gcc/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:121:12: error: '_Bind_simple_helper' is not a template function [...]/source-gcc/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:121:31: error: expected ';' before '<' token template _Bind_simple_helper>::__type __bind_simple(void (thread::*&&)(), reference_wrapper&&); ^ Erk, I meant to move the removed code to the compatibility file, but lost that part of the commit, sorry. Fix coming up ... Fix committed to trunk, and tested with a clean build this time. commit 58542a85cfa34ee186542c879352a9802fec6e7d Author: Jonathan Wakely Date: Thu Oct 13 13:33:07 2016 +0100 Restore __bind_simple for compat symbols * src/c++11/compatibility-thread-c++0x.cc (_Bind_simple) (_Bind_simple_helper, __bind_simple): Restore for ABI compat symbols. diff --git a/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc b/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc index 922fa00..5ca2da8 100644 --- a/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc +++ b/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc @@ -116,6 +116,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Replaced with inline definition in gcc-4.8.0 __future_base::_Async_state_common::~_Async_state_common() { _M_join(); } + template +struct _Bind_simple; + + template +struct _Bind_simple<_Callable(_Args...)> +{ + typedef typename result_of<_Callable(_Args...)>::type result_type; + + template +explicit +_Bind_simple(_Tp&& __f, _Up&&... __args) +: _M_bound(std::forward<_Tp>(__f), std::forward<_Up>(__args)...) +{ } + + _Bind_simple(const _Bind_simple&) = default; + _Bind_simple(_Bind_simple&&) = default; + + result_type + operator()() + { +typedef typename _Build_index_tuple::__type _Indices; +return _M_invoke(_Indices()); + } + +private: + template +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 +struct _Bind_simple_helper +{ + typedef _Maybe_wrap_member_pointer::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 _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)...); +} + // Explicit instantiation due to -fno-implicit-instantiation. template void call_once(once_flag&, void (thread::*&&)(), reference_wrapper&&); template _Bind_simple_helper>::__type __bind_simple(void (thread::*&&)(), reference_wrapper&&);
Re: [PATCH] Replace __bind_simple with std::thread::__make_invoker
On 13/10/16 14:16 +0200, Thomas Schwinge wrote: Hi! Build failure after trunk r241093: [...]/source-gcc/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:121:12: error: ISO C++ forbids declaration of '_Bind_simple_helper' with no type [-fpermissive] template _Bind_simple_helper>::__type __bind_simple(void (thread::*&&)(), reference_wrapper&&); ^~~ [...]/source-gcc/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:121:12: error: '_Bind_simple_helper' is not a template function [...]/source-gcc/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:121:31: error: expected ';' before '<' token template _Bind_simple_helper>::__type __bind_simple(void (thread::*&&)(), reference_wrapper&&); ^ Erk, I meant to move the removed code to the compatibility file, but lost that part of the commit, sorry. Fix coming up ...
Re: [PATCH] Replace __bind_simple with std::thread::__make_invoker
Hi! Build failure after trunk r241093: [...]/source-gcc/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:121:12: error: ISO C++ forbids declaration of '_Bind_simple_helper' with no type [-fpermissive] template _Bind_simple_helper>::__type __bind_simple(void (thread::*&&)(), reference_wrapper&&); ^~~ [...]/source-gcc/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:121:12: error: '_Bind_simple_helper' is not a template function [...]/source-gcc/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:121:31: error: expected ';' before '<' token template _Bind_simple_helper>::__type __bind_simple(void (thread::*&&)(), reference_wrapper&&); ^ For reference: On Thu, 13 Oct 2016 11:37:06 +0100, Jonathan Wakely wrote: > Some time ago I added __bind_simple, which is a simpler version of > std::bind that doesn't support placeholders and nested bind > expressions. It's only needed by a few concurrency components that do > INVOKE(DECAY_COPY(f), DECAY_COPY(args)...) but those conponents have > to include the whole of to get it. > > Now that std::call_once() doesn't use it, it's only needed in > and so I'm moving it into , renaming it to > std::thread::__make_invoker, and adding some comments about its > purpose. > > std::packaged_task shouldn't be using that function anyway, because it > doesn't want the DECAY_COPY semantics and I was forced to wrap the > arguments in reference_wrappers to prevent the decaying. Like > std::call_once it can just use a lambda-expression instead. > > This allows us to remove from and . That > doesn't reduce the size of preprocessed source yet, because > includes the whole of anyway, but I'll reduce that soon. > > * include/std/functional (_Bind_simple, _Bind_simple_helper) > (__bind_simple): Remove. > * include/std/future: Include instead of . > (__future_base::_Task_state::_M_run) > (__future_base::_Task_state::_M_run_delayed): Use lambda expressions > instead of __bind_simple. > (__future_base::_Task_state::_S_maybe_wrap_ref): Remove. > (async): Use thread::__make_invoker instead of __bind_simple. > * include/std/thread: Include and instead of > . > (thread::_Invoker, thread::__make_invoker): Define helpers to do > INVOKE(DECAY_COPY(f), DECAY_COPY(args)...). > > Tested powerpc64le-linux, committed to trunk. > > commit 13c071f6ee2e3edb177e6150f7a3903ecaf9de68 > Author: Jonathan Wakely > Date: Wed Oct 12 17:15:46 2016 +0100 > > Replace __bind_simple with std::thread::__make_invoker > > * include/std/functional (_Bind_simple, _Bind_simple_helper) > (__bind_simple): Remove. > * include/std/future: Include instead of . > (__future_base::_Task_state::_M_run) > (__future_base::_Task_state::_M_run_delayed): Use lambda expressions > instead of __bind_simple. > (__future_base::_Task_state::_S_maybe_wrap_ref): Remove. > (async): Use thread::__make_invoker instead of __bind_simple. > * include/std/thread: Include and instead of > . > (thread::_Invoker, thread::__make_invoker): Define helpers to do > INVOKE(DECAY_COPY(f), DECAY_COPY(args)...). > > diff --git a/libstdc++-v3/include/std/functional > b/libstdc++-v3/include/std/functional > index 58134b7..3877033 100644 > --- a/libstdc++-v3/include/std/functional > +++ b/libstdc++-v3/include/std/functional > @@ -1300,69 +1300,6 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) > std::forward<_BoundArgs>(__args)...); > } > > - template > -struct _Bind_simple; > - > - template > -struct _Bind_simple<_Callable(_Args...)> > -{ > - typedef typename result_of<_Callable(_Args...)>::type result_type; > - > - template > -explicit > -_Bind_simple(_Tp&& __f, _Up&&... __args) > -: _M_bound(std::forward<_Tp>(__f), std::forward<_Up>(__args)...) > -{ } > - > - _Bind_simple(const _Bind_simple&) = default; > - _Bind_simple(_Bind_simple&&) = default; > - > - result_type > - operator()() > - { > -typedef typename _Build_index_tuple::__type > _Indices; > -return _M_invoke(_Indices()); > - } > - > -private: > - template > -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 > -struct _Bind_simple_helper > -: _Bind_check_arity::type, _BoundArgs...> > -{ > - typedef _Maybe_wrap_member_pointer::typ
[PATCH] Replace __bind_simple with std::thread::__make_invoker
Some time ago I added __bind_simple, which is a simpler version of std::bind that doesn't support placeholders and nested bind expressions. It's only needed by a few concurrency components that do INVOKE(DECAY_COPY(f), DECAY_COPY(args)...) but those conponents have to include the whole of to get it. Now that std::call_once() doesn't use it, it's only needed in and so I'm moving it into , renaming it to std::thread::__make_invoker, and adding some comments about its purpose. std::packaged_task shouldn't be using that function anyway, because it doesn't want the DECAY_COPY semantics and I was forced to wrap the arguments in reference_wrappers to prevent the decaying. Like std::call_once it can just use a lambda-expression instead. This allows us to remove from and . That doesn't reduce the size of preprocessed source yet, because includes the whole of anyway, but I'll reduce that soon. * include/std/functional (_Bind_simple, _Bind_simple_helper) (__bind_simple): Remove. * include/std/future: Include instead of . (__future_base::_Task_state::_M_run) (__future_base::_Task_state::_M_run_delayed): Use lambda expressions instead of __bind_simple. (__future_base::_Task_state::_S_maybe_wrap_ref): Remove. (async): Use thread::__make_invoker instead of __bind_simple. * include/std/thread: Include and instead of . (thread::_Invoker, thread::__make_invoker): Define helpers to do INVOKE(DECAY_COPY(f), DECAY_COPY(args)...). Tested powerpc64le-linux, committed to trunk. commit 13c071f6ee2e3edb177e6150f7a3903ecaf9de68 Author: Jonathan Wakely Date: Wed Oct 12 17:15:46 2016 +0100 Replace __bind_simple with std::thread::__make_invoker * include/std/functional (_Bind_simple, _Bind_simple_helper) (__bind_simple): Remove. * include/std/future: Include instead of . (__future_base::_Task_state::_M_run) (__future_base::_Task_state::_M_run_delayed): Use lambda expressions instead of __bind_simple. (__future_base::_Task_state::_S_maybe_wrap_ref): Remove. (async): Use thread::__make_invoker instead of __bind_simple. * include/std/thread: Include and instead of . (thread::_Invoker, thread::__make_invoker): Define helpers to do INVOKE(DECAY_COPY(f), DECAY_COPY(args)...). diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 58134b7..3877033 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -1300,69 +1300,6 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) std::forward<_BoundArgs>(__args)...); } - template -struct _Bind_simple; - - template -struct _Bind_simple<_Callable(_Args...)> -{ - typedef typename result_of<_Callable(_Args...)>::type result_type; - - template -explicit -_Bind_simple(_Tp&& __f, _Up&&... __args) -: _M_bound(std::forward<_Tp>(__f), std::forward<_Up>(__args)...) -{ } - - _Bind_simple(const _Bind_simple&) = default; - _Bind_simple(_Bind_simple&&) = default; - - result_type - operator()() - { -typedef typename _Build_index_tuple::__type _Indices; -return _M_invoke(_Indices()); - } - -private: - template -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 -struct _Bind_simple_helper -: _Bind_check_arity::type, _BoundArgs...> -{ - typedef _Maybe_wrap_member_pointer::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 _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. diff --git a/libstdc++-v3/include/