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 TEST_CONSTEXPR_CXX17 bool tests()
37 {
38     {
39         typedef std::array<int, 5> C;
40         C array = {};
41         typename C::iterator i = array.begin();
42         typename C::const_iterator j = array.cbegin();
43         assert(i == j);
44     }
45     {
46         typedef std::array<int, 0> C;
47         C array = {};
48         typename C::iterator i = array.begin();
49         typename C::const_iterator j = array.cbegin();
50         assert(i == j);
51     }
52 
53     {
54         typedef std::array<int, 0> C;
55         C array = {};
56         typename C::iterator i = array.begin();
57         typename C::const_iterator j = array.cbegin();
58         assert(i == array.end());
59         assert(j == array.cend());
60     }
61     {
62         typedef std::array<int, 1> C;
63         C array = {1};
64         typename C::iterator i = array.begin();
65         assert(*i == 1);
66         assert(&*i == array.data());
67         *i = 99;
68         assert(array[0] == 99);
69     }
70     {
71         typedef std::array<int, 2> C;
72         C array = {1, 2};
73         typename C::iterator i = array.begin();
74         assert(*i == 1);
75         assert(&*i == array.data());
76         *i = 99;
77         assert(array[0] == 99);
78         assert(array[1] == 2);
79     }
80     {
81         typedef std::array<double, 3> C;
82         C array = {1, 2, 3.5};
83         typename C::iterator i = array.begin();
84         assert(*i == 1);
85         assert(&*i == array.data());
86         *i = 5.5;
87         assert(array[0] == 5.5);
88         assert(array[1] == 2.0);
89     }
90     {
91         typedef std::array<NoDefault, 0> C;
92         C array = {};
93         typename C::iterator ib = array.begin();
94         typename C::iterator ie = array.end();
95         assert(ib == ie);
96     }
97 
98 #if TEST_STD_VER >= 14
99     { // N3644 testing
100         {
101             typedef std::array<int, 5> C;
102             C::iterator ii1{}, ii2{};
103             C::iterator ii4 = ii1;
104             C::const_iterator cii{};
105             assert(ii1 == ii2);
106             assert(ii1 == ii4);
107             assert(ii1 == cii);
108 
109             assert(!(ii1 != ii2));
110             assert(!(ii1 != cii));
111 
112             C c = {};
113             assert(c.begin()   == std::begin(c));
114             assert(c.cbegin()  == std::cbegin(c));
115             assert(c.rbegin()  == std::rbegin(c));
116             assert(c.crbegin() == std::crbegin(c));
117             assert(c.end()     == std::end(c));
118             assert(c.cend()    == std::cend(c));
119             assert(c.rend()    == std::rend(c));
120             assert(c.crend()   == std::crend(c));
121 
122             assert(std::begin(c)   != std::end(c));
123             assert(std::rbegin(c)  != std::rend(c));
124             assert(std::cbegin(c)  != std::cend(c));
125             assert(std::crbegin(c) != std::crend(c));
126         }
127         {
128             typedef std::array<int, 0> C;
129             C::iterator ii1{}, ii2{};
130             C::iterator ii4 = ii1;
131             C::const_iterator cii{};
132             assert(ii1 == ii2);
133             assert(ii1 == ii4);
134 
135             assert(!(ii1 != ii2));
136 
137             assert( (ii1 == cii));
138             assert( (cii == ii1));
139             assert(!(ii1 != cii));
140             assert(!(cii != ii1));
141             assert(!(ii1 <  cii));
142             assert(!(cii <  ii1));
143             assert( (ii1 <= cii));
144             assert( (cii <= ii1));
145             assert(!(ii1 >  cii));
146             assert(!(cii >  ii1));
147             assert( (ii1 >= cii));
148             assert( (cii >= ii1));
149             assert(cii - ii1 == 0);
150             assert(ii1 - cii == 0);
151 
152             C c = {};
153             assert(c.begin()   == std::begin(c));
154             assert(c.cbegin()  == std::cbegin(c));
155             assert(c.rbegin()  == std::rbegin(c));
156             assert(c.crbegin() == std::crbegin(c));
157             assert(c.end()     == std::end(c));
158             assert(c.cend()    == std::cend(c));
159             assert(c.rend()    == std::rend(c));
160             assert(c.crend()   == std::crend(c));
161 
162             assert(std::begin(c)   == std::end(c));
163             assert(std::rbegin(c)  == std::rend(c));
164             assert(std::cbegin(c)  == std::cend(c));
165             assert(std::crbegin(c) == std::crend(c));
166         }
167     }
168 #endif
169     return true;
170 }
171 
172 int main(int, char**)
173 {
174     tests();
175 #if TEST_STD_VER >= 17
176     static_assert(tests(), "");
177 #endif
178   return 0;
179 }
180