brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · 6d5427f Raw
251 lines · cpp
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-exception6//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 16struct NoDefault {17  TEST_CONSTEXPR NoDefault(int) {}18};19 20struct test_initialization {21  template <typename T>22  TEST_CONSTEXPR_CXX14 void operator()() const {23    // Check default initialization24    {25      std::array<T, 0> a0;26      (void)a0;27      // Before C++20, default initialization doesn't work inside constexpr for28      // trivially default constructible types. This only apply to non-empty arrays,29      // since empty arrays don't hold an element of type T.30#if TEST_STD_VER < 2031      if (!(TEST_IS_CONSTANT_EVALUATED && std::is_trivially_default_constructible<T>::value))32#endif33      {34        std::array<T, 1> a1;35        (void)a1;36        std::array<T, 2> a2;37        (void)a2;38        std::array<T, 3> a3;39        (void)a3;40      }41 42      std::array<NoDefault, 0> nodefault;43      (void)nodefault;44    }45 46    // A const empty array can also be default-initialized regardless of the type47    // it contains. For non-empty arrays, this doesn't work whenever T doesn't48    // have a user-provided default constructor.49    {50      const std::array<T, 0> a0;51      (void)a0;52      const std::array<NoDefault, 0> nodefault;53      (void)nodefault;54    }55 56    // Check direct-list-initialization syntax (introduced in C++11)57#if TEST_STD_VER >= 1158    {59      {60        std::array<T, 0> a0_0{};61        (void)a0_0;62      }63      {64        std::array<T, 1> a1_0{};65        (void)a1_0;66        std::array<T, 1> a1_1{T()};67        (void)a1_1;68      }69      {70        std::array<T, 2> a2_0{};71        (void)a2_0;72        std::array<T, 2> a2_1{T()};73        (void)a2_1;74        std::array<T, 2> a2_2{T(), T()};75        (void)a2_2;76      }77      {78        std::array<T, 3> a3_0{};79        (void)a3_0;80        std::array<T, 3> a3_1{T()};81        (void)a3_1;82        std::array<T, 3> a3_2{T(), T()};83        (void)a3_2;84        std::array<T, 3> a3_3{T(), T(), T()};85        (void)a3_3;86      }87 88      std::array<NoDefault, 0> nodefault{};89      (void)nodefault;90    }91#endif92 93    // Check copy-list-initialization syntax94    {95      {96        std::array<T, 0> a0_0 = {};97        (void)a0_0;98      }99      {100        std::array<T, 1> a1_0 = {};101        (void)a1_0;102        std::array<T, 1> a1_1 = {T()};103        (void)a1_1;104      }105      {106        std::array<T, 2> a2_0 = {};107        (void)a2_0;108        std::array<T, 2> a2_1 = {T()};109        (void)a2_1;110        std::array<T, 2> a2_2 = {T(), T()};111        (void)a2_2;112      }113      {114        std::array<T, 3> a3_0 = {};115        (void)a3_0;116        std::array<T, 3> a3_1 = {T()};117        (void)a3_1;118        std::array<T, 3> a3_2 = {T(), T()};119        (void)a3_2;120        std::array<T, 3> a3_3 = {T(), T(), T()};121        (void)a3_3;122      }123 124      std::array<NoDefault, 0> nodefault = {};125      (void)nodefault;126    }127 128    // Test aggregate initialization129    {130      {131        std::array<T, 0> a0_0 = {{}};132        (void)a0_0;133      }134      {135        std::array<T, 1> a1_0 = {{}};136        (void)a1_0;137        std::array<T, 1> a1_1 = {{T()}};138        (void)a1_1;139      }140      {141        std::array<T, 2> a2_0 = {{}};142        (void)a2_0;143        std::array<T, 2> a2_1 = {{T()}};144        (void)a2_1;145        std::array<T, 2> a2_2 = {{T(), T()}};146        (void)a2_2;147      }148      {149        std::array<T, 3> a3_0 = {{}};150        (void)a3_0;151        std::array<T, 3> a3_1 = {{T()}};152        (void)a3_1;153        std::array<T, 3> a3_2 = {{T(), T()}};154        (void)a3_2;155        std::array<T, 3> a3_3 = {{T(), T(), T()}};156        (void)a3_3;157      }158 159      // See http://wg21.link/LWG2157160      std::array<NoDefault, 0> nodefault = {{}};161      (void)nodefault;162    }163  }164};165 166// Test construction from an initializer-list167TEST_CONSTEXPR_CXX14 bool test_initializer_list() {168  {169    std::array<double, 3> const a3_0 = {};170    assert(a3_0[0] == double());171    assert(a3_0[1] == double());172    assert(a3_0[2] == double());173  }174  {175    std::array<double, 3> const a3_1 = {1};176    assert(a3_1[0] == double(1));177    assert(a3_1[1] == double());178    assert(a3_1[2] == double());179  }180  {181    std::array<double, 3> const a3_2 = {1, 2.2};182    assert(a3_2[0] == double(1));183    assert(a3_2[1] == 2.2);184    assert(a3_2[2] == double());185  }186  {187    std::array<double, 3> const a3_3 = {1, 2, 3.5};188    assert(a3_3[0] == double(1));189    assert(a3_3[1] == double(2));190    assert(a3_3[2] == 3.5);191  }192 193  return true;194}195 196struct Empty {};197struct Trivial {198  int i;199  int j;200};201struct NonTrivial {202  TEST_CONSTEXPR NonTrivial() {}203  TEST_CONSTEXPR NonTrivial(NonTrivial const&) {}204};205struct NonEmptyNonTrivial {206  int i;207  int j;208  TEST_CONSTEXPR NonEmptyNonTrivial() : i(22), j(33) {}209  TEST_CONSTEXPR NonEmptyNonTrivial(NonEmptyNonTrivial const&) : i(22), j(33) {}210};211 212template <typename F>213TEST_CONSTEXPR_CXX14 bool with_all_types() {214  F().template operator()<char>();215  F().template operator()<int>();216  F().template operator()<long>();217  F().template operator()<float>();218  F().template operator()<double>();219  F().template operator()<long double>();220  F().template operator()<Empty>();221  F().template operator()<Trivial>();222  F().template operator()<NonTrivial>();223  F().template operator()<NonEmptyNonTrivial>();224  return true;225}226 227// This is a regression test -- previously, libc++ would implement empty arrays by228// storing an array of characters, which means that the array would be initializable229// from nonsense like an integer (or anything else that can be narrowed to char).230#if TEST_STD_VER >= 20231template <class T>232concept is_list_initializable_int = requires {233  { T{123} };234};235 236struct Foo {};237static_assert(!is_list_initializable_int<std::array<Foo, 0>>);238static_assert(!is_list_initializable_int<std::array<Foo, 1>>);239#endif240 241int main(int, char**) {242  with_all_types<test_initialization>();243  test_initializer_list();244#if TEST_STD_VER >= 14245  static_assert(with_all_types<test_initialization>(), "");246  static_assert(test_initializer_list(), "");247#endif248 249  return 0;250}251