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