blob: e579f207a33f25bb13d536494255ff6d13dd84de [file] [log] [blame]
Eric Fiselier48aa2cf2015-07-28 01:25:36 +00001//===----------------------------------------------------------------------===//
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)
Dan Albert1d4a1ed2016-05-25 22:36:09 -070017// - Bullet 2 -- ((*t1).*f)(t2, ..., tN)
Eric Fiselier48aa2cf2015-07-28 01:25:36 +000018//
19// Overview:
Dan Albert1d4a1ed2016-05-25 22:36:09 -070020// Bullets 1 and 2 handle the case where 'f' is a pointer to member function.
Eric Fiselier48aa2cf2015-07-28 01:25:36 +000021// Bullet 1 only handles the cases where t1 is an object of type T or a
Dan Albert1d4a1ed2016-05-25 22:36:09 -070022// type derived from 'T'. Bullet 2 handles all other cases.
Eric Fiselier48aa2cf2015-07-28 01:25:36 +000023//
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.
65struct 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
82public:
83 MemFun03() {}
84private:
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.
94struct 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
116public:
117 MemFun11() {}
118private:
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.
134template <class ClassType, class CallSig, int Arity, class CV,
135 bool RValue = false, bool ArgRValue = false>
136struct TestCaseImp {
137public:
138
139 static void run() { TestCaseImp().doTest(); }
140
141private:
142 //==========================================================================
143 // TEST DISPATCH
144 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);
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700161 runTestDispatchIf(NotRValue, tag, dref);
162 runTestDispatchIf(NotRValue, tag, obj_ptr);
Eric Fiselier48aa2cf2015-07-28 01:25:36 +0000163 runTestDispatchIf(NotRValue, tag, der_ptr);
164 }
165
166 template <class QT, class Tp>
167 void runTestDispatchIf(Bool<true>, QT q, Tp& v) {
168 runTestDispatch(q, v);
169 }
170
171 template <class QT, class Tp>
172 void runTestDispatchIf(Bool<false>, QT, Tp&) {
173 }
174
175 template <class Tp>
176 void runTestDispatch(Q_None, Tp& v) {
177 runTest(v);
178 }
179
180 template <class Tp>
181 void runTestDispatch(Q_Const, Tp& v) {
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700182 Tp const& cv = v;
Eric Fiselier48aa2cf2015-07-28 01:25:36 +0000183 runTest(v);
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700184 runTest(cv);
Eric Fiselier48aa2cf2015-07-28 01:25:36 +0000185 }
186
187 template <class Tp>
188 void runTestDispatch(Q_Volatile, Tp& v) {
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700189 Tp volatile& vv = v;
Eric Fiselier48aa2cf2015-07-28 01:25:36 +0000190 runTest(v);
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700191 runTest(vv);
Eric Fiselier48aa2cf2015-07-28 01:25:36 +0000192 }
193
194 template <class Tp>
195 void runTestDispatch(Q_CV, Tp& v) {
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700196 Tp const& cv = v;
197 Tp volatile& vv = v;
198 Tp const volatile& cvv = v;
Eric Fiselier48aa2cf2015-07-28 01:25:36 +0000199 runTest(v);
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700200 runTest(cv);
201 runTest(vv);
202 runTest(cvv);
Eric Fiselier48aa2cf2015-07-28 01:25:36 +0000203 }
204
205 template <class Obj>
206 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
216template <class Sig, int Arity, class CV>
217struct TestCase : public TestCaseImp<MemFun03, Sig, Arity, CV> {};
218
219#if TEST_STD_VER >= 11
220template <class Sig, int Arity, class CV, bool RValue = false>
221struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {};
222#endif
223
224int 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();
Eric Fiselier48aa2cf2015-07-28 01:25:36 +0000317#endif
318}