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.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