321 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s2 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) 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 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 s265 {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> &&...) {}287 // expected-note@-1 {{candidate template ignored: could not match 'tuple<T, U>' against 'int'}}288 // expected-note@-2 {{candidate template ignored: substitution failure: deduced incomplete pack <(no value)> for template parameter 'U'}}289 290 template<typename...U>291 struct X {292 template<typename...V>293 void x(tuple<T, U, V> &&...); // expected-error {{different lengths}}294 };295 };296 297 void test() {298 S<>().f();299 S<>().f(0);300 S<int>().f(0);301 S<int>().f(0, 1);302 S<int, int>().f(0); // expected-error {{no matching member function for call}}303 304 S<>().g();305 S<>().g(0);306 S<int>().g(0);307 S<int>().g(0, 1); // expected-error {{no matching member function for call}}308 S<int>().g<int>(0, 1);309 S<int, int>().g(0, 1);310 311 S<>().h();312 S<>().h(0); // expected-error {{no matching member function for call}}313 S<int>().h({}); // expected-error {{no matching member function for call}}314 S<int>().h<int>({});315 S<int>().h(tuple<int,int>{});316 S<int, int>().h(tuple<int,int>{}, tuple<int,int>{});317 318 S<int, int>::X<char>(); // expected-note {{here}}319 }320}321