This is a simplified (and superior) implementation of __invoke, __invokable and __invoke_of. It is superior in that __invoke now handles reference qualified member functions whereas the previous implementation did not. And it simply has less infrastructure in its implementation. I'm still learning how to program in C++11 (and probably will be for a long time). This change does not impact the behavior we're seeing in http://llvm.org/bugs/show_bug.cgi?id=9975
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@131761 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0148a838d0
commit
bd89e4b0dd
@ -281,169 +281,55 @@ struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) const volatile>
|
||||
|
||||
// __invoke
|
||||
|
||||
// first bullet
|
||||
// bullets 1 and 2
|
||||
|
||||
template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
|
||||
template <class _F, class _A0, class ..._Args>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
sizeof...(_Param) == sizeof...(_Arg) &&
|
||||
is_base_of<_T, typename remove_reference<_T1>::type>::value,
|
||||
_R
|
||||
>::type
|
||||
__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg)
|
||||
auto
|
||||
__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
-> decltype((_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...))
|
||||
{
|
||||
return (_STD::forward<_T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
|
||||
return (_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
|
||||
template <class _F, class _A0, class ..._Args>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
sizeof...(_Param) == sizeof...(_Arg) &&
|
||||
is_base_of<_T, typename remove_reference<_T1>::type>::value,
|
||||
_R
|
||||
>::type
|
||||
__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg)
|
||||
auto
|
||||
__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
-> decltype(((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...))
|
||||
{
|
||||
return (_STD::forward<const _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
|
||||
return ((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
|
||||
// bullets 3 and 4
|
||||
|
||||
template <class _F, class _A0>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
sizeof...(_Param) == sizeof...(_Arg) &&
|
||||
is_base_of<_T, typename remove_reference<_T1>::type>::value,
|
||||
_R
|
||||
>::type
|
||||
__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg)
|
||||
auto
|
||||
__invoke(_F&& __f, _A0&& __a0)
|
||||
-> decltype(_STD::forward<_A0>(__a0).*__f)
|
||||
{
|
||||
return (_STD::forward<volatile _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
|
||||
return _STD::forward<_A0>(__a0).*__f;
|
||||
}
|
||||
|
||||
template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
|
||||
template <class _F, class _A0>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
sizeof...(_Param) == sizeof...(_Arg) &&
|
||||
is_base_of<_T, typename remove_reference<_T1>::type>::value,
|
||||
_R
|
||||
>::type
|
||||
__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg)
|
||||
auto
|
||||
__invoke(_F&& __f, _A0&& __a0)
|
||||
-> decltype((*_STD::forward<_A0>(__a0)).*__f)
|
||||
{
|
||||
return (_STD::forward<const volatile _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
|
||||
return (*_STD::forward<_A0>(__a0)).*__f;
|
||||
}
|
||||
|
||||
// second bullet
|
||||
// bullet 5
|
||||
|
||||
template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
|
||||
template <class _F, class ..._Args>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
sizeof...(_Param) == sizeof...(_Arg) &&
|
||||
!is_base_of<_T, typename remove_reference<_T1>::type>::value,
|
||||
_R
|
||||
>::type
|
||||
__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg)
|
||||
auto
|
||||
__invoke(_F&& __f, _Args&& ...__args)
|
||||
-> decltype(_STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...))
|
||||
{
|
||||
return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
|
||||
}
|
||||
|
||||
template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
sizeof...(_Param) == sizeof...(_Arg) &&
|
||||
!is_base_of<_T, typename remove_reference<_T1>::type>::value,
|
||||
_R
|
||||
>::type
|
||||
__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg)
|
||||
{
|
||||
return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
|
||||
}
|
||||
|
||||
template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
sizeof...(_Param) == sizeof...(_Arg) &&
|
||||
!is_base_of<_T, typename remove_reference<_T1>::type>::value,
|
||||
_R
|
||||
>::type
|
||||
__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg)
|
||||
{
|
||||
return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
|
||||
}
|
||||
|
||||
template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
sizeof...(_Param) == sizeof...(_Arg) &&
|
||||
!is_base_of<_T, typename remove_reference<_T1>::type>::value,
|
||||
_R
|
||||
>::type
|
||||
__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg)
|
||||
{
|
||||
return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
|
||||
}
|
||||
|
||||
// third bullet
|
||||
|
||||
template <class _R, class _T, class _T1>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
is_base_of<_T, typename remove_reference<_T1>::type>::value,
|
||||
typename __apply_cv<_T1, _R>::type&&
|
||||
>::type
|
||||
__invoke(_R _T::* __f, _T1&& __t1)
|
||||
{
|
||||
return _STD::forward<_T1>(__t1).*__f;
|
||||
}
|
||||
|
||||
// forth bullet
|
||||
|
||||
template <class _T1, class _R, bool>
|
||||
struct __4th_helper
|
||||
{
|
||||
};
|
||||
|
||||
template <class _T1, class _R>
|
||||
struct __4th_helper<_T1, _R, true>
|
||||
{
|
||||
typedef typename __apply_cv<decltype(*_STD::declval<_T1>()), _R>::type type;
|
||||
};
|
||||
|
||||
template <class _R, class _T, class _T1>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename __4th_helper<_T1, _R,
|
||||
!is_base_of<_T,
|
||||
typename remove_reference<_T1>::type
|
||||
>::value
|
||||
>::type&&
|
||||
__invoke(_R _T::* __f, _T1&& __t1)
|
||||
{
|
||||
return (*_STD::forward<_T1>(__t1)).*__f;
|
||||
}
|
||||
|
||||
// fifth bullet
|
||||
|
||||
template <class _R, class ..._Param, class ..._Args>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_R
|
||||
__invoke(_R (*__f)(_Param...), _Args&& ...__args)
|
||||
{
|
||||
return __f(_STD::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
template <class _F, class ..._T>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename __invoke_of<_F, _T...>::type
|
||||
__invoke(_F&& __f, _T&& ...__t)
|
||||
{
|
||||
return _STD::forward<_F>(__f)(_STD::forward<_T>(__t)...);
|
||||
return _STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
template <class _Tp, class ..._Args>
|
||||
|
@ -2775,105 +2775,61 @@ template <class _Tp> struct _LIBCPP_VISIBLE is_trivial
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
|
||||
// __invokable
|
||||
// __invoke forward declarations
|
||||
|
||||
template <unsigned, class _F, class ..._Args>
|
||||
struct __invokable_imp
|
||||
: false_type
|
||||
{
|
||||
};
|
||||
|
||||
// __invokable member function pointer
|
||||
|
||||
template <class _A0, class _F, class ..._Args>
|
||||
auto
|
||||
__invokable_mfp_test(_A0&& __a0, _F __f, _Args&& ...__args)
|
||||
-> decltype((_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...));
|
||||
|
||||
template <class _A0, class _F, class ..._Args>
|
||||
auto
|
||||
__invokable_mfp_test(_A0&& __a0, _F __f, _Args&& ...__args)
|
||||
-> decltype(((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...));
|
||||
|
||||
template <class _F, class ..._Args>
|
||||
auto
|
||||
__invokable_mfp_test(__any, _F __f, _Args&& ...__args)
|
||||
-> __nat;
|
||||
|
||||
template <class _F, class _A0, class ..._Args>
|
||||
struct __invokable_imp<2, _F, _A0, _Args...>
|
||||
{
|
||||
typedef decltype(
|
||||
__invokable_mfp_test(_STD::declval<_A0>(), _STD::declval<_F>(),
|
||||
_STD::declval<_Args>()...)
|
||||
) type;
|
||||
static const bool value = !is_same<type, __nat>::value;
|
||||
};
|
||||
|
||||
// __invokable member object pointer
|
||||
|
||||
template <class _A0, class _F>
|
||||
auto
|
||||
__invokable_mop_test(_A0&& __a0, _F __f)
|
||||
-> decltype(_STD::forward<_A0>(__a0).*__f);
|
||||
|
||||
template <class _A0, class _F>
|
||||
auto
|
||||
__invokable_mop_test(_A0&& __a0, _F __f)
|
||||
-> decltype((*_STD::forward<_A0>(__a0)).*__f);
|
||||
|
||||
template <class _F>
|
||||
auto
|
||||
__invokable_mop_test(__any, _F __f)
|
||||
-> __nat;
|
||||
|
||||
template <class _F, class _A0>
|
||||
struct __invokable_imp<1, _F, _A0>
|
||||
{
|
||||
typedef decltype(
|
||||
__invokable_mop_test(_STD::declval<_A0>(), _STD::declval<_F>())
|
||||
) type;
|
||||
static const bool value = !is_same<type, __nat>::value;
|
||||
};
|
||||
|
||||
// __invokable other
|
||||
|
||||
template <class _F, class ..._Args>
|
||||
auto
|
||||
__invokable_other_test(_F&& __f, _Args&& ...__args)
|
||||
-> decltype(_STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...));
|
||||
// fall back - none of the bullets
|
||||
|
||||
template <class ..._Args>
|
||||
auto
|
||||
__invokable_other_test(__any, _Args&& ...__args)
|
||||
__invoke(__any, _Args&& ...__args)
|
||||
-> __nat;
|
||||
|
||||
// bullets 1 and 2
|
||||
|
||||
template <class _F, class _A0, class ..._Args>
|
||||
auto
|
||||
__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
-> decltype((_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...));
|
||||
|
||||
template <class _F, class _A0, class ..._Args>
|
||||
auto
|
||||
__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
-> decltype(((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...));
|
||||
|
||||
// bullets 3 and 4
|
||||
|
||||
template <class _F, class _A0>
|
||||
auto
|
||||
__invoke(_F&& __f, _A0&& __a0)
|
||||
-> decltype(_STD::forward<_A0>(__a0).*__f);
|
||||
|
||||
template <class _F, class _A0>
|
||||
auto
|
||||
__invoke(_F&& __f, _A0&& __a0)
|
||||
-> decltype((*_STD::forward<_A0>(__a0)).*__f);
|
||||
|
||||
// bullet 5
|
||||
|
||||
template <class _F, class ..._Args>
|
||||
struct __invokable_imp<0, _F, _Args...>
|
||||
auto
|
||||
__invoke(_F&& __f, _Args&& ...__args)
|
||||
-> decltype(_STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...));
|
||||
|
||||
// __invokable
|
||||
|
||||
template <class _F, class ..._Args>
|
||||
struct __invokable_imp
|
||||
{
|
||||
typedef decltype(
|
||||
__invokable_other_test(_STD::declval<_F>(), _STD::declval<_Args>()...)
|
||||
__invoke(_STD::declval<_F>(), _STD::declval<_Args>()...)
|
||||
) type;
|
||||
static const bool value = !is_same<type, __nat>::value;
|
||||
};
|
||||
|
||||
// __invokable_classify
|
||||
|
||||
template <class _F>
|
||||
struct __invokable_classify
|
||||
{
|
||||
typedef typename remove_reference<_F>::type _FR;
|
||||
static const unsigned value = is_member_function_pointer<_FR>::value ?
|
||||
2 :
|
||||
is_member_object_pointer<_FR>::value ?
|
||||
1 :
|
||||
0;
|
||||
};
|
||||
|
||||
template <class _F, class ..._Args>
|
||||
struct __invokable
|
||||
: public integral_constant<bool,
|
||||
__invokable_imp<__invokable_classify<_F>::value, _F, _Args...>::value>
|
||||
__invokable_imp<_F, _Args...>::value>
|
||||
{
|
||||
};
|
||||
|
||||
@ -2887,7 +2843,7 @@ struct __invoke_of_imp // false
|
||||
template <class _F, class ..._Args>
|
||||
struct __invoke_of_imp<true, _F, _Args...>
|
||||
{
|
||||
typedef typename __invokable_imp<__invokable_classify<_F>::value, _F, _Args...>::type type;
|
||||
typedef typename __invokable_imp<_F, _Args...>::type type;
|
||||
};
|
||||
|
||||
template <class _F, class ..._Args>
|
||||
|
Loading…
x
Reference in New Issue
Block a user