Use INVOKE<R> in std::function, std::bind and std::packaged_task

Message ID 20190514152528.GA9251@redhat.com
State New
Headers show
Series
  • Use INVOKE<R> in std::function, std::bind and std::packaged_task
Related show

Commit Message

Jonathan Wakely May 14, 2019, 3:25 p.m.
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.

Tested powerpc64le-linux, committed to trunk.
commit 251e0fb712bb801cae130f838e02ee697b97e73c
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Apr 9 20:07:33 2019 +0100

    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.

Patch

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<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;
 
@@ -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<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,
@@ -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<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 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));