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