Commit de1d0794 by Jonathan Wakely Committed by Jonathan Wakely

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
parent 064ed55a
2016-10-14 Jonathan Wakely <jwakely@redhat.com> 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 * include/std/scoped_allocator (scoped_allocator_adaptor): Forward
piecewise construction arguments as tuples of references, to avoid piecewise construction arguments as tuples of references, to avoid
copies (related to LWG 2511). copies (related to LWG 2511).
......
...@@ -742,7 +742,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -742,7 +742,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
const _Index_tuple<_Indexes...>&) const volatile const _Index_tuple<_Indexes...>&) const volatile
-> decltype(__arg(declval<_Args>()...)) -> 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) ...@@ -759,10 +759,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
_Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&& _Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&&
operator()(const volatile _Arg&, _Tuple& __tuple) const volatile operator()(const volatile _Arg&, _Tuple& __tuple) const volatile
{ {
using __type return
= __tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>; ::std::get<(is_placeholder<_Arg>::value - 1)>(std::move(__tuple));
return std::forward<__type>(
::std::get<(is_placeholder<_Arg>::value - 1)>(__tuple));
} }
}; };
...@@ -781,50 +779,6 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -781,50 +779,6 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
{ return std::forward<_CVArg>(__arg); } { 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 // std::get<I> for volatile-qualified tuples
template<std::size_t _Ind, typename... _Tp> template<std::size_t _Ind, typename... _Tp>
inline auto inline auto
...@@ -858,8 +812,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -858,8 +812,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
_Result _Result
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
{ {
return _M_f(_Mu<_Bound_args>() return std::__invoke(_M_f,
(std::get<_Indexes>(_M_bound_args), __args)...); _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)...
);
} }
// Call as const // Call as const
...@@ -867,8 +822,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -867,8 +822,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
_Result _Result
__call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const __call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
{ {
return _M_f(_Mu<_Bound_args>() return std::__invoke(_M_f,
(std::get<_Indexes>(_M_bound_args), __args)...); _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)...
);
} }
// Call as volatile // Call as volatile
...@@ -877,8 +833,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -877,8 +833,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
__call_v(tuple<_Args...>&& __args, __call_v(tuple<_Args...>&& __args,
_Index_tuple<_Indexes...>) volatile _Index_tuple<_Indexes...>) volatile
{ {
return _M_f(_Mu<_Bound_args>() return std::__invoke(_M_f,
(__volget<_Indexes>(_M_bound_args), __args)...); _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)...
);
} }
// Call as const volatile // Call as const volatile
...@@ -887,10 +844,33 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -887,10 +844,33 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
__call_c_v(tuple<_Args...>&& __args, __call_c_v(tuple<_Args...>&& __args,
_Index_tuple<_Indexes...>) const volatile _Index_tuple<_Indexes...>) const volatile
{ {
return _M_f(_Mu<_Bound_args>() return std::__invoke(_M_f,
(__volget<_Indexes>(_M_bound_args), __args)...); _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: public:
template<typename... _Args> template<typename... _Args>
explicit _Bind(const _Functor& __f, _Args&&... __args) explicit _Bind(const _Functor& __f, _Args&&... __args)
...@@ -909,10 +889,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -909,10 +889,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
{ } { }
// Call unqualified // Call unqualified
template<typename... _Args, typename _Result template<typename... _Args,
= decltype( std::declval<_Functor&>()( typename _Result = _Res_type<tuple<_Args...>>>
_Mu<_Bound_args>()( std::declval<_Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )>
_Result _Result
operator()(_Args&&... __args) operator()(_Args&&... __args)
{ {
...@@ -922,11 +900,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -922,11 +900,8 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
} }
// Call as const // Call as const
template<typename... _Args, typename _Result template<typename... _Args,
= decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0), typename _Result = _Res_type_cv<tuple<_Args...>, add_const>>
typename add_const<_Functor>::type&>::type>()(
_Mu<_Bound_args>()( std::declval<const _Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )>
_Result _Result
operator()(_Args&&... __args) const operator()(_Args&&... __args) const
{ {
...@@ -935,12 +910,16 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -935,12 +910,16 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
_Bound_indexes()); _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 // Call as volatile
template<typename... _Args, typename _Result template<typename... _Args,
= decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0), typename _Result = _Res_type_cv<tuple<_Args...>, add_volatile>>
typename add_volatile<_Functor>::type&>::type>()( _GLIBCXX_DEPR_BIND
_Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )>
_Result _Result
operator()(_Args&&... __args) volatile operator()(_Args&&... __args) volatile
{ {
...@@ -950,11 +929,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -950,11 +929,9 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
} }
// Call as const volatile // Call as const volatile
template<typename... _Args, typename _Result template<typename... _Args,
= decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0), typename _Result = _Res_type_cv<tuple<_Args...>, add_cv>>
typename add_cv<_Functor>::type&>::type>()( _GLIBCXX_DEPR_BIND
_Mu<_Bound_args>()( std::declval<const volatile _Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )>
_Result _Result
operator()(_Args&&... __args) const volatile operator()(_Args&&... __args) const volatile
{ {
...@@ -991,7 +968,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -991,7 +968,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
__disable_if_void<_Res> __disable_if_void<_Res>
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) __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)...); (std::get<_Indexes>(_M_bound_args), __args)...);
} }
...@@ -1000,7 +977,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1000,7 +977,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
__enable_if_void<_Res> __enable_if_void<_Res>
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) __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)...); (std::get<_Indexes>(_M_bound_args), __args)...);
} }
...@@ -1009,7 +986,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1009,7 +986,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
__disable_if_void<_Res> __disable_if_void<_Res>
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const __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)...); (std::get<_Indexes>(_M_bound_args), __args)...);
} }
...@@ -1018,7 +995,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1018,7 +995,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
__enable_if_void<_Res> __enable_if_void<_Res>
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const __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)...); (std::get<_Indexes>(_M_bound_args), __args)...);
} }
...@@ -1027,7 +1004,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1027,7 +1004,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
__disable_if_void<_Res> __disable_if_void<_Res>
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile __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)...); (__volget<_Indexes>(_M_bound_args), __args)...);
} }
...@@ -1036,7 +1013,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1036,7 +1013,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
__enable_if_void<_Res> __enable_if_void<_Res>
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile __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)...); (__volget<_Indexes>(_M_bound_args), __args)...);
} }
...@@ -1046,7 +1023,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1046,7 +1023,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
__call(tuple<_Args...>&& __args, __call(tuple<_Args...>&& __args,
_Index_tuple<_Indexes...>) const volatile _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)...); (__volget<_Indexes>(_M_bound_args), __args)...);
} }
...@@ -1056,7 +1033,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1056,7 +1033,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
__call(tuple<_Args...>&& __args, __call(tuple<_Args...>&& __args,
_Index_tuple<_Indexes...>) const volatile _Index_tuple<_Indexes...>) const volatile
{ {
_M_f(_Mu<_Bound_args>() std::__invoke(_M_f, _Mu<_Bound_args>()
(__volget<_Indexes>(_M_bound_args), __args)...); (__volget<_Indexes>(_M_bound_args), __args)...);
} }
...@@ -1101,6 +1078,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1101,6 +1078,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
// Call as volatile // Call as volatile
template<typename... _Args> template<typename... _Args>
_GLIBCXX_DEPR_BIND
result_type result_type
operator()(_Args&&... __args) volatile operator()(_Args&&... __args) volatile
{ {
...@@ -1111,6 +1089,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1111,6 +1089,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
// Call as const volatile // Call as const volatile
template<typename... _Args> template<typename... _Args>
_GLIBCXX_DEPR_BIND
result_type result_type
operator()(_Args&&... __args) const volatile operator()(_Args&&... __args) const volatile
{ {
...@@ -1119,6 +1098,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1119,6 +1098,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
_Bound_indexes()); _Bound_indexes());
} }
}; };
#undef _GLIBCXX_DEPR_BIND
/** /**
* @brief Class template _Bind is always a bind expression. * @brief Class template _Bind is always a bind expression.
...@@ -1222,9 +1202,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1222,9 +1202,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
struct _Bind_helper struct _Bind_helper
: _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...> : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...>
{ {
typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type> typedef typename decay<_Func>::type __func_type;
__maybe_type;
typedef typename __maybe_type::type __func_type;
typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type; typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type;
}; };
...@@ -1245,9 +1223,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1245,9 +1223,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
bind(_Func&& __f, _BoundArgs&&... __args) bind(_Func&& __f, _BoundArgs&&... __args)
{ {
typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type; typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type;
typedef typename __helper_type::__maybe_type __maybe_type; return typename __helper_type::type(std::forward<_Func>(__f),
typedef typename __helper_type::type __result_type;
return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)),
std::forward<_BoundArgs>(__args)...); std::forward<_BoundArgs>(__args)...);
} }
...@@ -1255,9 +1231,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1255,9 +1231,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
struct _Bindres_helper struct _Bindres_helper
: _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...> : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...>
{ {
typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type> typedef typename decay<_Func>::type __functor_type;
__maybe_type;
typedef typename __maybe_type::type __functor_type;
typedef _Bind_result<_Result, typedef _Bind_result<_Result,
__functor_type(typename decay<_BoundArgs>::type...)> __functor_type(typename decay<_BoundArgs>::type...)>
type; type;
...@@ -1273,9 +1247,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) ...@@ -1273,9 +1247,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
bind(_Func&& __f, _BoundArgs&&... __args) bind(_Func&& __f, _BoundArgs&&... __args)
{ {
typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type; typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type;
typedef typename __helper_type::__maybe_type __maybe_type; return typename __helper_type::type(std::forward<_Func>(__f),
typedef typename __helper_type::type __result_type;
return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)),
std::forward<_BoundArgs>(__args)...); std::forward<_BoundArgs>(__args)...);
} }
......
...@@ -116,6 +116,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -116,6 +116,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Replaced with inline definition in gcc-4.8.0 // Replaced with inline definition in gcc-4.8.0
__future_base::_Async_state_common::~_Async_state_common() { _M_join(); } __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> template<typename _Signature>
struct _Bind_simple; struct _Bind_simple;
......
...@@ -45,8 +45,10 @@ void test01() ...@@ -45,8 +45,10 @@ void test01()
A res = bound(1.0); A res = bound(1.0);
const auto bound_c = bound; const auto bound_c = bound;
B res_c = bound_c(1.0); B res_c = bound_c(1.0);
#if __cplusplus <= 201402L
volatile auto bound_v = bound; volatile auto bound_v = bound;
C res_v = bound_v(1.0); C res_v = bound_v(1.0);
volatile const auto bound_cv = bound; volatile const auto bound_cv = bound;
D res_cv = bound_cv(1.0); D res_cv = bound_cv(1.0);
#endif
} }
...@@ -48,11 +48,13 @@ void test01() ...@@ -48,11 +48,13 @@ void test01()
const auto b1 = std::bind(X()); const auto b1 = std::bind(X());
VERIFY( b1() == 1 ); VERIFY( b1() == 1 );
#if __cplusplus <= 201402L
volatile auto b2 = std::bind(X()); volatile auto b2 = std::bind(X());
VERIFY( b2() == 2 ); VERIFY( b2() == 2 );
const volatile auto b3 = std::bind(X()); const volatile auto b3 = std::bind(X());
VERIFY( b3() == 3 ); VERIFY( b3() == 3 );
#endif
} }
void test02() void test02()
...@@ -63,11 +65,13 @@ void test02() ...@@ -63,11 +65,13 @@ void test02()
const auto b1 = std::bind<int>(X()); const auto b1 = std::bind<int>(X());
VERIFY( b1() == 1 ); VERIFY( b1() == 1 );
#if __cplusplus <= 201402L
volatile auto b2 = std::bind<int>(X()); volatile auto b2 = std::bind<int>(X());
VERIFY( b2() == 2 ); VERIFY( b2() == 2 );
const volatile auto b3 = std::bind<int>(X()); const volatile auto b3 = std::bind<int>(X());
VERIFY( b3() == 3 ); VERIFY( b3() == 3 );
#endif
} }
void test03() void test03()
...@@ -78,11 +82,13 @@ void test03() ...@@ -78,11 +82,13 @@ void test03()
const auto b1 = std::bind(X(), _1, 0, _2); const auto b1 = std::bind(X(), _1, 0, _2);
VERIFY( b1(0, 0) == 1 ); VERIFY( b1(0, 0) == 1 );
#if __cplusplus <= 201402L
volatile auto b2 = std::bind(X(), _1, _2, 0); volatile auto b2 = std::bind(X(), _1, _2, 0);
VERIFY( b2(0, 0) == 2 ); VERIFY( b2(0, 0) == 2 );
const volatile auto b3 = std::bind(X(), _1, 0, _2); const volatile auto b3 = std::bind(X(), _1, 0, _2);
VERIFY( b3(0, 0) == 3 ); VERIFY( b3(0, 0) == 3 );
#endif
} }
void test04() void test04()
...@@ -93,11 +99,13 @@ void test04() ...@@ -93,11 +99,13 @@ void test04()
const auto b1 = std::bind<int>(X(), _1, 0, _2); const auto b1 = std::bind<int>(X(), _1, 0, _2);
VERIFY( b1(0, 0) == 1 ); VERIFY( b1(0, 0) == 1 );
#if __cplusplus <= 201402L
volatile auto b2 = std::bind<int>(X(), _1, _2, 0); volatile auto b2 = std::bind<int>(X(), _1, _2, 0);
VERIFY( b2(0, 0) == 2 ); VERIFY( b2(0, 0) == 2 );
const volatile auto b3 = std::bind<int>(X(), _1, 0, _2); const volatile auto b3 = std::bind<int>(X(), _1, 0, _2);
VERIFY( b3(0, 0) == 3 ); VERIFY( b3(0, 0) == 3 );
#endif
} }
......
...@@ -33,11 +33,13 @@ void test01() ...@@ -33,11 +33,13 @@ void test01()
const auto b0 = std::bind(X()); const auto b0 = std::bind(X());
VERIFY( b0() == 0 ); VERIFY( b0() == 0 );
#if __cplusplus <= 201402L
volatile auto b1 = std::bind(X()); volatile auto b1 = std::bind(X());
VERIFY( b1() == 1 ); VERIFY( b1() == 1 );
const volatile auto b2 = std::bind(X()); const volatile auto b2 = std::bind(X());
VERIFY( b2() == 2 ); VERIFY( b2() == 2 );
#endif
} }
int main() int main()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment