is_invocable.pass.cpp (6375B)
1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03, c++11, c++14 11 12 // type_traits 13 14 // is_invocable 15 16 // Most testing of is_invocable is done within the [meta.trans.other] result_of 17 // tests. 18 19 #include <type_traits> 20 #include <functional> 21 #include <memory> 22 23 #include "test_macros.h" 24 25 struct Tag {}; 26 struct DerFromTag : Tag {}; 27 28 struct Implicit { 29 Implicit(int) {} 30 }; 31 32 struct Explicit { 33 explicit Explicit(int) {} 34 }; 35 36 struct NotCallableWithInt { 37 int operator()(int) = delete; 38 int operator()(Tag) { return 42; } 39 }; 40 41 int main() 42 { 43 { 44 using Fn = int(Tag::*)(int); 45 using RFn = int(Tag::*)(int) &&; 46 // INVOKE bullet 1, 2 and 3 47 { 48 // Bullet 1 49 static_assert(std::is_invocable<Fn, Tag&, int>::value, ""); 50 static_assert(std::is_invocable<Fn, DerFromTag&, int>::value, ""); 51 static_assert(std::is_invocable<RFn, Tag&&, int>::value, ""); 52 static_assert(!std::is_invocable<RFn, Tag&, int>::value, ""); 53 static_assert(!std::is_invocable<Fn, Tag&>::value, ""); 54 static_assert(!std::is_invocable<Fn, Tag const&, int>::value, ""); 55 } 56 { 57 // Bullet 2 58 using T = std::reference_wrapper<Tag>; 59 using DT = std::reference_wrapper<DerFromTag>; 60 using CT = std::reference_wrapper<const Tag>; 61 static_assert(std::is_invocable<Fn, T&, int>::value, ""); 62 static_assert(std::is_invocable<Fn, DT&, int>::value, ""); 63 static_assert(std::is_invocable<Fn, const T&, int>::value, ""); 64 static_assert(std::is_invocable<Fn, T&&, int>::value, ""); 65 static_assert(!std::is_invocable<Fn, CT&, int>::value, ""); 66 static_assert(!std::is_invocable<RFn, T, int>::value, ""); 67 } 68 { 69 // Bullet 3 70 using T = Tag*; 71 using DT = DerFromTag*; 72 using CT = const Tag*; 73 using ST = std::unique_ptr<Tag>; 74 static_assert(std::is_invocable<Fn, T&, int>::value, ""); 75 static_assert(std::is_invocable<Fn, DT&, int>::value, ""); 76 static_assert(std::is_invocable<Fn, const T&, int>::value, ""); 77 static_assert(std::is_invocable<Fn, T&&, int>::value, ""); 78 static_assert(std::is_invocable<Fn, ST, int>::value, ""); 79 static_assert(!std::is_invocable<Fn, CT&, int>::value, ""); 80 static_assert(!std::is_invocable<RFn, T, int>::value, ""); 81 } 82 } 83 { 84 // Bullets 4, 5 and 6 85 using Fn = int (Tag::*); 86 static_assert(!std::is_invocable<Fn>::value, ""); 87 { 88 // Bullet 4 89 static_assert(std::is_invocable<Fn, Tag&>::value, ""); 90 static_assert(std::is_invocable<Fn, DerFromTag&>::value, ""); 91 static_assert(std::is_invocable<Fn, Tag&&>::value, ""); 92 static_assert(std::is_invocable<Fn, Tag const&>::value, ""); 93 } 94 { 95 // Bullet 5 96 using T = std::reference_wrapper<Tag>; 97 using DT = std::reference_wrapper<DerFromTag>; 98 using CT = std::reference_wrapper<const Tag>; 99 static_assert(std::is_invocable<Fn, T&>::value, ""); 100 static_assert(std::is_invocable<Fn, DT&>::value, ""); 101 static_assert(std::is_invocable<Fn, const T&>::value, ""); 102 static_assert(std::is_invocable<Fn, T&&>::value, ""); 103 static_assert(std::is_invocable<Fn, CT&>::value, ""); 104 } 105 { 106 // Bullet 6 107 using T = Tag*; 108 using DT = DerFromTag*; 109 using CT = const Tag*; 110 using ST = std::unique_ptr<Tag>; 111 static_assert(std::is_invocable<Fn, T&>::value, ""); 112 static_assert(std::is_invocable<Fn, DT&>::value, ""); 113 static_assert(std::is_invocable<Fn, const T&>::value, ""); 114 static_assert(std::is_invocable<Fn, T&&>::value, ""); 115 static_assert(std::is_invocable<Fn, ST>::value, ""); 116 static_assert(std::is_invocable<Fn, CT&>::value, ""); 117 } 118 } 119 { 120 // INVOKE bullet 7 121 { 122 // Function pointer 123 using Fp = void(*)(Tag&, int); 124 static_assert(std::is_invocable<Fp, Tag&, int>::value, ""); 125 static_assert(std::is_invocable<Fp, DerFromTag&, int>::value, ""); 126 static_assert(!std::is_invocable<Fp, const Tag&, int>::value, ""); 127 static_assert(!std::is_invocable<Fp>::value, ""); 128 static_assert(!std::is_invocable<Fp, Tag&>::value, ""); 129 } 130 { 131 // Function reference 132 using Fp = void(&)(Tag&, int); 133 static_assert(std::is_invocable<Fp, Tag&, int>::value, ""); 134 static_assert(std::is_invocable<Fp, DerFromTag&, int>::value, ""); 135 static_assert(!std::is_invocable<Fp, const Tag&, int>::value, ""); 136 static_assert(!std::is_invocable<Fp>::value, ""); 137 static_assert(!std::is_invocable<Fp, Tag&>::value, ""); 138 } 139 { 140 // Function object 141 using Fn = NotCallableWithInt; 142 static_assert(std::is_invocable<Fn, Tag>::value, ""); 143 static_assert(!std::is_invocable<Fn, int>::value, ""); 144 } 145 } 146 { 147 // Check that the conversion to the return type is properly checked 148 using Fn = int(*)(); 149 static_assert(std::is_invocable_r<Implicit, Fn>::value, ""); 150 static_assert(std::is_invocable_r<double, Fn>::value, ""); 151 static_assert(std::is_invocable_r<const volatile void, Fn>::value, ""); 152 static_assert(!std::is_invocable_r<Explicit, Fn>::value, ""); 153 } 154 { 155 // Check for is_invocable_v 156 using Fn = void(*)(); 157 static_assert(std::is_invocable_v<Fn>, ""); 158 static_assert(!std::is_invocable_v<Fn, int>, ""); 159 } 160 { 161 // Check for is_invocable_r_v 162 using Fn = void(*)(); 163 static_assert(std::is_invocable_r_v<void, Fn>, ""); 164 static_assert(!std::is_invocable_r_v<int, Fn>, ""); 165 } 166 }