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