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