1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8
9 // <functional>
10
11 // INVOKE (f, t1, t2, ..., tN)
12
13 //------------------------------------------------------------------------------
14 // TESTING INVOKE(f, t1, t2, ..., tN)
15 // - Bullet 7 -- f(t2, ..., tN)
16 //
17 // Overview:
18 // Bullet 7 handles the cases where the first argument is not a member
19 // function.
20 //
21 // Concerns:
22 // 1) Different types of callable objects are supported. Including
23 // 1a) Free Function pointers and references.
24 // 1b) Classes which provide a call operator
25 // 1c) lambdas
26 // 2) The callable objects are perfect forwarded.
27 // 3) The arguments are perfect forwarded.
28 // 4) Signatures which include varargs are supported.
29 // 5) In C++03 3 extra arguments should be allowed.
30 //
31 // Plan:
32 // 1) Define a set of free functions, 'SF', and class types with call
33 // operators, 'SC', that address concerns 4 and 5. The free functions should
34 // return 'FunctionID::setUncheckedCall()' and the call operators should
35 // return 'MethodID::setUncheckedCall()'.
36 //
37 // 2) For each function 'f' in 'SF' and 'SC' attempt to call 'f'
38 // using the correct number of arguments and cv-ref qualifiers. Check that
39 // 'f' has been called using 'FunctionID::checkCall()' if 'f' is a free
40 // function and 'MethodID::checkCall()' otherwise.
41
42
43
44 #include <functional>
45 #include <type_traits>
46 #include <cassert>
47
48 #include "test_macros.h"
49 #include "invoke_helpers.h"
50
51
52 //==============================================================================
53 // freeFunction03 - A C++03 free function.
freeFunction03()54 void*& freeFunction03() {
55 return FunctionPtrID<void*&(), freeFunction03>::setUncheckedCall();
56 }
57
freeFunction03(...)58 void*& freeFunction03(...) {
59 return FunctionPtrID<void*&(...), freeFunction03>::setUncheckedCall();
60 }
61
62 template <class A0>
freeFunction03(A0 &)63 void*& freeFunction03(A0&) {
64 return FunctionPtrID<void*&(A0&), freeFunction03>::setUncheckedCall();
65 }
66
67
68 template <class A0>
freeFunction03(A0 &,...)69 void*& freeFunction03(A0&, ...) {
70 return FunctionPtrID<void*&(A0&, ...), freeFunction03>::setUncheckedCall();
71 }
72
73 template <class A0, class A1>
freeFunction03(A0 &,A1 &)74 void*& freeFunction03(A0&, A1&) {
75 return FunctionPtrID<void*&(A0&, A1&), freeFunction03>::setUncheckedCall();
76 }
77
78
79 template <class A0, class A1>
freeFunction03(A0 &,A1 &,...)80 void*& freeFunction03(A0&, A1&, ...) {
81 return FunctionPtrID<void*&(A0&, A1&, ...), freeFunction03>::setUncheckedCall();
82 }
83
84 template <class A0, class A1, class A2>
freeFunction03(A0 &,A1 &,A2 &)85 void*& freeFunction03(A0&, A1&, A2&) {
86 return FunctionPtrID<void*&(A0&, A1&, A2&), freeFunction03>::setUncheckedCall();
87 }
88
89 template <class A0, class A1, class A2>
freeFunction03(A0 &,A1 &,A2 &,...)90 void*& freeFunction03(A0&, A1&, A2&, ...) {
91 return FunctionPtrID<void*&(A0&, A1&, A2&, ...), freeFunction03>::setUncheckedCall();
92 }
93
94 //==============================================================================
95 // Functor03 - C++03 compatible functor object
96 struct Functor03 {
97 typedef void*& R;
98 typedef Functor03 C;
99 #define F(Args, ...) \
100 __VA_ARGS__ R operator() Args { return MethodID<R(C::*) Args>::setUncheckedCall(); } \
101 __VA_ARGS__ R operator() Args const { return MethodID<R(C::*) Args const>::setUncheckedCall(); } \
102 __VA_ARGS__ R operator() Args volatile { return MethodID<R(C::*) Args volatile>::setUncheckedCall(); } \
103 __VA_ARGS__ R operator() Args const volatile { return MethodID<R(C::*) Args const volatile>::setUncheckedCall(); }
104 #
105 F(())
106 F((A0&), template <class A0>)
107 F((A0&, A1&), template <class A0, class A1>)
108 F((A0&, A1&, A2&), template <class A0, class A1, class A2>)
109 #undef F
110 public:
Functor03Functor03111 Functor03() {}
112 private:
113 Functor03(Functor03 const&);
114 Functor03& operator=(Functor03 const&);
115 };
116
117
118 #if TEST_STD_VER >= 11
119
120 //==============================================================================
121 // freeFunction11 - A C++11 free function.
122 template <class ...Args>
freeFunction11(Args &&...)123 void*& freeFunction11(Args&&...) {
124 return FunctionPtrID<void*&(Args&&...), freeFunction11>::setUncheckedCall();
125 }
126
127 template <class ...Args>
freeFunction11(Args &&...,...)128 void*& freeFunction11(Args&&...,...) {
129 return FunctionPtrID<void*&(Args&&...,...), freeFunction11>::setUncheckedCall();
130 }
131
132 //==============================================================================
133 // Functor11 - C++11 reference qualified test member functions.
134 struct Functor11 {
135 typedef void*& R;
136 typedef Functor11 C;
137
138 #define F(CV) \
139 template <class ...Args> \
140 R operator()(Args&&...) CV { return MethodID<R(C::*)(Args&&...) CV>::setUncheckedCall(); }
141 #
142 F(&)
143 F(const &)
144 F(volatile &)
145 F(const volatile &)
146 F(&&)
147 F(const &&)
148 F(volatile &&)
149 F(const volatile &&)
150 #undef F
151 public:
Functor11Functor11152 Functor11() {}
153 private:
154 Functor11(Functor11 const&);
155 Functor11& operator=(Functor11 const&);
156 };
157
158 #endif // TEST_STD_VER >= 11
159
160
161 //==============================================================================
162 // TestCaseFunctorImp - A test case for an operator() class method.
163 // ClassType - The type of the call object.
164 // CallSig - The function signature of the call operator being tested.
165 // Arity - the arity of 'CallSig'
166 // ObjCaster - Transformation function applied to call object.
167 // ArgCaster - Transformation function applied to the extra arguments.
168 template <class ClassType, class CallSig, int Arity,
169 class ObjCaster, class ArgCaster = LValueCaster>
170 struct TestCaseFunctorImp {
171 public:
runTestCaseFunctorImp172 static void run() {
173 typedef MethodID<CallSig ClassType::*> MID;
174 BasicTest<MID, Arity, ObjCaster, ArgCaster> t;
175 typedef ClassType T;
176 typedef DerivedFromType<T> D;
177 T obj;
178 D der;
179 t.runTest(obj);
180 t.runTest(der);
181 }
182 };
183
184 //==============================================================================
185 // TestCaseFreeFunction - A test case for a free function.
186 // CallSig - The function signature of the free function being tested.
187 // FnPtr - The function being tested.
188 // Arity - the arity of 'CallSig'
189 // ArgCaster - Transformation function to be applied to the extra arguments.
190 template <class CallSig, CallSig* FnPtr, int Arity, class ArgCaster>
191 struct TestCaseFreeFunction {
192 public:
runTestCaseFreeFunction193 static void run() {
194 typedef FunctionPtrID<CallSig, FnPtr> FID;
195 BasicTest<FID, Arity, LValueCaster, ArgCaster> t;
196
197 DerefToType<CallSig*> deref_to(FnPtr);
198 DerefToType<CallSig&> deref_to_ref(*FnPtr);
199
200 t.runTest(FnPtr);
201 t.runTest(*FnPtr);
202 t.runTest(deref_to);
203 t.runTest(deref_to_ref);
204 }
205 };
206
207 //==============================================================================
208 // runTest Helpers
209 //==============================================================================
210 #if TEST_STD_VER >= 11
211 template <class Sig, int Arity, class ArgCaster>
runFunctionTestCase11()212 void runFunctionTestCase11() {
213 TestCaseFreeFunction<Sig, freeFunction11, Arity, ArgCaster>();
214 }
215 #endif
216
217 template <class Sig, int Arity, class ArgCaster>
runFunctionTestCase()218 void runFunctionTestCase() {
219 TestCaseFreeFunction<Sig, freeFunction03, Arity, ArgCaster>();
220 #if TEST_STD_VER >= 11
221 runFunctionTestCase11<Sig, Arity, ArgCaster>();
222 #endif
223 }
224
225 template <class Sig, int Arity, class ObjCaster, class ArgCaster>
runFunctorTestCase()226 void runFunctorTestCase() {
227 TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster, ArgCaster>::run();
228 }
229
230 template <class Sig, int Arity, class ObjCaster>
runFunctorTestCase()231 void runFunctorTestCase() {
232 TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster>::run();
233 }
234
235 #if TEST_STD_VER >= 11
236 // runTestCase - Run a test case for C++11 class functor types
237 template <class Sig, int Arity, class ObjCaster, class ArgCaster = LValueCaster>
runFunctorTestCase11()238 void runFunctorTestCase11() {
239 TestCaseFunctorImp<Functor11, Sig, Arity, ObjCaster, ArgCaster>::run();
240 }
241 #endif
242
243 // runTestCase - Run a test case for both function and functor types.
244 template <class Sig, int Arity, class ArgCaster>
runTestCase()245 void runTestCase() {
246 runFunctionTestCase<Sig, Arity, ArgCaster>();
247 runFunctorTestCase <Sig, Arity, LValueCaster, ArgCaster>();
248 };
249
main(int,char **)250 int main(int, char**) {
251 typedef void*& R;
252 typedef ArgType A;
253 typedef A const CA;
254
255 runTestCase< R(), 0, LValueCaster >();
256 runTestCase< R(A&), 1, LValueCaster >();
257 runTestCase< R(A&, A&), 2, LValueCaster >();
258 runTestCase< R(A&, A&, A&), 3, LValueCaster >();
259 runTestCase< R(CA&), 1, ConstCaster >();
260 runTestCase< R(CA&, CA&), 2, ConstCaster >();
261 runTestCase< R(CA&, CA&, CA&), 3, ConstCaster >();
262
263 runFunctionTestCase<R(...), 0, LValueCaster >();
264 runFunctionTestCase<R(A&, ...), 1, LValueCaster >();
265 runFunctionTestCase<R(A&, A&, ...), 2, LValueCaster >();
266 runFunctionTestCase<R(A&, A&, A&, ...), 3, LValueCaster >();
267
268 #if TEST_STD_VER >= 11
269 runFunctionTestCase11<R(A&&), 1, MoveCaster >();
270 runFunctionTestCase11<R(A&&, ...), 1, MoveCaster >();
271 #endif
272
273 runFunctorTestCase<R(), 0, LValueCaster >();
274 runFunctorTestCase<R() const, 0, ConstCaster >();
275 runFunctorTestCase<R() volatile, 0, VolatileCaster >();
276 runFunctorTestCase<R() const volatile, 0, CVCaster >();
277 runFunctorTestCase<R(A&), 1, LValueCaster >();
278 runFunctorTestCase<R(A&) const, 1, ConstCaster >();
279 runFunctorTestCase<R(A&) volatile, 1, VolatileCaster >();
280 runFunctorTestCase<R(A&) const volatile, 1, CVCaster >();
281 runFunctorTestCase<R(A&, A&), 2, LValueCaster >();
282 runFunctorTestCase<R(A&, A&) const, 2, ConstCaster >();
283 runFunctorTestCase<R(A&, A&) volatile, 2, VolatileCaster >();
284 runFunctorTestCase<R(A&, A&) const volatile, 2, CVCaster >();
285 runFunctorTestCase<R(A&, A&, A&), 3, LValueCaster >();
286 runFunctorTestCase<R(A&, A&, A&) const, 3, ConstCaster >();
287 runFunctorTestCase<R(A&, A&, A&) volatile, 3, VolatileCaster >();
288 runFunctorTestCase<R(A&, A&, A&) const volatile, 3, CVCaster >();
289 {
290 typedef ConstCaster CC;
291 runFunctorTestCase<R(CA&), 1, LValueCaster, CC>();
292 runFunctorTestCase<R(CA&) const, 1, ConstCaster, CC>();
293 runFunctorTestCase<R(CA&) volatile, 1, VolatileCaster, CC>();
294 runFunctorTestCase<R(CA&) const volatile, 1, CVCaster, CC>();
295 runFunctorTestCase<R(CA&, CA&), 2, LValueCaster, CC>();
296 runFunctorTestCase<R(CA&, CA&) const, 2, ConstCaster, CC>();
297 runFunctorTestCase<R(CA&, CA&) volatile, 2, VolatileCaster, CC>();
298 runFunctorTestCase<R(CA&, CA&) const volatile, 2, CVCaster, CC>();
299 runFunctorTestCase<R(CA&, CA&, CA&), 3, LValueCaster, CC>();
300 runFunctorTestCase<R(CA&, CA&, CA&) const, 3, ConstCaster, CC>();
301 runFunctorTestCase<R(CA&, CA&, CA&) volatile, 3, VolatileCaster, CC>();
302 runFunctorTestCase<R(CA&, CA&, CA&) const volatile, 3, CVCaster, CC>();
303 }
304
305 #if TEST_STD_VER >= 11
306 runFunctorTestCase11<R() &, 0, LValueCaster >();
307 runFunctorTestCase11<R() const &, 0, ConstCaster >();
308 runFunctorTestCase11<R() volatile &, 0, VolatileCaster >();
309 runFunctorTestCase11<R() const volatile &, 0, CVCaster >();
310 runFunctorTestCase11<R() &&, 0, MoveCaster >();
311 runFunctorTestCase11<R() const &&, 0, MoveConstCaster >();
312 runFunctorTestCase11<R() volatile &&, 0, MoveVolatileCaster >();
313 runFunctorTestCase11<R() const volatile &&, 0, MoveCVCaster >();
314 {
315 typedef MoveCaster MC;
316 runFunctorTestCase11<R(A&&) &, 1, LValueCaster, MC>();
317 runFunctorTestCase11<R(A&&) const &, 1, ConstCaster, MC>();
318 runFunctorTestCase11<R(A&&) volatile &, 1, VolatileCaster, MC>();
319 runFunctorTestCase11<R(A&&) const volatile &, 1, CVCaster, MC>();
320 runFunctorTestCase11<R(A&&) &&, 1, MoveCaster, MC>();
321 runFunctorTestCase11<R(A&&) const &&, 1, MoveConstCaster, MC>();
322 runFunctorTestCase11<R(A&&) volatile &&, 1, MoveVolatileCaster, MC>();
323 runFunctorTestCase11<R(A&&) const volatile &&, 1, MoveCVCaster, MC>();
324 }
325 #endif
326
327 return 0;
328 }
329