Constrain __invoke functions more accurately. This fixes http://llvm.org/bugs/show_bug.cgi?id=15861 .
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@181377 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5f1286f574
commit
ecc9742f27
@ -292,7 +292,8 @@ struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
|
||||
|
||||
// bullets 1 and 2
|
||||
|
||||
template <class _Fp, class _A0, class ..._Args>
|
||||
template <class _Fp, class _A0, class ..._Args,
|
||||
class>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
auto
|
||||
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
@ -301,7 +302,8 @@ __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
template <class _Fp, class _A0, class ..._Args>
|
||||
template <class _Fp, class _A0, class ..._Args,
|
||||
class>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
auto
|
||||
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
@ -312,7 +314,8 @@ __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
|
||||
// bullets 3 and 4
|
||||
|
||||
template <class _Fp, class _A0>
|
||||
template <class _Fp, class _A0,
|
||||
class>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
auto
|
||||
__invoke(_Fp&& __f, _A0&& __a0)
|
||||
@ -321,7 +324,8 @@ __invoke(_Fp&& __f, _A0&& __a0)
|
||||
return _VSTD::forward<_A0>(__a0).*__f;
|
||||
}
|
||||
|
||||
template <class _Fp, class _A0>
|
||||
template <class _Fp, class _A0,
|
||||
class>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
auto
|
||||
__invoke(_Fp&& __f, _A0&& __a0)
|
||||
|
@ -2878,13 +2878,27 @@ __invoke(__any, _Args&& ...__args)
|
||||
|
||||
// bullets 1 and 2
|
||||
|
||||
template <class _Fp, class _A0, class ..._Args>
|
||||
template <class _Fp, class _A0, class ..._Args,
|
||||
class = typename enable_if
|
||||
<
|
||||
is_member_function_pointer<typename remove_reference<_Fp>::type>::value &&
|
||||
is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
|
||||
typename remove_reference<_A0>::type>::value
|
||||
>::type
|
||||
>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
auto
|
||||
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
-> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...));
|
||||
|
||||
template <class _Fp, class _A0, class ..._Args>
|
||||
template <class _Fp, class _A0, class ..._Args,
|
||||
class = typename enable_if
|
||||
<
|
||||
is_member_function_pointer<typename remove_reference<_Fp>::type>::value &&
|
||||
!is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
|
||||
typename remove_reference<_A0>::type>::value
|
||||
>::type
|
||||
>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
auto
|
||||
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
@ -2892,13 +2906,27 @@ __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
|
||||
|
||||
// bullets 3 and 4
|
||||
|
||||
template <class _Fp, class _A0>
|
||||
template <class _Fp, class _A0,
|
||||
class = typename enable_if
|
||||
<
|
||||
is_member_object_pointer<typename remove_reference<_Fp>::type>::value &&
|
||||
is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
|
||||
typename remove_reference<_A0>::type>::value
|
||||
>::type
|
||||
>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
auto
|
||||
__invoke(_Fp&& __f, _A0&& __a0)
|
||||
-> decltype(_VSTD::forward<_A0>(__a0).*__f);
|
||||
|
||||
template <class _Fp, class _A0>
|
||||
template <class _Fp, class _A0,
|
||||
class = typename enable_if
|
||||
<
|
||||
is_member_object_pointer<typename remove_reference<_Fp>::type>::value &&
|
||||
!is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
|
||||
typename remove_reference<_A0>::type>::value
|
||||
>::type
|
||||
>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
auto
|
||||
__invoke(_Fp&& __f, _A0&& __a0)
|
||||
|
@ -28,6 +28,12 @@ struct S
|
||||
typedef void (S::*PMS)(long) const;
|
||||
typedef char S::*PMD;
|
||||
|
||||
struct wat
|
||||
{
|
||||
wat& operator*() { return *this; }
|
||||
void foo();
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
static_assert((std::is_same<std::result_of<S(int)>::type, short>::value), "Error!");
|
||||
@ -40,4 +46,5 @@ int main()
|
||||
static_assert((std::is_same<std::result_of<PMD(S)>::type, char&&>::value), "Error!");
|
||||
#endif
|
||||
static_assert((std::is_same<std::result_of<PMD(const S*)>::type, const char&>::value), "Error!");
|
||||
using type = std::result_of<decltype(&wat::foo)(wat)>::type;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user