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 // <array>
10 
11 // reference front();       // constexpr in C++17
12 // reference back();        // constexpr in C++17
13 // const_reference front(); // constexpr in C++14
14 // const_reference back();  // constexpr in C++14
15 
16 #include <array>
17 #include <cassert>
18 
19 #include "test_macros.h"
20 
21 // std::array is explicitly allowed to be initialized with A a = { init-list };.
22 // Disable the missing braces warning for this reason.
23 #include "disable_missing_braces_warning.h"
24 
25 #if TEST_STD_VER > 14
26 constexpr bool check_front( double val )
27 {
28     std::array<double, 3> arr = {1, 2, 3.5};
29     return arr.front() == val;
30 }
31 
32 constexpr bool check_back( double val )
33 {
34     std::array<double, 3> arr = {1, 2, 3.5};
35     return arr.back() == val;
36 }
37 #endif
38 
39 int main(int, char**)
40 {
41     {
42         typedef double T;
43         typedef std::array<T, 3> C;
44         C c = {1, 2, 3.5};
45 
46         C::reference r1 = c.front();
47         assert(r1 == 1);
48         r1 = 5.5;
49         assert(c[0] == 5.5);
50 
51         C::reference r2 = c.back();
52         assert(r2 == 3.5);
53         r2 = 7.5;
54         assert(c[2] == 7.5);
55     }
56     {
57         typedef double T;
58         typedef std::array<T, 3> C;
59         const C c = {1, 2, 3.5};
60         C::const_reference r1 = c.front();
61         assert(r1 == 1);
62 
63         C::const_reference r2 = c.back();
64         assert(r2 == 3.5);
65     }
66     {
67       typedef double T;
68       typedef std::array<T, 0> C;
69       C c = {};
70       C const& cc = c;
71       static_assert((std::is_same<decltype(c.front()), T &>::value), "");
72       static_assert((std::is_same<decltype(cc.front()), const T &>::value), "");
73       static_assert((std::is_same<decltype(c.back()), T &>::value), "");
74       static_assert((std::is_same<decltype(cc.back()), const T &>::value), "");
75       if (c.size() > (0)) { // always false
76         TEST_IGNORE_NODISCARD c.front();
77         TEST_IGNORE_NODISCARD c.back();
78         TEST_IGNORE_NODISCARD cc.front();
79         TEST_IGNORE_NODISCARD cc.back();
80       }
81     }
82     {
83       typedef double T;
84       typedef std::array<const T, 0> C;
85       C c = {{}};
86       C const& cc = c;
87       static_assert((std::is_same<decltype(c.front()),  const T &>::value), "");
88       static_assert((std::is_same<decltype(cc.front()), const T &>::value), "");
89       static_assert((std::is_same<decltype(c.back()),   const T &>::value), "");
90       static_assert((std::is_same<decltype(cc.back()),  const T &>::value), "");
91       if (c.size() > (0)) {
92         TEST_IGNORE_NODISCARD c.front();
93         TEST_IGNORE_NODISCARD c.back();
94         TEST_IGNORE_NODISCARD cc.front();
95         TEST_IGNORE_NODISCARD cc.back();
96       }
97     }
98 #if TEST_STD_VER > 11
99     {
100         typedef double T;
101         typedef std::array<T, 3> C;
102         constexpr C c = {1, 2, 3.5};
103 
104         constexpr T t1 = c.front();
105         static_assert (t1 == 1, "");
106 
107         constexpr T t2 = c.back();
108         static_assert (t2 == 3.5, "");
109     }
110 #endif
111 
112 #if TEST_STD_VER > 14
113     {
114         static_assert (check_front(1),   "");
115         static_assert (check_back (3.5), "");
116     }
117 #endif
118 
119   return 0;
120 }
121