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 | // <vector> |
10 | |
11 | // template <class Iter> |
12 | // iterator insert(const_iterator position, Iter first, Iter last); |
13 | |
14 | // XFAIL: FROZEN-CXX03-HEADERS-FIXME |
15 | |
16 | #include <vector> |
17 | #include <cassert> |
18 | #include <cstddef> |
19 | |
20 | #include "test_macros.h" |
21 | #include "test_allocator.h" |
22 | #include "test_iterators.h" |
23 | #include "min_allocator.h" |
24 | #include "asan_testing.h" |
25 | |
26 | namespace adl { |
27 | struct S {}; |
28 | void make_move_iterator(S*) {} |
29 | } // namespace adl |
30 | |
31 | TEST_CONSTEXPR_CXX20 bool tests() { |
32 | // |
33 | // Tests for input_iterator |
34 | // Vector may or may not reallocate during insertion -- test both cases. |
35 | // |
36 | { // Test insertion into a vector with less spare space available than the input range, triggering reallocation |
37 | typedef std::vector<int> V; |
38 | V v(100); |
39 | int a[] = {1, 2, 3, 4, 5}; |
40 | const int N = sizeof(a) / sizeof(a[0]); |
41 | V::iterator i = |
42 | v.insert(v.cbegin() + 10, cpp17_input_iterator<const int*>(a), cpp17_input_iterator<const int*>(a + N)); |
43 | assert(v.size() == 100 + N); |
44 | assert(is_contiguous_container_asan_correct(v)); |
45 | assert(i == v.begin() + 10); |
46 | int j; |
47 | for (j = 0; j < 10; ++j) |
48 | assert(v[j] == 0); |
49 | for (std::size_t k = 0; k < N; ++j, ++k) |
50 | assert(v[j] == a[k]); |
51 | for (; j < 105; ++j) |
52 | assert(v[j] == 0); |
53 | } |
54 | { // Test insertion into a vector with sufficient spare space where no reallocation happens |
55 | typedef std::vector<int> V; |
56 | V v(100); |
57 | v.reserve(n: v.size() + 10); |
58 | int a[] = {1, 2, 3, 4, 5}; |
59 | const int N = sizeof(a) / sizeof(a[0]); |
60 | V::iterator i = |
61 | v.insert(v.cbegin() + 10, cpp17_input_iterator<const int*>(a), cpp17_input_iterator<const int*>(a + N)); |
62 | assert(v.size() == 100 + N); |
63 | assert(is_contiguous_container_asan_correct(v)); |
64 | assert(i == v.begin() + 10); |
65 | int j; |
66 | for (j = 0; j < 10; ++j) |
67 | assert(v[j] == 0); |
68 | for (std::size_t k = 0; k < N; ++j, ++k) |
69 | assert(v[j] == a[k]); |
70 | for (; j < 105; ++j) |
71 | assert(v[j] == 0); |
72 | } |
73 | |
74 | // |
75 | // Tests for forward_iterator |
76 | // |
77 | { |
78 | typedef std::vector<int> V; |
79 | V v(100); |
80 | int a[] = {1, 2, 3, 4, 5}; |
81 | const int N = sizeof(a) / sizeof(a[0]); |
82 | V::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a), forward_iterator<const int*>(a + N)); |
83 | assert(v.size() == 100 + N); |
84 | assert(is_contiguous_container_asan_correct(v)); |
85 | assert(i == v.begin() + 10); |
86 | int j; |
87 | for (j = 0; j < 10; ++j) |
88 | assert(v[j] == 0); |
89 | for (std::size_t k = 0; k < N; ++j, ++k) |
90 | assert(v[j] == a[k]); |
91 | for (; j < 105; ++j) |
92 | assert(v[j] == 0); |
93 | } |
94 | { |
95 | typedef std::vector<int> V; |
96 | V v(100); |
97 | while (v.size() < v.capacity()) |
98 | v.push_back(x: 0); // force reallocation |
99 | std::size_t sz = v.size(); |
100 | int a[] = {1, 2, 3, 4, 5}; |
101 | const unsigned N = sizeof(a) / sizeof(a[0]); |
102 | V::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a), forward_iterator<const int*>(a + N)); |
103 | assert(v.size() == sz + N); |
104 | assert(i == v.begin() + 10); |
105 | std::size_t j; |
106 | for (j = 0; j < 10; ++j) |
107 | assert(v[j] == 0); |
108 | for (std::size_t k = 0; k < N; ++j, ++k) |
109 | assert(v[j] == a[k]); |
110 | for (; j < v.size(); ++j) |
111 | assert(v[j] == 0); |
112 | } |
113 | { |
114 | typedef std::vector<int> V; |
115 | V v(100); |
116 | v.reserve(n: 128); // force no reallocation |
117 | std::size_t sz = v.size(); |
118 | int a[] = {1, 2, 3, 4, 5}; |
119 | const unsigned N = sizeof(a) / sizeof(a[0]); |
120 | V::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a), forward_iterator<const int*>(a + N)); |
121 | assert(v.size() == sz + N); |
122 | assert(i == v.begin() + 10); |
123 | std::size_t j; |
124 | for (j = 0; j < 10; ++j) |
125 | assert(v[j] == 0); |
126 | for (std::size_t k = 0; k < N; ++j, ++k) |
127 | assert(v[j] == a[k]); |
128 | for (; j < v.size(); ++j) |
129 | assert(v[j] == 0); |
130 | } |
131 | { |
132 | typedef std::vector<int, limited_allocator<int, 308> > V; |
133 | V v(100); |
134 | int a[] = {1, 2, 3, 4, 5}; |
135 | const int N = sizeof(a) / sizeof(a[0]); |
136 | V::iterator i = |
137 | v.insert(v.cbegin() + 10, cpp17_input_iterator<const int*>(a), cpp17_input_iterator<const int*>(a + N)); |
138 | assert(v.size() == 100 + N); |
139 | assert(is_contiguous_container_asan_correct(v)); |
140 | assert(i == v.begin() + 10); |
141 | int j; |
142 | for (j = 0; j < 10; ++j) |
143 | assert(v[j] == 0); |
144 | for (std::size_t k = 0; k < N; ++j, ++k) |
145 | assert(v[j] == a[k]); |
146 | for (; j < 105; ++j) |
147 | assert(v[j] == 0); |
148 | } |
149 | { |
150 | typedef std::vector<int, limited_allocator<int, 300> > V; |
151 | V v(100); |
152 | int a[] = {1, 2, 3, 4, 5}; |
153 | const int N = sizeof(a) / sizeof(a[0]); |
154 | V::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a), forward_iterator<const int*>(a + N)); |
155 | assert(v.size() == 100 + N); |
156 | assert(is_contiguous_container_asan_correct(v)); |
157 | assert(i == v.begin() + 10); |
158 | int j; |
159 | for (j = 0; j < 10; ++j) |
160 | assert(v[j] == 0); |
161 | for (std::size_t k = 0; k < N; ++j, ++k) |
162 | assert(v[j] == a[k]); |
163 | for (; j < 105; ++j) |
164 | assert(v[j] == 0); |
165 | } |
166 | { // Ensure that iterator-pair insert() doesn't use unexpected assignment. |
167 | struct Wrapper { |
168 | TEST_CONSTEXPR Wrapper(int n) : n_(n) {} |
169 | |
170 | int n_; |
171 | |
172 | private: |
173 | void operator=(int); |
174 | }; |
175 | |
176 | int a[] = {1, 2, 3, 4, 5}; |
177 | const std::size_t count = sizeof(a) / sizeof(a[0]); |
178 | std::vector<Wrapper> v; |
179 | v.insert(position: v.end(), first: a, last: a + count); |
180 | assert(v.size() == count); |
181 | for (std::size_t i = 0; i != count; ++i) |
182 | assert(v[i].n_ == a[i]); |
183 | } |
184 | #if TEST_STD_VER >= 11 |
185 | { |
186 | typedef std::vector<int, min_allocator<int> > V; |
187 | V v(100); |
188 | int a[] = {1, 2, 3, 4, 5}; |
189 | const int N = sizeof(a) / sizeof(a[0]); |
190 | V::iterator i = |
191 | v.insert(v.cbegin() + 10, cpp17_input_iterator<const int*>(a), cpp17_input_iterator<const int*>(a + N)); |
192 | assert(v.size() == 100 + N); |
193 | assert(is_contiguous_container_asan_correct(v)); |
194 | assert(i == v.begin() + 10); |
195 | int j; |
196 | for (j = 0; j < 10; ++j) |
197 | assert(v[j] == 0); |
198 | for (std::size_t k = 0; k < N; ++j, ++k) |
199 | assert(v[j] == a[k]); |
200 | for (; j < 105; ++j) |
201 | assert(v[j] == 0); |
202 | } |
203 | { |
204 | typedef std::vector<int, min_allocator<int> > V; |
205 | V v(100); |
206 | int a[] = {1, 2, 3, 4, 5}; |
207 | const int N = sizeof(a) / sizeof(a[0]); |
208 | V::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a), forward_iterator<const int*>(a + N)); |
209 | assert(v.size() == 100 + N); |
210 | assert(is_contiguous_container_asan_correct(v)); |
211 | assert(i == v.begin() + 10); |
212 | int j; |
213 | for (j = 0; j < 10; ++j) |
214 | assert(v[j] == 0); |
215 | for (std::size_t k = 0; k < N; ++j, ++k) |
216 | assert(v[j] == a[k]); |
217 | for (; j < 105; ++j) |
218 | assert(v[j] == 0); |
219 | } |
220 | #endif |
221 | |
222 | { |
223 | std::vector<adl::S> s; |
224 | s.insert(s.end(), cpp17_input_iterator<adl::S*>(nullptr), cpp17_input_iterator<adl::S*>(nullptr)); |
225 | } |
226 | |
227 | return true; |
228 | } |
229 | |
230 | int main(int, char**) { |
231 | tests(); |
232 | #if TEST_STD_VER > 17 |
233 | static_assert(tests()); |
234 | #endif |
235 | return 0; |
236 | } |
237 | |