brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.7 KiB · ba1c655 Raw
241 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// <functional>10 11// INVOKE (f, t1, t2, ..., tN)12 13//------------------------------------------------------------------------------14// TESTING INVOKE(f, t1, t2, ..., tN)15//   - Bullet 7 -- f(t2, ..., tN)16//17// Overview:18//    Bullet 7 handles the cases where the first argument is not a member19//   function.20//21// Concerns:22//   1) Different types of callable objects are supported. Including23//      1a) Free Function pointers and references.24//      1b) Classes which provide a call operator25//      1c) lambdas26//   2) The callable objects are perfect forwarded.27//   3) The arguments are perfect forwarded.28//   4) Signatures which include varargs are supported.29//   5) In C++03 3 extra arguments should be allowed.30//31// Plan:32//  1) Define a set of free functions, 'SF', and class types with call33//     operators, 'SC', that address concerns 4 and 5. The free functions should34//     return 'FunctionID::setUncheckedCall()' and the call operators should35//     return 'MethodID::setUncheckedCall()'.36//37//  2) For each function 'f' in 'SF' and 'SC' attempt to call 'f'38//     using the correct number of arguments and cv-ref qualifiers. Check that39//     'f' has been called using 'FunctionID::checkCall()' if 'f' is a free40//     function and 'MethodID::checkCall()' otherwise.41 42 43 44#include <functional>45#include <type_traits>46#include <cassert>47 48#include "test_macros.h"49#include "invoke_helpers.h"50 51 52//==============================================================================53// freeFunction03 - A C++03 free function.54void*& freeFunction03() {55    return FunctionPtrID<void*&(), freeFunction03>::setUncheckedCall();56}57 58void*& freeFunction03(...) {59    return FunctionPtrID<void*&(...), freeFunction03>::setUncheckedCall();60}61 62template <class A0>63void*& freeFunction03(A0&) {64    return FunctionPtrID<void*&(A0&), freeFunction03>::setUncheckedCall();65}66 67 68template <class A0>69void*& freeFunction03(A0&, ...) {70    return FunctionPtrID<void*&(A0&, ...), freeFunction03>::setUncheckedCall();71}72 73template <class A0, class A1>74void*& freeFunction03(A0&, A1&) {75    return FunctionPtrID<void*&(A0&, A1&), freeFunction03>::setUncheckedCall();76}77 78 79template <class A0, class A1>80void*& freeFunction03(A0&, A1&, ...) {81    return FunctionPtrID<void*&(A0&, A1&, ...), freeFunction03>::setUncheckedCall();82}83 84template <class A0, class A1, class A2>85void*& freeFunction03(A0&, A1&, A2&) {86    return FunctionPtrID<void*&(A0&, A1&, A2&), freeFunction03>::setUncheckedCall();87}88 89template <class A0, class A1, class A2>90void*& freeFunction03(A0&, A1&, A2&, ...) {91    return FunctionPtrID<void*&(A0&, A1&, A2&, ...), freeFunction03>::setUncheckedCall();92}93 94//==============================================================================95// Functor03 - C++03 compatible functor object96struct Functor03 {97    typedef void*& R;98    typedef Functor03 C;99#define F(Args, ...) \100    __VA_ARGS__ R operator() Args { return MethodID<R(C::*) Args>::setUncheckedCall(); } \101    __VA_ARGS__ R operator() Args const { return MethodID<R(C::*) Args const>::setUncheckedCall(); } \102    __VA_ARGS__ R operator() Args volatile { return MethodID<R(C::*) Args volatile>::setUncheckedCall(); } \103    __VA_ARGS__ R operator() Args const volatile { return MethodID<R(C::*) Args const volatile>::setUncheckedCall(); }104#105    F(())106    F((A0&), template <class A0>)107    F((A0&, A1&), template <class A0, class A1>)108    F((A0&, A1&, A2&), template <class A0, class A1, class A2>)109#undef F110public:111    Functor03() {}112private:113    Functor03(Functor03 const&);114    Functor03& operator=(Functor03 const&);115};116 117 118//==============================================================================119// TestCaseFunctorImp - A test case for an operator() class method.120//   ClassType - The type of the call object.121//   CallSig   - The function signature of the call operator being tested.122//   Arity     - the arity of 'CallSig'123//   ObjCaster - Transformation function applied to call object.124//   ArgCaster - Transformation function applied to the extra arguments.125template <class ClassType, class CallSig, int Arity,126          class ObjCaster, class ArgCaster = LValueCaster>127struct TestCaseFunctorImp {128public:129    static void run() {130        typedef MethodID<CallSig ClassType::*> MID;131        BasicTest<MID, Arity, ObjCaster, ArgCaster> t;132        typedef ClassType T;133        typedef DerivedFromType<T> D;134        T obj;135        D der;136        t.runTest(obj);137        t.runTest(der);138    }139};140 141//==============================================================================142// TestCaseFreeFunction - A test case for a free function.143//   CallSig   - The function signature of the free function being tested.144//   FnPtr     - The function being tested.145//   Arity     - the arity of 'CallSig'146//   ArgCaster - Transformation function to be applied to the extra arguments.147template <class CallSig, CallSig* FnPtr, int Arity, class ArgCaster>148struct TestCaseFreeFunction {149public:150    static void run() {151        typedef FunctionPtrID<CallSig, FnPtr> FID;152        BasicTest<FID, Arity, LValueCaster, ArgCaster> t;153 154        DerefToType<CallSig*> deref_to(FnPtr);155        DerefToType<CallSig&> deref_to_ref(*FnPtr);156 157        t.runTest(FnPtr);158        t.runTest(*FnPtr);159        t.runTest(deref_to);160        t.runTest(deref_to_ref);161    }162};163 164//==============================================================================165//                          runTest Helpers166//==============================================================================167template <class Sig, int Arity, class ArgCaster>168void runFunctionTestCase() {169    TestCaseFreeFunction<Sig, freeFunction03, Arity, ArgCaster>();170}171 172template <class Sig, int Arity, class ObjCaster, class ArgCaster>173void runFunctorTestCase() {174    TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster, ArgCaster>::run();175}176 177template <class Sig, int Arity, class ObjCaster>178void runFunctorTestCase() {179    TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster>::run();180}181 182// runTestCase - Run a test case for both function and functor types.183template <class Sig, int Arity, class ArgCaster>184void runTestCase() {185    runFunctionTestCase<Sig, Arity, ArgCaster>();186    runFunctorTestCase <Sig, Arity, LValueCaster, ArgCaster>();187};188 189int main(int, char**) {190    typedef void*& R;191    typedef ArgType A;192    typedef A const CA;193 194    runTestCase< R(),                                   0, LValueCaster      >();195    runTestCase< R(A&),                                 1, LValueCaster      >();196    runTestCase< R(A&, A&),                             2, LValueCaster      >();197    runTestCase< R(A&, A&, A&),                         3, LValueCaster      >();198    runTestCase< R(CA&),                                1, ConstCaster       >();199    runTestCase< R(CA&, CA&),                           2, ConstCaster       >();200    runTestCase< R(CA&, CA&, CA&),                      3, ConstCaster       >();201 202    runFunctionTestCase<R(...),                         0, LValueCaster      >();203    runFunctionTestCase<R(A&, ...),                     1, LValueCaster      >();204    runFunctionTestCase<R(A&, A&, ...),                 2, LValueCaster      >();205    runFunctionTestCase<R(A&, A&, A&, ...),             3, LValueCaster      >();206 207    runFunctorTestCase<R(),                             0, LValueCaster      >();208    runFunctorTestCase<R() const,                       0, ConstCaster       >();209    runFunctorTestCase<R() volatile,                    0, VolatileCaster    >();210    runFunctorTestCase<R() const volatile,              0, CVCaster          >();211    runFunctorTestCase<R(A&),                           1, LValueCaster      >();212    runFunctorTestCase<R(A&) const,                     1, ConstCaster       >();213    runFunctorTestCase<R(A&) volatile,                  1, VolatileCaster    >();214    runFunctorTestCase<R(A&) const volatile,            1, CVCaster          >();215    runFunctorTestCase<R(A&, A&),                       2, LValueCaster      >();216    runFunctorTestCase<R(A&, A&) const,                 2, ConstCaster       >();217    runFunctorTestCase<R(A&, A&) volatile,              2, VolatileCaster    >();218    runFunctorTestCase<R(A&, A&) const volatile,        2, CVCaster          >();219    runFunctorTestCase<R(A&, A&, A&),                   3, LValueCaster      >();220    runFunctorTestCase<R(A&, A&, A&) const,             3, ConstCaster       >();221    runFunctorTestCase<R(A&, A&, A&) volatile,          3, VolatileCaster    >();222    runFunctorTestCase<R(A&, A&, A&) const volatile,    3, CVCaster          >();223    {224    typedef ConstCaster CC;225    runFunctorTestCase<R(CA&),                          1, LValueCaster,   CC>();226    runFunctorTestCase<R(CA&) const,                    1, ConstCaster,    CC>();227    runFunctorTestCase<R(CA&) volatile,                 1, VolatileCaster, CC>();228    runFunctorTestCase<R(CA&) const volatile,           1, CVCaster,       CC>();229    runFunctorTestCase<R(CA&, CA&),                     2, LValueCaster,   CC>();230    runFunctorTestCase<R(CA&, CA&) const,               2, ConstCaster,    CC>();231    runFunctorTestCase<R(CA&, CA&) volatile,            2, VolatileCaster, CC>();232    runFunctorTestCase<R(CA&, CA&) const volatile,      2, CVCaster,       CC>();233    runFunctorTestCase<R(CA&, CA&, CA&),                3, LValueCaster,   CC>();234    runFunctorTestCase<R(CA&, CA&, CA&) const,          3, ConstCaster,    CC>();235    runFunctorTestCase<R(CA&, CA&, CA&) volatile,       3, VolatileCaster, CC>();236    runFunctorTestCase<R(CA&, CA&, CA&) const volatile, 3, CVCaster,       CC>();237    }238 239  return 0;240}241