| 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 | |