]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/constexpr.cc
libstdc++: Make __gnu_debug::vector usable in constant expressions [PR109536]
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 23_containers / vector / bool / modifiers / constexpr.cc
1 // { dg-do compile { target c++20 } }
2
3 #include <vector>
4 #include <testsuite_hooks.h>
5
6 template<typename T>
7 struct Alloc : std::allocator<T>
8 {
9 using std::allocator<T>::allocator;
10
11 constexpr explicit Alloc(int p) : personality(p) { }
12
13 template<typename U>
14 constexpr Alloc(const Alloc<U>& a) : personality(a.personality) { }
15
16 int personality = 0;
17
18 constexpr bool operator==(const Alloc& a) const noexcept
19 { return personality == a.personality; }
20 };
21
22 constexpr bool
23 test_push_back()
24 {
25 std::vector<bool> v;
26 std::vector<bool>::reference r = v.emplace_back("");
27 VERIFY( r == true );
28 v.emplace_back(r);
29 VERIFY( v.back() == true );
30 v.emplace_back(v.front());
31 VERIFY( v.back() == true );
32 v.resize(64);
33 v.emplace_back(v.back());
34 VERIFY( v.back() == false );
35 VERIFY( v.size() == 65 );
36 v.emplace_back(8);
37 VERIFY( v.size() == 66 );
38 VERIFY( v.back() == true );
39 v.emplace_back();
40 VERIFY( v.size() == 67 );
41 VERIFY( v.back() == false );
42
43 v.pop_back();
44 VERIFY( v.size() == 66 );
45 VERIFY( v.back() == true );
46 for (int i = 0, n = v.size(); i < n; ++i)
47 v.pop_back();
48 VERIFY( v.empty() );
49
50 v.push_back(true);
51 for (std::size_t i = 0, c = v.capacity(); i <= c; ++i)
52 v.push_back(v.front());
53 VERIFY( v.capacity() > v.size() );
54
55 std::vector<bool, Alloc<bool>> va;
56 va.push_back(true);
57 va.push_back(va.front());
58 VERIFY( va.size() == 2 );
59
60 return true;
61 }
62
63 static_assert( test_push_back() );
64
65 template<typename T = bool>
66 constexpr std::false_type
67 pop_back_empty() { return {}; }
68
69 template<typename T = bool>
70 requires (std::bool_constant<(std::vector<T>().pop_back(), true)>::value)
71 constexpr std::true_type
72 pop_back_empty() { return {}; }
73
74 static_assert( ! pop_back_empty() );
75
76 constexpr bool
77 test_insert_erase()
78 {
79 std::vector<bool> v;
80
81 // vector::emplace(const_iterator, Args&&...)
82 auto p = v.emplace(v.begin());
83 VERIFY( p == v.begin() );
84 p = v.emplace(v.end(), '7');
85 VERIFY( p == --v.end() );
86
87 // vector::insert(const_iterator, const T&)
88 p = v.insert(v.begin(), *p);
89 VERIFY( p == v.begin() );
90 VERIFY( *p );
91 // vector::insert(const_iterator, T&&)
92 p = v.insert(v.end(), 1);
93 VERIFY( p == --v.end() );
94 v.insert(p, v.front());
95 v.insert(v.end(), v.back());
96 VERIFY( v.size() == 6 );
97 v.insert(v.end(), true);
98 VERIFY( v.size() == 7 );
99 VERIFY( v.back() == true );
100
101 // vector::insert(const_iterator, size_type, const T&)
102 v.insert(v.begin(), 2, v.front());
103 v.insert(v.end(), 3, 99);
104 VERIFY( v.size() == 12 );
105
106 struct input_iterator
107 {
108 using iterator_category = std::input_iterator_tag;
109 using value_type = bool;
110 using pointer = const bool*;
111 using reference = bool;
112 using difference_type = int;
113
114 constexpr input_iterator() : val(0) { }
115 constexpr input_iterator(int i) : val(i) { }
116
117 constexpr input_iterator& operator++() { --val; return *this; }
118 constexpr input_iterator operator++(int) { return {val--}; }
119
120 constexpr bool operator*() const { return val % 2; }
121 constexpr const bool* operator->() const { return nullptr; }
122
123 constexpr bool operator==(const input_iterator&) const = default;
124
125 int val;
126 };
127
128 // vector::insert(const_iterator, Iter, Iter);
129 v.insert(v.begin() + 2, input_iterator(), input_iterator());
130 VERIFY( v.size() == 12 );
131 v.insert(v.end() - 9, input_iterator(18), input_iterator());
132 VERIFY( v.size() == 30 );
133 short a[] = { false, true };
134 v.insert(v.end(), a, a + 2);
135 VERIFY( v.size() == 32 );
136
137 // vector::insert(const_iterator, initializer_list<T>)
138 v.insert(v.begin(), {1,1,1});
139 VERIFY( v.size() == 35 );
140
141 // vector::erase(const_iterator)
142 v.erase(v.end() - 1);
143 VERIFY( v.size() == 34 );
144 VERIFY( v.back() == false );
145 v.erase(v.begin());
146 v.erase(v.begin() + 1);
147 v.erase(v.end() - 1);
148 VERIFY( v.size() == 31 );
149
150 // vector::erase(const_iterator, const_iterator)
151 v.erase(v.begin(), v.begin());
152 v.erase(v.end(), v.end());
153 v.erase(v.begin(), v.begin() + 1);
154 VERIFY( v.size() == 30 );
155 v.erase(v.begin() + 2, v.end() - 2);
156 VERIFY( v.size() == 4 );
157 v.erase(v.begin(), v.end());
158 VERIFY( v.empty() );
159 v.erase( v.begin(), v.begin() );
160 VERIFY( v.empty() );
161
162 v.insert(v.end(), 99);
163 for (std::size_t i = 0, c = v.capacity(); i <= c; ++i)
164 v.insert(v.end() - 1, v.front());
165 VERIFY( v.capacity() > v.size() );
166 v.insert(v.end(), 999);
167 for (std::size_t i = 0, c = v.capacity(); i <= c; ++i)
168 v.insert(v.begin(), v.front());
169
170 std::vector<bool, Alloc<bool>> va;
171 va.insert(va.begin(), 99);
172 va.insert(va.begin(), va.front());
173 VERIFY( va.size() == 2 );
174 va.erase(va.begin());
175
176 return true;
177 }
178
179 static_assert( test_insert_erase() );
180
181 constexpr std::size_t
182 capacity_for(std::size_t n)
183 {
184 std::size_t N = std::vector<bool>(1).capacity();
185 if (auto r = n % N)
186 return n - r + N;
187 return n;
188 }
189
190 constexpr bool
191 test_clear()
192 {
193 std::vector<bool> v0;
194 v0.clear();
195 VERIFY( v0.size() == 0 );
196 VERIFY( v0.capacity() == 0 );
197
198 std::vector<bool> v{1, 0, 0};
199 v.clear();
200 VERIFY( v.size() == 0 );
201 VERIFY( v.capacity() == capacity_for(3) );
202
203 std::vector<bool, Alloc<bool>> va;
204 va.clear();
205 va.push_back(1);
206 va.clear();
207 va.clear();
208
209 return true;
210 }
211
212 static_assert( test_clear() );
213
214 constexpr bool
215 test_flip()
216 {
217 std::vector<bool> v{1, 0, 0, 1, 0, 1, 1, 0};
218 v.flip();
219 VERIFY( !v[0] && v[1] && v[2] && !v[3] && v[4] && !v[5] && !v[6] && v[7] );
220 v[2].flip();
221 VERIFY( !v[2] );
222 v[2].flip();
223 VERIFY( v[2] );
224
225 return true;
226 }
227
228 static_assert( test_flip() );
229
230 constexpr bool
231 test_erasure()
232 {
233 std::vector<bool> e{true,true,true,false,true,false};
234
235 auto n = std::erase(e, false);
236 VERIFY( n == 2 );
237 VERIFY( e.size() == 4 );
238 e[2] = false;
239 n = std::erase_if(e, [](std::vector<bool>::reference val) { return !val; });
240 VERIFY( n == 1 );
241 VERIFY( e.size() == 3 );
242
243 return true;
244 }
245
246 static_assert( test_erasure() );