1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // REQUIRES: long_tests
11
12 // <deque>
13
14 // template <class InputIterator>
15 // iterator insert (const_iterator p, InputIterator f, InputIterator l);
16
17 #include <deque>
18 #include <cassert>
19
20 #include "test_macros.h"
21 #include "test_iterators.h"
22 #include "MoveOnly.h"
23 #include "../../../stack_allocator.h"
24 #include "min_allocator.h"
25
26 template <class C>
27 C
make(int size,int start=0)28 make(int size, int start = 0 )
29 {
30 const int b = 4096 / sizeof(int);
31 int init = 0;
32 if (start > 0)
33 {
34 init = (start+1) / b + ((start+1) % b != 0);
35 init *= b;
36 --init;
37 }
38 C c(init, 0);
39 for (int i = 0; i < init-start; ++i)
40 c.pop_back();
41 for (int i = 0; i < size; ++i)
42 c.push_back(i);
43 for (int i = 0; i < start; ++i)
44 c.pop_front();
45 return c;
46 }
47
48 template <class C>
49 void
test(int P,const C & c0,const C & c2)50 test(int P, const C& c0, const C& c2)
51 {
52 {
53 typedef typename C::const_iterator CI;
54 typedef input_iterator<CI> BCI;
55 C c1 = c0;
56 std::size_t c1_osize = c1.size();
57 CI i = c1.insert(c1.begin() + P, BCI(c2.begin()), BCI(c2.end()));
58 assert(i == c1.begin() + P);
59 assert(c1.size() == c1_osize + c2.size());
60 assert(distance(c1.begin(), c1.end()) == c1.size());
61 i = c1.begin();
62 for (int j = 0; j < P; ++j, ++i)
63 assert(*i == j);
64 for (int j = 0; j < c2.size(); ++j, ++i)
65 assert(*i == j);
66 for (int j = P; j < c1_osize; ++j, ++i)
67 assert(*i == j);
68 }
69 {
70 typedef typename C::const_iterator CI;
71 typedef forward_iterator<CI> BCI;
72 C c1 = c0;
73 std::size_t c1_osize = c1.size();
74 CI i = c1.insert(c1.begin() + P, BCI(c2.begin()), BCI(c2.end()));
75 assert(i == c1.begin() + P);
76 assert(c1.size() == c1_osize + c2.size());
77 assert(distance(c1.begin(), c1.end()) == c1.size());
78 i = c1.begin();
79 for (int j = 0; j < P; ++j, ++i)
80 assert(*i == j);
81 for (int j = 0; j < c2.size(); ++j, ++i)
82 assert(*i == j);
83 for (int j = P; j < c1_osize; ++j, ++i)
84 assert(*i == j);
85 }
86 {
87 typedef typename C::const_iterator CI;
88 typedef bidirectional_iterator<CI> BCI;
89 C c1 = c0;
90 std::size_t c1_osize = c1.size();
91 CI i = c1.insert(c1.begin() + P, BCI(c2.begin()), BCI(c2.end()));
92 assert(i == c1.begin() + P);
93 assert(c1.size() == c1_osize + c2.size());
94 assert(distance(c1.begin(), c1.end()) == c1.size());
95 i = c1.begin();
96 for (int j = 0; j < P; ++j, ++i)
97 assert(*i == j);
98 for (int j = 0; j < c2.size(); ++j, ++i)
99 assert(*i == j);
100 for (int j = P; j < c1_osize; ++j, ++i)
101 assert(*i == j);
102 }
103 }
104
105 template <class C>
106 void
testN(int start,int N,int M)107 testN(int start, int N, int M)
108 {
109 for (int i = 0; i <= 3; ++i)
110 {
111 if (0 <= i && i <= N)
112 {
113 C c1 = make<C>(N, start);
114 C c2 = make<C>(M);
115 test(i, c1, c2);
116 }
117 }
118 for (int i = M-1; i <= M+1; ++i)
119 {
120 if (0 <= i && i <= N)
121 {
122 C c1 = make<C>(N, start);
123 C c2 = make<C>(M);
124 test(i, c1, c2);
125 }
126 }
127 for (int i = N/2-1; i <= N/2+1; ++i)
128 {
129 if (0 <= i && i <= N)
130 {
131 C c1 = make<C>(N, start);
132 C c2 = make<C>(M);
133 test(i, c1, c2);
134 }
135 }
136 for (int i = N - M - 1; i <= N - M + 1; ++i)
137 {
138 if (0 <= i && i <= N)
139 {
140 C c1 = make<C>(N, start);
141 C c2 = make<C>(M);
142 test(i, c1, c2);
143 }
144 }
145 for (int i = N - M - 1; i <= N - M + 1; ++i)
146 {
147 if (0 <= i && i <= N)
148 {
149 C c1 = make<C>(N, start);
150 C c2 = make<C>(M);
151 test(i, c1, c2);
152 }
153 }
154 for (int i = N - 3; i <= N; ++i)
155 {
156 if (0 <= i && i <= N)
157 {
158 C c1 = make<C>(N, start);
159 C c2 = make<C>(M);
160 test(i, c1, c2);
161 }
162 }
163 }
164
165 template <class C>
166 void
testI(int P,C & c1,const C & c2)167 testI(int P, C& c1, const C& c2)
168 {
169 typedef typename C::const_iterator CI;
170 typedef input_iterator<CI> ICI;
171 std::size_t c1_osize = c1.size();
172 CI i = c1.insert(c1.begin() + P, ICI(c2.begin()), ICI(c2.end()));
173 assert(i == c1.begin() + P);
174 assert(c1.size() == c1_osize + c2.size());
175 assert(distance(c1.begin(), c1.end()) == c1.size());
176 i = c1.begin();
177 for (int j = 0; j < P; ++j, ++i)
178 assert(*i == j);
179 for (int j = 0; j < c2.size(); ++j, ++i)
180 assert(*i == j);
181 for (int j = P; j < c1_osize; ++j, ++i)
182 assert(*i == j);
183 }
184
185 template <class C>
186 void
testNI(int start,int N,int M)187 testNI(int start, int N, int M)
188 {
189 for (int i = 0; i <= 3; ++i)
190 {
191 if (0 <= i && i <= N)
192 {
193 C c1 = make<C>(N, start);
194 C c2 = make<C>(M);
195 testI(i, c1, c2);
196 }
197 }
198 for (int i = M-1; i <= M+1; ++i)
199 {
200 if (0 <= i && i <= N)
201 {
202 C c1 = make<C>(N, start);
203 C c2 = make<C>(M);
204 testI(i, c1, c2);
205 }
206 }
207 for (int i = N/2-1; i <= N/2+1; ++i)
208 {
209 if (0 <= i && i <= N)
210 {
211 C c1 = make<C>(N, start);
212 C c2 = make<C>(M);
213 testI(i, c1, c2);
214 }
215 }
216 for (int i = N - M - 1; i <= N - M + 1; ++i)
217 {
218 if (0 <= i && i <= N)
219 {
220 C c1 = make<C>(N, start);
221 C c2 = make<C>(M);
222 testI(i, c1, c2);
223 }
224 }
225 for (int i = N - 3; i <= N; ++i)
226 {
227 if (0 <= i && i <= N)
228 {
229 C c1 = make<C>(N, start);
230 C c2 = make<C>(M);
231 testI(i, c1, c2);
232 }
233 }
234 }
235
236 template <class C>
237 void
test_move()238 test_move()
239 {
240 #if TEST_STD_VER >= 11
241 C c;
242 typedef typename C::const_iterator CI;
243 {
244 MoveOnly mo(0);
245 typedef MoveOnly* I;
246 c.insert(c.end(), std::move_iterator<I>(&mo), std::move_iterator<I>(&mo+1));
247 }
248 int j = 0;
249 for (CI i = c.begin(); i != c.end(); ++i, ++j)
250 assert(*i == MoveOnly(j));
251 {
252 MoveOnly mo(1);
253 typedef input_iterator<MoveOnly*> I;
254 c.insert(c.end(), std::move_iterator<I>(I(&mo)), std::move_iterator<I>(I(&mo+1)));
255 }
256 j = 0;
257 for (CI i = c.begin(); i != c.end(); ++i, ++j)
258 assert(*i == MoveOnly(j));
259 #endif
260 }
261
main()262 int main()
263 {
264 {
265 int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
266 const int N = sizeof(rng)/sizeof(rng[0]);
267 for (int i = 0; i < N; ++i)
268 for (int j = 0; j < N; ++j)
269 for (int k = 0; k < N; ++k)
270 testN<std::deque<int> >(rng[i], rng[j], rng[k]);
271 testNI<std::deque<int> >(1500, 2000, 1000);
272 #if TEST_STD_VER >= 11
273 test_move<std::deque<MoveOnly, stack_allocator<MoveOnly, 2000> > >();
274 #endif
275 }
276 #if TEST_STD_VER >= 11
277 {
278 int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
279 const int N = sizeof(rng)/sizeof(rng[0]);
280 for (int i = 0; i < N; ++i)
281 for (int j = 0; j < N; ++j)
282 for (int k = 0; k < N; ++k)
283 testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j], rng[k]);
284 testNI<std::deque<int> >(1500, 2000, 1000);
285 test_move<std::deque<MoveOnly, min_allocator<MoveOnly> > >();
286 }
287 #endif
288 }
289