From 330b17474c618af0574c0b8e83a06287e53afe87 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 14 May 2019 16:25:08 +0100 Subject: [PATCH] Use INVOKE in std::function, std::bind and std::packaged_task As well as simpifying the code by removing duplication, this means that we only need to touch std::__invoke_r if we need to implement changes to INVOKE, such as those in P0932R0. * include/bits/std_function.h (_Simple_type_wrapper): Remove. (_Function_handler): Remove partial specializations for void return types and pointers to member. (_Function_handler::_M_manager): Adapt to removal of _Simple_type_wrapper. (_Function_handler::_M_invoke): Use __invoke_r instead of __invoke. * include/std/functional (_Bind_result::__enable_if_void) (_Bind_result::__disable_if_void): Remove sfinae helpers. (_Bind_result::__call): Use __invoke_r and remove overloads for void return types. * include/std/future (__future_base::_Task_state::_M_run) (__future_base::_Task_state::_M_run_delayed): Use __invoke_r and change return type of lambda expressions. From-SVN: r271174 --- libstdc++-v3/ChangeLog | 14 +++++ libstdc++-v3/include/bits/std_function.h | 74 ++---------------------- libstdc++-v3/include/std/functional | 62 +++----------------- libstdc++-v3/include/std/future | 10 ++-- 4 files changed, 32 insertions(+), 128 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8330ad1a308..c2466cefaa5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,19 @@ 2019-05-14 Jonathan Wakely + * include/bits/std_function.h (_Simple_type_wrapper): Remove. + (_Function_handler): Remove partial specializations for void return + types and pointers to member. + (_Function_handler::_M_manager): Adapt to removal of + _Simple_type_wrapper. + (_Function_handler::_M_invoke): Use __invoke_r instead of __invoke. + * include/std/functional (_Bind_result::__enable_if_void) + (_Bind_result::__disable_if_void): Remove sfinae helpers. + (_Bind_result::__call): Use __invoke_r and remove overloads for void + return types. + * include/std/future (__future_base::_Task_state::_M_run) + (__future_base::_Task_state::_M_run_delayed): Use __invoke_r and + change return type of lambda expressions. + * include/bits/invoke.h (__invoke_r): Define new function implementing the INVOKE pseudo-function. * testsuite/20_util/function_objects/invoke/1.cc: Add more tests. diff --git a/libstdc++-v3/include/bits/std_function.h b/libstdc++-v3/include/bits/std_function.h index b70ed564d11..5733bf5f3f9 100644 --- a/libstdc++-v3/include/bits/std_function.h +++ b/libstdc++-v3/include/bits/std_function.h @@ -109,21 +109,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __destroy_functor }; - // Simple type wrapper that helps avoid annoying const problems - // when casting between void pointers and pointers-to-pointers. - template - struct _Simple_type_wrapper - { - _Simple_type_wrapper(_Tp __value) : __value(__value) { } - - _Tp __value; - }; - - template - struct __is_location_invariant<_Simple_type_wrapper<_Tp> > - : __is_location_invariant<_Tp> - { }; - template class function; @@ -278,56 +263,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef _Function_base::_Base_manager<_Functor> _Base; - public: - static _Res - _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) - { - return (*_Base::_M_get_pointer(__functor))( - std::forward<_ArgTypes>(__args)...); - } - }; - - template - class _Function_handler - : public _Function_base::_Base_manager<_Functor> - { - typedef _Function_base::_Base_manager<_Functor> _Base; - - public: - static void - _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) - { - (*_Base::_M_get_pointer(__functor))( - std::forward<_ArgTypes>(__args)...); - } - }; - - template - class _Function_handler<_Res(_ArgTypes...), _Member _Class::*> - : public _Function_handler - { - typedef _Function_handler - _Base; - - public: - static _Res - _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) - { - return std::__invoke(_Base::_M_get_pointer(__functor)->__value, - std::forward<_ArgTypes>(__args)...); - } - }; - - template - class _Function_handler - : public _Function_base::_Base_manager< - _Simple_type_wrapper< _Member _Class::* > > - { - typedef _Member _Class::* _Functor; - typedef _Simple_type_wrapper<_Functor> _Wrapper; - typedef _Function_base::_Base_manager<_Wrapper> _Base; - public: static bool _M_manager(_Any_data& __dest, const _Any_data& __source, @@ -341,8 +276,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION break; #endif case __get_functor_ptr: - __dest._M_access<_Functor*>() = - &_Base::_M_get_pointer(__source)->__value; + __dest._M_access<_Functor*>() = _Base::_M_get_pointer(__source); break; default: @@ -351,11 +285,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; } - static void + static _Res _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) { - std::__invoke(_Base::_M_get_pointer(__functor)->__value, - std::forward<_ArgTypes>(__args)...); + return std::__invoke_r<_Res>(*_Base::_M_get_pointer(__functor), + std::forward<_ArgTypes>(__args)...); } }; diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 0c290b9670b..d610e914b59 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -539,89 +539,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Functor _M_f; tuple<_Bound_args...> _M_bound_args; - // sfinae types - template - using __enable_if_void - = typename enable_if{}>::type; - - template - using __disable_if_void - = typename enable_if{}, _Result>::type; - // Call unqualified template - __disable_if_void<_Res> + _Res __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { - return std::__invoke(_M_f, _Mu<_Bound_args>() + return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } - // Call unqualified, return void - template - __enable_if_void<_Res> - __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) - { - std::__invoke(_M_f, _Mu<_Bound_args>() - (std::get<_Indexes>(_M_bound_args), __args)...); - } - // Call as const template - __disable_if_void<_Res> + _Res __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { - return std::__invoke(_M_f, _Mu<_Bound_args>() + return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } - // Call as const, return void - template - __enable_if_void<_Res> - __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const - { - std::__invoke(_M_f, _Mu<_Bound_args>() - (std::get<_Indexes>(_M_bound_args), __args)...); - } - // Call as volatile template - __disable_if_void<_Res> + _Res __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { - return std::__invoke(_M_f, _Mu<_Bound_args>() + return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } - // Call as volatile, return void - template - __enable_if_void<_Res> - __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile - { - std::__invoke(_M_f, _Mu<_Bound_args>() - (__volget<_Indexes>(_M_bound_args), __args)...); - } - // Call as const volatile template - __disable_if_void<_Res> + _Res __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { - return std::__invoke(_M_f, _Mu<_Bound_args>() + return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } - // Call as const volatile, return void - template - __enable_if_void<_Res> - __call(tuple<_Args...>&& __args, - _Index_tuple<_Indexes...>) const volatile - { - std::__invoke(_M_f, _Mu<_Bound_args>() - (__volget<_Indexes>(_M_bound_args), __args)...); - } - public: typedef _Result result_type; diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index 10136e57a84..967110050b8 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -1417,8 +1417,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION virtual void _M_run(_Args&&... __args) { - auto __boundfn = [&] () -> typename result_of<_Fn&(_Args&&...)>::type { - return std::__invoke(_M_impl._M_fn, std::forward<_Args>(__args)...); + auto __boundfn = [&] () -> _Res { + return std::__invoke_r<_Res>(_M_impl._M_fn, + std::forward<_Args>(__args)...); }; this->_M_set_result(_S_task_setter(this->_M_result, __boundfn)); } @@ -1426,8 +1427,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION virtual void _M_run_delayed(_Args&&... __args, weak_ptr<_State_base> __self) { - auto __boundfn = [&] () -> typename result_of<_Fn&(_Args&&...)>::type { - return std::__invoke(_M_impl._M_fn, std::forward<_Args>(__args)...); + auto __boundfn = [&] () -> _Res { + return std::__invoke_r<_Res>(_M_impl._M_fn, + std::forward<_Args>(__args)...); }; this->_M_set_delayed_result(_S_task_setter(this->_M_result, __boundfn), std::move(__self)); -- 2.30.2