• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 1 -- (t1.*f)(t2, ..., tN)
17 //   - Bullet 2 -- ((*t1).*f)(t2, ..., tN)
18 //
19 // Overview:
20 //    Bullets 1 and 2 handle the case where 'f' is a pointer to member function.
21 //    Bullet 1 only handles the cases where t1 is an object of type T or a
22 //    type derived from 'T'. Bullet 2 handles all other cases.
23 //
24 // Concerns:
25 //   1) cv-qualified member function signatures are accepted.
26 //   2) reference qualified member function signatures are accepted.
27 //   3) member functions with varargs at the end are accepted.
28 //   4) The arguments are perfect forwarded to the member function call.
29 //   5) Classes that are publicly derived from 'T' are accepted as the call object
30 //   6) All types that dereference to T or a type derived from T can be used
31 //      as the call object.
32 //   7) Pointers to T or a type derived from T can be used as the call object.
33 //   8) Reference return types are properly deduced.
34 //
35 //
36 // Plan:
37 //   1) Create a class that contains a set, 'S', of non-static functions.
38 //     'S' should include functions that cover every single combination
39 //      of qualifiers and varargs for arities of 0, 1 and 2 (C-1,2,3).
40 //      The argument types used in the functions should be non-copyable (C-4).
41 //      The functions should return 'MethodID::setUncheckedCall()'.
42 //
43 //   2) Create a set of supported call object, 'Objs', of different types
44 //      and behaviors. (C-5,6,7)
45 //
46 //   3) Attempt to call each function, 'f', in 'S' with each call object, 'c',
47 //      in 'Objs'. After every attempted call to 'f' check that 'f' was
48 //      actually called using 'MethodID::checkCalled(<return-value>)'
49 //
50 //       3b) If 'f' is reference qualified call 'f' with the properly qualified
51 //       call object. Otherwise call 'f' with lvalue call objects.
52 //
53 //       3a) If 'f' is const, volatile, or cv qualified then call it with call
54 //       objects that are equally or less cv-qualified.
55 
56 #include <functional>
57 #include <type_traits>
58 #include <cassert>
59 
60 #include "test_macros.h"
61 #include "invoke_helpers.h"
62 
63 //==============================================================================
64 // MemFun03 - C++03 compatible set of test member functions.
65 struct MemFun03 {
66     typedef void*& R;
67 #define F(...) \
68     R f(__VA_ARGS__) { return MethodID<R(MemFun03::*)(__VA_ARGS__)>::setUncheckedCall(); } \
69     R f(__VA_ARGS__) const { return MethodID<R(MemFun03::*)(__VA_ARGS__) const>::setUncheckedCall(); } \
70     R f(__VA_ARGS__) volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) volatile>::setUncheckedCall(); } \
71     R f(__VA_ARGS__) const volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) const volatile>::setUncheckedCall(); }
72 #
73     F()
74     F(...)
75     F(ArgType&)
76     F(ArgType&, ...)
77     F(ArgType&, ArgType&)
78     F(ArgType&, ArgType&, ...)
79     F(ArgType&, ArgType&, ArgType&)
80     F(ArgType&, ArgType&, ArgType&, ...)
81 #undef F
82 public:
MemFun03MemFun0383     MemFun03() {}
84 private:
85     MemFun03(MemFun03 const&);
86     MemFun03& operator=(MemFun03 const&);
87 };
88 
89 
90 #if TEST_STD_VER >= 11
91 
92 //==============================================================================
93 // MemFun11 - C++11 reference qualified test member functions.
94 struct MemFun11 {
95     typedef void*& R;
96     typedef MemFun11 C;
97 #define F(...) \
98     R f(__VA_ARGS__) & { return MethodID<R(C::*)(__VA_ARGS__) &>::setUncheckedCall(); } \
99     R f(__VA_ARGS__) const & { return MethodID<R(C::*)(__VA_ARGS__) const &>::setUncheckedCall(); } \
100     R f(__VA_ARGS__) volatile & { return MethodID<R(C::*)(__VA_ARGS__) volatile &>::setUncheckedCall(); } \
101     R f(__VA_ARGS__) const volatile & { return MethodID<R(C::*)(__VA_ARGS__) const volatile &>::setUncheckedCall(); } \
102     R f(__VA_ARGS__) && { return MethodID<R(C::*)(__VA_ARGS__) &&>::setUncheckedCall(); } \
103     R f(__VA_ARGS__) const && { return MethodID<R(C::*)(__VA_ARGS__) const &&>::setUncheckedCall(); } \
104     R f(__VA_ARGS__) volatile && { return MethodID<R(C::*)(__VA_ARGS__) volatile &&>::setUncheckedCall(); } \
105     R f(__VA_ARGS__) const volatile && { return MethodID<R(C::*)(__VA_ARGS__) const volatile &&>::setUncheckedCall(); }
106 #
107     F()
108     F(...)
109     F(ArgType&&)
110     F(ArgType&&, ...)
111     F(ArgType&&, ArgType&&)
112     F(ArgType&&, ArgType&&, ...)
113     F(ArgType&&, ArgType&&, ArgType&&)
114     F(ArgType&&, ArgType&&, ArgType&&, ...)
115 #undef F
116 public:
MemFun11MemFun11117     MemFun11() {}
118 private:
119     MemFun11(MemFun11 const&);
120     MemFun11& operator=(MemFun11 const&);
121 };
122 
123 #endif // TEST_STD_VER >= 11
124 
125 
126 //==============================================================================
127 // TestCase - A test case for a single member function.
128 //   ClassType - The type of the class being tested.
129 //   CallSig   - The function signature of the method being tested.
130 //   Arity     - the arity of 'CallSig'
131 //   CV        - the cv qualifiers of 'CallSig' represented as a type tag.
132 //   RValue    - The method is RValue qualified.
133 //   ArgRValue - Call the method with RValue arguments.
134 template <class ClassType, class CallSig, int Arity, class CV,
135           bool RValue = false, bool ArgRValue = false>
136 struct TestCaseImp {
137 public:
138 
runTestCaseImp139     static void run() { TestCaseImp().doTest(); }
140 
141 private:
142     //==========================================================================
143     // TEST DISPATCH
doTestTestCaseImp144     void doTest() {
145          // (Plan-2) Create test call objects.
146         typedef ClassType T;
147         typedef DerivedFromType<T> D;
148         T obj;
149         T* obj_ptr = &obj;
150         D der;
151         D* der_ptr = &der;
152         DerefToType<T>   dref;
153         DerefPropType<T> dref2;
154 
155          // (Plan-3) Dispatch based on the CV tags.
156         CV tag;
157         Bool<!RValue> NotRValue;
158         runTestDispatch(tag,  obj);
159         runTestDispatch(tag,  der);
160         runTestDispatch(tag, dref2);
161         runTestDispatchIf(NotRValue, tag,  dref);
162         runTestDispatchIf(NotRValue, tag,  obj_ptr);
163         runTestDispatchIf(NotRValue, tag, der_ptr);
164     }
165 
166     template <class QT, class Tp>
runTestDispatchIfTestCaseImp167     void runTestDispatchIf(Bool<true>, QT q, Tp& v) {
168         runTestDispatch(q, v);
169     }
170 
171     template <class QT, class Tp>
runTestDispatchIfTestCaseImp172     void runTestDispatchIf(Bool<false>, QT, Tp&) {
173     }
174 
175     template <class Tp>
runTestDispatchTestCaseImp176     void runTestDispatch(Q_None, Tp& v) {
177         runTest(v);
178     }
179 
180     template <class Tp>
runTestDispatchTestCaseImp181     void runTestDispatch(Q_Const, Tp& v) {
182         Tp const& cv = v;
183         runTest(v);
184         runTest(cv);
185     }
186 
187     template <class Tp>
runTestDispatchTestCaseImp188     void runTestDispatch(Q_Volatile, Tp& v) {
189         Tp volatile& vv = v;
190         runTest(v);
191         runTest(vv);
192     }
193 
194     template <class Tp>
runTestDispatchTestCaseImp195     void runTestDispatch(Q_CV, Tp& v) {
196         Tp const& cv = v;
197         Tp volatile& vv = v;
198         Tp const volatile& cvv = v;
199         runTest(v);
200         runTest(cv);
201         runTest(vv);
202         runTest(cvv);
203     }
204 
205     template <class Obj>
runTestTestCaseImp206     void runTest(Obj& obj) {
207         typedef Caster<Q_None, RValue> SCast;
208         typedef Caster<Q_None, ArgRValue> ACast;
209         typedef CallSig (ClassType::*MemPtr);
210         // Delegate test to logic in invoke_helpers.h
211         BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
212         b.runTest( (MemPtr)&ClassType::f, obj);
213     }
214 };
215 
216 template <class Sig, int Arity, class CV>
217 struct TestCase : public TestCaseImp<MemFun03, Sig, Arity, CV> {};
218 
219 #if TEST_STD_VER >= 11
220 template <class Sig, int Arity, class CV, bool RValue = false>
221 struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {};
222 #endif
223 
main()224 int main() {
225     typedef void*& R;
226     typedef ArgType A;
227     TestCase<R(),                                   0, Q_None>::run();
228     TestCase<R() const,                             0, Q_Const>::run();
229     TestCase<R() volatile,                          0, Q_Volatile>::run();
230     TestCase<R() const volatile,                    0, Q_CV>::run();
231     TestCase<R(...),                                0, Q_None>::run();
232     TestCase<R(...) const,                          0, Q_Const>::run();
233     TestCase<R(...) volatile,                       0, Q_Volatile>::run();
234     TestCase<R(...) const volatile,                 0, Q_CV>::run();
235     TestCase<R(A&),                                 1, Q_None>::run();
236     TestCase<R(A&) const,                           1, Q_Const>::run();
237     TestCase<R(A&) volatile,                        1, Q_Volatile>::run();
238     TestCase<R(A&) const volatile,                  1, Q_CV>::run();
239     TestCase<R(A&, ...),                            1, Q_None>::run();
240     TestCase<R(A&, ...) const,                      1, Q_Const>::run();
241     TestCase<R(A&, ...) volatile,                   1, Q_Volatile>::run();
242     TestCase<R(A&, ...) const volatile,             1, Q_CV>::run();
243     TestCase<R(A&, A&),                             2, Q_None>::run();
244     TestCase<R(A&, A&) const,                       2, Q_Const>::run();
245     TestCase<R(A&, A&) volatile,                    2, Q_Volatile>::run();
246     TestCase<R(A&, A&) const volatile,              2, Q_CV>::run();
247     TestCase<R(A&, A&, ...),                        2, Q_None>::run();
248     TestCase<R(A&, A&, ...) const,                  2, Q_Const>::run();
249     TestCase<R(A&, A&, ...) volatile,               2, Q_Volatile>::run();
250     TestCase<R(A&, A&, ...) const volatile,         2, Q_CV>::run();
251     TestCase<R(A&, A&, A&),                         3, Q_None>::run();
252     TestCase<R(A&, A&, A&) const,                   3, Q_Const>::run();
253     TestCase<R(A&, A&, A&) volatile,                3, Q_Volatile>::run();
254     TestCase<R(A&, A&, A&) const volatile,          3, Q_CV>::run();
255     TestCase<R(A&, A&, A&, ...),                    3, Q_None>::run();
256     TestCase<R(A&, A&, A&, ...) const,              3, Q_Const>::run();
257     TestCase<R(A&, A&, A&, ...) volatile,           3, Q_Volatile>::run();
258     TestCase<R(A&, A&, A&, ...) const volatile,     3, Q_CV>::run();
259 
260 #if TEST_STD_VER >= 11
261     TestCase11<R() &,                               0, Q_None>::run();
262     TestCase11<R() const &,                         0, Q_Const>::run();
263     TestCase11<R() volatile &,                      0, Q_Volatile>::run();
264     TestCase11<R() const volatile &,                0, Q_CV>::run();
265     TestCase11<R(...) &,                            0, Q_None>::run();
266     TestCase11<R(...) const &,                      0, Q_Const>::run();
267     TestCase11<R(...) volatile &,                   0, Q_Volatile>::run();
268     TestCase11<R(...) const volatile &,             0, Q_CV>::run();
269     TestCase11<R(A&&) &,                            1, Q_None>::run();
270     TestCase11<R(A&&) const &,                      1, Q_Const>::run();
271     TestCase11<R(A&&) volatile &,                   1, Q_Volatile>::run();
272     TestCase11<R(A&&) const volatile &,             1, Q_CV>::run();
273     TestCase11<R(A&&, ...) &,                       1, Q_None>::run();
274     TestCase11<R(A&&, ...) const &,                 1, Q_Const>::run();
275     TestCase11<R(A&&, ...) volatile &,              1, Q_Volatile>::run();
276     TestCase11<R(A&&, ...) const volatile &,        1, Q_CV>::run();
277     TestCase11<R(A&&, A&&) &,                       2, Q_None>::run();
278     TestCase11<R(A&&, A&&) const &,                 2, Q_Const>::run();
279     TestCase11<R(A&&, A&&) volatile &,              2, Q_Volatile>::run();
280     TestCase11<R(A&&, A&&) const volatile &,        2, Q_CV>::run();
281     TestCase11<R(A&&, A&&, ...) &,                  2, Q_None>::run();
282     TestCase11<R(A&&, A&&, ...) const &,            2, Q_Const>::run();
283     TestCase11<R(A&&, A&&, ...) volatile &,         2, Q_Volatile>::run();
284     TestCase11<R(A&&, A&&, ...) const volatile &,   2, Q_CV>::run();
285     TestCase11<R() &&,                              0, Q_None, /* RValue */ true>::run();
286     TestCase11<R() const &&,                        0, Q_Const, /* RValue */ true>::run();
287     TestCase11<R() volatile &&,                     0, Q_Volatile, /* RValue */ true>::run();
288     TestCase11<R() const volatile &&,               0, Q_CV, /* RValue */ true>::run();
289     TestCase11<R(...) &&,                           0, Q_None, /* RValue */ true>::run();
290     TestCase11<R(...) const &&,                     0, Q_Const, /* RValue */ true>::run();
291     TestCase11<R(...) volatile &&,                  0, Q_Volatile, /* RValue */ true>::run();
292     TestCase11<R(...) const volatile &&,            0, Q_CV, /* RValue */ true>::run();
293     TestCase11<R(A&&) &&,                           1, Q_None, /* RValue */ true>::run();
294     TestCase11<R(A&&) const &&,                     1, Q_Const, /* RValue */ true>::run();
295     TestCase11<R(A&&) volatile &&,                  1, Q_Volatile, /* RValue */ true>::run();
296     TestCase11<R(A&&) const volatile &&,            1, Q_CV, /* RValue */ true>::run();
297     TestCase11<R(A&&, ...) &&,                      1, Q_None, /* RValue */ true>::run();
298     TestCase11<R(A&&, ...) const &&,                1, Q_Const, /* RValue */ true>::run();
299     TestCase11<R(A&&, ...) volatile &&,             1, Q_Volatile, /* RValue */ true>::run();
300     TestCase11<R(A&&, ...) const volatile &&,       1, Q_CV, /* RValue */ true>::run();
301     TestCase11<R(A&&, A&&) &&,                      2, Q_None, /* RValue */ true>::run();
302     TestCase11<R(A&&, A&&) const &&,                2, Q_Const, /* RValue */ true>::run();
303     TestCase11<R(A&&, A&&) volatile &&,             2, Q_Volatile, /* RValue */ true>::run();
304     TestCase11<R(A&&, A&&) const volatile &&,       2, Q_CV, /* RValue */ true>::run();
305     TestCase11<R(A&&, A&&, ...) &&,                 2, Q_None, /* RValue */ true>::run();
306     TestCase11<R(A&&, A&&, ...) const &&,           2, Q_Const, /* RValue */ true>::run();
307     TestCase11<R(A&&, A&&, ...) volatile &&,        2, Q_Volatile, /* RValue */ true>::run();
308     TestCase11<R(A&&, A&&, ...) const volatile &&,  2, Q_CV, /* RValue */ true>::run();
309     TestCase11<R(A&&, A&&, A&&) &&,                 3, Q_None, /* RValue */ true>::run();
310     TestCase11<R(A&&, A&&, A&&) const &&,           3, Q_Const, /* RValue */ true>::run();
311     TestCase11<R(A&&, A&&, A&&) volatile &&,        3, Q_Volatile, /* RValue */ true>::run();
312     TestCase11<R(A&&, A&&, A&&) const volatile &&,  3, Q_CV, /* RValue */ true>::run();
313     TestCase11<R(A&&, A&&, A&&, ...)  &&,                 3, Q_None, /* RValue */ true>::run();
314     TestCase11<R(A&&, A&&, A&&, ...)  const &&,           3, Q_Const, /* RValue */ true>::run();
315     TestCase11<R(A&&, A&&, A&&, ...)  volatile &&,        3, Q_Volatile, /* RValue */ true>::run();
316     TestCase11<R(A&&, A&&, A&&, ...)  const volatile &&,  3, Q_CV, /* RValue */ true>::run();
317 #endif
318 }