Home | History | Annotate | Download | only in func.require
      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 }