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 5 -- f(t2, ..., tN) 17 // 18 // Overview: 19 // Bullet 5 handles the cases where the first argument is not a member 20 // function. 21 // 22 // Concerns: 23 // 1) Different types of callable objects are supported. Including 24 // 1a) Free Function pointers and references. 25 // 1b) Classes which provide a call operator 26 // 1c) lambdas 27 // 2) The callable objects are perfect forwarded. 28 // 3) The arguments are perfect forwarded. 29 // 4) Signatures which include varargs are supported. 30 // 5) In C++03 3 extra arguments should be allowed. 31 // 32 // Plan: 33 // 1) Define a set of free functions, 'SF', and class types with call 34 // operators, 'SC', that address concerns 4 and 5. The free functions should 35 // return 'FunctionID::setUncheckedCall()' and the call operators should 36 // return 'MethodID::setUncheckedCall()'. 37 // 38 // 2) For each function 'f' in 'SF' and 'SC' attempt to call 'f' 39 // using the correct number of arguments and cv-ref qualifiers. Check that 40 // 'f' has been called using 'FunctionID::checkCall()' if 'f' is a free 41 // function and 'MethodID::checkCall()' otherwise. 42 43 44 45 #include <functional> 46 #include <type_traits> 47 #include <cassert> 48 49 #include "test_macros.h" 50 #include "invoke_helpers.h" 51 52 53 //============================================================================== 54 // freeFunction03 - A C++03 free function. 55 void*& freeFunction03() { 56 return FunctionPtrID<void*&(), freeFunction03>::setUncheckedCall(); 57 } 58 59 void*& freeFunction03(...) { 60 return FunctionPtrID<void*&(...), freeFunction03>::setUncheckedCall(); 61 } 62 63 template <class A0> 64 void*& freeFunction03(A0&) { 65 return FunctionPtrID<void*&(A0&), freeFunction03>::setUncheckedCall(); 66 } 67 68 69 template <class A0> 70 void*& freeFunction03(A0&, ...) { 71 return FunctionPtrID<void*&(A0&, ...), freeFunction03>::setUncheckedCall(); 72 } 73 74 template <class A0, class A1> 75 void*& freeFunction03(A0&, A1&) { 76 return FunctionPtrID<void*&(A0&, A1&), freeFunction03>::setUncheckedCall(); 77 } 78 79 80 template <class A0, class A1> 81 void*& freeFunction03(A0&, A1&, ...) { 82 return FunctionPtrID<void*&(A0&, A1&, ...), freeFunction03>::setUncheckedCall(); 83 } 84 85 template <class A0, class A1, class A2> 86 void*& freeFunction03(A0&, A1&, A2&) { 87 return FunctionPtrID<void*&(A0&, A1&, A2&), freeFunction03>::setUncheckedCall(); 88 } 89 90 template <class A0, class A1, class A2> 91 void*& freeFunction03(A0&, A1&, A2&, ...) { 92 return FunctionPtrID<void*&(A0&, A1&, A2&, ...), freeFunction03>::setUncheckedCall(); 93 } 94 95 //============================================================================== 96 // Functor03 - C++03 compatible functor object 97 struct Functor03 { 98 typedef void*& R; 99 typedef Functor03 C; 100 #define F(Args, ...) \ 101 __VA_ARGS__ R operator() Args { return MethodID<R(C::*) Args>::setUncheckedCall(); } \ 102 __VA_ARGS__ R operator() Args const { return MethodID<R(C::*) Args const>::setUncheckedCall(); } \ 103 __VA_ARGS__ R operator() Args volatile { return MethodID<R(C::*) Args volatile>::setUncheckedCall(); } \ 104 __VA_ARGS__ R operator() Args const volatile { return MethodID<R(C::*) Args const volatile>::setUncheckedCall(); } 105 # 106 F(()) 107 F((A0&), template <class A0>) 108 F((A0&, A1&), template <class A0, class A1>) 109 F((A0&, A1&, A2&), template <class A0, class A1, class A2>) 110 #undef F 111 public: 112 Functor03() {} 113 private: 114 Functor03(Functor03 const&); 115 Functor03& operator=(Functor03 const&); 116 }; 117 118 119 #if TEST_STD_VER >= 11 120 121 //============================================================================== 122 // freeFunction11 - A C++11 free function. 123 template <class ...Args> 124 void*& freeFunction11(Args&&...) { 125 return FunctionPtrID<void*&(Args&&...), freeFunction11>::setUncheckedCall(); 126 } 127 128 template <class ...Args> 129 void*& freeFunction11(Args&&...,...) { 130 return FunctionPtrID<void*&(Args&&...,...), freeFunction11>::setUncheckedCall(); 131 } 132 133 //============================================================================== 134 // Functor11 - C++11 reference qualified test member functions. 135 struct Functor11 { 136 typedef void*& R; 137 typedef Functor11 C; 138 139 #define F(CV) \ 140 template <class ...Args> \ 141 R operator()(Args&&...) CV { return MethodID<R(C::*)(Args&&...) CV>::setUncheckedCall(); } 142 # 143 F(&) 144 F(const &) 145 F(volatile &) 146 F(const volatile &) 147 F(&&) 148 F(const &&) 149 F(volatile &&) 150 F(const volatile &&) 151 #undef F 152 public: 153 Functor11() {} 154 private: 155 Functor11(Functor11 const&); 156 Functor11& operator=(Functor11 const&); 157 }; 158 159 #endif // TEST_STD_VER >= 11 160 161 162 //============================================================================== 163 // TestCaseFunctorImp - A test case for an operator() class method. 164 // ClassType - The type of the call object. 165 // CallSig - The function signature of the call operator being tested. 166 // Arity - the arity of 'CallSig' 167 // ObjCaster - Transformation function applied to call object. 168 // ArgCaster - Transformation function applied to the extra arguments. 169 template <class ClassType, class CallSig, int Arity, 170 class ObjCaster, class ArgCaster = LValueCaster> 171 struct TestCaseFunctorImp { 172 public: 173 static void run() { 174 typedef MethodID<CallSig ClassType::*> MID; 175 BasicTest<MID, Arity, ObjCaster, ArgCaster> t; 176 typedef ClassType T; 177 typedef DerivedFromType<T> D; 178 T obj; 179 D der; 180 t.runTest(obj); 181 t.runTest(der); 182 } 183 }; 184 185 //============================================================================== 186 // TestCaseFreeFunction - A test case for a free function. 187 // CallSig - The function signature of the free function being tested. 188 // FnPtr - The function being tested. 189 // Arity - the arity of 'CallSig' 190 // ArgCaster - Transformation function to be applied to the extra arguments. 191 template <class CallSig, CallSig* FnPtr, int Arity, class ArgCaster> 192 struct TestCaseFreeFunction { 193 public: 194 static void run() { 195 typedef FunctionPtrID<CallSig, FnPtr> FID; 196 BasicTest<FID, Arity, LValueCaster, ArgCaster> t; 197 198 DerefToType<CallSig*> deref_to(FnPtr); 199 DerefToType<CallSig&> deref_to_ref(*FnPtr); 200 201 t.runTest(FnPtr); 202 t.runTest(*FnPtr); 203 t.runTest(deref_to); 204 t.runTest(deref_to_ref); 205 } 206 }; 207 208 //============================================================================== 209 // runTest Helpers 210 //============================================================================== 211 #if TEST_STD_VER >= 11 212 template <class Sig, int Arity, class ArgCaster> 213 void runFunctionTestCase11() { 214 TestCaseFreeFunction<Sig, freeFunction11, Arity, ArgCaster>(); 215 } 216 #endif 217 218 template <class Sig, int Arity, class ArgCaster> 219 void runFunctionTestCase() { 220 TestCaseFreeFunction<Sig, freeFunction03, Arity, ArgCaster>(); 221 #if TEST_STD_VER >= 11 222 runFunctionTestCase11<Sig, Arity, ArgCaster>(); 223 #endif 224 } 225 226 template <class Sig, int Arity, class ObjCaster, class ArgCaster> 227 void runFunctorTestCase() { 228 TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster, ArgCaster>::run(); 229 } 230 231 template <class Sig, int Arity, class ObjCaster> 232 void runFunctorTestCase() { 233 TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster>::run(); 234 } 235 236 #if TEST_STD_VER >= 11 237 // runTestCase - Run a test case for C++11 class functor types 238 template <class Sig, int Arity, class ObjCaster, class ArgCaster = LValueCaster> 239 void runFunctorTestCase11() { 240 TestCaseFunctorImp<Functor11, Sig, Arity, ObjCaster, ArgCaster>::run(); 241 } 242 #endif 243 244 // runTestCase - Run a test case for both function and functor types. 245 template <class Sig, int Arity, class ArgCaster> 246 void runTestCase() { 247 runFunctionTestCase<Sig, Arity, ArgCaster>(); 248 runFunctorTestCase <Sig, Arity, LValueCaster, ArgCaster>(); 249 }; 250 251 int main() { 252 typedef void*& R; 253 typedef ArgType A; 254 typedef A const CA; 255 256 runTestCase< R(), 0, LValueCaster >(); 257 runTestCase< R(A&), 1, LValueCaster >(); 258 runTestCase< R(A&, A&), 2, LValueCaster >(); 259 runTestCase< R(A&, A&, A&), 3, LValueCaster >(); 260 runTestCase< R(CA&), 1, ConstCaster >(); 261 runTestCase< R(CA&, CA&), 2, ConstCaster >(); 262 runTestCase< R(CA&, CA&, CA&), 3, ConstCaster >(); 263 264 runFunctionTestCase<R(...), 0, LValueCaster >(); 265 runFunctionTestCase<R(A&, ...), 1, LValueCaster >(); 266 runFunctionTestCase<R(A&, A&, ...), 2, LValueCaster >(); 267 runFunctionTestCase<R(A&, A&, A&, ...), 3, LValueCaster >(); 268 269 #if TEST_STD_VER >= 11 270 runFunctionTestCase11<R(A&&), 1, MoveCaster >(); 271 runFunctionTestCase11<R(A&&, ...), 1, MoveCaster >(); 272 #endif 273 274 runFunctorTestCase<R(), 0, LValueCaster >(); 275 runFunctorTestCase<R() const, 0, ConstCaster >(); 276 runFunctorTestCase<R() volatile, 0, VolatileCaster >(); 277 runFunctorTestCase<R() const volatile, 0, CVCaster >(); 278 runFunctorTestCase<R(A&), 1, LValueCaster >(); 279 runFunctorTestCase<R(A&) const, 1, ConstCaster >(); 280 runFunctorTestCase<R(A&) volatile, 1, VolatileCaster >(); 281 runFunctorTestCase<R(A&) const volatile, 1, CVCaster >(); 282 runFunctorTestCase<R(A&, A&), 2, LValueCaster >(); 283 runFunctorTestCase<R(A&, A&) const, 2, ConstCaster >(); 284 runFunctorTestCase<R(A&, A&) volatile, 2, VolatileCaster >(); 285 runFunctorTestCase<R(A&, A&) const volatile, 2, CVCaster >(); 286 runFunctorTestCase<R(A&, A&, A&), 3, LValueCaster >(); 287 runFunctorTestCase<R(A&, A&, A&) const, 3, ConstCaster >(); 288 runFunctorTestCase<R(A&, A&, A&) volatile, 3, VolatileCaster >(); 289 runFunctorTestCase<R(A&, A&, A&) const volatile, 3, CVCaster >(); 290 { 291 typedef ConstCaster CC; 292 runFunctorTestCase<R(CA&), 1, LValueCaster, CC>(); 293 runFunctorTestCase<R(CA&) const, 1, ConstCaster, CC>(); 294 runFunctorTestCase<R(CA&) volatile, 1, VolatileCaster, CC>(); 295 runFunctorTestCase<R(CA&) const volatile, 1, CVCaster, CC>(); 296 runFunctorTestCase<R(CA&, CA&), 2, LValueCaster, CC>(); 297 runFunctorTestCase<R(CA&, CA&) const, 2, ConstCaster, CC>(); 298 runFunctorTestCase<R(CA&, CA&) volatile, 2, VolatileCaster, CC>(); 299 runFunctorTestCase<R(CA&, CA&) const volatile, 2, CVCaster, CC>(); 300 runFunctorTestCase<R(CA&, CA&, CA&), 3, LValueCaster, CC>(); 301 runFunctorTestCase<R(CA&, CA&, CA&) const, 3, ConstCaster, CC>(); 302 runFunctorTestCase<R(CA&, CA&, CA&) volatile, 3, VolatileCaster, CC>(); 303 runFunctorTestCase<R(CA&, CA&, CA&) const volatile, 3, CVCaster, CC>(); 304 } 305 306 #if TEST_STD_VER >= 11 307 runFunctorTestCase11<R() &, 0, LValueCaster >(); 308 runFunctorTestCase11<R() const &, 0, ConstCaster >(); 309 runFunctorTestCase11<R() volatile &, 0, VolatileCaster >(); 310 runFunctorTestCase11<R() const volatile &, 0, CVCaster >(); 311 runFunctorTestCase11<R() &&, 0, MoveCaster >(); 312 runFunctorTestCase11<R() const &&, 0, MoveConstCaster >(); 313 runFunctorTestCase11<R() volatile &&, 0, MoveVolatileCaster >(); 314 runFunctorTestCase11<R() const volatile &&, 0, MoveCVCaster >(); 315 { 316 typedef MoveCaster MC; 317 runFunctorTestCase11<R(A&&) &, 1, LValueCaster, MC>(); 318 runFunctorTestCase11<R(A&&) const &, 1, ConstCaster, MC>(); 319 runFunctorTestCase11<R(A&&) volatile &, 1, VolatileCaster, MC>(); 320 runFunctorTestCase11<R(A&&) const volatile &, 1, CVCaster, MC>(); 321 runFunctorTestCase11<R(A&&) &&, 1, MoveCaster, MC>(); 322 runFunctorTestCase11<R(A&&) const &&, 1, MoveConstCaster, MC>(); 323 runFunctorTestCase11<R(A&&) volatile &&, 1, MoveVolatileCaster, MC>(); 324 runFunctorTestCase11<R(A&&) const volatile &&, 1, MoveCVCaster, MC>(); 325 } 326 #endif 327 } 328