multi-level-substitution.cpp revision 089e8939b7b3e72c32477e39df82f18e6a8f436e
11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
31176bdada62cabc6ec4b0308a930e83b679d5d36John Recktemplate<typename T, T ...Values> struct value_tuple {};
41176bdada62cabc6ec4b0308a930e83b679d5d36John Recktemplate<typename...> struct tuple { };
51176bdada62cabc6ec4b0308a930e83b679d5d36John Recktemplate<typename T, typename U> struct pair { };
61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
71176bdada62cabc6ec4b0308a930e83b679d5d36John Recktemplate<typename T, T Value> struct value_c;
81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
91176bdada62cabc6ec4b0308a930e83b679d5d36John Recktemplate<typename T, typename U>
101176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstruct is_same {
111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  static const bool value = false;
121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck};
131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
141176bdada62cabc6ec4b0308a930e83b679d5d36John Recktemplate<typename T>
151176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstruct is_same<T, T> {
161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  static const bool value = true;
171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck};
181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
191176bdada62cabc6ec4b0308a930e83b679d5d36John Recktemplate<typename T>
201176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstruct X0 {
211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<T ...Values>
221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  void f(value_tuple<T, Values...> * = 0);
231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck};
241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
251176bdada62cabc6ec4b0308a930e83b679d5d36John Reckvoid test_X0() {
261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  X0<int>().f<1, 2, 3, 4, 5>();
271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
291176bdada62cabc6ec4b0308a930e83b679d5d36John Recknamespace PacksAtDifferentLevels {
301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<typename ...Types>
321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  struct X {
331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename> struct Inner {
341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = 1;
351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename ...YTypes>
381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    struct Inner<tuple<pair<Types, YTypes>...> > {
391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = sizeof...(Types) - sizeof...(YTypes);
401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  };
421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check0[X<short, int, long>::Inner<tuple<pair<short, unsigned short>,
441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                             pair<int, unsigned int>,
451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                             pair<long, unsigned long>>
461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                       >::value == 0? 1 : -1];
471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check1[X<short, int>::Inner<tuple<pair<short, unsigned short>,
491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                        pair<int, unsigned int>,
501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                        pair<long, unsigned long>>
511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                       >::value == 1? 1 : -1];
521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<unsigned ...Values> struct unsigned_tuple { };
541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<typename ...Types>
551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  struct X1 {
561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename, typename> struct Inner {
571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = 0;
581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename ...YTypes>
611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    struct Inner<tuple<pair<Types, YTypes>...>,
621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                 unsigned_tuple<sizeof(Types) + sizeof(YTypes)...>> {
631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = 1;
641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  };
661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check2[X1<short, int, long>::Inner<tuple<pair<short, unsigned short>,
681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                               pair<int, unsigned int>,
691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                               pair<long, unsigned long>>,
701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                      unsigned_tuple<sizeof(short) + sizeof(unsigned short),
711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                     sizeof(int) + sizeof(unsigned int),
721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                     sizeof(long) + sizeof(unsigned long)>
731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                       >::value == 1? 1 : -1];
741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check3[X1<short, int>::Inner<tuple<pair<short, unsigned short>,
751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                         pair<int, unsigned int>,
761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                         pair<long, unsigned long>>,
771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                      unsigned_tuple<sizeof(short) + sizeof(unsigned short),
781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                     sizeof(int) + sizeof(unsigned int),
791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                     sizeof(long) + sizeof(unsigned long)>
801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                       >::value == 0? 1 : -1];
811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<typename ...Types>
831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  struct X2 {
841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename> struct Inner {
851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = 1;
861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename R, typename ...YTypes>
891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    struct Inner<R(pair<Types, YTypes>...)> {
901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = sizeof...(Types) - sizeof...(YTypes);
911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  };
931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check4[X2<short, int, long>::Inner<int(pair<short, unsigned short>,
951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                            pair<int, unsigned int>,
961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                            pair<long, unsigned long>)
971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                     >::value == 0? 1 : -1];
981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check5[X2<short, int>::Inner<int(pair<short, unsigned short>,
1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                       pair<int, unsigned int>,
1011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                       pair<long, unsigned long>)
1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                     >::value == 1? 1 : -1];
1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<typename T, typename U>
1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  struct some_function_object {
1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename>
1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    struct result_of;
1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  };
1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<template<class> class...> struct metafun_tuple { };
1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<typename ...Types1>
1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  struct X3 {
1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename, typename> struct Inner {
1151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = 0;
1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename ...Types2>
1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    struct Inner<tuple<pair<Types1, Types2>...>,
1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                 metafun_tuple<some_function_object<Types1, Types2>::template result_of...> > {
1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = 1;
1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  };
1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check6[X3<short, int, long>::Inner<tuple<pair<short, unsigned short>,
1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                               pair<int, unsigned int>,
1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                               pair<long, unsigned long>>,
1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 metafun_tuple<
1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         some_function_object<short, unsigned short>::result_of,
1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         some_function_object<int, unsigned int>::result_of,
1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         some_function_object<long, unsigned long>::result_of>
1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                     >::value == 1? 1 : -1];
1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check7[X3<short, int>::Inner<tuple<pair<short, unsigned short>,
1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                               pair<int, unsigned int>,
1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                               pair<long, unsigned long>>,
1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                 metafun_tuple<
1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         some_function_object<short, unsigned short>::result_of,
1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         some_function_object<int, unsigned int>::result_of,
1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                         some_function_object<long, unsigned long>::result_of>
1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                     >::value == 0? 1 : -1];
1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<unsigned I, unsigned J> struct unsigned_pair { };
1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<unsigned ...Values1>
1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  struct X4 {
1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename> struct Inner {
1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = 0;
1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<unsigned ...Values2>
1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    struct Inner<tuple<unsigned_pair<Values1, Values2>...>> {
1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = 1;
1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  };
1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check8[X4<1, 3, 5>::Inner<tuple<unsigned_pair<1, 2>,
1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                      unsigned_pair<3, 4>,
1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                      unsigned_pair<5, 6>>
1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                >::value == 1? 1 : -1];
1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check9[X4<1, 3>::Inner<tuple<unsigned_pair<1, 2>,
1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                   unsigned_pair<3, 4>,
1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                                   unsigned_pair<5, 6>>
1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                             >::value == 0? 1 : -1];
1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<class> struct add_reference;
1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<class> struct add_pointer;
1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<class> struct add_const;
1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<template<class> class ...Templates>
1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  struct X5 {
1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename> struct Inner {
1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = 0;
1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<typename ...Types>
1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    struct Inner<tuple<Templates<Types>...>> {
1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      static const unsigned value = 1;
1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  };
1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check10[X5<add_reference, add_pointer, add_const>
1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                ::Inner<tuple<add_reference<int>,
1831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              add_pointer<float>,
1841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              add_const<double>>>::value == 1? 1 : -1];
1851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int check11[X5<add_reference, add_pointer>
1861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                ::Inner<tuple<add_reference<int>,
1871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              add_pointer<float>,
1881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              add_const<double>>>::value == 0? 1 : -1];
1891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1921176bdada62cabc6ec4b0308a930e83b679d5d36John Recknamespace ExpandingNonTypeTemplateParameters {
1931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  template<typename ...Types>
1941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  struct tuple_of_values {
1951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    template<Types ...Values> // expected-error{{a non-type template parameter cannot have type 'float'}} \
1961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    // expected-note{{template parameter is declared here}}
1971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    struct apply { // expected-note 2{{template is declared here}}
1981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      typedef tuple<value_c<Types, Values>...> type;
1991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
2001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  };
2011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  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
220namespace 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
238namespace 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