From 840fa745ca493123c44d7e9b62676f3a0cd23c0d Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Wed, 20 Apr 2016 00:14:32 +0000 Subject: 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). llvm-svn: 266836 --- .../func.require/bullet_1_2_3.pass.cpp | 3 + .../func.require/bullet_4_5_6.pass.cpp | 21 ++- .../function.objects/func.require/invoke_helpers.h | 196 +++++++++++++++------ 3 files changed, 165 insertions(+), 55 deletions(-) (limited to 'libcxx/test/std/utilities/function.objects/func.require') diff --git a/libcxx/test/std/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp b/libcxx/test/std/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp index 09e8e21137a..509c751b455 100644 --- a/libcxx/test/std/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp @@ -260,8 +260,11 @@ void test_derived_from_ref_wrap() { DerivedFromRefWrap d(x); auto get_fn = &std::reference_wrapper::get; auto& ret = std::__invoke(get_fn, r); + auto& cret = std::__invoke_constexpr(get_fn, r); assert(&ret == &x); + assert(&cret == &x); auto& ret2 = std::__invoke(get_fn, d); + auto& cret2 = std::__invoke_constexpr(get_fn, d); assert(&ret2 == &x); auto& ret3 = std::__invoke(get_fn, r2); assert(&ret3 == &x); diff --git a/libcxx/test/std/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp b/libcxx/test/std/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp index 2007c417a62..803c501f8c9 100644 --- a/libcxx/test/std/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp @@ -185,11 +185,22 @@ private: #else void runTest(Fn M, T& obj, ObjectType* expect ) { #endif - static_assert((std::is_same< - decltype(std::__invoke(M, std::forward(obj))), Expect - >::value), ""); - Expect e = std::__invoke(M, std::forward(obj)); - assert(&e == expect); + { + static_assert((std::is_same< + decltype(std::__invoke(M, std::forward(obj))), Expect + >::value), ""); + Expect e = std::__invoke(M, std::forward(obj)); + assert(&e == expect); + } +#if TEST_STD_VER >= 11 + { + static_assert((std::is_same< + decltype(std::__invoke_constexpr(M, std::forward(obj))), Expect + >::value), ""); + Expect e = std::__invoke_constexpr(M, std::forward(obj)); + assert(&e == expect); + } +#endif } }; diff --git a/libcxx/test/std/utilities/function.objects/func.require/invoke_helpers.h b/libcxx/test/std/utilities/function.objects/func.require/invoke_helpers.h index 495703d0e32..7e7a5fd24a6 100644 --- a/libcxx/test/std/utilities/function.objects/func.require/invoke_helpers.h +++ b/libcxx/test/std/utilities/function.objects/func.require/invoke_helpers.h @@ -271,89 +271,185 @@ private: ArgType a0, a1, a2; //========================================================================== - // BULLET 1 AND 2 TEST METHODS + // BULLET 1, 2 AND 3 TEST METHODS //========================================================================== template 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 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 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 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 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 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 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 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 } }; -- cgit v1.2.3