1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // Test all the ways of initializing a std::array.
13 #include <type_traits>
14 #include "test_macros.h"
18 TEST_CONSTEXPR
NoDefault(int) { }
21 struct test_initialization
{
23 TEST_CONSTEXPR_CXX14
void operator()() const
25 // Check default initalization
27 std::array
<T
, 0> a0
; (void)a0
;
28 // Before C++20, default initialization doesn't work inside constexpr for
29 // trivially default constructible types. This only apply to non-empty arrays,
30 // since empty arrays don't hold an element of type T.
32 if (!(TEST_IS_CONSTANT_EVALUATED
&& std::is_trivially_default_constructible
<T
>::value
))
43 std::array
<NoDefault
, 0> nodefault
; (void)nodefault
;
46 // A const empty array can also be default-initialized regardless of the type
47 // it contains. For non-empty arrays, this doesn't work whenever T doesn't
48 // have a user-provided default constructor.
50 const std::array
<T
, 0> a0
; (void)a0
;
51 const std::array
<NoDefault
, 0> nodefault
; (void)nodefault
;
54 // Check direct-list-initialization syntax (introduced in C++11)
55 #if TEST_STD_VER >= 11
58 std::array
<T
, 0> a0_0
{}; (void)a0_0
;
61 std::array
<T
, 1> a1_0
{}; (void)a1_0
;
62 std::array
<T
, 1> a1_1
{T()}; (void)a1_1
;
65 std::array
<T
, 2> a2_0
{}; (void)a2_0
;
66 std::array
<T
, 2> a2_1
{T()}; (void)a2_1
;
67 std::array
<T
, 2> a2_2
{T(), T()}; (void)a2_2
;
70 std::array
<T
, 3> a3_0
{}; (void)a3_0
;
71 std::array
<T
, 3> a3_1
{T()}; (void)a3_1
;
72 std::array
<T
, 3> a3_2
{T(), T()}; (void)a3_2
;
73 std::array
<T
, 3> a3_3
{T(), T(), T()}; (void)a3_3
;
76 std::array
<NoDefault
, 0> nodefault
{}; (void)nodefault
;
80 // Check copy-list-initialization syntax
83 std::array
<T
, 0> a0_0
= {}; (void)a0_0
;
86 std::array
<T
, 1> a1_0
= {}; (void)a1_0
;
87 std::array
<T
, 1> a1_1
= {T()}; (void)a1_1
;
90 std::array
<T
, 2> a2_0
= {}; (void)a2_0
;
91 std::array
<T
, 2> a2_1
= {T()}; (void)a2_1
;
92 std::array
<T
, 2> a2_2
= {T(), T()}; (void)a2_2
;
95 std::array
<T
, 3> a3_0
= {}; (void)a3_0
;
96 std::array
<T
, 3> a3_1
= {T()}; (void)a3_1
;
97 std::array
<T
, 3> a3_2
= {T(), T()}; (void)a3_2
;
98 std::array
<T
, 3> a3_3
= {T(), T(), T()}; (void)a3_3
;
101 std::array
<NoDefault
, 0> nodefault
= {}; (void)nodefault
;
104 // Test aggregate initialization
107 std::array
<T
, 0> a0_0
= {{}}; (void)a0_0
;
110 std::array
<T
, 1> a1_0
= {{}}; (void)a1_0
;
111 std::array
<T
, 1> a1_1
= {{T()}}; (void)a1_1
;
114 std::array
<T
, 2> a2_0
= {{}}; (void)a2_0
;
115 std::array
<T
, 2> a2_1
= {{T()}}; (void)a2_1
;
116 std::array
<T
, 2> a2_2
= {{T(), T()}}; (void)a2_2
;
119 std::array
<T
, 3> a3_0
= {{}}; (void)a3_0
;
120 std::array
<T
, 3> a3_1
= {{T()}}; (void)a3_1
;
121 std::array
<T
, 3> a3_2
= {{T(), T()}}; (void)a3_2
;
122 std::array
<T
, 3> a3_3
= {{T(), T(), T()}}; (void)a3_3
;
125 // See http://wg21.link/LWG2157
126 std::array
<NoDefault
, 0> nodefault
= {{}}; (void)nodefault
;
131 // Test construction from an initializer-list
132 TEST_CONSTEXPR_CXX14
bool test_initializer_list()
135 std::array
<double, 3> const a3_0
= {};
136 assert(a3_0
[0] == double());
137 assert(a3_0
[1] == double());
138 assert(a3_0
[2] == double());
141 std::array
<double, 3> const a3_1
= {1};
142 assert(a3_1
[0] == double(1));
143 assert(a3_1
[1] == double());
144 assert(a3_1
[2] == double());
147 std::array
<double, 3> const a3_2
= {1, 2.2};
148 assert(a3_2
[0] == double(1));
149 assert(a3_2
[1] == 2.2);
150 assert(a3_2
[2] == double());
153 std::array
<double, 3> const a3_3
= {1, 2, 3.5};
154 assert(a3_3
[0] == double(1));
155 assert(a3_3
[1] == double(2));
156 assert(a3_3
[2] == 3.5);
163 struct Trivial
{ int i
; int j
; };
165 TEST_CONSTEXPR
NonTrivial() { }
166 TEST_CONSTEXPR
NonTrivial(NonTrivial
const&) { }
168 struct NonEmptyNonTrivial
{
170 TEST_CONSTEXPR
NonEmptyNonTrivial() : i(22), j(33) { }
171 TEST_CONSTEXPR
NonEmptyNonTrivial(NonEmptyNonTrivial
const&) : i(22), j(33) { }
174 template <typename F
>
175 TEST_CONSTEXPR_CXX14
bool with_all_types()
177 F().template operator()<char>();
178 F().template operator()<int>();
179 F().template operator()<long>();
180 F().template operator()<float>();
181 F().template operator()<double>();
182 F().template operator()<long double>();
183 F().template operator()<Empty
>();
184 F().template operator()<Trivial
>();
185 F().template operator()<NonTrivial
>();
186 F().template operator()<NonEmptyNonTrivial
>();
190 // This is a regression test -- previously, libc++ would implement empty arrays by
191 // storing an array of characters, which means that the array would be initializable
192 // from nonsense like an integer (or anything else that can be narrowed to char).
193 #if TEST_STD_VER >= 20
195 concept is_list_initializable_int
= requires
{
200 static_assert(!is_list_initializable_int
<std::array
<Foo
, 0>>);
201 static_assert(!is_list_initializable_int
<std::array
<Foo
, 1>>);
204 int main(int, char**)
206 with_all_types
<test_initialization
>();
207 test_initializer_list();
208 #if TEST_STD_VER >= 14
209 static_assert(with_all_types
<test_initialization
>(), "");
210 static_assert(test_initializer_list(), "");