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
test_X0()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
test()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
main()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
253 namespace PR13386 {
254 template<typename...> struct tuple {};
255 template<typename...T>
256 struct S {
257 template<typename...U>
fPR13386::S258 void f(T &&...t, U &&...u) {} // expected-note {{candidate}}
259 template<typename...U>
gPR13386::S260 void g(U &&...u, T &&...t) {} // expected-note {{candidate}}
261 template<typename...U>
hPR13386::S262 void h(tuple<T, U> &&...) {} // expected-note 2{{candidate}}
263
264 template<typename...U>
265 struct X {
266 template<typename...V>
267 void x(tuple<T, U, V> &&...); // expected-error {{different lengths}}
268 };
269 };
270
test()271 void test() {
272 S<>().f();
273 S<>().f(0);
274 S<int>().f(0);
275 S<int>().f(0, 1);
276 S<int, int>().f(0); // expected-error {{no matching member function for call}}
277
278 S<>().g();
279 S<>().g(0);
280 S<int>().g(0);
281 S<int>().g(0, 1); // expected-error {{no matching member function for call}}
282 S<int>().g<int>(0, 1);
283 S<int, int>().g(0, 1);
284
285 S<>().h();
286 S<>().h(0); // expected-error {{no matching member function for call}}
287 S<int>().h({}); // expected-error {{no matching member function for call}}
288 S<int>().h<int>({});
289 S<int>().h(tuple<int,int>{});
290 S<int, int>().h(tuple<int,int>{}, tuple<int,int>{});
291
292 S<int, int>::X<char>(); // expected-note {{here}}
293 }
294 }
295