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: 86 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: 120 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 143 static void run() { TestCaseImp().doTest(); } 144 145 private: 146 //========================================================================== 147 // TEST DISPATCH 148 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> 177 void runTestDispatchIf(Bool<true>, QT q, Tp& v) { 178 runTestDispatch(q, v); 179 } 180 181 template <class QT, class Tp> 182 void runTestDispatchIf(Bool<false>, QT, Tp&) { 183 } 184 185 template <class Tp> 186 void runTestDispatch(Q_None, Tp& v) { 187 runTest(v); 188 } 189 190 template <class Tp> 191 void runTestDispatch(Q_Const, Tp& v) { 192 runTest(v); 193 runTest(makeConst(v)); 194 } 195 196 template <class Tp> 197 void runTestDispatch(Q_Volatile, Tp& v) { 198 runTest(v); 199 runTest(makeVolatile(v)); 200 201 } 202 203 template <class Tp> 204 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> 212 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> 222 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> 232 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> { 252 DerivedFromRefWrap(Tp& tp) : std::reference_wrapper<Tp>(tp) {} 253 }; 254 255 #if TEST_STD_VER >= 11 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 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