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

@@ -271,89 +271,185 @@ private:
ArgType a0, a1, a2;
//==========================================================================
// BULLET 1 AND 2 TEST METHODS
// BULLET 1, 2 AND 3 TEST METHODS
//==========================================================================
template <class MethodPtr, class ObjectT>
void runTestImp(Int<0>, MethodPtr ptr, ObjectT& object) {
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object));
assert(ID::checkCalled(ret));
{
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(ptr, object_cast(object)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(ptr, object_cast(object));
assert(ID::checkCalled(ret));
}
#endif
}
template <class MethodPtr, class ObjectT>
void runTestImp(Int<1>, MethodPtr ptr, ObjectT& object) {
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0));
assert(ID::checkCalled(ret));
{
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0));
assert(ID::checkCalled(ret));
}
#endif
}
template <class MethodPtr, class ObjectT>
void runTestImp(Int<2>, MethodPtr ptr, ObjectT& object) {
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1));
assert(ID::checkCalled(ret));
{
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1));
assert(ID::checkCalled(ret));
}
#endif
}
template <class MethodPtr, class ObjectT>
void runTestImp(Int<3>, MethodPtr ptr, ObjectT& object) {
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
assert(ID::checkCalled(ret));
{
static_assert((std::is_same<
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
assert(ID::checkCalled(ret));
}
#endif
}
//==========================================================================
// BULLET 5 TEST METHODS
// BULLET 7 TEST METHODS
//==========================================================================
template <class ObjectT>
void runTestImp(Int<0>, ObjectT& object) {
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object));
assert(ID::checkCalled(ret));
{
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(object_cast(object)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(object_cast(object));
assert(ID::checkCalled(ret));
}
#endif
}
template <class ObjectT>
void runTestImp(Int<1>, ObjectT& object) {
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object), arg_cast(a0)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0));
assert(ID::checkCalled(ret));
{
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object), arg_cast(a0)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0));
assert(ID::checkCalled(ret));
}
#endif
}
template <class ObjectT>
void runTestImp(Int<2>, ObjectT& object) {
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1));
assert(ID::checkCalled(ret));
{
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1));
assert(ID::checkCalled(ret));
}
#endif
}
template <class ObjectT>
void runTestImp(Int<3>, ObjectT& object) {
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
assert(ID::checkCalled(ret));
{
static_assert((std::is_same<
decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
assert(ID::checkCalled(ret));
}
#if TEST_STD_VER >= 11
{
static_assert((std::is_same<
decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
, CallRet>::value), "");
assert(ID::unchecked_call == false);
CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
assert(ID::checkCalled(ret));
}
#endif
}
};