Use INVOKE<R> in std::function, std::bind and std::packaged_task
authorJonathan Wakely <jwakely@redhat.com>
Tue, 14 May 2019 15:25:08 +0000 (16:25 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 14 May 2019 15:25:08 +0000 (16:25 +0100)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/std_function.h
libstdc++-v3/include/std/functional
libstdc++-v3/include/std/future

index 8330ad1a3089def8edde93c6f5a0b30fd55335fc..c2466cefaa595bfe81cbbe9ee9073afa928f84b0 100644 (file)
@@ -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.
index b70ed564d11a2bda4f34bcc23c3340c1fa7db17f..5733bf5f3f9fe314125498f5cb1ea199603caa8a 100644 (file)
@@ -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)...);
       }
     };
 
index 0c290b9670b29c9650b0c1273348058d5fdb36ff..d610e914b59856ae011fc51cad34eb69b7fc0e70 100644 (file)
@@ -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;
 
index 10136e57a84983448486b6c1ad6d2385d337b695..967110050b8aa5a438ad602a1401c98f7c587300 100644 (file)
@@ -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));