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 { 18 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> 26 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> 39 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 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 { 152 TEST_CONSTEXPR NonTrivial() { } 153 TEST_CONSTEXPR NonTrivial(NonTrivial const&) { } 154 }; 155 struct NonEmptyNonTrivial { 156 int i; int j; 157 TEST_CONSTEXPR NonEmptyNonTrivial() : i(22), j(33) { } 158 TEST_CONSTEXPR NonEmptyNonTrivial(NonEmptyNonTrivial const&) : i(22), j(33) { } 159 }; 160 161 template <typename F> 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 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