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.
21 #include <type_traits>
26 #include "test_macros.h"
29 struct DerFromTag
: Tag
{};
36 explicit Explicit(int) {}
39 struct NotCallableWithInt
{
40 int operator()(int) = delete;
41 int operator()(Tag
) { return 42; }
45 template <class ...Args
>
46 void operator()(Args
&&...) const {}
49 int main(int, char**) {
50 using AbominableFunc
= void(...) const;
52 // Non-callable things
54 static_assert(!std::is_invocable
<void>::value
, "");
55 static_assert(!std::is_invocable
<const void>::value
, "");
56 static_assert(!std::is_invocable
<volatile void>::value
, "");
57 static_assert(!std::is_invocable
<const volatile void>::value
, "");
58 static_assert(!std::is_invocable
<std::nullptr_t
>::value
, "");
59 static_assert(!std::is_invocable
<int>::value
, "");
60 static_assert(!std::is_invocable
<double>::value
, "");
62 static_assert(!std::is_invocable
<int[]>::value
, "");
63 static_assert(!std::is_invocable
<int[3]>::value
, "");
65 static_assert(!std::is_invocable
<int*>::value
, "");
66 static_assert(!std::is_invocable
<const int*>::value
, "");
67 static_assert(!std::is_invocable
<int const*>::value
, "");
69 static_assert(!std::is_invocable
<int&>::value
, "");
70 static_assert(!std::is_invocable
<const int&>::value
, "");
71 static_assert(!std::is_invocable
<int&&>::value
, "");
73 static_assert(!std::is_invocable
<std::vector
<int> >::value
, "");
74 static_assert(!std::is_invocable
<std::vector
<int*> >::value
, "");
75 static_assert(!std::is_invocable
<std::vector
<int**> >::value
, "");
77 static_assert(!std::is_invocable
<AbominableFunc
>::value
, "");
80 static_assert(!std::is_invocable
<int, int>::value
, "");
81 static_assert(!std::is_invocable
<int, double, float>::value
, "");
82 static_assert(!std::is_invocable
<int, char, float, double>::value
, "");
83 static_assert(!std::is_invocable
<Sink
, AbominableFunc
>::value
, "");
84 static_assert(!std::is_invocable
<Sink
, void>::value
, "");
85 static_assert(!std::is_invocable
<Sink
, const volatile void>::value
,
89 static_assert(!std::is_invocable_r
<int, void>::value
, "");
90 static_assert(!std::is_invocable_r
<int, const void>::value
, "");
91 static_assert(!std::is_invocable_r
<int, volatile void>::value
, "");
92 static_assert(!std::is_invocable_r
<int, const volatile void>::value
, "");
93 static_assert(!std::is_invocable_r
<int, std::nullptr_t
>::value
, "");
94 static_assert(!std::is_invocable_r
<int, int>::value
, "");
95 static_assert(!std::is_invocable_r
<int, double>::value
, "");
97 static_assert(!std::is_invocable_r
<int, int[]>::value
, "");
98 static_assert(!std::is_invocable_r
<int, int[3]>::value
, "");
100 static_assert(!std::is_invocable_r
<int, int*>::value
, "");
101 static_assert(!std::is_invocable_r
<int, const int*>::value
, "");
102 static_assert(!std::is_invocable_r
<int, int const*>::value
, "");
104 static_assert(!std::is_invocable_r
<int, int&>::value
, "");
105 static_assert(!std::is_invocable_r
<int, const int&>::value
, "");
106 static_assert(!std::is_invocable_r
<int, 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
<int, std::vector
<int**> >::value
, "");
111 static_assert(!std::is_invocable_r
<void, AbominableFunc
>::value
, "");
114 static_assert(!std::is_invocable_r
<int, int, int>::value
, "");
115 static_assert(!std::is_invocable_r
<int, int, double, float>::value
, "");
116 static_assert(!std::is_invocable_r
<int, int, char, float, double>::value
,
118 static_assert(!std::is_invocable_r
<void, Sink
, AbominableFunc
>::value
, "");
119 static_assert(!std::is_invocable_r
<void, Sink
, void>::value
, "");
120 static_assert(!std::is_invocable_r
<void, Sink
, const volatile void>::value
,
124 using Fn
= int (Tag::*)(int);
125 using RFn
= int (Tag::*)(int)&&;
126 // INVOKE bullet 1, 2 and 3
129 static_assert(std::is_invocable
<Fn
, Tag
&, int>::value
, "");
130 static_assert(std::is_invocable
<Fn
, DerFromTag
&, int>::value
, "");
131 static_assert(std::is_invocable
<RFn
, Tag
&&, int>::value
, "");
132 static_assert(!std::is_invocable
<RFn
, Tag
&, int>::value
, "");
133 static_assert(!std::is_invocable
<Fn
, Tag
&>::value
, "");
134 static_assert(!std::is_invocable
<Fn
, Tag
const&, int>::value
, "");
138 using T
= std::reference_wrapper
<Tag
>;
139 using DT
= std::reference_wrapper
<DerFromTag
>;
140 using CT
= std::reference_wrapper
<const Tag
>;
141 static_assert(std::is_invocable
<Fn
, T
&, int>::value
, "");
142 static_assert(std::is_invocable
<Fn
, DT
&, int>::value
, "");
143 static_assert(std::is_invocable
<Fn
, const T
&, int>::value
, "");
144 static_assert(std::is_invocable
<Fn
, T
&&, int>::value
, "");
145 static_assert(!std::is_invocable
<Fn
, CT
&, int>::value
, "");
146 static_assert(!std::is_invocable
<RFn
, T
, int>::value
, "");
151 using DT
= DerFromTag
*;
152 using CT
= const Tag
*;
153 using ST
= std::unique_ptr
<Tag
>;
154 static_assert(std::is_invocable
<Fn
, T
&, int>::value
, "");
155 static_assert(std::is_invocable
<Fn
, DT
&, int>::value
, "");
156 static_assert(std::is_invocable
<Fn
, const T
&, int>::value
, "");
157 static_assert(std::is_invocable
<Fn
, T
&&, int>::value
, "");
158 static_assert(std::is_invocable
<Fn
, ST
, int>::value
, "");
159 static_assert(!std::is_invocable
<Fn
, CT
&, int>::value
, "");
160 static_assert(!std::is_invocable
<RFn
, T
, int>::value
, "");
164 // Bullets 4, 5 and 6
165 using Fn
= int(Tag::*);
166 static_assert(!std::is_invocable
<Fn
>::value
, "");
169 static_assert(std::is_invocable
<Fn
, Tag
&>::value
, "");
170 static_assert(std::is_invocable
<Fn
, DerFromTag
&>::value
, "");
171 static_assert(std::is_invocable
<Fn
, Tag
&&>::value
, "");
172 static_assert(std::is_invocable
<Fn
, Tag
const&>::value
, "");
176 using T
= std::reference_wrapper
<Tag
>;
177 using DT
= std::reference_wrapper
<DerFromTag
>;
178 using CT
= std::reference_wrapper
<const Tag
>;
179 static_assert(std::is_invocable
<Fn
, T
&>::value
, "");
180 static_assert(std::is_invocable
<Fn
, DT
&>::value
, "");
181 static_assert(std::is_invocable
<Fn
, const T
&>::value
, "");
182 static_assert(std::is_invocable
<Fn
, T
&&>::value
, "");
183 static_assert(std::is_invocable
<Fn
, CT
&>::value
, "");
188 using DT
= DerFromTag
*;
189 using CT
= const Tag
*;
190 using ST
= std::unique_ptr
<Tag
>;
191 static_assert(std::is_invocable
<Fn
, T
&>::value
, "");
192 static_assert(std::is_invocable
<Fn
, DT
&>::value
, "");
193 static_assert(std::is_invocable
<Fn
, const T
&>::value
, "");
194 static_assert(std::is_invocable
<Fn
, T
&&>::value
, "");
195 static_assert(std::is_invocable
<Fn
, ST
>::value
, "");
196 static_assert(std::is_invocable
<Fn
, CT
&>::value
, "");
201 using Fp
= void(*)(Tag
&, int);
202 static_assert(std::is_invocable
<Fp
, Tag
&, int>::value
, "");
203 static_assert(std::is_invocable
<Fp
, DerFromTag
&, int>::value
, "");
204 static_assert(!std::is_invocable
<Fp
, const Tag
&, int>::value
, "");
205 static_assert(!std::is_invocable
<Fp
>::value
, "");
206 static_assert(!std::is_invocable
<Fp
, Tag
&>::value
, "");
209 // Function reference
210 using Fp
= void (&)(Tag
&, int);
211 static_assert(std::is_invocable
<Fp
, Tag
&, int>::value
, "");
212 static_assert(std::is_invocable
<Fp
, DerFromTag
&, int>::value
, "");
213 static_assert(!std::is_invocable
<Fp
, const Tag
&, int>::value
, "");
214 static_assert(!std::is_invocable
<Fp
>::value
, "");
215 static_assert(!std::is_invocable
<Fp
, Tag
&>::value
, "");
219 using Fn
= NotCallableWithInt
;
220 static_assert(std::is_invocable
<Fn
, Tag
>::value
, "");
221 static_assert(!std::is_invocable
<Fn
, int>::value
, "");
225 // Check that the conversion to the return type is properly checked
226 using Fn
= int (*)();
227 static_assert(std::is_invocable_r
<Implicit
, Fn
>::value
, "");
228 static_assert(std::is_invocable_r
<double, Fn
>::value
, "");
229 static_assert(std::is_invocable_r
<const volatile void, Fn
>::value
, "");
230 static_assert(!std::is_invocable_r
<Explicit
, Fn
>::value
, "");
233 // Check for is_invocable_v
234 using Fn
= void (*)();
235 static_assert(std::is_invocable_v
<Fn
>, "");
236 static_assert(!std::is_invocable_v
<Fn
, int>, "");
239 // Check for is_invocable_r_v
240 using Fn
= void (*)();
241 static_assert(std::is_invocable_r_v
<void, Fn
>, "");
242 static_assert(!std::is_invocable_r_v
<int, Fn
>, "");