1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // UNSUPPORTED: c++03, c++11, c++14, c++17 |
10 | |
11 | // <array> |
12 | |
13 | // LWG-3382 NTTP for pair and array: |
14 | // array<T, N> is a structural type ([temp.param]) if T is a structural type. |
15 | |
16 | #include <array> |
17 | |
18 | #include <cstddef> |
19 | #include <string> |
20 | |
21 | struct LiteralBase {}; |
22 | struct LiteralNSDM {}; |
23 | |
24 | struct LiteralType : LiteralBase { |
25 | LiteralNSDM nsdm; |
26 | }; |
27 | |
28 | struct NotALiteral { |
29 | NotALiteral() {} |
30 | }; |
31 | |
32 | int i; |
33 | NotALiteral not_a_literal; |
34 | |
35 | namespace test_full_type { |
36 | template <class T, std::size_t S, std::array<T, S> A> |
37 | struct test {}; |
38 | |
39 | using A = test<int, 2, std::array{2, 3}>; |
40 | using B = test<LiteralType, 0, std::array<LiteralType, 0>{}>; |
41 | using C = test<int*, 1, std::array<int*, 1>{&i}>; |
42 | using D = test<NotALiteral*, 1, std::array<NotALiteral*, 1>{¬_a_literal}>; |
43 | |
44 | using E = test<NotALiteral, 1, std::array<NotALiteral, 1>{}>; |
45 | // expected-error-re@*:* {{non-type template parameter has non-literal type 'std::array<NotALiteral, 1U{{L{0,2}.*}}>'}} |
46 | |
47 | using F = test<std::string, 2, std::array<std::string, 2>{}>; |
48 | // expected-error-re@*:* {{type 'std::array<{{(std::)?}}string, 2U{{L{0,2}.*}}>' {{(\(aka 'array<basic_string<char>, 2UL{0,2}>'\) )?}}of non-type template parameter is not a structural type}} |
49 | } // namespace test_full_type |
50 | |
51 | namespace test_ctad { |
52 | template <std::array A> |
53 | struct test {}; |
54 | |
55 | using A = test<std::array{2, 3}>; |
56 | using B = test<std::array<LiteralType, 0>{}>; |
57 | using C = test<std::array<int*, 1>{&i}>; |
58 | using D = test<std::array<NotALiteral*, 1>{¬_a_literal}>; |
59 | |
60 | using E = test<std::array<NotALiteral, 1>{}>; |
61 | // expected-error@-1 {{non-type template parameter has non-literal type 'std::array<NotALiteral, 1>'}} |
62 | |
63 | using F = test<std::array<std::string, 2>{}>; |
64 | // expected-error-re@-1 {{type 'std::array<{{(std::)?}}string, 2>'{{( \(aka 'std::array<std::string, 2>'\))?}} of non-type template parameter is not a structural type}} |
65 | } // namespace test_ctad |
66 | |
67 | namespace test_auto { |
68 | template <auto A> |
69 | struct test {}; |
70 | |
71 | using A = test<std::array{2, 3}>; |
72 | using B = test<std::array<LiteralType, 0>{}>; |
73 | using C = test<std::array<int*, 1>{&i}>; |
74 | using D = test<std::array<NotALiteral*, 1>{¬_a_literal}>; |
75 | |
76 | using E = test<std::array<NotALiteral, 1>{}>; |
77 | // expected-error@-1 {{non-type template parameter has non-literal type 'std::array<NotALiteral, 1>'}} |
78 | |
79 | using F = test<std::array<std::string, 2>{}>; |
80 | // expected-error@-1 {{type 'std::array<std::string, 2>' (aka 'array<basic_string<char>, 2>') of non-type template parameter is not a structural type}} |
81 | } // namespace test_auto |
82 | |