1 // RUN: %clang_cc1 -std=c++2c -verify %s 2 3 struct NotAPack; 4 template <typename T, auto V, template<typename> typename Tp> 5 void not_pack() { 6 int i = 0; 7 i...[0]; // expected-error {{i does not refer to the name of a parameter pack}} 8 V...[0]; // expected-error {{V does not refer to the name of a parameter pack}} 9 NotAPack...[0] a; // expected-error{{'NotAPack' does not refer to the name of a parameter pack}} 10 T...[0] b; // expected-error{{'T' does not refer to the name of a parameter pack}} 11 Tp...[0] c; // expected-error{{'Tp' does not refer to the name of a parameter pack}} 12 } 13 14 template <typename T, auto V, template<typename> typename Tp> 15 void not_pack_arrays() { 16 NotAPack...[0] a[1]; // expected-error{{'NotAPack' does not refer to the name of a parameter pack}} 17 T...[0] b[1]; // expected-error{{'T' does not refer to the name of a parameter pack}} 18 Tp...[0] c[1]; // expected-error{{'Tp' does not refer to the name of a parameter pack}} 19 } 20 21 template <typename T> 22 struct TTP; 23 24 void test_errors() { 25 not_pack<int, 0, TTP>(); 26 not_pack_arrays<int, 0, TTP>(); 27 } 28 29 namespace invalid_indexes { 30 31 int non_constant_index(); // expected-note 2{{declared here}} 32 33 template <int idx> 34 int params(auto... p) { 35 return p...[idx]; // #error-param-size 36 } 37 38 template <auto N, typename...T> 39 int test_types() { 40 T...[N] a; // #error-type-size 41 } 42 43 void test() { 44 params<0>(); // expected-note{{here}} \ 45 // expected-error@#error-param-size {{invalid index 0 for pack p of size 0}} 46 params<1>(0); // expected-note{{here}} \ 47 // expected-error@#error-param-size {{invalid index 1 for pack p of size 1}} 48 params<-1>(0); // expected-note{{here}} \ 49 // expected-error@#error-param-size {{invalid index -1 for pack p of size 1}} 50 51 test_types<-1>(); //expected-note {{in instantiation}} \ 52 // expected-error@#error-type-size {{invalid index -1 for pack 'T' of size 0}} 53 test_types<-1, int>(); //expected-note {{in instantiation}} \ 54 // expected-error@#error-type-size {{invalid index -1 for pack 'T' of size 1}} 55 test_types<0>(); //expected-note {{in instantiation}} \ 56 // expected-error@#error-type-size {{invalid index 0 for pack 'T' of size 0}} 57 test_types<1, int>(); //expected-note {{in instantiation}} \ 58 // expected-error@#error-type-size {{invalid index 1 for pack 'T' of size 1}} 59 } 60 61 void invalid_indexes(auto... p) { 62 p...[non_constant_index()]; // expected-error {{array size is not a constant expression}}\ 63 // expected-note {{cannot be used in a constant expression}} 64 65 const char* no_index = ""; 66 p...[no_index]; // expected-error {{value of type 'const char *' is not implicitly convertible}} 67 } 68 69 void invalid_index_types() { 70 []<typename... T> { 71 T...[non_constant_index()] a; // expected-error {{array size is not a constant expression}}\ 72 // expected-note {{cannot be used in a constant expression}} 73 }(); //expected-note {{in instantiation}} 74 } 75 76 } 77 78 template <typename T, typename U> 79 constexpr bool is_same = false; 80 81 template <typename T> 82 constexpr bool is_same<T, T> = true; 83 84 template <typename T> 85 constexpr bool f(auto&&... p) { 86 return is_same<T, decltype(p...[0])>; 87 } 88 89 void g() { 90 int a = 0; 91 const int b = 0; 92 static_assert(f<int&&>(0)); 93 static_assert(f<int&>(a)); 94 static_assert(f<const int&>(b)); 95 } 96 97 template <auto... p> 98 struct check_ice { 99 enum e { 100 x = p...[0] 101 }; 102 }; 103 104 static_assert(check_ice<42>::x == 42); 105 106 struct S{}; 107 template <auto... p> 108 constexpr auto constant_initializer = p...[0]; 109 constexpr auto InitOk = constant_initializer<S{}>; 110 111 consteval int evaluate(auto... p) { 112 return p...[0]; 113 } 114 constexpr int x = evaluate(42, S{}); 115 static_assert(x == 42); 116 117 118 namespace splice { 119 template <auto ... Is> 120 struct IL{}; 121 122 template <typename ... Ts> 123 struct TL{}; 124 125 template <typename Tl, typename Il> 126 struct SpliceImpl; 127 128 template <typename ... Ts, auto ...Is> 129 struct SpliceImpl<TL<Ts...>, IL<Is...>>{ 130 using type = TL<Ts...[Is]...>; 131 }; 132 133 template <typename Tl, typename Il> 134 using Splice = typename SpliceImpl<Tl, Il>::type; 135 using type = Splice<TL<char, short, long, double>, IL<1, 2>>; 136 static_assert(is_same<type, TL<short, long>>); 137 } 138 139 140 namespace GH81697 { 141 142 template<class... Ts> struct tuple { 143 int __x0; 144 }; 145 146 template<auto I, class... Ts> 147 Ts...[I]& get(tuple<Ts...>& t) { 148 return t.__x0; 149 } 150 151 void f() { 152 tuple<int> x; 153 get<0>(x); 154 } 155 156 } 157 158 namespace GH88929 { 159 bool b = a...[0]; // expected-error {{use of undeclared identifier 'a'}} 160 using E = P...[0]; // expected-error {{unknown type name 'P'}} \ 161 // expected-error {{expected ';' after alias declaration}} 162 } 163 164 namespace GH88925 { 165 template <typename...> struct S {}; 166 167 template <auto...> struct W {}; 168 169 template <int...> struct sequence {}; 170 171 template <typename... args, int... indices> auto f(sequence<indices...>) { 172 return S<args...[indices]...>(); // #use 173 } 174 175 template <auto... args, int... indices> auto g(sequence<indices...>) { 176 return W<args...[indices]...>(); // #nttp-use 177 } 178 179 void h() { 180 static_assert(__is_same(decltype(f<int>(sequence<0, 0>())), S<int, int>)); 181 static_assert(__is_same(decltype(f<int, long>(sequence<0, 0>())), S<int, int>)); 182 static_assert(__is_same(decltype(f<int, long>(sequence<0, 1>())), S<int, long>)); 183 f<int, long>(sequence<3>()); 184 // expected-error@#use {{invalid index 3 for pack 'args' of size 2}}} 185 // expected-note-re@-2 {{function template specialization '{{.*}}' requested here}} 186 187 struct foo {}; 188 struct bar {}; 189 struct baz {}; 190 191 static_assert(__is_same(decltype(g<foo{}, bar{}, baz{}>(sequence<0, 2, 1>())), W<foo{}, baz{}, bar{}>)); 192 g<foo{}>(sequence<4>()); 193 // expected-error@#nttp-use {{invalid index 4 for pack args of size 1}} 194 // expected-note-re@-2 {{function template specialization '{{.*}}' requested here}} 195 } 196 } 197 198 namespace GH91885 { 199 200 void test(auto...args){ 201 [&]<int idx>(){ 202 using R = decltype( args...[idx] ) ; 203 }.template operator()<0>(); 204 } 205 206 template<int... args> 207 void test2(){ 208 [&]<int idx>(){ 209 using R = decltype( args...[idx] ) ; // #test2-R 210 }.template operator()<0>(); // #test2-call 211 } 212 213 void f( ) { 214 test(1); 215 test2<1>(); 216 test2(); 217 // expected-error@#test2-R {{invalid index 0 for pack args of size 0}} 218 // expected-note@#test2-call {{requested here}} 219 // expected-note@-3 {{requested here}} 220 } 221 222 223 } 224 225 namespace std { 226 struct type_info { 227 const char *name; 228 }; 229 } // namespace std 230 231 namespace GH93650 { 232 auto func(auto... inputArgs) { return typeid(inputArgs...[0]); } 233 } // namespace GH93650 234 235 236 namespace GH105900 { 237 238 template <typename... opts> 239 struct types { 240 template <unsigned idx> 241 static constexpr __SIZE_TYPE__ get_index() { return idx; } 242 243 template <unsigned s> 244 static auto x() -> opts...[get_index<s>()] {} 245 }; 246 247 template <auto... opts> 248 struct vars { 249 template <unsigned idx> 250 static constexpr __SIZE_TYPE__ get_index() { return idx; } 251 252 template <unsigned s> 253 static auto x() -> decltype(opts...[get_index<s>()]) {return 0;} 254 }; 255 256 void f() { 257 types<void>::x<0>(); 258 vars<0>::x<0>(); 259 } 260 261 } // namespace GH105900 262 263 namespace GH105903 { 264 265 template <typename... opts> struct temp { 266 template <unsigned s> static auto x() -> opts... [s] {} // expected-note {{invalid index 0 for pack 'opts' of size 0}} 267 }; 268 269 void f() { 270 temp<>::x<0>(); // expected-error {{no matching}} 271 } 272 273 } // namespace GH105903 274 275 namespace GH116105 { 276 277 template <unsigned long Np, class... Ts> using pack_type = Ts...[Np]; 278 279 template <unsigned long Np, auto... Ts> using pack_expr = decltype(Ts...[Np]); 280 281 template <class...> struct types; 282 283 template <class, long... Is> struct indices; 284 285 template <class> struct repack; 286 287 template <long... Idx> struct repack<indices<long, Idx...>> { 288 template <class... Ts> 289 using pack_type_alias = types<pack_type<Idx, Ts...>...>; 290 291 template <class... Ts> 292 using pack_expr_alias = types<pack_expr<Idx, Ts{}...>...>; 293 }; 294 295 template <class... Args> struct mdispatch_ { 296 using Idx = __make_integer_seq<indices, long, sizeof...(Args)>; 297 298 static_assert(__is_same( 299 typename repack<Idx>::template pack_type_alias<Args...>, types<Args...>)); 300 301 static_assert(__is_same( 302 typename repack<Idx>::template pack_expr_alias<Args...>, types<Args...>)); 303 }; 304 305 mdispatch_<int, int> d; 306 307 } // namespace GH116105 308 309 namespace GH121242 { 310 // Non-dependent type pack access 311 template <int...x> 312 int y = x...[0]; 313 314 struct X {}; 315 316 template <X...x> 317 X z = x...[0]; 318 319 void foo() { 320 (void)y<0>; 321 (void)z<X{}>; 322 } 323 } // namespace GH121242 324 325 namespace GH123033 { 326 template <class... Types> 327 requires __is_same_as(Types...[0], int) 328 void print(double d); 329 330 template <class... Types> 331 requires __is_same_as(Types...[0], int) 332 void print(double d); 333 334 template <class... Types> 335 Types...[0] convert(double d); 336 337 template <class... Types> 338 Types...[0] convert(double d) { 339 return static_cast<Types...[0]>(d); 340 } 341 342 void f() { 343 print<int, int>(12.34); 344 convert<int, int>(12.34); 345 } 346 } 347