diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-05-14 16:25:08 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-05-14 16:25:08 +0100 |
commit | 330b17474c618af0574c0b8e83a06287e53afe87 (patch) | |
tree | 1224a465498d4e2f0f682ff786b28def3273b5c6 | |
parent | 78c2855df612af45edb78426348296f43f2a8602 (diff) | |
download | gcc-330b17474c618af0574c0b8e83a06287e53afe87.zip gcc-330b17474c618af0574c0b8e83a06287e53afe87.tar.gz gcc-330b17474c618af0574c0b8e83a06287e53afe87.tar.bz2 |
Use INVOKE<R> 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<R>, 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
-rw-r--r-- | libstdc++-v3/ChangeLog | 14 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/std_function.h | 74 | ||||
-rw-r--r-- | libstdc++-v3/include/std/functional | 62 | ||||
-rw-r--r-- | libstdc++-v3/include/std/future | 10 |
4 files changed, 32 insertions, 128 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8330ad1..c2466ce 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,19 @@ 2019-05-14 Jonathan Wakely <jwakely@redhat.com> + * 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<R> 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 b70ed56..5733bf5 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<typename _Tp> - struct _Simple_type_wrapper - { - _Simple_type_wrapper(_Tp __value) : __value(__value) { } - - _Tp __value; - }; - - template<typename _Tp> - struct __is_location_invariant<_Simple_type_wrapper<_Tp> > - : __is_location_invariant<_Tp> - { }; - template<typename _Signature> class function; @@ -279,56 +264,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<typename _Functor, typename... _ArgTypes> - class _Function_handler<void(_ArgTypes...), _Functor> - : 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<typename _Class, typename _Member, typename _Res, - typename... _ArgTypes> - class _Function_handler<_Res(_ArgTypes...), _Member _Class::*> - : public _Function_handler<void(_ArgTypes...), _Member _Class::*> - { - typedef _Function_handler<void(_ArgTypes...), _Member _Class::*> - _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<typename _Class, typename _Member, typename... _ArgTypes> - class _Function_handler<void(_ArgTypes...), _Member _Class::*> - : 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, _Manager_operation __op) @@ -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 0c290b9..d610e91 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<typename _Res> - using __enable_if_void - = typename enable_if<is_void<_Res>{}>::type; - - template<typename _Res> - using __disable_if_void - = typename enable_if<!is_void<_Res>{}, _Result>::type; - // Call unqualified template<typename _Res, typename... _Args, std::size_t... _Indexes> - __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<typename _Res, typename... _Args, std::size_t... _Indexes> - __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<typename _Res, typename... _Args, std::size_t... _Indexes> - __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<typename _Res, typename... _Args, std::size_t... _Indexes> - __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<typename _Res, typename... _Args, std::size_t... _Indexes> - __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<typename _Res, typename... _Args, std::size_t... _Indexes> - __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<typename _Res, typename... _Args, std::size_t... _Indexes> - __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<typename _Res, typename... _Args, std::size_t... _Indexes> - __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 10136e5..9671100 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)); |