forked from OSchip/llvm-project
Cleanup C++03 __invoke for Bullets 3 and 4.
The key changes in this patch are: 1. Remove the zero-argument overload in mem_fn. A member function must always be invoked with at least one argument, the class instance. The zero-argument operator()() in mem_fn would cause mem_fn to fail to compile when because the call to '__invoke(pm)' is not well formed. 2. Prevent evaluation of '__apply_cv<Tp, Ret>' when 'Ret' is a function type. 'Ret' is a function type whenever 'Ret Tp::*' is a pointer to member function. Attempting to add cv and ref qualifiers to a function type can cause a hard compile error. 3. Remove the dummy overload __invoke(Rp Tp::*). It was present to help work around #1. It will be replaced with a different '__invoke' overload that represents a bad call to invoke. After applying this patch the test func.wrap.func.inv/invoke.pass.cpp now passes. llvm-svn: 243370
This commit is contained in:
parent
d29116331d
commit
e62bda70aa
|
@ -408,20 +408,15 @@ template <class _Rp, class _Tp, class _T1>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
typename enable_if
|
typename enable_if
|
||||||
<
|
<
|
||||||
|
is_member_object_pointer<_Rp _Tp::*>::value &&
|
||||||
is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
|
is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
|
||||||
typename __apply_cv<_T1, _Rp>::type&
|
__apply_cv<_T1, _Rp>
|
||||||
>::type
|
>::type::type&
|
||||||
__invoke(_Rp _Tp::* __f, _T1& __t1)
|
__invoke(_Rp _Tp::* __f, _T1& __t1)
|
||||||
{
|
{
|
||||||
return __t1.*__f;
|
return __t1.*__f;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Rp, class _Tp>
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
|
||||||
void
|
|
||||||
__invoke(_Rp _Tp::*)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// forth bullet
|
// forth bullet
|
||||||
|
|
||||||
|
@ -439,10 +434,9 @@ struct __4th_helper<_T1, _Rp, true>
|
||||||
template <class _Rp, class _Tp, class _T1>
|
template <class _Rp, class _Tp, class _T1>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
typename __4th_helper<_T1, _Rp,
|
typename __4th_helper<_T1, _Rp,
|
||||||
!is_base_of<_Tp,
|
is_member_object_pointer<_Rp _Tp::*>::value &&
|
||||||
typename remove_reference<_T1>::type
|
!is_base_of<_Tp, typename remove_reference<_T1>::type>::value
|
||||||
>::value
|
>::type&
|
||||||
>::type&
|
|
||||||
__invoke(_Rp _Tp::* __f, _T1& __t1)
|
__invoke(_Rp _Tp::* __f, _T1& __t1)
|
||||||
{
|
{
|
||||||
return (*__t1).*__f;
|
return (*__t1).*__f;
|
||||||
|
@ -494,20 +488,20 @@ struct __invoke_return<_Fp, false>
|
||||||
typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;
|
typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Tp, class _A0>
|
template <class _Tp, class _A0, bool = is_member_object_pointer<_Tp>::value>
|
||||||
struct __invoke_return0
|
struct __invoke_return0
|
||||||
{
|
{
|
||||||
typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;
|
typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Rp, class _Tp, class _A0>
|
template <class _Rp, class _Tp, class _A0>
|
||||||
struct __invoke_return0<_Rp _Tp::*, _A0>
|
struct __invoke_return0<_Rp _Tp::*, _A0, true>
|
||||||
{
|
{
|
||||||
typedef typename __apply_cv<_A0, _Rp>::type& type;
|
typedef typename __apply_cv<_A0, _Rp>::type& type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Rp, class _Tp, class _A0>
|
template <class _Rp, class _Tp, class _A0>
|
||||||
struct __invoke_return0<_Rp _Tp::*, _A0*>
|
struct __invoke_return0<_Rp _Tp::*, _A0*, true>
|
||||||
{
|
{
|
||||||
typedef typename __apply_cv<_A0, _Rp>::type& type;
|
typedef typename __apply_cv<_A0, _Rp>::type& type;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1260,10 +1260,6 @@ public:
|
||||||
return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
|
return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
typename __invoke_return<type>::type
|
|
||||||
operator() () const {
|
|
||||||
return __invoke(__f_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class _A0>
|
template <class _A0>
|
||||||
typename __invoke_return0<type, _A0>::type
|
typename __invoke_return0<type, _A0>::type
|
||||||
|
|
Loading…
Reference in New Issue