1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
15 // Most testing of is_invocable is done within the [meta.trans.other] result_of
18 // Fn and all types in the template parameter pack ArgTypes shall be
19 // complete types, cv void, or arrays of unknown bound.
24 #include <type_traits>
28 struct DerFromTag
: Tag
{};
35 explicit Explicit(int) {}
38 struct NotCallableWithInt
{
39 int operator()(int) = delete;
40 int operator()(Tag
) { return 42; }
44 template <class ...Args
>
45 void operator()(Args
&&...) const {}
48 int main(int, char**) {
49 using AbominableFunc
= void(...) const;
51 // Non-callable things
53 static_assert(!std::is_invocable
<void>::value
, "");
54 static_assert(!std::is_invocable
<const void>::value
, "");
55 static_assert(!std::is_invocable
<volatile void>::value
, "");
56 static_assert(!std::is_invocable
<const volatile void>::value
, "");
57 static_assert(!std::is_invocable
<std::nullptr_t
>::value
, "");
58 static_assert(!std::is_invocable
<int>::value
, "");
59 static_assert(!std::is_invocable
<double>::value
, "");
61 static_assert(!std::is_invocable
<int[]>::value
, "");
62 static_assert(!std::is_invocable
<int[3]>::value
, "");
64 static_assert(!std::is_invocable
<int*>::value
, "");
65 static_assert(!std::is_invocable
<const int*>::value
, "");
66 static_assert(!std::is_invocable
<int const*>::value
, "");
68 static_assert(!std::is_invocable
<int&>::value
, "");
69 static_assert(!std::is_invocable
<const int&>::value
, "");
70 static_assert(!std::is_invocable
<int&&>::value
, "");
72 static_assert(!std::is_invocable
<std::vector
<int> >::value
, "");
73 static_assert(!std::is_invocable
<std::vector
<int*> >::value
, "");
74 static_assert(!std::is_invocable
<std::vector
<int**> >::value
, "");
76 static_assert(!std::is_invocable
<AbominableFunc
>::value
, "");
79 static_assert(!std::is_invocable
<int, int>::value
, "");
80 static_assert(!std::is_invocable
<int, double, float>::value
, "");
81 static_assert(!std::is_invocable
<int, char, float, double>::value
, "");
82 static_assert(!std::is_invocable
<Sink
, AbominableFunc
>::value
, "");
83 static_assert(!std::is_invocable
<Sink
, void>::value
, "");
84 static_assert(!std::is_invocable
<Sink
, const volatile void>::value
,
88 static_assert(!std::is_invocable_r
<int, void>::value
, "");
89 static_assert(!std::is_invocable_r
<int, const void>::value
, "");
90 static_assert(!std::is_invocable_r
<int, volatile void>::value
, "");
91 static_assert(!std::is_invocable_r
<int, const volatile void>::value
, "");
92 static_assert(!std::is_invocable_r
<int, std::nullptr_t
>::value
, "");
93 static_assert(!std::is_invocable_r
<int, int>::value
, "");
94 static_assert(!std::is_invocable_r
<int, double>::value
, "");
96 static_assert(!std::is_invocable_r
<int, int[]>::value
, "");
97 static_assert(!std::is_invocable_r
<int, int[3]>::value
, "");
99 static_assert(!std::is_invocable_r
<int, int*>::value
, "");
100 static_assert(!std::is_invocable_r
<int, const int*>::value
, "");
101 static_assert(!std::is_invocable_r
<int, int const*>::value
, "");
103 static_assert(!std::is_invocable_r
<int, int&>::value
, "");
104 static_assert(!std::is_invocable_r
<int, const int&>::value
, "");
105 static_assert(!std::is_invocable_r
<int, int&&>::value
, "");
107 static_assert(!std::is_invocable_r
<int, std::vector
<int> >::value
, "");
108 static_assert(!std::is_invocable_r
<int, std::vector
<int*> >::value
, "");
109 static_assert(!std::is_invocable_r
<int, std::vector
<int**> >::value
, "");
110 static_assert(!std::is_invocable_r
<void, AbominableFunc
>::value
, "");
113 static_assert(!std::is_invocable_r
<int, int, int>::value
, "");
114 static_assert(!std::is_invocable_r
<int, int, double, float>::value
, "");
115 static_assert(!std::is_invocable_r
<int, int, char, float, double>::value
,
117 static_assert(!std::is_invocable_r
<void, Sink
, AbominableFunc
>::value
, "");
118 static_assert(!std::is_invocable_r
<void, Sink
, void>::value
, "");
119 static_assert(!std::is_invocable_r
<void, Sink
, const volatile void>::value
,
123 using Fn
= int (Tag::*)(int);
124 using RFn
= int (Tag::*)(int)&&;
125 // INVOKE bullet 1, 2 and 3
128 static_assert(std::is_invocable
<Fn
, Tag
&, int>::value
, "");
129 static_assert(std::is_invocable
<Fn
, DerFromTag
&, int>::value
, "");
130 static_assert(std::is_invocable
<RFn
, Tag
&&, int>::value
, "");
131 static_assert(!std::is_invocable
<RFn
, Tag
&, int>::value
, "");
132 static_assert(!std::is_invocable
<Fn
, Tag
&>::value
, "");
133 static_assert(!std::is_invocable
<Fn
, Tag
const&, int>::value
, "");
137 using T
= std::reference_wrapper
<Tag
>;
138 using DT
= std::reference_wrapper
<DerFromTag
>;
139 using CT
= std::reference_wrapper
<const Tag
>;
140 static_assert(std::is_invocable
<Fn
, T
&, int>::value
, "");
141 static_assert(std::is_invocable
<Fn
, DT
&, int>::value
, "");
142 static_assert(std::is_invocable
<Fn
, const T
&, int>::value
, "");
143 static_assert(std::is_invocable
<Fn
, T
&&, int>::value
, "");
144 static_assert(!std::is_invocable
<Fn
, CT
&, int>::value
, "");
145 static_assert(!std::is_invocable
<RFn
, T
, int>::value
, "");
150 using DT
= DerFromTag
*;
151 using CT
= const Tag
*;
152 using ST
= std::unique_ptr
<Tag
>;
153 static_assert(std::is_invocable
<Fn
, T
&, int>::value
, "");
154 static_assert(std::is_invocable
<Fn
, DT
&, int>::value
, "");
155 static_assert(std::is_invocable
<Fn
, const T
&, int>::value
, "");
156 static_assert(std::is_invocable
<Fn
, T
&&, int>::value
, "");
157 static_assert(std::is_invocable
<Fn
, ST
, int>::value
, "");
158 static_assert(!std::is_invocable
<Fn
, CT
&, int>::value
, "");
159 static_assert(!std::is_invocable
<RFn
, T
, int>::value
, "");
163 // Bullets 4, 5 and 6
164 using Fn
= int(Tag::*);
165 static_assert(!std::is_invocable
<Fn
>::value
, "");
168 static_assert(std::is_invocable
<Fn
, Tag
&>::value
, "");
169 static_assert(std::is_invocable
<Fn
, DerFromTag
&>::value
, "");
170 static_assert(std::is_invocable
<Fn
, Tag
&&>::value
, "");
171 static_assert(std::is_invocable
<Fn
, Tag
const&>::value
, "");
175 using T
= std::reference_wrapper
<Tag
>;
176 using DT
= std::reference_wrapper
<DerFromTag
>;
177 using CT
= std::reference_wrapper
<const Tag
>;
178 static_assert(std::is_invocable
<Fn
, T
&>::value
, "");
179 static_assert(std::is_invocable
<Fn
, DT
&>::value
, "");
180 static_assert(std::is_invocable
<Fn
, const T
&>::value
, "");
181 static_assert(std::is_invocable
<Fn
, T
&&>::value
, "");
182 static_assert(std::is_invocable
<Fn
, CT
&>::value
, "");
187 using DT
= DerFromTag
*;
188 using CT
= const Tag
*;
189 using ST
= std::unique_ptr
<Tag
>;
190 static_assert(std::is_invocable
<Fn
, T
&>::value
, "");
191 static_assert(std::is_invocable
<Fn
, DT
&>::value
, "");
192 static_assert(std::is_invocable
<Fn
, const T
&>::value
, "");
193 static_assert(std::is_invocable
<Fn
, T
&&>::value
, "");
194 static_assert(std::is_invocable
<Fn
, ST
>::value
, "");
195 static_assert(std::is_invocable
<Fn
, CT
&>::value
, "");
200 using Fp
= void(*)(Tag
&, int);
201 static_assert(std::is_invocable
<Fp
, Tag
&, int>::value
, "");
202 static_assert(std::is_invocable
<Fp
, DerFromTag
&, int>::value
, "");
203 static_assert(!std::is_invocable
<Fp
, const Tag
&, int>::value
, "");
204 static_assert(!std::is_invocable
<Fp
>::value
, "");
205 static_assert(!std::is_invocable
<Fp
, Tag
&>::value
, "");
208 // Function reference
209 using Fp
= void (&)(Tag
&, int);
210 static_assert(std::is_invocable
<Fp
, Tag
&, int>::value
, "");
211 static_assert(std::is_invocable
<Fp
, DerFromTag
&, int>::value
, "");
212 static_assert(!std::is_invocable
<Fp
, const Tag
&, int>::value
, "");
213 static_assert(!std::is_invocable
<Fp
>::value
, "");
214 static_assert(!std::is_invocable
<Fp
, Tag
&>::value
, "");
218 using Fn
= NotCallableWithInt
;
219 static_assert(std::is_invocable
<Fn
, Tag
>::value
, "");
220 static_assert(!std::is_invocable
<Fn
, int>::value
, "");
224 // Check that the conversion to the return type is properly checked
225 using Fn
= int (*)();
226 static_assert(std::is_invocable_r
<Implicit
, Fn
>::value
, "");
227 static_assert(std::is_invocable_r
<double, Fn
>::value
, "");
228 static_assert(std::is_invocable_r
<const volatile void, Fn
>::value
, "");
229 static_assert(!std::is_invocable_r
<Explicit
, Fn
>::value
, "");
232 // Check for is_invocable_v
233 using Fn
= void (*)();
234 static_assert(std::is_invocable_v
<Fn
>, "");
235 static_assert(!std::is_invocable_v
<Fn
, int>, "");
238 // Check for is_invocable_r_v
239 using Fn
= void (*)();
240 static_assert(std::is_invocable_r_v
<void, Fn
>, "");
241 static_assert(!std::is_invocable_r_v
<int, Fn
>, "");