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