//===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // INVOKE (f, t1, t2, ..., tN) //------------------------------------------------------------------------------ // TESTING INVOKE(f, t1, t2, ..., tN) // - Bullet 5 -- f(t2, ..., tN) // // Overview: // Bullet 5 handles the cases where the first argument is not a member // function. // // Concerns: // 1) Different types of callable objects are supported. Including // 1a) Free Function pointers and references. // 1b) Classes which provide a call operator // 1c) lambdas // 2) The callable objects are perfect forwarded. // 3) The arguments are perfect forwarded. // 4) Signatures which include varargs are supported. // 5) In C++03 3 extra arguments should be allowed. // // Plan: // 1) Define a set of free functions, 'SF', and class types with call // operators, 'SC', that address concerns 4 and 5. The free functions should // return 'FunctionID::setUncheckedCall()' and the call operators should // return 'MethodID::setUncheckedCall()'. // // 2) For each function 'f' in 'SF' and 'SC' attempt to call 'f' // using the correct number of arguments and cv-ref qualifiers. Check that // 'f' has been called using 'FunctionID::checkCall()' if 'f' is a free // function and 'MethodID::checkCall()' otherwise. #include #include #include #include "test_macros.h" #include "invoke_helpers.h" //============================================================================== // freeFunction03 - A C++03 free function. void*& freeFunction03() { return FunctionPtrID::setUncheckedCall(); } void*& freeFunction03(...) { return FunctionPtrID::setUncheckedCall(); } template void*& freeFunction03(A0&) { return FunctionPtrID::setUncheckedCall(); } template void*& freeFunction03(A0&, ...) { return FunctionPtrID::setUncheckedCall(); } template void*& freeFunction03(A0&, A1&) { return FunctionPtrID::setUncheckedCall(); } template void*& freeFunction03(A0&, A1&, ...) { return FunctionPtrID::setUncheckedCall(); } template void*& freeFunction03(A0&, A1&, A2&) { return FunctionPtrID::setUncheckedCall(); } template void*& freeFunction03(A0&, A1&, A2&, ...) { return FunctionPtrID::setUncheckedCall(); } //============================================================================== // Functor03 - C++03 compatible functor object struct Functor03 { typedef void*& R; typedef Functor03 C; #define F(Args, ...) \ __VA_ARGS__ R operator() Args { return MethodID::setUncheckedCall(); } \ __VA_ARGS__ R operator() Args const { return MethodID::setUncheckedCall(); } \ __VA_ARGS__ R operator() Args volatile { return MethodID::setUncheckedCall(); } \ __VA_ARGS__ R operator() Args const volatile { return MethodID::setUncheckedCall(); } # F(()) F((A0&), template ) F((A0&, A1&), template ) F((A0&, A1&, A2&), template ) #undef F public: Functor03() {} private: Functor03(Functor03 const&); Functor03& operator=(Functor03 const&); }; #if TEST_STD_VER >= 11 //============================================================================== // freeFunction11 - A C++11 free function. template void*& freeFunction11(Args&&...) { return FunctionPtrID::setUncheckedCall(); } template void*& freeFunction11(Args&&...,...) { return FunctionPtrID::setUncheckedCall(); } //============================================================================== // Functor11 - C++11 reference qualified test member functions. struct Functor11 { typedef void*& R; typedef Functor11 C; #define F(CV) \ template \ R operator()(Args&&...) CV { return MethodID::setUncheckedCall(); } # F(&) F(const &) F(volatile &) F(const volatile &) F(&&) F(const &&) F(volatile &&) F(const volatile &&) #undef F public: Functor11() {} private: Functor11(Functor11 const&); Functor11& operator=(Functor11 const&); }; #endif // TEST_STD_VER >= 11 //============================================================================== // TestCaseFunctorImp - A test case for an operator() class method. // ClassType - The type of the call object. // CallSig - The function signature of the call operator being tested. // Arity - the arity of 'CallSig' // ObjCaster - Transformation function applied to call object. // ArgCaster - Transformation function applied to the extra arguments. template struct TestCaseFunctorImp { public: static void run() { typedef MethodID MID; BasicTest t; typedef ClassType T; typedef DerivedFromType D; T obj; D der; t.runTest(obj); t.runTest(der); } }; //============================================================================== // TestCaseFreeFunction - A test case for a free function. // CallSig - The function signature of the free function being tested. // FnPtr - The function being tested. // Arity - the arity of 'CallSig' // ArgCaster - Transformation function to be applied to the extra arguments. template struct TestCaseFreeFunction { public: static void run() { typedef FunctionPtrID FID; BasicTest t; DerefToType deref_to(FnPtr); DerefToType deref_to_ref(*FnPtr); t.runTest(FnPtr); t.runTest(*FnPtr); t.runTest(deref_to); t.runTest(deref_to_ref); } }; //============================================================================== // runTest Helpers //============================================================================== #if TEST_STD_VER >= 11 template void runFunctionTestCase11() { TestCaseFreeFunction(); } #endif template void runFunctionTestCase() { TestCaseFreeFunction(); #if TEST_STD_VER >= 11 runFunctionTestCase11(); #endif } template void runFunctorTestCase() { TestCaseFunctorImp::run(); } template void runFunctorTestCase() { TestCaseFunctorImp::run(); } #if TEST_STD_VER >= 11 // runTestCase - Run a test case for C++11 class functor types template void runFunctorTestCase11() { TestCaseFunctorImp::run(); } #endif // runTestCase - Run a test case for both function and functor types. template void runTestCase() { runFunctionTestCase(); runFunctorTestCase (); }; int main() { typedef void*& R; typedef ArgType A; typedef A const CA; runTestCase< R(), 0, LValueCaster >(); runTestCase< R(A&), 1, LValueCaster >(); runTestCase< R(A&, A&), 2, LValueCaster >(); runTestCase< R(A&, A&, A&), 3, LValueCaster >(); runTestCase< R(CA&), 1, ConstCaster >(); runTestCase< R(CA&, CA&), 2, ConstCaster >(); runTestCase< R(CA&, CA&, CA&), 3, ConstCaster >(); runFunctionTestCase(); runFunctionTestCase(); runFunctionTestCase(); runFunctionTestCase(); #if TEST_STD_VER >= 11 runFunctionTestCase11(); runFunctionTestCase11(); #endif runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); { typedef ConstCaster CC; runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); runFunctorTestCase(); } #if TEST_STD_VER >= 11 runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); { typedef MoveCaster MC; runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); runFunctorTestCase11(); } #endif }