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 namespace PR13811 {
g(int n,int m)191 constexpr int g(int n, int m) { return n * 10 + m; }
192
193 template<typename...A>
194 struct X6 {
195 template<typename...B>
f1PacksAtDifferentLevels::PR13811::X6196 constexpr auto f1(A ...a) const -> decltype(g(A(a + B())...)) { return g(A(a + B())...); }
197
198 template<typename...B>
f2PacksAtDifferentLevels::PR13811::X6199 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>
fPacksAtDifferentLevels::PR13811::X6::Inner203 constexpr auto f(A ...a, B ...b, C ...c) const -> decltype(g(a+b+c...)) { return g(a+b+c...); }
204 };
205 };
operator intPacksAtDifferentLevels::PR13811::A206 struct A { constexpr operator int() const { return 2; } };
operator intPacksAtDifferentLevels::PR13811::B207 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
test()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
main()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>
fPR13386::S282 void f(T &&...t, U &&...u) {} // expected-note {{candidate}}
283 template<typename...U>
gPR13386::S284 void g(U &&...u, T &&...t) {} // expected-note {{candidate}}
285 template<typename...U>
hPR13386::S286 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
test()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