diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2016-10-14 20:04:56 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2016-10-14 20:04:56 +0100 |
commit | de1d079440179287ff154a66218b2f2fd41a9acf (patch) | |
tree | 7409d6610897d518f0e50d3ca93a99dd2df1707d /libstdc++-v3 | |
parent | 064ed55a66a788b1939fb93bd64ea3705e8384c7 (diff) | |
download | gcc-de1d079440179287ff154a66218b2f2fd41a9acf.zip gcc-de1d079440179287ff154a66218b2f2fd41a9acf.tar.gz gcc-de1d079440179287ff154a66218b2f2fd41a9acf.tar.bz2 |
Make std::bind use std::invoke
* include/std/functional (_Mu<A, false, true>, _Mu<A, true, false>):
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<R>): 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
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 24 | ||||
-rw-r--r-- | libstdc++-v3/include/std/functional | 168 | ||||
-rw-r--r-- | libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc | 13 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/bind/68912.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/bind/cv_quals.cc | 8 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/bind/cv_quals_2.cc | 2 |
6 files changed, 119 insertions, 98 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7a3fdaf2..2ce5932 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,29 @@ 2016-10-14 Jonathan Wakely <jwakely@redhat.com> + * include/std/functional (_Mu<A, false, true>, _Mu<A, true, false>): + 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<R>): 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. + * include/std/scoped_allocator (scoped_allocator_adaptor): Forward piecewise construction arguments as tuples of references, to avoid copies (related to LWG 2511). 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<typename _Tp> - 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<typename _Tp, typename _Class> - 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<void>() is called, because argument deduction instantiates - // _Maybe_wrap_member_pointer<void> outside the immediate context where - // SFINAE applies. - template<> - struct _Maybe_wrap_member_pointer<void> - { - typedef void type; - }; - // std::get<I> for volatile-qualified tuples template<std::size_t _Ind, typename... _Tp> 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<typename _BoundArg, typename _CallArgs> + using _Mu_type = decltype( + _Mu<typename remove_cv<_BoundArg>::type>()( + std::declval<_BoundArg&>(), std::declval<_CallArgs&>()) ); + + template<typename _Fn, typename _CallArgs, typename... _BArgs> + using _Res_type_impl + = typename result_of< _Fn&(_Mu_type<_BArgs, _CallArgs>...) >::type; + + template<typename _CallArgs> + using _Res_type = _Res_type_impl<_Functor, _CallArgs, _Bound_args...>; + + template<typename _CallArgs> + using __dependent = typename + enable_if<bool(tuple_size<_CallArgs>::value+1), _Functor>::type; + + template<typename _CallArgs, template<class> 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<typename... _Args> explicit _Bind(const _Functor& __f, _Args&&... __args) @@ -909,10 +889,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) { } // Call unqualified - template<typename... _Args, typename _Result - = decltype( std::declval<_Functor&>()( - _Mu<_Bound_args>()( std::declval<_Bound_args&>(), - std::declval<tuple<_Args...>&>() )... ) )> + template<typename... _Args, + typename _Result = _Res_type<tuple<_Args...>>> _Result operator()(_Args&&... __args) { @@ -922,11 +900,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) } // Call as const - template<typename... _Args, typename _Result - = decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0), - typename add_const<_Functor>::type&>::type>()( - _Mu<_Bound_args>()( std::declval<const _Bound_args&>(), - std::declval<tuple<_Args...>&>() )... ) )> + template<typename... _Args, + typename _Result = _Res_type_cv<tuple<_Args...>, 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<typename... _Args, typename _Result - = decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0), - typename add_volatile<_Functor>::type&>::type>()( - _Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(), - std::declval<tuple<_Args...>&>() )... ) )> + template<typename... _Args, + typename _Result = _Res_type_cv<tuple<_Args...>, 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<typename... _Args, typename _Result - = decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0), - typename add_cv<_Functor>::type&>::type>()( - _Mu<_Bound_args>()( std::declval<const volatile _Bound_args&>(), - std::declval<tuple<_Args...>&>() )... ) )> + template<typename... _Args, + typename _Result = _Res_type_cv<tuple<_Args...>, 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<typename... _Args> + _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<typename... _Args> + _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<typename decay<_Func>::type, _BoundArgs...> { - typedef _Maybe_wrap_member_pointer<typename decay<_Func>::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<false, _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)...); } template<typename _Result, typename _Func, typename... _BoundArgs> struct _Bindres_helper : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...> { - typedef _Maybe_wrap_member_pointer<typename decay<_Func>::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)...); } /** diff --git a/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc b/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc index 5ca2da8..066b08b 100644 --- a/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc +++ b/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc @@ -116,6 +116,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Replaced with inline definition in gcc-4.8.0 __future_base::_Async_state_common::~_Async_state_common() { _M_join(); } + template<typename _Tp> + struct _Maybe_wrap_member_pointer; + + template<typename _Tp, typename _Class> + struct _Maybe_wrap_member_pointer<_Tp _Class::*> + { + typedef _Mem_fn<_Tp _Class::*> type; + + static constexpr type + __do_wrap(_Tp _Class::* __pm) + { return type(__pm); } + }; + template<typename _Signature> struct _Bind_simple; diff --git a/libstdc++-v3/testsuite/20_util/bind/68912.cc b/libstdc++-v3/testsuite/20_util/bind/68912.cc index 7d19141..a32b44b 100644 --- a/libstdc++-v3/testsuite/20_util/bind/68912.cc +++ b/libstdc++-v3/testsuite/20_util/bind/68912.cc @@ -45,8 +45,10 @@ void test01() A res = bound(1.0); const auto bound_c = bound; B res_c = bound_c(1.0); +#if __cplusplus <= 201402L volatile auto bound_v = bound; C res_v = bound_v(1.0); volatile const auto bound_cv = bound; D res_cv = bound_cv(1.0); +#endif } diff --git a/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc b/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc index ebf654f..5165f87 100644 --- a/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc +++ b/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc @@ -48,11 +48,13 @@ void test01() const auto b1 = std::bind(X()); VERIFY( b1() == 1 ); +#if __cplusplus <= 201402L volatile auto b2 = std::bind(X()); VERIFY( b2() == 2 ); const volatile auto b3 = std::bind(X()); VERIFY( b3() == 3 ); +#endif } void test02() @@ -63,11 +65,13 @@ void test02() const auto b1 = std::bind<int>(X()); VERIFY( b1() == 1 ); +#if __cplusplus <= 201402L volatile auto b2 = std::bind<int>(X()); VERIFY( b2() == 2 ); const volatile auto b3 = std::bind<int>(X()); VERIFY( b3() == 3 ); +#endif } void test03() @@ -78,11 +82,13 @@ void test03() const auto b1 = std::bind(X(), _1, 0, _2); VERIFY( b1(0, 0) == 1 ); +#if __cplusplus <= 201402L volatile auto b2 = std::bind(X(), _1, _2, 0); VERIFY( b2(0, 0) == 2 ); const volatile auto b3 = std::bind(X(), _1, 0, _2); VERIFY( b3(0, 0) == 3 ); +#endif } void test04() @@ -93,11 +99,13 @@ void test04() const auto b1 = std::bind<int>(X(), _1, 0, _2); VERIFY( b1(0, 0) == 1 ); +#if __cplusplus <= 201402L volatile auto b2 = std::bind<int>(X(), _1, _2, 0); VERIFY( b2(0, 0) == 2 ); const volatile auto b3 = std::bind<int>(X(), _1, 0, _2); VERIFY( b3(0, 0) == 3 ); +#endif } diff --git a/libstdc++-v3/testsuite/20_util/bind/cv_quals_2.cc b/libstdc++-v3/testsuite/20_util/bind/cv_quals_2.cc index 9252285..cd9b204 100644 --- a/libstdc++-v3/testsuite/20_util/bind/cv_quals_2.cc +++ b/libstdc++-v3/testsuite/20_util/bind/cv_quals_2.cc @@ -33,11 +33,13 @@ void test01() const auto b0 = std::bind(X()); VERIFY( b0() == 0 ); +#if __cplusplus <= 201402L volatile auto b1 = std::bind(X()); VERIFY( b1() == 1 ); const volatile auto b2 = std::bind(X()); VERIFY( b2() == 2 ); +#endif } int main() |