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 // Test all the ways of initializing a std::array.
10 
11 #include <array>
12 #include <cassert>
13 #include <type_traits>
14 #include "test_macros.h"
15 
16 
17 struct NoDefault {
NoDefaultNoDefault18     TEST_CONSTEXPR NoDefault(int) { }
19 };
20 
21 // Test default initialization
22 // This one isn't constexpr because omitting to initialize fundamental types
23 // isn't valid in a constexpr context.
24 struct test_default_initialization {
25     template <typename T>
operator ()test_default_initialization26     void operator()() const
27     {
28         std::array<T, 0> a0; (void)a0;
29         std::array<T, 1> a1; (void)a1;
30         std::array<T, 2> a2; (void)a2;
31         std::array<T, 3> a3; (void)a3;
32 
33         std::array<NoDefault, 0> nodefault; (void)nodefault;
34     }
35 };
36 
37 struct test_nondefault_initialization {
38     template <typename T>
operator ()test_nondefault_initialization39     TEST_CONSTEXPR_CXX14 void operator()() const
40     {
41         // Check direct-list-initialization syntax (introduced in C++11)
42     #if TEST_STD_VER >= 11
43         {
44             {
45                 std::array<T, 0> a0_0{}; (void)a0_0;
46             }
47             {
48                 std::array<T, 1> a1_0{}; (void)a1_0;
49                 std::array<T, 1> a1_1{T()}; (void)a1_1;
50             }
51             {
52                 std::array<T, 2> a2_0{}; (void)a2_0;
53                 std::array<T, 2> a2_1{T()}; (void)a2_1;
54                 std::array<T, 2> a2_2{T(), T()}; (void)a2_2;
55             }
56             {
57                 std::array<T, 3> a3_0{}; (void)a3_0;
58                 std::array<T, 3> a3_1{T()}; (void)a3_1;
59                 std::array<T, 3> a3_2{T(), T()}; (void)a3_2;
60                 std::array<T, 3> a3_3{T(), T(), T()}; (void)a3_3;
61             }
62 
63             std::array<NoDefault, 0> nodefault{}; (void)nodefault;
64         }
65     #endif
66 
67         // Check copy-list-initialization syntax
68         {
69             {
70                 std::array<T, 0> a0_0 = {}; (void)a0_0;
71             }
72             {
73                 std::array<T, 1> a1_0 = {}; (void)a1_0;
74                 std::array<T, 1> a1_1 = {T()}; (void)a1_1;
75             }
76             {
77                 std::array<T, 2> a2_0 = {}; (void)a2_0;
78                 std::array<T, 2> a2_1 = {T()}; (void)a2_1;
79                 std::array<T, 2> a2_2 = {T(), T()}; (void)a2_2;
80             }
81             {
82                 std::array<T, 3> a3_0 = {}; (void)a3_0;
83                 std::array<T, 3> a3_1 = {T()}; (void)a3_1;
84                 std::array<T, 3> a3_2 = {T(), T()}; (void)a3_2;
85                 std::array<T, 3> a3_3 = {T(), T(), T()}; (void)a3_3;
86             }
87 
88             std::array<NoDefault, 0> nodefault = {}; (void)nodefault;
89         }
90 
91         // Test aggregate initialization
92         {
93             {
94                 std::array<T, 0> a0_0 = {{}}; (void)a0_0;
95             }
96             {
97                 std::array<T, 1> a1_0 = {{}}; (void)a1_0;
98                 std::array<T, 1> a1_1 = {{T()}}; (void)a1_1;
99             }
100             {
101                 std::array<T, 2> a2_0 = {{}}; (void)a2_0;
102                 std::array<T, 2> a2_1 = {{T()}}; (void)a2_1;
103                 std::array<T, 2> a2_2 = {{T(), T()}}; (void)a2_2;
104             }
105             {
106                 std::array<T, 3> a3_0 = {{}}; (void)a3_0;
107                 std::array<T, 3> a3_1 = {{T()}}; (void)a3_1;
108                 std::array<T, 3> a3_2 = {{T(), T()}}; (void)a3_2;
109                 std::array<T, 3> a3_3 = {{T(), T(), T()}}; (void)a3_3;
110             }
111 
112             // See http://wg21.link/LWG2157
113             std::array<NoDefault, 0> nodefault = {{}}; (void)nodefault;
114         }
115     }
116 };
117 
118 // Test construction from an initializer-list
test_initializer_list()119 TEST_CONSTEXPR_CXX14 bool test_initializer_list()
120 {
121     {
122         std::array<double, 3> const a3_0 = {};
123         assert(a3_0[0] == double());
124         assert(a3_0[1] == double());
125         assert(a3_0[2] == double());
126     }
127     {
128         std::array<double, 3> const a3_1 = {1};
129         assert(a3_1[0] == double(1));
130         assert(a3_1[1] == double());
131         assert(a3_1[2] == double());
132     }
133     {
134         std::array<double, 3> const a3_2 = {1, 2.2};
135         assert(a3_2[0] == double(1));
136         assert(a3_2[1] == 2.2);
137         assert(a3_2[2] == double());
138     }
139     {
140         std::array<double, 3> const a3_3 = {1, 2, 3.5};
141         assert(a3_3[0] == double(1));
142         assert(a3_3[1] == double(2));
143         assert(a3_3[2] == 3.5);
144     }
145 
146     return true;
147 }
148 
149 struct Empty { };
150 struct Trivial { int i; int j; };
151 struct NonTrivial {
NonTrivialNonTrivial152     TEST_CONSTEXPR NonTrivial() { }
NonTrivialNonTrivial153     TEST_CONSTEXPR NonTrivial(NonTrivial const&) { }
154 };
155 struct NonEmptyNonTrivial {
156     int i; int j;
NonEmptyNonTrivialNonEmptyNonTrivial157     TEST_CONSTEXPR NonEmptyNonTrivial() : i(22), j(33) { }
NonEmptyNonTrivialNonEmptyNonTrivial158     TEST_CONSTEXPR NonEmptyNonTrivial(NonEmptyNonTrivial const&) : i(22), j(33) { }
159 };
160 
161 template <typename F>
with_all_types()162 TEST_CONSTEXPR_CXX14 bool with_all_types()
163 {
164     F().template operator()<char>();
165     F().template operator()<int>();
166     F().template operator()<long>();
167     F().template operator()<float>();
168     F().template operator()<double>();
169     F().template operator()<long double>();
170     F().template operator()<Empty>();
171     F().template operator()<Trivial>();
172     F().template operator()<NonTrivial>();
173     F().template operator()<NonEmptyNonTrivial>();
174     return true;
175 }
176 
main(int,char **)177 int main(int, char**)
178 {
179     with_all_types<test_nondefault_initialization>();
180     with_all_types<test_default_initialization>(); // not constexpr
181     test_initializer_list();
182 #if TEST_STD_VER >= 14
183     static_assert(with_all_types<test_nondefault_initialization>(), "");
184     static_assert(test_initializer_list(), "");
185 #endif
186 
187     return 0;
188 }
189