multi-level-substitution.cpp revision 9a4db032ecd991626d236a502e770126db32bd31
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2
3template<typename T, T ...Values> struct value_tuple {};
4template<typename...> struct tuple { };
5template<typename T, typename U> struct pair { };
6
7template<typename T, T Value> struct value_c;
8
9template<typename T, typename U>
10struct is_same {
11  static const bool value = false;
12};
13
14template<typename T>
15struct is_same<T, T> {
16  static const bool value = true;
17};
18
19template<typename T>
20struct X0 {
21  template<T ...Values>
22  void f(value_tuple<T, Values...> * = 0);
23};
24
25void test_X0() {
26  X0<int>().f<1, 2, 3, 4, 5>();
27}
28
29namespace 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) -> decltype(g(A(a + B())...)) { return g(A(a + B())...); }
197
198      template<typename...B>
199      constexpr auto f2(A ...a, B ...b) -> 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) -> decltype(g(a+b+c...)) { return g(a+b+c...); }
204      };
205    };
206    struct A { constexpr operator int() { return 2; } };
207    struct B { constexpr operator int() { 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
216namespace 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
244namespace 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
262namespace 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
277namespace 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