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 }
    191 
    192 namespace ExpandingNonTypeTemplateParameters {
    193   template<typename ...Types>
    194   struct tuple_of_values {
    195     template<Types ...Values> // expected-error{{a non-type template parameter cannot have type 'float'}} \
    196     // expected-note{{template parameter is declared here}}
    197     struct apply { // expected-note 2{{template is declared here}}
    198       typedef tuple<value_c<Types, Values>...> type;
    199     };
    200   };
    201 
    202   int i;
    203   float f;
    204   int check_tuple_of_values_1[
    205         is_same<tuple_of_values<int&, float&, char, int>::apply<i, f, 'a', 17>
    206                   ::type,
    207                 tuple<value_c<int&, i>, value_c<float&, f>, value_c<char, 'a'>,
    208                       value_c<int, 17>>
    209                 >::value? 1 : -1];
    210 
    211   tuple_of_values<int, float> tv1; // expected-note{{in instantiation of template class 'ExpandingNonTypeTemplateParameters::tuple_of_values<int, float>' requested here}}
    212 
    213   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'}}
    214 
    215   tuple_of_values<int&, float&>::apply<i>::type tv3; // expected-error{{too few template arguments for class template 'apply'}}
    216 
    217   tuple_of_values<int&, float&>::apply<i, f, i>::type tv4; // expected-error{{too many template arguments for class template 'apply'}}
    218 }
    219 
    220 namespace ExpandingFunctionParameters {
    221   template<typename ...T>
    222   struct X0 {
    223     typedef int type;
    224   };
    225 
    226   template<typename ...T>
    227   struct X1 {
    228     template<typename ... U>
    229     typename X0<T(T, U...)...>::type f(U...);
    230   };
    231 
    232   void test() {
    233     X1<float> x1;
    234     x1.f(17, 3.14159);
    235   }
    236 }
    237 
    238 namespace PR10230 {
    239   template<typename>
    240   struct s
    241   {
    242     template<typename... Args>
    243     auto f() -> int(&)[sizeof...(Args)];
    244   };
    245 
    246   void main()
    247   {
    248     int (&ir1)[1] = s<int>().f<int>();
    249     int (&ir3)[3] = s<int>().f<int, float, double>();
    250   }
    251 }
    252