xref: /llvm-project/libcxx/test/std/containers/sequences/array/iterators.pass.cpp (revision 8d3252a8987818171878a26e4298b4b5dbf2a7e9)
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 {
33     TEST_CONSTEXPR NoDefault(int) { }
34 };
35 
36 template <class T>
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 
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 #  if TEST_STD_VER >= 20
153             // P1614 + LWG3352
154             std::same_as<std::strong_ordering> decltype(auto) r1 = ii1 <=> ii2;
155             assert(r1 == std::strong_ordering::equal);
156 
157             std::same_as<std::strong_ordering> decltype(auto) r2 = cii <=> ii2;
158             assert(r2 == std::strong_ordering::equal);
159 #  endif
160         }
161         {
162             typedef std::array<int, 0> C;
163             C::iterator ii1{}, ii2{};
164             C::iterator ii4 = ii1;
165             C::const_iterator cii{};
166             assert(ii1 == ii2);
167             assert(ii1 == ii4);
168 
169             assert(!(ii1 != ii2));
170 
171             assert( (ii1 == cii));
172             assert( (cii == ii1));
173             assert(!(ii1 != cii));
174             assert(!(cii != ii1));
175             assert(!(ii1 <  cii));
176             assert(!(cii <  ii1));
177             assert( (ii1 <= cii));
178             assert( (cii <= ii1));
179             assert(!(ii1 >  cii));
180             assert(!(cii >  ii1));
181             assert( (ii1 >= cii));
182             assert( (cii >= ii1));
183             assert(cii - ii1 == 0);
184             assert(ii1 - cii == 0);
185 
186             C c = {};
187             check_noexcept(c);
188             assert(c.begin()   == std::begin(c));
189             assert(c.cbegin()  == std::cbegin(c));
190             assert(c.rbegin()  == std::rbegin(c));
191             assert(c.crbegin() == std::crbegin(c));
192             assert(c.end()     == std::end(c));
193             assert(c.cend()    == std::cend(c));
194             assert(c.rend()    == std::rend(c));
195             assert(c.crend()   == std::crend(c));
196 
197             assert(std::begin(c)   == std::end(c));
198             assert(std::rbegin(c)  == std::rend(c));
199             assert(std::cbegin(c)  == std::cend(c));
200             assert(std::crbegin(c) == std::crend(c));
201 
202 #  if TEST_STD_VER >= 20
203             // P1614 + LWG3352
204             std::same_as<std::strong_ordering> decltype(auto) r1 = ii1 <=> ii2;
205             assert(r1 == std::strong_ordering::equal);
206 
207             std::same_as<std::strong_ordering> decltype(auto) r2 = cii <=> ii2;
208             assert(r2 == std::strong_ordering::equal);
209 #  endif
210         }
211     }
212 #endif
213     return true;
214 }
215 
216 int main(int, char**)
217 {
218     tests();
219 #if TEST_STD_VER >= 17
220     static_assert(tests(), "");
221 #endif
222   return 0;
223 }
224