From de1d079440179287ff154a66218b2f2fd41a9acf Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 14 Oct 2016 20:04:56 +0100 Subject: Make std::bind use std::invoke * include/std/functional (_Mu, _Mu): Simplify forwarding from tuple of references. (_Maybe_wrap_member_pointer): Remove. (_Bind::__call, _Bind::__call_c, _Bind::__call_v, _Bind::__call_c_v): Use std::__invoke. (_Bind::_Mu_type, _Bind::_Res_type_impl, _Bind::_Res_type) (_Bind::__dependent, _Bind::_Res_type_cv): New helpers to simplify return type deduction. (_Bind::operator(), _Bind::operator() const): Use new helpers. (_Bind::operator() volatile, _Bind::operator() const volatile): Likewise. Add deprecated attribute for C++17 mode. (_Bind_result::__call): Use std::__invoke. (_Bind_result::operator() volatile) (_Bind_result::operator() const volatile): Add deprecated attribute. (_Bind_helper::__maybe_type, _Bindres_helper::__maybe_type): Remove. (_Bind_helper, _Bindres_helper): Don't use _Maybe_wrap_member_pointer. (bind, bind): Don't use __maybe_type. * src/c++11/compatibility-thread-c++0x.cc (_Maybe_wrap_member_pointer): Define here for compatibility symbols. * testsuite/20_util/bind/68912.cc: Don't test volatile-qualification in C++17 mode. * testsuite/20_util/bind/cv_quals.cc: Likewise. * testsuite/20_util/bind/cv_quals_2.cc: Likewise. From-SVN: r241178 --- libstdc++-v3/include/std/functional | 168 +++++++++++++++--------------------- 1 file changed, 70 insertions(+), 98 deletions(-) (limited to 'libstdc++-v3/include/std') diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index d39b519..ad67a1d 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -742,7 +742,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) const _Index_tuple<_Indexes...>&) const volatile -> decltype(__arg(declval<_Args>()...)) { - return __arg(std::forward<_Args>(std::get<_Indexes>(__tuple))...); + return __arg(std::get<_Indexes>(std::move(__tuple))...); } }; @@ -759,10 +759,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) _Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&& operator()(const volatile _Arg&, _Tuple& __tuple) const volatile { - using __type - = __tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>; - return std::forward<__type>( - ::std::get<(is_placeholder<_Arg>::value - 1)>(__tuple)); + return + ::std::get<(is_placeholder<_Arg>::value - 1)>(std::move(__tuple)); } }; @@ -781,50 +779,6 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) { return std::forward<_CVArg>(__arg); } }; - /** - * Maps member pointers into instances of _Mem_fn but leaves all - * other function objects untouched. Used by std::bind(). The - * primary template handles the non-member-pointer case. - */ - template - struct _Maybe_wrap_member_pointer - { - typedef _Tp type; - - static constexpr const _Tp& - __do_wrap(const _Tp& __x) - { return __x; } - - static constexpr _Tp&& - __do_wrap(_Tp&& __x) - { return static_cast<_Tp&&>(__x); } - }; - - /** - * Maps member pointers into instances of _Mem_fn but leaves all - * other function objects untouched. Used by std::bind(). This - * partial specialization handles the member pointer case. - */ - template - struct _Maybe_wrap_member_pointer<_Tp _Class::*> - { - typedef _Mem_fn<_Tp _Class::*> type; - - static constexpr type - __do_wrap(_Tp _Class::* __pm) - { return type(__pm); } - }; - - // Specialization needed to prevent "forming reference to void" errors when - // bind() is called, because argument deduction instantiates - // _Maybe_wrap_member_pointer outside the immediate context where - // SFINAE applies. - template<> - struct _Maybe_wrap_member_pointer - { - typedef void type; - }; - // std::get for volatile-qualified tuples template inline auto @@ -858,8 +812,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) _Result __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { - return _M_f(_Mu<_Bound_args>() - (std::get<_Indexes>(_M_bound_args), __args)...); + return std::__invoke(_M_f, + _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)... + ); } // Call as const @@ -867,8 +822,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) _Result __call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { - return _M_f(_Mu<_Bound_args>() - (std::get<_Indexes>(_M_bound_args), __args)...); + return std::__invoke(_M_f, + _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)... + ); } // Call as volatile @@ -877,8 +833,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) __call_v(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { - return _M_f(_Mu<_Bound_args>() - (__volget<_Indexes>(_M_bound_args), __args)...); + return std::__invoke(_M_f, + _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)... + ); } // Call as const volatile @@ -887,10 +844,33 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) __call_c_v(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { - return _M_f(_Mu<_Bound_args>() - (__volget<_Indexes>(_M_bound_args), __args)...); + return std::__invoke(_M_f, + _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)... + ); } + template + using _Mu_type = decltype( + _Mu::type>()( + std::declval<_BoundArg&>(), std::declval<_CallArgs&>()) ); + + template + using _Res_type_impl + = typename result_of< _Fn&(_Mu_type<_BArgs, _CallArgs>...) >::type; + + template + using _Res_type = _Res_type_impl<_Functor, _CallArgs, _Bound_args...>; + + template + using __dependent = typename + enable_if::value+1), _Functor>::type; + + template class __cv_quals> + using _Res_type_cv = _Res_type_impl< + typename __cv_quals<__dependent<_CallArgs>>::type, + _CallArgs, + typename __cv_quals<_Bound_args>::type...>; + public: template explicit _Bind(const _Functor& __f, _Args&&... __args) @@ -909,10 +889,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) { } // Call unqualified - template()( - _Mu<_Bound_args>()( std::declval<_Bound_args&>(), - std::declval&>() )... ) )> + template>> _Result operator()(_Args&&... __args) { @@ -922,11 +900,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) } // Call as const - template= 0), - typename add_const<_Functor>::type&>::type>()( - _Mu<_Bound_args>()( std::declval(), - std::declval&>() )... ) )> + template, add_const>> _Result operator()(_Args&&... __args) const { @@ -935,12 +910,16 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) _Bound_indexes()); } +#if __cplusplus > 201402L +# define _GLIBCXX_DEPR_BIND \ + [[deprecated("std::bind does not support volatile in C++17")]] +#else +# define _GLIBCXX_DEPR_BIND +#endif // Call as volatile - template= 0), - typename add_volatile<_Functor>::type&>::type>()( - _Mu<_Bound_args>()( std::declval(), - std::declval&>() )... ) )> + template, add_volatile>> + _GLIBCXX_DEPR_BIND _Result operator()(_Args&&... __args) volatile { @@ -950,11 +929,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) } // Call as const volatile - template= 0), - typename add_cv<_Functor>::type&>::type>()( - _Mu<_Bound_args>()( std::declval(), - std::declval&>() )... ) )> + template, add_cv>> + _GLIBCXX_DEPR_BIND _Result operator()(_Args&&... __args) const volatile { @@ -991,7 +968,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { - return _M_f(_Mu<_Bound_args>() + return std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } @@ -1000,7 +977,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { - _M_f(_Mu<_Bound_args>() + std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } @@ -1009,7 +986,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { - return _M_f(_Mu<_Bound_args>() + return std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } @@ -1018,7 +995,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { - _M_f(_Mu<_Bound_args>() + std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } @@ -1027,7 +1004,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { - return _M_f(_Mu<_Bound_args>() + return std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } @@ -1036,7 +1013,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { - _M_f(_Mu<_Bound_args>() + std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } @@ -1046,7 +1023,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { - return _M_f(_Mu<_Bound_args>() + return std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } @@ -1056,7 +1033,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { - _M_f(_Mu<_Bound_args>() + std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } @@ -1101,6 +1078,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) // Call as volatile template + _GLIBCXX_DEPR_BIND result_type operator()(_Args&&... __args) volatile { @@ -1111,6 +1089,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) // Call as const volatile template + _GLIBCXX_DEPR_BIND result_type operator()(_Args&&... __args) const volatile { @@ -1119,6 +1098,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) _Bound_indexes()); } }; +#undef _GLIBCXX_DEPR_BIND /** * @brief Class template _Bind is always a bind expression. @@ -1222,9 +1202,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) struct _Bind_helper : _Bind_check_arity::type, _BoundArgs...> { - typedef _Maybe_wrap_member_pointer::type> - __maybe_type; - typedef typename __maybe_type::type __func_type; + typedef typename decay<_Func>::type __func_type; typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type; }; @@ -1245,19 +1223,15 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) bind(_Func&& __f, _BoundArgs&&... __args) { typedef _Bind_helper __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<_Func>(__f)), - std::forward<_BoundArgs>(__args)...); + return typename __helper_type::type(std::forward<_Func>(__f), + std::forward<_BoundArgs>(__args)...); } template struct _Bindres_helper : _Bind_check_arity::type, _BoundArgs...> { - typedef _Maybe_wrap_member_pointer::type> - __maybe_type; - typedef typename __maybe_type::type __functor_type; + typedef typename decay<_Func>::type __functor_type; typedef _Bind_result<_Result, __functor_type(typename decay<_BoundArgs>::type...)> type; @@ -1273,10 +1247,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) bind(_Func&& __f, _BoundArgs&&... __args) { typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __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<_Func>(__f)), - std::forward<_BoundArgs>(__args)...); + return typename __helper_type::type(std::forward<_Func>(__f), + std::forward<_BoundArgs>(__args)...); } /** -- cgit v1.1