Add 'is_callable' and 'is_nothrow_callable' traits and cleanup INVOKE.

The primary purpose of this patch is to add the 'is_callable' traits.
Since 'is_nothrow_callable' required making 'INVOKE' conditionally noexcept
I also took this oppertunity to implement a constexpr version of INVOKE.
This fixes 'std::experimental::apply' which required constexpr 'INVOKE support'.

This patch will be followed up with some cleanup. Primarly removing most
of "__member_function_traits" since it's no longer used by INVOKE (in C++11 at least).


git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@266836 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2016-04-20 00:14:32 +00:00
parent 9c6f00d616
commit 8d5cbd7ce2
15 changed files with 732 additions and 237 deletions

View File

@@ -306,97 +306,19 @@ struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
#endif // _LIBCPP_HAS_NO_VARIADICS
// __invoke
#ifndef _LIBCPP_CXX03_LANG
#ifndef _LIBCPP_HAS_NO_VARIADICS
// bullets 1 and 2
template <class _Fp, class _A0, class ..._Args,
class>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
-> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...))
{
return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...);
}
template <class _Fp, class _A0, class ..._Args,
class>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
-> decltype((__a0.get().*__f)(_VSTD::forward<_Args>(__args)...))
{
return (__a0.get().*__f)(_VSTD::forward<_Args>(__args)...);
}
template <class _Fp, class _A0, class ..._Args,
class>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
-> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...))
{
return ((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...);
}
// bullets 3 and 4
template <class _Fp, class _A0,
class>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _A0&& __a0)
-> decltype(_VSTD::forward<_A0>(__a0).*__f)
{
return _VSTD::forward<_A0>(__a0).*__f;
}
template <class _Fp, class _A0,
class>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _A0&& __a0)
-> decltype(__a0.get().*__f)
{
return __a0.get().*__f;
}
template <class _Fp, class _A0,
class>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _A0&& __a0)
-> decltype((*_VSTD::forward<_A0>(__a0)).*__f)
{
return (*_VSTD::forward<_A0>(__a0)).*__f;
}
// bullet 5
template <class _Fp, class ..._Args>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _Args&& ...__args)
-> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...))
{
return _VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...);
}
template <class _Tp, class ..._Args>
struct __invoke_return
{
typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type;
};
#else // _LIBCPP_HAS_NO_VARIADICS
#else // defined(_LIBCPP_CXX03_LANG)
#include <__functional_base_03>
#endif // _LIBCPP_HAS_NO_VARIADICS
#endif // !defined(_LIBCPP_CXX03_LANG)
template <class _Ret>