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