Home | History | Annotate | Download | only in tuple.apply
      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 // UNSUPPORTED: c++98, c++03, c++11
     11 
     12 // <experimental/tuple>
     13 
     14 // template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
     15 
     16 // Test function types.
     17 
     18 #include <experimental/tuple>
     19 #include <array>
     20 #include <utility>
     21 #include <cassert>
     22 
     23 // std::array is explicitly allowed to be initialized with A a = { init-list };.
     24 // Disable the missing braces warning for this reason.
     25 #include "disable_missing_braces_warning.h"
     26 
     27 namespace ex = std::experimental;
     28 
     29 int count = 0;
     30 
     31 void f_void_0() { ++count; }
     32 void f_void_1(int i) { count += i; }
     33 void f_void_2(int x, int y) { count += (x + y); }
     34 void f_void_3(int x, int y, int z) { count += (x + y + z); }
     35 
     36 int f_int_0() { return ++count; }
     37 int f_int_1(int x) { return count += x; }
     38 int f_int_2(int x, int y) { return count += (x + y); }
     39 int f_int_3(int x, int y, int z) { return count += (x + y + z); }
     40 
     41 struct A_void_0
     42 {
     43     A_void_0() {}
     44     void operator()() { ++count; }
     45     void operator()() const { ++count; ++count; }
     46 };
     47 
     48 struct A_void_1
     49 {
     50     A_void_1() {}
     51     void operator()(int x) { count += x; }
     52     void operator()(int x) const { count += x + 1; }
     53 };
     54 
     55 struct A_void_2
     56 {
     57     A_void_2() {}
     58     void operator()(int x, int y) { count += (x + y); }
     59     void operator()(int x, int y) const { count += (x + y) + 1; }
     60 };
     61 
     62 struct A_void_3
     63 {
     64     A_void_3() {}
     65     void operator()(int x, int y, int z) { count += (x + y + z); }
     66     void operator()(int x, int y, int z) const { count += (x + y + z) + 1; }
     67 };
     68 
     69 
     70 struct A_int_0
     71 {
     72     A_int_0() {}
     73     int operator()() { return ++count; }
     74     int operator()() const { ++count; return ++count; }
     75 };
     76 
     77 struct A_int_1
     78 {
     79     A_int_1() {}
     80     int operator()(int x) { return count += x; }
     81     int operator()(int x) const { return count += (x + 1); }
     82 
     83 };
     84 
     85 struct A_int_2
     86 {
     87     A_int_2() {}
     88     int operator()(int x, int y) { return count += (x + y); }
     89     int operator()(int x, int y) const { return count += (x + y + 1); }
     90 };
     91 
     92 struct A_int_3
     93 {
     94     A_int_3() {}
     95     int operator()(int x, int y, int z) { return count += (x + y + z); }
     96     int operator()(int x, int y, int z) const { return count += (x + y + z + 1); }
     97 };
     98 
     99 
    100 template <class Tuple>
    101 void test_void_0()
    102 {
    103     count = 0;
    104     // function
    105     {
    106         Tuple t{};
    107         ex::apply(f_void_0, t);
    108         assert(count == 1);
    109     }
    110     count = 0;
    111     // function pointer
    112     {
    113         Tuple t{};
    114         auto fp = &f_void_0;
    115         ex::apply(fp, t);
    116         assert(count == 1);
    117     }
    118     count = 0;
    119     // functor
    120     {
    121         Tuple t{};
    122         A_void_0 a;
    123         ex::apply(a, t);
    124         assert(count == 1);
    125     }
    126     count = 0;
    127     // const functor
    128     {
    129         Tuple t{};
    130         A_void_0 const a;
    131         ex::apply(a, t);
    132         assert(count == 2);
    133     }
    134 }
    135 
    136 template <class Tuple>
    137 void test_void_1()
    138 {
    139     count = 0;
    140     // function
    141     {
    142         Tuple t{1};
    143         ex::apply(f_void_1, t);
    144         assert(count == 1);
    145     }
    146     count = 0;
    147     // function pointer
    148     {
    149         Tuple t{2};
    150         void (*fp)(int) = f_void_1;
    151         ex::apply(fp, t);
    152         assert(count == 2);
    153     }
    154     count = 0;
    155     // functor
    156     {
    157         Tuple t{3};
    158         A_void_1 fn;
    159         ex::apply(fn, t);
    160         assert(count == 3);
    161     }
    162     count = 0;
    163     // const functor
    164     {
    165         Tuple t{4};
    166         A_void_1 const a;
    167         ex::apply(a, t);
    168         assert(count == 5);
    169     }
    170 }
    171 
    172 template <class Tuple>
    173 void test_void_2()
    174 {
    175     count = 0;
    176     // function
    177     {
    178         Tuple t{1, 2};
    179         ex::apply(f_void_2, t);
    180         assert(count == 3);
    181     }
    182     count = 0;
    183     // function pointer
    184     {
    185         Tuple t{2, 3};
    186         auto fp = &f_void_2;
    187         ex::apply(fp, t);
    188         assert(count == 5);
    189     }
    190     count = 0;
    191     // functor
    192     {
    193         Tuple t{3, 4};
    194         A_void_2 a;
    195         ex::apply(a, t);
    196         assert(count == 7);
    197     }
    198     count = 0;
    199     // const functor
    200     {
    201         Tuple t{4, 5};
    202         A_void_2 const a;
    203         ex::apply(a, t);
    204         assert(count == 10);
    205     }
    206 }
    207 
    208 template <class Tuple>
    209 void test_void_3()
    210 {
    211     count = 0;
    212     // function
    213     {
    214         Tuple t{1, 2, 3};
    215         ex::apply(f_void_3, t);
    216         assert(count == 6);
    217     }
    218     count = 0;
    219     // function pointer
    220     {
    221         Tuple t{2, 3, 4};
    222         auto fp = &f_void_3;
    223         ex::apply(fp, t);
    224         assert(count == 9);
    225     }
    226     count = 0;
    227     // functor
    228     {
    229         Tuple t{3, 4, 5};
    230         A_void_3 a;
    231         ex::apply(a, t);
    232         assert(count == 12);
    233     }
    234     count = 0;
    235     // const functor
    236     {
    237         Tuple t{4, 5, 6};
    238         A_void_3 const a;
    239         ex::apply(a, t);
    240         assert(count == 16);
    241     }
    242 }
    243 
    244 
    245 
    246 template <class Tuple>
    247 void test_int_0()
    248 {
    249     count = 0;
    250     // function
    251     {
    252         Tuple t{};
    253         assert(1 == ex::apply(f_int_0, t));
    254         assert(count == 1);
    255     }
    256     count = 0;
    257     // function pointer
    258     {
    259         Tuple t{};
    260         auto fp = &f_int_0;
    261         assert(1 == ex::apply(fp, t));
    262         assert(count == 1);
    263     }
    264     count = 0;
    265     // functor
    266     {
    267         Tuple t{};
    268         A_int_0 a;
    269         assert(1 == ex::apply(a, t));
    270         assert(count == 1);
    271     }
    272     count = 0;
    273     // const functor
    274     {
    275         Tuple t{};
    276         A_int_0 const a;
    277         assert(2 == ex::apply(a, t));
    278         assert(count == 2);
    279     }
    280 }
    281 
    282 template <class Tuple>
    283 void test_int_1()
    284 {
    285     count = 0;
    286     // function
    287     {
    288         Tuple t{1};
    289         assert(1 == ex::apply(f_int_1, t));
    290         assert(count == 1);
    291     }
    292     count = 0;
    293     // function pointer
    294     {
    295         Tuple t{2};
    296         int (*fp)(int) = f_int_1;
    297         assert(2 == ex::apply(fp, t));
    298         assert(count == 2);
    299     }
    300     count = 0;
    301     // functor
    302     {
    303         Tuple t{3};
    304         A_int_1 fn;
    305         assert(3 == ex::apply(fn, t));
    306         assert(count == 3);
    307     }
    308     count = 0;
    309     // const functor
    310     {
    311         Tuple t{4};
    312         A_int_1 const a;
    313         assert(5 == ex::apply(a, t));
    314         assert(count == 5);
    315     }
    316 }
    317 
    318 template <class Tuple>
    319 void test_int_2()
    320 {
    321     count = 0;
    322     // function
    323     {
    324         Tuple t{1, 2};
    325         assert(3 == ex::apply(f_int_2, t));
    326         assert(count == 3);
    327     }
    328     count = 0;
    329     // function pointer
    330     {
    331         Tuple t{2, 3};
    332         auto fp = &f_int_2;
    333         assert(5 == ex::apply(fp, t));
    334         assert(count == 5);
    335     }
    336     count = 0;
    337     // functor
    338     {
    339         Tuple t{3, 4};
    340         A_int_2 a;
    341         assert(7 == ex::apply(a, t));
    342         assert(count == 7);
    343     }
    344     count = 0;
    345     // const functor
    346     {
    347         Tuple t{4, 5};
    348         A_int_2 const a;
    349         assert(10 == ex::apply(a, t));
    350         assert(count == 10);
    351     }
    352 }
    353 
    354 template <class Tuple>
    355 void test_int_3()
    356 {
    357     count = 0;
    358     // function
    359     {
    360         Tuple t{1, 2, 3};
    361         assert(6 == ex::apply(f_int_3, t));
    362         assert(count == 6);
    363     }
    364     count = 0;
    365     // function pointer
    366     {
    367         Tuple t{2, 3, 4};
    368         auto fp = &f_int_3;
    369         assert(9 == ex::apply(fp, t));
    370         assert(count == 9);
    371     }
    372     count = 0;
    373     // functor
    374     {
    375         Tuple t{3, 4, 5};
    376         A_int_3 a;
    377         assert(12 == ex::apply(a, t));
    378         assert(count == 12);
    379     }
    380     count = 0;
    381     // const functor
    382     {
    383         Tuple t{4, 5, 6};
    384         A_int_3 const a;
    385         assert(16 == ex::apply(a, t));
    386         assert(count == 16);
    387     }
    388 }
    389 
    390 template <class Tuple>
    391 void test_0()
    392 {
    393     test_void_0<Tuple>();
    394     test_int_0<Tuple>();
    395 }
    396 
    397 template <class Tuple>
    398 void test_1()
    399 {
    400     test_void_1<Tuple>();
    401     test_int_1<Tuple>();
    402 }
    403 
    404 template <class Tuple>
    405 void test_2()
    406 {
    407     test_void_2<Tuple>();
    408     test_int_2<Tuple>();
    409 }
    410 
    411 template <class Tuple>
    412 void test_3()
    413 {
    414     test_void_3<Tuple>();
    415     test_int_3<Tuple>();
    416 }
    417 
    418 int main()
    419 {
    420     test_0<std::tuple<>>();
    421 
    422     test_1<std::tuple<int>>();
    423     test_1<std::array<int, 1>>();
    424 
    425     test_2<std::tuple<int, int>>();
    426     test_2<std::pair<int, int>>();
    427     test_2<std::array<int, 2>>();
    428 
    429     test_3<std::tuple<int, int, int>>();
    430     test_3<std::array<int, 3>>();
    431 }
    432