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: 83 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: 117 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 139 static void run() { TestCaseImp().doTest(); } 140 141 private: 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); 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> 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) { 182 Tp const& cv = v; 183 runTest(v); 184 runTest(cv); 185 } 186 187 template <class Tp> 188 void runTestDispatch(Q_Volatile, Tp& v) { 189 Tp volatile& vv = v; 190 runTest(v); 191 runTest(vv); 192 } 193 194 template <class Tp> 195 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> 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 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 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 }