libstdc++: Make __gnu_debug::vector usable in constant expressions [PR109536]
[official-gcc.git] / libstdc++-v3 / testsuite / 23_containers / vector / modifiers / constexpr.cc
blob4aa1f1f67b73ab89b4d8688f8ecf09b0b2b01770
1 // { dg-do compile { target c++20 } }
3 #include <vector>
4 #include <testsuite_hooks.h>
6 template<typename T>
7 struct Alloc : std::allocator<T>
9 using std::allocator<T>::allocator;
11 constexpr explicit Alloc(int p) : personality(p) { }
13 template<typename U>
14 constexpr Alloc(const Alloc<U>& a) : personality(a.personality) { }
16 int personality = 0;
18 constexpr bool operator==(const Alloc& a) const noexcept
19 { return personality == a.personality; }
22 constexpr bool
23 test_push_back()
25 std::vector<int> v;
26 int& r = v.emplace_back(7);
27 VERIFY( r == 7 );
28 VERIFY( &r == &v.front() );
29 v.emplace_back(r);
30 v.emplace_back(v.front());
31 v.emplace_back(v.back());
32 VERIFY( v.size() == 4 );
33 v.emplace_back(8);
34 VERIFY( v.size() == 5 );
35 VERIFY( v.back() == 8 );
37 v.pop_back();
38 VERIFY( v.size() == 4 );
39 VERIFY( v.back() == 7 );
40 v.pop_back();
41 v.pop_back();
42 v.pop_back();
43 v.pop_back();
44 VERIFY( v.empty() );
46 v.push_back(99);
47 for (std::size_t i = 0, c = v.capacity(); i <= c; ++i)
48 v.push_back(v.front());
49 VERIFY( v.capacity() > v.size() );
51 std::vector<int, Alloc<int>> va;
52 va.push_back(99);
53 va.push_back(va.front());
54 VERIFY( va.size() == 2 );
56 return true;
59 static_assert( test_push_back() );
61 template<typename T = int>
62 constexpr std::false_type
63 pop_back_empty() { return {}; }
65 template<typename T = int>
66 requires (std::bool_constant<(std::vector<T>().pop_back(), true)>::value)
67 constexpr std::true_type
68 pop_back_empty() { return {}; }
70 static_assert( ! pop_back_empty() );
72 constexpr bool
73 test_insert_erase()
75 std::vector<int> v;
77 // vector::emplace(const_iterator, Args&&...)
78 auto p = v.emplace(v.begin());
79 VERIFY( p == v.begin() );
80 p = v.emplace(v.end(), 7);
81 VERIFY( p == --v.end() );
83 // vector::insert(const_iterator, const T&)
84 p = v.insert(v.begin(), *p);
85 VERIFY( p == v.begin() );
86 VERIFY( *p == 7 );
87 VERIFY( &*p == &v.front() );
88 // vector::insert(const_iterator, T&&)
89 p = v.insert(v.end(), 1);
90 VERIFY( p == --v.end() );
91 v.insert(p, v.front());
92 v.insert(v.end(), v.back());
93 VERIFY( v.size() == 6 );
94 v.insert(v.end(), 8);
95 VERIFY( v.size() == 7 );
96 VERIFY( v.back() == 8 );
98 // vector::insert(const_iterator, size_type, const T&)
99 v.insert(v.begin(), 2, v.front());
100 v.insert(v.end(), 3, 99);
101 VERIFY( v.size() == 12 );
103 struct input_iterator
105 using iterator_category = std::input_iterator_tag;
106 using value_type = int;
107 using pointer = const int*;
108 using reference = int;
109 using difference_type = int;
111 constexpr input_iterator() : val(0) { }
112 constexpr input_iterator(int i) : val(i) { }
114 constexpr input_iterator& operator++() { --val; return *this; }
115 constexpr input_iterator operator++(int) { return {val--}; }
117 constexpr int operator*() const { return val; }
118 constexpr const int* operator->() const { return &val; }
120 constexpr bool operator==(const input_iterator&) const = default;
122 int val;
125 // vector::insert(const_iterator, Iter, Iter);
126 v.insert(v.begin() + 2, input_iterator(), input_iterator());
127 VERIFY( v.size() == 12 );
128 v.reserve(13);
129 auto n = v.capacity() - v.size();
130 v.insert(v.end() - 9, input_iterator(n), input_iterator()); // no reallocation
131 VERIFY( v.size() == (12 + n) );
132 short a[] = { 84, 85 };
133 v.insert(v.end() - 1, a, a + 2); // reallocation needed
134 VERIFY( v.size() == (12 + n + 2) );
135 v.resize(32);
137 // vector::insert(const_iterator, initializer_list<T>)
138 v.insert(v.begin(), {1,2,3});
139 VERIFY( v.size() == 35 );
141 v.rbegin()[0] = 999;
142 v.rbegin()[1] = 888;
144 // vector::erase(const_iterator)
145 v.erase(v.end() - 1);
146 VERIFY( v.size() == 34 );
147 VERIFY( v.back() == 888 );
148 v.erase(v.begin());
149 v.erase(v.begin() + 1);
150 v.erase(v.end() - 1);
151 VERIFY( v.size() == 31 );
153 // vector::erase(const_iterator, const_iterator)
154 v.erase(v.begin(), v.begin());
155 v.erase(v.end(), v.end());
156 v.erase(v.begin(), v.begin() + 1);
157 VERIFY( v.size() == 30 );
158 v.erase(v.begin() + 2, v.end() - 2);
159 VERIFY( v.size() == 4 );
160 v.erase(v.begin(), v.end());
161 VERIFY( v.empty() );
162 v.erase( v.begin(), v.begin() );
163 VERIFY( v.empty() );
165 v.insert(v.end(), 99);
166 for (std::size_t i = 0, c = v.capacity(); i <= c; ++i)
167 v.insert(v.end() - 1, v.front());
168 VERIFY( v.capacity() > v.size() );
169 v.insert(v.end(), 999);
170 for (std::size_t i = 0, c = v.capacity(); i <= c; ++i)
171 v.insert(v.begin(), v.front());
173 std::vector<int, Alloc<int>> va;
174 va.insert(va.begin(), 99);
175 va.insert(va.begin(), va.front());
176 VERIFY( va.size() == 2 );
177 va.erase(va.begin());
179 return true;
182 static_assert( test_insert_erase() );
184 constexpr bool
185 test_clear()
187 std::vector<int> v0;
188 v0.clear();
189 VERIFY( v0.size() == 0 );
190 VERIFY( v0.capacity() == 0 );
192 std::vector<int> v{1, 10, 100};
193 v.clear();
194 VERIFY( v.size() == 0 );
195 VERIFY( v.capacity() == 3 );
197 std::vector<int, Alloc<int>> va;
198 va.clear();
199 va.push_back(1);
200 va.clear();
201 va.clear();
203 return true;
206 static_assert( test_clear() );
208 constexpr bool
209 test_erasure()
211 const char* names[] = { "Vince", "Clarke", "Andy", "Bell" };
212 std::vector<const char*> e(std::begin(names), std::end(names));
214 auto n = std::erase(e, names[0]);
215 VERIFY( n == 1 );
216 VERIFY( e.size() == 3 );
217 n = std::erase_if(e, [](auto name) { return name[4] == '\0'; });
218 VERIFY( n == 2 );
219 VERIFY( e.size() == 1 );
221 return true;
224 static_assert( test_erasure() );