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 // iterator begin() noexcept;                         // constexpr in C++17
12 // const_iterator begin() const noexcept;             // constexpr in C++17
13 // iterator end() noexcept;                           // constexpr in C++17
14 // const_iterator end() const noexcept;               // constexpr in C++17
15 //
16 // reverse_iterator rbegin() noexcept;                // constexpr in C++17
17 // const_reverse_iterator rbegin() const noexcept;    // constexpr in C++17
18 // reverse_iterator rend() noexcept;                  // constexpr in C++17
19 // const_reverse_iterator rend() const noexcept;      // constexpr in C++17
20 //
21 // const_iterator cbegin() const noexcept;            // constexpr in C++17
22 // const_iterator cend() const noexcept;              // constexpr in C++17
23 // const_reverse_iterator crbegin() const noexcept;   // constexpr in C++17
24 // const_reverse_iterator crend() const noexcept;     // constexpr in C++17
25 
26 #include <array>
27 #include <iterator>
28 #include <cassert>
29 
30 #include "test_macros.h"
31 
32 struct NoDefault {
NoDefaultNoDefault33     TEST_CONSTEXPR NoDefault(int) { }
34 };
35 
36 template <class T>
check_noexcept(T & c)37 TEST_CONSTEXPR_CXX17 void check_noexcept(T& c) {
38     ASSERT_NOEXCEPT(c.begin());
39     ASSERT_NOEXCEPT(c.end());
40     ASSERT_NOEXCEPT(c.cbegin());
41     ASSERT_NOEXCEPT(c.cend());
42     ASSERT_NOEXCEPT(c.rbegin());
43     ASSERT_NOEXCEPT(c.rend());
44     ASSERT_NOEXCEPT(c.crbegin());
45     ASSERT_NOEXCEPT(c.crend());
46 
47     const T& cc = c; (void)cc;
48     ASSERT_NOEXCEPT(cc.begin());
49     ASSERT_NOEXCEPT(cc.end());
50     ASSERT_NOEXCEPT(cc.rbegin());
51     ASSERT_NOEXCEPT(cc.rend());
52 }
53 
tests()54 TEST_CONSTEXPR_CXX17 bool tests()
55 {
56     {
57         typedef std::array<int, 5> C;
58         C array = {};
59         check_noexcept(array);
60         typename C::iterator i = array.begin();
61         typename C::const_iterator j = array.cbegin();
62         assert(i == j);
63     }
64     {
65         typedef std::array<int, 0> C;
66         C array = {};
67         check_noexcept(array);
68         typename C::iterator i = array.begin();
69         typename C::const_iterator j = array.cbegin();
70         assert(i == j);
71     }
72 
73     {
74         typedef std::array<int, 0> C;
75         C array = {};
76         check_noexcept(array);
77         typename C::iterator i = array.begin();
78         typename C::const_iterator j = array.cbegin();
79         assert(i == array.end());
80         assert(j == array.cend());
81     }
82     {
83         typedef std::array<int, 1> C;
84         C array = {1};
85         check_noexcept(array);
86         typename C::iterator i = array.begin();
87         assert(*i == 1);
88         assert(&*i == array.data());
89         *i = 99;
90         assert(array[0] == 99);
91     }
92     {
93         typedef std::array<int, 2> C;
94         C array = {1, 2};
95         check_noexcept(array);
96         typename C::iterator i = array.begin();
97         assert(*i == 1);
98         assert(&*i == array.data());
99         *i = 99;
100         assert(array[0] == 99);
101         assert(array[1] == 2);
102     }
103     {
104         typedef std::array<double, 3> C;
105         C array = {1, 2, 3.5};
106         check_noexcept(array);
107         typename C::iterator i = array.begin();
108         assert(*i == 1);
109         assert(&*i == array.data());
110         *i = 5.5;
111         assert(array[0] == 5.5);
112         assert(array[1] == 2.0);
113     }
114     {
115         typedef std::array<NoDefault, 0> C;
116         C array = {};
117         typename C::iterator ib = array.begin();
118         typename C::iterator ie = array.end();
119         assert(ib == ie);
120     }
121 
122 #if TEST_STD_VER >= 14
123     { // N3644 testing
124         {
125             typedef std::array<int, 5> C;
126             C::iterator ii1{}, ii2{};
127             C::iterator ii4 = ii1;
128             C::const_iterator cii{};
129             assert(ii1 == ii2);
130             assert(ii1 == ii4);
131             assert(ii1 == cii);
132 
133             assert(!(ii1 != ii2));
134             assert(!(ii1 != cii));
135 
136             C c = {};
137             check_noexcept(c);
138             assert(c.begin()   == std::begin(c));
139             assert(c.cbegin()  == std::cbegin(c));
140             assert(c.rbegin()  == std::rbegin(c));
141             assert(c.crbegin() == std::crbegin(c));
142             assert(c.end()     == std::end(c));
143             assert(c.cend()    == std::cend(c));
144             assert(c.rend()    == std::rend(c));
145             assert(c.crend()   == std::crend(c));
146 
147             assert(std::begin(c)   != std::end(c));
148             assert(std::rbegin(c)  != std::rend(c));
149             assert(std::cbegin(c)  != std::cend(c));
150             assert(std::crbegin(c) != std::crend(c));
151         }
152         {
153             typedef std::array<int, 0> C;
154             C::iterator ii1{}, ii2{};
155             C::iterator ii4 = ii1;
156             C::const_iterator cii{};
157             assert(ii1 == ii2);
158             assert(ii1 == ii4);
159 
160             assert(!(ii1 != ii2));
161 
162             assert( (ii1 == cii));
163             assert( (cii == ii1));
164             assert(!(ii1 != cii));
165             assert(!(cii != ii1));
166             assert(!(ii1 <  cii));
167             assert(!(cii <  ii1));
168             assert( (ii1 <= cii));
169             assert( (cii <= ii1));
170             assert(!(ii1 >  cii));
171             assert(!(cii >  ii1));
172             assert( (ii1 >= cii));
173             assert( (cii >= ii1));
174             assert(cii - ii1 == 0);
175             assert(ii1 - cii == 0);
176 
177             C c = {};
178             check_noexcept(c);
179             assert(c.begin()   == std::begin(c));
180             assert(c.cbegin()  == std::cbegin(c));
181             assert(c.rbegin()  == std::rbegin(c));
182             assert(c.crbegin() == std::crbegin(c));
183             assert(c.end()     == std::end(c));
184             assert(c.cend()    == std::cend(c));
185             assert(c.rend()    == std::rend(c));
186             assert(c.crend()   == std::crend(c));
187 
188             assert(std::begin(c)   == std::end(c));
189             assert(std::rbegin(c)  == std::rend(c));
190             assert(std::cbegin(c)  == std::cend(c));
191             assert(std::crbegin(c) == std::crend(c));
192         }
193     }
194 #endif
195     return true;
196 }
197 
main(int,char **)198 int main(int, char**)
199 {
200     tests();
201 #if TEST_STD_VER >= 17
202     static_assert(tests(), "");
203 #endif
204   return 0;
205 }
206