Home | History | Annotate | Download | only in temp.variadic
      1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
      2 
      3 template<typename T, T ...Values> struct value_tuple {};
      4 template<typename...> struct tuple { };
      5 template<typename T, typename U> struct pair { };
      6 
      7 template<typename T, T Value> struct value_c;
      8 
      9 template<typename T, typename U>
     10 struct is_same {
     11   static const bool value = false;
     12 };
     13 
     14 template<typename T>
     15 struct is_same<T, T> {
     16   static const bool value = true;
     17 };
     18 
     19 template<typename T>
     20 struct X0 {
     21   template<T ...Values>
     22   void f(value_tuple<T, Values...> * = 0);
     23 };
     24 
     25 void test_X0() {
     26   X0<int>().f<1, 2, 3, 4, 5>();
     27 }
     28 
     29 namespace PacksAtDifferentLevels {
     30 
     31   template<typename ...Types>
     32   struct X {
     33     template<typename> struct Inner {
     34       static const unsigned value = 1;
     35     };
     36 
     37     template<typename ...YTypes>
     38     struct Inner<tuple<pair<Types, YTypes>...> > {
     39       static const unsigned value = sizeof...(Types) - sizeof...(YTypes);
     40     };
     41   };
     42 
     43   int check0[X<short, int, long>::Inner<tuple<pair<short, unsigned short>,
     44                                              pair<int, unsigned int>,
     45                                              pair<long, unsigned long>>
     46                                        >::value == 0? 1 : -1];
     47 
     48   int check1[X<short, int>::Inner<tuple<pair<short, unsigned short>,
     49                                         pair<int, unsigned int>,
     50                                         pair<long, unsigned long>>
     51                                        >::value == 1? 1 : -1];
     52 
     53   template<unsigned ...Values> struct unsigned_tuple { };
     54   template<typename ...Types>
     55   struct X1 {
     56     template<typename, typename> struct Inner {
     57       static const unsigned value = 0;
     58     };
     59 
     60     template<typename ...YTypes>
     61     struct Inner<tuple<pair<Types, YTypes>...>,
     62                  unsigned_tuple<sizeof(Types) + sizeof(YTypes)...>> {
     63       static const unsigned value = 1;
     64     };
     65   };
     66 
     67   int check2[X1<short, int, long>::Inner<tuple<pair<short, unsigned short>,
     68                                                pair<int, unsigned int>,
     69                                                pair<long, unsigned long>>,
     70                       unsigned_tuple<sizeof(short) + sizeof(unsigned short),
     71                                      sizeof(int) + sizeof(unsigned int),
     72                                      sizeof(long) + sizeof(unsigned long)>
     73                                        >::value == 1? 1 : -1];
     74   int check3[X1<short, int>::Inner<tuple<pair<short, unsigned short>,
     75                                          pair<int, unsigned int>,
     76                                          pair<long, unsigned long>>,
     77                       unsigned_tuple<sizeof(short) + sizeof(unsigned short),
     78                                      sizeof(int) + sizeof(unsigned int),
     79                                      sizeof(long) + sizeof(unsigned long)>
     80                                        >::value == 0? 1 : -1];
     81 
     82   template<typename ...Types>
     83   struct X2 {
     84     template<typename> struct Inner {
     85       static const unsigned value = 1;
     86     };
     87 
     88     template<typename R, typename ...YTypes>
     89     struct Inner<R(pair<Types, YTypes>...)> {
     90       static const unsigned value = sizeof...(Types) - sizeof...(YTypes);
     91     };
     92   };
     93 
     94   int check4[X2<short, int, long>::Inner<int(pair<short, unsigned short>,
     95                                             pair<int, unsigned int>,
     96                                             pair<long, unsigned long>)
     97                                      >::value == 0? 1 : -1];
     98 
     99   int check5[X2<short, int>::Inner<int(pair<short, unsigned short>,
    100                                        pair<int, unsigned int>,
    101                                        pair<long, unsigned long>)
    102                                      >::value == 1? 1 : -1];
    103 
    104   template<typename T, typename U>
    105   struct some_function_object {
    106     template<typename>
    107     struct result_of;
    108   };
    109 
    110   template<template<class> class...> struct metafun_tuple { };
    111 
    112   template<typename ...Types1>
    113   struct X3 {
    114     template<typename, typename> struct Inner {
    115       static const unsigned value = 0;
    116     };
    117 
    118     template<typename ...Types2>
    119     struct Inner<tuple<pair<Types1, Types2>...>,
    120                  metafun_tuple<some_function_object<Types1, Types2>::template result_of...> > {
    121       static const unsigned value = 1;
    122     };
    123   };
    124 
    125   int check6[X3<short, int, long>::Inner<tuple<pair<short, unsigned short>,
    126                                                pair<int, unsigned int>,
    127                                                pair<long, unsigned long>>,
    128                                  metafun_tuple<
    129                          some_function_object<short, unsigned short>::result_of,
    130                          some_function_object<int, unsigned int>::result_of,
    131                          some_function_object<long, unsigned long>::result_of>
    132                                      >::value == 1? 1 : -1];
    133   int check7[X3<short, int>::Inner<tuple<pair<short, unsigned short>,
    134                                                pair<int, unsigned int>,
    135                                                pair<long, unsigned long>>,
    136                                  metafun_tuple<
    137                          some_function_object<short, unsigned short>::result_of,
    138                          some_function_object<int, unsigned int>::result_of,
    139                          some_function_object<long, unsigned long>::result_of>
    140                                      >::value == 0? 1 : -1];
    141 
    142   template<unsigned I, unsigned J> struct unsigned_pair { };
    143 
    144   template<unsigned ...Values1>
    145   struct X4 {
    146     template<typename> struct Inner {
    147       static const unsigned value = 0;
    148     };
    149 
    150     template<unsigned ...Values2>
    151     struct Inner<tuple<unsigned_pair<Values1, Values2>...>> {
    152       static const unsigned value = 1;
    153     };
    154   };
    155 
    156   int check8[X4<1, 3, 5>::Inner<tuple<unsigned_pair<1, 2>,
    157                                       unsigned_pair<3, 4>,
    158                                       unsigned_pair<5, 6>>
    159                                 >::value == 1? 1 : -1];
    160   int check9[X4<1, 3>::Inner<tuple<unsigned_pair<1, 2>,
    161                                    unsigned_pair<3, 4>,
    162                                    unsigned_pair<5, 6>>
    163                              >::value == 0? 1 : -1];
    164 
    165   template<class> struct add_reference;
    166   template<class> struct add_pointer;
    167   template<class> struct add_const;
    168 
    169   template<template<class> class ...Templates>
    170   struct X5 {
    171     template<typename> struct Inner {
    172       static const unsigned value = 0;
    173     };
    174 
    175     template<typename ...Types>
    176     struct Inner<tuple<Templates<Types>...>> {
    177       static const unsigned value = 1;
    178     };
    179   };
    180 
    181   int check10[X5<add_reference, add_pointer, add_const>
    182                 ::Inner<tuple<add_reference<int>,
    183                               add_pointer<float>,
    184                               add_const<double>>>::value == 1? 1 : -1];
    185   int check11[X5<add_reference, add_pointer>
    186                 ::Inner<tuple<add_reference<int>,
    187                               add_pointer<float>,
    188                               add_const<double>>>::value == 0? 1 : -1];
    189 
    190   namespace PR13811 {
    191     constexpr int g(int n, int m) { return n * 10 + m; }
    192 
    193     template<typename...A>
    194     struct X6 {
    195       template<typename...B>
    196       constexpr auto f1(A ...a) const -> decltype(g(A(a + B())...)) { return g(A(a + B())...); }
    197 
    198       template<typename...B>
    199       constexpr auto f2(A ...a, B ...b) const -> decltype(g((&a)[b] ...)) { return g((&a)[b] ...); } // expected-note {{past-the-end}}
    200 
    201       template<typename...B> struct Inner {
    202         template<typename...C>
    203         constexpr auto f(A ...a, B ...b, C ...c) const -> decltype(g(a+b+c...)) { return g(a+b+c...); }
    204       };
    205     };
    206     struct A { constexpr operator int() const { return 2; } };
    207     struct B { constexpr operator int() const { return 1; } };
    208 
    209     static_assert(X6<unsigned char, int>().f1<A, B>(255, 1) == 12, "");
    210     static_assert(X6<int, int>().f2(3, 4, 0, 0) == 34, "");
    211     static_assert(X6<int, int>().f2(3, 4, 0, 1) == 34, ""); // expected-error {{constant expression}} expected-note {{in call}}
    212     static_assert(X6<int, int>::Inner<int, int>().f(1, 2, 3, 4, 5, 6) == 102, "");
    213   }
    214 }
    215 
    216 namespace ExpandingNonTypeTemplateParameters {
    217   template<typename ...Types>
    218   struct tuple_of_values {
    219     template<Types ...Values> // expected-error{{a non-type template parameter cannot have type 'float'}} \
    220     // expected-note{{template parameter is declared here}}
    221     struct apply { // expected-note 2{{template is declared here}}
    222       typedef tuple<value_c<Types, Values>...> type;
    223     };
    224   };
    225 
    226   int i;
    227   float f;
    228   int check_tuple_of_values_1[
    229         is_same<tuple_of_values<int&, float&, char, int>::apply<i, f, 'a', 17>
    230                   ::type,
    231                 tuple<value_c<int&, i>, value_c<float&, f>, value_c<char, 'a'>,
    232                       value_c<int, 17>>
    233                 >::value? 1 : -1];
    234 
    235   tuple_of_values<int, float> tv1; // expected-note{{in instantiation of template class 'ExpandingNonTypeTemplateParameters::tuple_of_values<int, float>' requested here}}
    236 
    237   tuple_of_values<int&, float&>::apply<i, i>::type tv2; // expected-error{{non-type template parameter of reference type 'float &' cannot bind to template argument of type 'int'}}
    238 
    239   tuple_of_values<int&, float&>::apply<i>::type tv3; // expected-error{{too few template arguments for class template 'apply'}}
    240 
    241   tuple_of_values<int&, float&>::apply<i, f, i>::type tv4; // expected-error{{too many template arguments for class template 'apply'}}
    242 }
    243 
    244 namespace ExpandingFunctionParameters {
    245   template<typename ...T>
    246   struct X0 {
    247     typedef int type;
    248   };
    249 
    250   template<typename ...T>
    251   struct X1 {
    252     template<typename ... U>
    253     typename X0<T(T, U...)...>::type f(U...);
    254   };
    255 
    256   void test() {
    257     X1<float> x1;
    258     x1.f(17, 3.14159);
    259   }
    260 }
    261 
    262 namespace PR10230 {
    263   template<typename>
    264   struct s
    265   {
    266     template<typename... Args>
    267     auto f() -> int(&)[sizeof...(Args)];
    268   };
    269 
    270   void main()
    271   {
    272     int (&ir1)[1] = s<int>().f<int>();
    273     int (&ir3)[3] = s<int>().f<int, float, double>();
    274   }
    275 }
    276 
    277 namespace PR13386 {
    278   template<typename...> struct tuple {};
    279   template<typename...T>
    280   struct S {
    281     template<typename...U>
    282     void f(T &&...t, U &&...u) {} // expected-note {{candidate}}
    283     template<typename...U>
    284     void g(U &&...u, T &&...t) {} // expected-note {{candidate}}
    285     template<typename...U>
    286     void h(tuple<T, U> &&...) {} // expected-note 2{{candidate}}
    287 
    288     template<typename...U>
    289     struct X {
    290       template<typename...V>
    291       void x(tuple<T, U, V> &&...); // expected-error {{different lengths}}
    292     };
    293   };
    294 
    295   void test() {
    296     S<>().f();
    297     S<>().f(0);
    298     S<int>().f(0);
    299     S<int>().f(0, 1);
    300     S<int, int>().f(0); // expected-error {{no matching member function for call}}
    301 
    302     S<>().g();
    303     S<>().g(0);
    304     S<int>().g(0);
    305     S<int>().g(0, 1); // expected-error {{no matching member function for call}}
    306     S<int>().g<int>(0, 1);
    307     S<int, int>().g(0, 1);
    308 
    309     S<>().h();
    310     S<>().h(0); // expected-error {{no matching member function for call}}
    311     S<int>().h({}); // expected-error {{no matching member function for call}}
    312     S<int>().h<int>({});
    313     S<int>().h(tuple<int,int>{});
    314     S<int, int>().h(tuple<int,int>{}, tuple<int,int>{});
    315 
    316     S<int, int>::X<char>(); // expected-note {{here}}
    317   }
    318 }
    319