//===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14 // type_traits // is_invocable // Most testing of is_invocable is done within the [meta.trans.other] result_of // tests. #include #include #include #include "test_macros.h" struct Tag {}; struct DerFromTag : Tag {}; struct Implicit { Implicit(int) {} }; struct Explicit { explicit Explicit(int) {} }; struct NotCallableWithInt { int operator()(int) = delete; int operator()(Tag) { return 42; } }; int main() { { using Fn = int(Tag::*)(int); using RFn = int(Tag::*)(int) &&; // INVOKE bullet 1, 2 and 3 { // Bullet 1 static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); } { // Bullet 2 using T = std::reference_wrapper; using DT = std::reference_wrapper; using CT = std::reference_wrapper; static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); } { // Bullet 3 using T = Tag*; using DT = DerFromTag*; using CT = const Tag*; using ST = std::unique_ptr; static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); } } { // Bullets 4, 5 and 6 using Fn = int (Tag::*); static_assert(!std::is_invocable::value, ""); { // Bullet 4 static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); } { // Bullet 5 using T = std::reference_wrapper; using DT = std::reference_wrapper; using CT = std::reference_wrapper; static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); } { // Bullet 6 using T = Tag*; using DT = DerFromTag*; using CT = const Tag*; using ST = std::unique_ptr; static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); } } { // INVOKE bullet 7 { // Function pointer using Fp = void(*)(Tag&, int); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); } { // Function reference using Fp = void(&)(Tag&, int); static_assert(std::is_invocable::value, ""); static_assert(std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); } { // Function object using Fn = NotCallableWithInt; static_assert(std::is_invocable::value, ""); static_assert(!std::is_invocable::value, ""); } } { // Check that the conversion to the return type is properly checked using Fn = int(*)(); static_assert(std::is_invocable_r::value, ""); static_assert(std::is_invocable_r::value, ""); static_assert(std::is_invocable_r::value, ""); static_assert(!std::is_invocable_r::value, ""); } { // Check for is_invocable_v using Fn = void(*)(); static_assert(std::is_invocable_v, ""); static_assert(!std::is_invocable_v, ""); } { // Check for is_invocable_r_v using Fn = void(*)(); static_assert(std::is_invocable_r_v, ""); static_assert(!std::is_invocable_r_v, ""); } }