347 lines · cpp
1// RUN: %clang_cc1 -std=c++2c -verify %s2 3struct NotAPack;4template <typename T, auto V, template<typename> typename Tp>5void 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 14template <typename T, auto V, template<typename> typename Tp>15void 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 21template <typename T>22struct TTP;23 24void test_errors() {25 not_pack<int, 0, TTP>();26 not_pack_arrays<int, 0, TTP>();27}28 29namespace invalid_indexes {30 31int non_constant_index(); // expected-note 2{{declared here}}32 33template <int idx>34int params(auto... p) {35 return p...[idx]; // #error-param-size36}37 38template <auto N, typename...T>39int test_types() {40 T...[N] a; // #error-type-size41}42 43void 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 61void 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 69void 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 78template <typename T, typename U>79constexpr bool is_same = false;80 81template <typename T>82constexpr bool is_same<T, T> = true;83 84template <typename T>85constexpr bool f(auto&&... p) {86 return is_same<T, decltype(p...[0])>;87}88 89void 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 97template <auto... p>98struct check_ice {99 enum e {100 x = p...[0]101 };102};103 104static_assert(check_ice<42>::x == 42);105 106struct S{};107template <auto... p>108constexpr auto constant_initializer = p...[0];109constexpr auto InitOk = constant_initializer<S{}>;110 111consteval int evaluate(auto... p) {112 return p...[0];113}114constexpr int x = evaluate(42, S{});115static_assert(x == 42);116 117 118namespace splice {119template <auto ... Is>120struct IL{};121 122template <typename ... Ts>123struct TL{};124 125template <typename Tl, typename Il>126struct SpliceImpl;127 128template <typename ... Ts, auto ...Is>129struct SpliceImpl<TL<Ts...>, IL<Is...>>{130 using type = TL<Ts...[Is]...>;131};132 133template <typename Tl, typename Il>134using Splice = typename SpliceImpl<Tl, Il>::type;135using type = Splice<TL<char, short, long, double>, IL<1, 2>>;136static_assert(is_same<type, TL<short, long>>);137}138 139 140namespace GH81697 {141 142template<class... Ts> struct tuple {143 int __x0;144};145 146template<auto I, class... Ts>147Ts...[I]& get(tuple<Ts...>& t) {148 return t.__x0;149}150 151void f() {152 tuple<int> x;153 get<0>(x);154}155 156}157 158namespace 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 164namespace GH88925 {165template <typename...> struct S {};166 167template <auto...> struct W {};168 169template <int...> struct sequence {};170 171template <typename... args, int... indices> auto f(sequence<indices...>) {172 return S<args...[indices]...>(); // #use173}174 175template <auto... args, int... indices> auto g(sequence<indices...>) {176 return W<args...[indices]...>(); // #nttp-use177}178 179void 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 198namespace GH91885 {199 200void test(auto...args){201 [&]<int idx>(){202 using R = decltype( args...[idx] ) ;203 }.template operator()<0>();204}205 206template<int... args>207void test2(){208 [&]<int idx>(){209 using R = decltype( args...[idx] ) ; // #test2-R210 }.template operator()<0>(); // #test2-call211}212 213void 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 225namespace std {226struct type_info {227 const char *name;228};229} // namespace std230 231namespace GH93650 {232auto func(auto... inputArgs) { return typeid(inputArgs...[0]); }233} // namespace GH93650234 235 236namespace GH105900 {237 238template <typename... opts>239struct 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 247template <auto... opts>248struct 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 256void f() {257 types<void>::x<0>();258 vars<0>::x<0>();259}260 261} // namespace GH105900262 263namespace GH105903 {264 265template <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 269void f() {270 temp<>::x<0>(); // expected-error {{no matching}}271}272 273} // namespace GH105903274 275namespace GH116105 {276 277template <unsigned long Np, class... Ts> using pack_type = Ts...[Np];278 279template <unsigned long Np, auto... Ts> using pack_expr = decltype(Ts...[Np]);280 281template <class...> struct types;282 283template <class, long... Is> struct indices;284 285template <class> struct repack;286 287template <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 295template <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 305mdispatch_<int, int> d;306 307} // namespace GH116105308 309namespace GH121242 {310 // Non-dependent type pack access311 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 GH121242324 325namespace 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