• 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.get().*f)(t2, ..., tN) // t1 is a reference_wrapper
18 //   - Bullet 3 -- ((*t1).*f)(t2, ..., tN)
19 //
20 // Overview:
21 //    Bullets 1, 2 and 3 handle the case where 'f' is a pointer to member function.
22 //    Bullet 1 only handles the cases where t1 is an object of type T or a
23 //    type derived from 'T'. Bullet 2 handles the case where 't1' is a reference
24 //    wrapper and bullet 3 handles all other cases.
25 //
26 // Concerns:
27 //   1) cv-qualified member function signatures are accepted.
28 //   2) reference qualified member function signatures are accepted.
29 //   3) member functions with varargs at the end are accepted.
30 //   4) The arguments are perfect forwarded to the member function call.
31 //   5) Classes that are publicly derived from 'T' are accepted as the call object
32 //   6) All types that dereference to T or a type derived from T can be used
33 //      as the call object.
34 //   7) Pointers to T or a type derived from T can be used as the call object.
35 //   8) Reference return types are properly deduced.
36 //   9) reference_wrappers are properly handled and unwrapped.
37 //
38 //
39 // Plan:
40 //   1) Create a class that contains a set, 'S', of non-static functions.
41 //     'S' should include functions that cover every single combination
42 //      of qualifiers and varargs for arities of 0, 1 and 2 (C-1,2,3).
43 //      The argument types used in the functions should be non-copyable (C-4).
44 //      The functions should return 'MethodID::setUncheckedCall()'.
45 //
46 //   2) Create a set of supported call object, 'Objs', of different types
47 //      and behaviors. (C-5,6,7)
48 //
49 //   3) Attempt to call each function, 'f', in 'S' with each call object, 'c',
50 //      in 'Objs'. After every attempted call to 'f' check that 'f' was
51 //      actually called using 'MethodID::checkCalled(<return-value>)'
52 //
53 //       3b) If 'f' is reference qualified call 'f' with the properly qualified
54 //       call object. Otherwise call 'f' with lvalue call objects.
55 //
56 //       3a) If 'f' is const, volatile, or cv qualified then call it with call
57 //       objects that are equally or less cv-qualified.
58 
59 #include <functional>
60 #include <type_traits>
61 #include <cassert>
62 
63 #include "test_macros.h"
64 #include "invoke_helpers.h"
65 
66 //==============================================================================
67 // MemFun03 - C++03 compatible set of test member functions.
68 struct MemFun03 {
69     typedef void*& R;
70 #define F(...) \
71     R f(__VA_ARGS__) { return MethodID<R(MemFun03::*)(__VA_ARGS__)>::setUncheckedCall(); } \
72     R f(__VA_ARGS__) const { return MethodID<R(MemFun03::*)(__VA_ARGS__) const>::setUncheckedCall(); } \
73     R f(__VA_ARGS__) volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) volatile>::setUncheckedCall(); } \
74     R f(__VA_ARGS__) const volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) const volatile>::setUncheckedCall(); }
75 #
76     F()
77     F(...)
78     F(ArgType&)
79     F(ArgType&, ...)
80     F(ArgType&, ArgType&)
81     F(ArgType&, ArgType&, ...)
82     F(ArgType&, ArgType&, ArgType&)
83     F(ArgType&, ArgType&, ArgType&, ...)
84 #undef F
85 public:
MemFun03MemFun0386     MemFun03() {}
87 private:
88     MemFun03(MemFun03 const&);
89     MemFun03& operator=(MemFun03 const&);
90 };
91 
92 
93 #if TEST_STD_VER >= 11
94 
95 //==============================================================================
96 // MemFun11 - C++11 reference qualified test member functions.
97 struct MemFun11 {
98     typedef void*& R;
99     typedef MemFun11 C;
100 #define F(...) \
101     R f(__VA_ARGS__) & { return MethodID<R(C::*)(__VA_ARGS__) &>::setUncheckedCall(); } \
102     R f(__VA_ARGS__) const & { return MethodID<R(C::*)(__VA_ARGS__) const &>::setUncheckedCall(); } \
103     R f(__VA_ARGS__) volatile & { return MethodID<R(C::*)(__VA_ARGS__) volatile &>::setUncheckedCall(); } \
104     R f(__VA_ARGS__) const volatile & { return MethodID<R(C::*)(__VA_ARGS__) const volatile &>::setUncheckedCall(); } \
105     R f(__VA_ARGS__) && { return MethodID<R(C::*)(__VA_ARGS__) &&>::setUncheckedCall(); } \
106     R f(__VA_ARGS__) const && { return MethodID<R(C::*)(__VA_ARGS__) const &&>::setUncheckedCall(); } \
107     R f(__VA_ARGS__) volatile && { return MethodID<R(C::*)(__VA_ARGS__) volatile &&>::setUncheckedCall(); } \
108     R f(__VA_ARGS__) const volatile && { return MethodID<R(C::*)(__VA_ARGS__) const volatile &&>::setUncheckedCall(); }
109 #
110     F()
111     F(...)
112     F(ArgType&&)
113     F(ArgType&&, ...)
114     F(ArgType&&, ArgType&&)
115     F(ArgType&&, ArgType&&, ...)
116     F(ArgType&&, ArgType&&, ArgType&&)
117     F(ArgType&&, ArgType&&, ArgType&&, ...)
118 #undef F
119 public:
MemFun11MemFun11120     MemFun11() {}
121 private:
122     MemFun11(MemFun11 const&);
123     MemFun11& operator=(MemFun11 const&);
124 };
125 
126 #endif // TEST_STD_VER >= 11
127 
128 
129 
130 //==============================================================================
131 // TestCase - A test case for a single member function.
132 //   ClassType - The type of the class being tested.
133 //   CallSig   - The function signature of the method being tested.
134 //   Arity     - the arity of 'CallSig'
135 //   CV        - the cv qualifiers of 'CallSig' represented as a type tag.
136 //   RValue    - The method is RValue qualified.
137 //   ArgRValue - Call the method with RValue arguments.
138 template <class ClassType, class CallSig, int Arity, class CV,
139           bool RValue = false, bool ArgRValue = false>
140 struct TestCaseImp {
141 public:
142 
runTestCaseImp143     static void run() { TestCaseImp().doTest(); }
144 
145 private:
146     //==========================================================================
147     // TEST DISPATCH
doTestTestCaseImp148     void doTest() {
149          // (Plan-2) Create test call objects.
150         typedef ClassType T;
151         typedef DerivedFromType<T> D;
152         T obj;
153         T* obj_ptr = &obj;
154         D der;
155         D* der_ptr = &der;
156         DerefToType<T>   dref;
157         DerefPropType<T> dref2;
158         std::reference_wrapper<T> rref(obj);
159         std::reference_wrapper<D> drref(der);
160 
161          // (Plan-3) Dispatch based on the CV tags.
162         CV tag;
163         Bool<!RValue> NotRValue;
164         runTestDispatch(tag,  obj);
165         runTestDispatch(tag,  der);
166         runTestDispatch(tag, dref2);
167         runTestDispatchIf(NotRValue, tag, dref);
168         runTestDispatchIf(NotRValue, tag, obj_ptr);
169         runTestDispatchIf(NotRValue, tag, der_ptr);
170 #if TEST_STD_VER >= 11
171         runTestDispatchIf(NotRValue, tag, rref);
172         runTestDispatchIf(NotRValue, tag, drref);
173 #endif
174     }
175 
176     template <class QT, class Tp>
runTestDispatchIfTestCaseImp177     void runTestDispatchIf(Bool<true>, QT q, Tp& v) {
178         runTestDispatch(q, v);
179     }
180 
181     template <class QT, class Tp>
runTestDispatchIfTestCaseImp182     void runTestDispatchIf(Bool<false>, QT, Tp&) {
183     }
184 
185     template <class Tp>
runTestDispatchTestCaseImp186     void runTestDispatch(Q_None, Tp& v) {
187         runTest(v);
188     }
189 
190     template <class Tp>
runTestDispatchTestCaseImp191     void runTestDispatch(Q_Const, Tp& v) {
192         runTest(v);
193         runTest(makeConst(v));
194     }
195 
196     template <class Tp>
runTestDispatchTestCaseImp197     void runTestDispatch(Q_Volatile, Tp& v) {
198         runTest(v);
199         runTest(makeVolatile(v));
200 
201     }
202 
203     template <class Tp>
runTestDispatchTestCaseImp204     void runTestDispatch(Q_CV, Tp& v) {
205         runTest(v);
206         runTest(makeConst(v));
207         runTest(makeVolatile(v));
208         runTest(makeCV(v));
209     }
210 
211     template <class T>
runTestTestCaseImp212     void runTest(const std::reference_wrapper<T>& obj) {
213         typedef Caster<Q_None, RValue> SCast;
214         typedef Caster<Q_None, ArgRValue> ACast;
215         typedef CallSig (ClassType::*MemPtr);
216         // Delegate test to logic in invoke_helpers.h
217         BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
218         b.runTest( (MemPtr)&ClassType::f, obj);
219     }
220 
221     template <class T>
runTestTestCaseImp222     void runTest(T* obj) {
223         typedef Caster<Q_None, RValue> SCast;
224         typedef Caster<Q_None, ArgRValue> ACast;
225         typedef CallSig (ClassType::*MemPtr);
226         // Delegate test to logic in invoke_helpers.h
227         BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
228         b.runTest( (MemPtr)&ClassType::f, obj);
229     }
230 
231     template <class Obj>
runTestTestCaseImp232     void runTest(Obj& obj) {
233         typedef Caster<Q_None, RValue> SCast;
234         typedef Caster<Q_None, ArgRValue> ACast;
235         typedef CallSig (ClassType::*MemPtr);
236         // Delegate test to logic in invoke_helpers.h
237         BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
238         b.runTest( (MemPtr)&ClassType::f, obj);
239     }
240 };
241 
242 template <class Sig, int Arity, class CV>
243 struct TestCase : public TestCaseImp<MemFun03, Sig, Arity, CV> {};
244 
245 #if TEST_STD_VER >= 11
246 template <class Sig, int Arity, class CV, bool RValue = false>
247 struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {};
248 #endif
249 
250 template <class Tp>
251 struct DerivedFromRefWrap : public std::reference_wrapper<Tp> {
DerivedFromRefWrapDerivedFromRefWrap252   DerivedFromRefWrap(Tp& tp) : std::reference_wrapper<Tp>(tp) {}
253 };
254 
255 #if TEST_STD_VER >= 11
test_derived_from_ref_wrap()256 void test_derived_from_ref_wrap() {
257     int x = 42;
258     std::reference_wrapper<int> r(x);
259     std::reference_wrapper<std::reference_wrapper<int>> r2(r);
260     DerivedFromRefWrap<int> d(x);
261     auto get_fn = &std::reference_wrapper<int>::get;
262     auto& ret = std::__invoke(get_fn, r);
263     auto& cret = std::__invoke_constexpr(get_fn, r);
264     assert(&ret == &x);
265     assert(&cret == &x);
266     auto& ret2 = std::__invoke(get_fn, d);
267     auto& cret2 = std::__invoke_constexpr(get_fn, d);
268     assert(&ret2 == &x);
269     assert(&cret2 == &x);
270     auto& ret3 = std::__invoke(get_fn, r2);
271     assert(&ret3 == &x);
272 }
273 #endif
274 
main()275 int main() {
276     typedef void*& R;
277     typedef ArgType A;
278     TestCase<R(),                                   0, Q_None>::run();
279     TestCase<R() const,                             0, Q_Const>::run();
280     TestCase<R() volatile,                          0, Q_Volatile>::run();
281     TestCase<R() const volatile,                    0, Q_CV>::run();
282     TestCase<R(...),                                0, Q_None>::run();
283     TestCase<R(...) const,                          0, Q_Const>::run();
284     TestCase<R(...) volatile,                       0, Q_Volatile>::run();
285     TestCase<R(...) const volatile,                 0, Q_CV>::run();
286     TestCase<R(A&),                                 1, Q_None>::run();
287     TestCase<R(A&) const,                           1, Q_Const>::run();
288     TestCase<R(A&) volatile,                        1, Q_Volatile>::run();
289     TestCase<R(A&) const volatile,                  1, Q_CV>::run();
290     TestCase<R(A&, ...),                            1, Q_None>::run();
291     TestCase<R(A&, ...) const,                      1, Q_Const>::run();
292     TestCase<R(A&, ...) volatile,                   1, Q_Volatile>::run();
293     TestCase<R(A&, ...) const volatile,             1, Q_CV>::run();
294     TestCase<R(A&, A&),                             2, Q_None>::run();
295     TestCase<R(A&, A&) const,                       2, Q_Const>::run();
296     TestCase<R(A&, A&) volatile,                    2, Q_Volatile>::run();
297     TestCase<R(A&, A&) const volatile,              2, Q_CV>::run();
298     TestCase<R(A&, A&, ...),                        2, Q_None>::run();
299     TestCase<R(A&, A&, ...) const,                  2, Q_Const>::run();
300     TestCase<R(A&, A&, ...) volatile,               2, Q_Volatile>::run();
301     TestCase<R(A&, A&, ...) const volatile,         2, Q_CV>::run();
302     TestCase<R(A&, A&, A&),                         3, Q_None>::run();
303     TestCase<R(A&, A&, A&) const,                   3, Q_Const>::run();
304     TestCase<R(A&, A&, A&) volatile,                3, Q_Volatile>::run();
305     TestCase<R(A&, A&, A&) const volatile,          3, Q_CV>::run();
306     TestCase<R(A&, A&, A&, ...),                    3, Q_None>::run();
307     TestCase<R(A&, A&, A&, ...) const,              3, Q_Const>::run();
308     TestCase<R(A&, A&, A&, ...) volatile,           3, Q_Volatile>::run();
309     TestCase<R(A&, A&, A&, ...) const volatile,     3, Q_CV>::run();
310 
311 #if TEST_STD_VER >= 11
312     TestCase11<R() &,                               0, Q_None>::run();
313     TestCase11<R() const &,                         0, Q_Const>::run();
314     TestCase11<R() volatile &,                      0, Q_Volatile>::run();
315     TestCase11<R() const volatile &,                0, Q_CV>::run();
316     TestCase11<R(...) &,                            0, Q_None>::run();
317     TestCase11<R(...) const &,                      0, Q_Const>::run();
318     TestCase11<R(...) volatile &,                   0, Q_Volatile>::run();
319     TestCase11<R(...) const volatile &,             0, Q_CV>::run();
320     TestCase11<R(A&&) &,                            1, Q_None>::run();
321     TestCase11<R(A&&) const &,                      1, Q_Const>::run();
322     TestCase11<R(A&&) volatile &,                   1, Q_Volatile>::run();
323     TestCase11<R(A&&) const volatile &,             1, Q_CV>::run();
324     TestCase11<R(A&&, ...) &,                       1, Q_None>::run();
325     TestCase11<R(A&&, ...) const &,                 1, Q_Const>::run();
326     TestCase11<R(A&&, ...) volatile &,              1, Q_Volatile>::run();
327     TestCase11<R(A&&, ...) const volatile &,        1, Q_CV>::run();
328     TestCase11<R(A&&, A&&) &,                       2, Q_None>::run();
329     TestCase11<R(A&&, A&&) const &,                 2, Q_Const>::run();
330     TestCase11<R(A&&, A&&) volatile &,              2, Q_Volatile>::run();
331     TestCase11<R(A&&, A&&) const volatile &,        2, Q_CV>::run();
332     TestCase11<R(A&&, A&&, ...) &,                  2, Q_None>::run();
333     TestCase11<R(A&&, A&&, ...) const &,            2, Q_Const>::run();
334     TestCase11<R(A&&, A&&, ...) volatile &,         2, Q_Volatile>::run();
335     TestCase11<R(A&&, A&&, ...) const volatile &,   2, Q_CV>::run();
336     TestCase11<R() &&,                              0, Q_None, /* RValue */ true>::run();
337     TestCase11<R() const &&,                        0, Q_Const, /* RValue */ true>::run();
338     TestCase11<R() volatile &&,                     0, Q_Volatile, /* RValue */ true>::run();
339     TestCase11<R() const volatile &&,               0, Q_CV, /* RValue */ true>::run();
340     TestCase11<R(...) &&,                           0, Q_None, /* RValue */ true>::run();
341     TestCase11<R(...) const &&,                     0, Q_Const, /* RValue */ true>::run();
342     TestCase11<R(...) volatile &&,                  0, Q_Volatile, /* RValue */ true>::run();
343     TestCase11<R(...) const volatile &&,            0, Q_CV, /* RValue */ true>::run();
344     TestCase11<R(A&&) &&,                           1, Q_None, /* RValue */ true>::run();
345     TestCase11<R(A&&) const &&,                     1, Q_Const, /* RValue */ true>::run();
346     TestCase11<R(A&&) volatile &&,                  1, Q_Volatile, /* RValue */ true>::run();
347     TestCase11<R(A&&) const volatile &&,            1, Q_CV, /* RValue */ true>::run();
348     TestCase11<R(A&&, ...) &&,                      1, Q_None, /* RValue */ true>::run();
349     TestCase11<R(A&&, ...) const &&,                1, Q_Const, /* RValue */ true>::run();
350     TestCase11<R(A&&, ...) volatile &&,             1, Q_Volatile, /* RValue */ true>::run();
351     TestCase11<R(A&&, ...) const volatile &&,       1, Q_CV, /* RValue */ true>::run();
352     TestCase11<R(A&&, A&&) &&,                      2, Q_None, /* RValue */ true>::run();
353     TestCase11<R(A&&, A&&) const &&,                2, Q_Const, /* RValue */ true>::run();
354     TestCase11<R(A&&, A&&) volatile &&,             2, Q_Volatile, /* RValue */ true>::run();
355     TestCase11<R(A&&, A&&) const volatile &&,       2, Q_CV, /* RValue */ true>::run();
356     TestCase11<R(A&&, A&&, ...) &&,                 2, Q_None, /* RValue */ true>::run();
357     TestCase11<R(A&&, A&&, ...) const &&,           2, Q_Const, /* RValue */ true>::run();
358     TestCase11<R(A&&, A&&, ...) volatile &&,        2, Q_Volatile, /* RValue */ true>::run();
359     TestCase11<R(A&&, A&&, ...) const volatile &&,  2, Q_CV, /* RValue */ true>::run();
360     TestCase11<R(A&&, A&&, A&&) &&,                 3, Q_None, /* RValue */ true>::run();
361     TestCase11<R(A&&, A&&, A&&) const &&,           3, Q_Const, /* RValue */ true>::run();
362     TestCase11<R(A&&, A&&, A&&) volatile &&,        3, Q_Volatile, /* RValue */ true>::run();
363     TestCase11<R(A&&, A&&, A&&) const volatile &&,  3, Q_CV, /* RValue */ true>::run();
364     TestCase11<R(A&&, A&&, A&&, ...)  &&,                 3, Q_None, /* RValue */ true>::run();
365     TestCase11<R(A&&, A&&, A&&, ...)  const &&,           3, Q_Const, /* RValue */ true>::run();
366     TestCase11<R(A&&, A&&, A&&, ...)  volatile &&,        3, Q_Volatile, /* RValue */ true>::run();
367     TestCase11<R(A&&, A&&, A&&, ...)  const volatile &&,  3, Q_CV, /* RValue */ true>::run();
368 
369     test_derived_from_ref_wrap();
370 #endif
371 }
372