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