]> git.proxmox.com Git - rustc.git/blob - src/liballoc/collections/vec_deque/tests.rs
New upstream version 1.46.0+dfsg1
[rustc.git] / src / liballoc / collections / vec_deque / tests.rs
1 use super::*;
2
3 #[bench]
4 #[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
5 fn bench_push_back_100(b: &mut test::Bencher) {
6 let mut deq = VecDeque::with_capacity(101);
7 b.iter(|| {
8 for i in 0..100 {
9 deq.push_back(i);
10 }
11 deq.head = 0;
12 deq.tail = 0;
13 })
14 }
15
16 #[bench]
17 #[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
18 fn bench_push_front_100(b: &mut test::Bencher) {
19 let mut deq = VecDeque::with_capacity(101);
20 b.iter(|| {
21 for i in 0..100 {
22 deq.push_front(i);
23 }
24 deq.head = 0;
25 deq.tail = 0;
26 })
27 }
28
29 #[bench]
30 #[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
31 fn bench_pop_back_100(b: &mut test::Bencher) {
32 let mut deq = VecDeque::<i32>::with_capacity(101);
33
34 b.iter(|| {
35 deq.head = 100;
36 deq.tail = 0;
37 while !deq.is_empty() {
38 test::black_box(deq.pop_back());
39 }
40 })
41 }
42
43 #[bench]
44 #[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
45 fn bench_pop_front_100(b: &mut test::Bencher) {
46 let mut deq = VecDeque::<i32>::with_capacity(101);
47
48 b.iter(|| {
49 deq.head = 100;
50 deq.tail = 0;
51 while !deq.is_empty() {
52 test::black_box(deq.pop_front());
53 }
54 })
55 }
56
57 #[test]
58 fn test_swap_front_back_remove() {
59 fn test(back: bool) {
60 // This test checks that every single combination of tail position and length is tested.
61 // Capacity 15 should be large enough to cover every case.
62 let mut tester = VecDeque::with_capacity(15);
63 let usable_cap = tester.capacity();
64 let final_len = usable_cap / 2;
65
66 for len in 0..final_len {
67 let expected: VecDeque<_> =
68 if back { (0..len).collect() } else { (0..len).rev().collect() };
69 for tail_pos in 0..usable_cap {
70 tester.tail = tail_pos;
71 tester.head = tail_pos;
72 if back {
73 for i in 0..len * 2 {
74 tester.push_front(i);
75 }
76 for i in 0..len {
77 assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i));
78 }
79 } else {
80 for i in 0..len * 2 {
81 tester.push_back(i);
82 }
83 for i in 0..len {
84 let idx = tester.len() - 1 - i;
85 assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i));
86 }
87 }
88 assert!(tester.tail < tester.cap());
89 assert!(tester.head < tester.cap());
90 assert_eq!(tester, expected);
91 }
92 }
93 }
94 test(true);
95 test(false);
96 }
97
98 #[test]
99 fn test_insert() {
100 // This test checks that every single combination of tail position, length, and
101 // insertion position is tested. Capacity 15 should be large enough to cover every case.
102
103 let mut tester = VecDeque::with_capacity(15);
104 // can't guarantee we got 15, so have to get what we got.
105 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
106 // this test isn't covering what it wants to
107 let cap = tester.capacity();
108
109 // len is the length *after* insertion
110 for len in 1..cap {
111 // 0, 1, 2, .., len - 1
112 let expected = (0..).take(len).collect::<VecDeque<_>>();
113 for tail_pos in 0..cap {
114 for to_insert in 0..len {
115 tester.tail = tail_pos;
116 tester.head = tail_pos;
117 for i in 0..len {
118 if i != to_insert {
119 tester.push_back(i);
120 }
121 }
122 tester.insert(to_insert, to_insert);
123 assert!(tester.tail < tester.cap());
124 assert!(tester.head < tester.cap());
125 assert_eq!(tester, expected);
126 }
127 }
128 }
129 }
130
131 #[test]
132 fn make_contiguous_big_tail() {
133 let mut tester = VecDeque::with_capacity(15);
134
135 for i in 0..3 {
136 tester.push_back(i);
137 }
138
139 for i in 3..10 {
140 tester.push_front(i);
141 }
142
143 // 012......9876543
144 assert_eq!(tester.capacity(), 15);
145 assert_eq!((&[9, 8, 7, 6, 5, 4, 3] as &[_], &[0, 1, 2] as &[_]), tester.as_slices());
146
147 let expected_start = tester.head;
148 tester.make_contiguous();
149 assert_eq!(tester.tail, expected_start);
150 assert_eq!((&[9, 8, 7, 6, 5, 4, 3, 0, 1, 2] as &[_], &[] as &[_]), tester.as_slices());
151 }
152
153 #[test]
154 fn make_contiguous_big_head() {
155 let mut tester = VecDeque::with_capacity(15);
156
157 for i in 0..8 {
158 tester.push_back(i);
159 }
160
161 for i in 8..10 {
162 tester.push_front(i);
163 }
164
165 // 01234567......98
166 let expected_start = 0;
167 tester.make_contiguous();
168 assert_eq!(tester.tail, expected_start);
169 assert_eq!((&[9, 8, 0, 1, 2, 3, 4, 5, 6, 7] as &[_], &[] as &[_]), tester.as_slices());
170 }
171
172 #[test]
173 fn make_contiguous_small_free() {
174 let mut tester = VecDeque::with_capacity(15);
175
176 for i in 'A' as u8..'I' as u8 {
177 tester.push_back(i as char);
178 }
179
180 for i in 'I' as u8..'N' as u8 {
181 tester.push_front(i as char);
182 }
183
184 // ABCDEFGH...MLKJI
185 let expected_start = 0;
186 tester.make_contiguous();
187 assert_eq!(tester.tail, expected_start);
188 assert_eq!(
189 (&['M', 'L', 'K', 'J', 'I', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] as &[_], &[] as &[_]),
190 tester.as_slices()
191 );
192
193 tester.clear();
194 for i in 'I' as u8..'N' as u8 {
195 tester.push_back(i as char);
196 }
197
198 for i in 'A' as u8..'I' as u8 {
199 tester.push_front(i as char);
200 }
201
202 // IJKLM...HGFEDCBA
203 let expected_start = 0;
204 tester.make_contiguous();
205 assert_eq!(tester.tail, expected_start);
206 assert_eq!(
207 (&['H', 'G', 'F', 'E', 'D', 'C', 'B', 'A', 'I', 'J', 'K', 'L', 'M'] as &[_], &[] as &[_]),
208 tester.as_slices()
209 );
210 }
211
212 #[test]
213 fn test_remove() {
214 // This test checks that every single combination of tail position, length, and
215 // removal position is tested. Capacity 15 should be large enough to cover every case.
216
217 let mut tester = VecDeque::with_capacity(15);
218 // can't guarantee we got 15, so have to get what we got.
219 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
220 // this test isn't covering what it wants to
221 let cap = tester.capacity();
222
223 // len is the length *after* removal
224 for len in 0..cap - 1 {
225 // 0, 1, 2, .., len - 1
226 let expected = (0..).take(len).collect::<VecDeque<_>>();
227 for tail_pos in 0..cap {
228 for to_remove in 0..=len {
229 tester.tail = tail_pos;
230 tester.head = tail_pos;
231 for i in 0..len {
232 if i == to_remove {
233 tester.push_back(1234);
234 }
235 tester.push_back(i);
236 }
237 if to_remove == len {
238 tester.push_back(1234);
239 }
240 tester.remove(to_remove);
241 assert!(tester.tail < tester.cap());
242 assert!(tester.head < tester.cap());
243 assert_eq!(tester, expected);
244 }
245 }
246 }
247 }
248
249 #[test]
250 fn test_range() {
251 let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
252
253 let cap = tester.capacity();
254 for len in 0..=cap {
255 for tail in 0..=cap {
256 for start in 0..=len {
257 for end in start..=len {
258 tester.tail = tail;
259 tester.head = tail;
260 for i in 0..len {
261 tester.push_back(i);
262 }
263
264 // Check that we iterate over the correct values
265 let range: VecDeque<_> = tester.range(start..end).copied().collect();
266 let expected: VecDeque<_> = (start..end).collect();
267 assert_eq!(range, expected);
268 }
269 }
270 }
271 }
272 }
273
274 #[test]
275 fn test_range_mut() {
276 let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
277
278 let cap = tester.capacity();
279 for len in 0..=cap {
280 for tail in 0..=cap {
281 for start in 0..=len {
282 for end in start..=len {
283 tester.tail = tail;
284 tester.head = tail;
285 for i in 0..len {
286 tester.push_back(i);
287 }
288
289 let head_was = tester.head;
290 let tail_was = tester.tail;
291
292 // Check that we iterate over the correct values
293 let range: VecDeque<_> = tester.range_mut(start..end).map(|v| *v).collect();
294 let expected: VecDeque<_> = (start..end).collect();
295 assert_eq!(range, expected);
296
297 // We shouldn't have changed the capacity or made the
298 // head or tail out of bounds
299 assert_eq!(tester.capacity(), cap);
300 assert_eq!(tester.tail, tail_was);
301 assert_eq!(tester.head, head_was);
302 }
303 }
304 }
305 }
306 }
307
308 #[test]
309 fn test_drain() {
310 let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
311
312 let cap = tester.capacity();
313 for len in 0..=cap {
314 for tail in 0..=cap {
315 for drain_start in 0..=len {
316 for drain_end in drain_start..=len {
317 tester.tail = tail;
318 tester.head = tail;
319 for i in 0..len {
320 tester.push_back(i);
321 }
322
323 // Check that we drain the correct values
324 let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect();
325 let drained_expected: VecDeque<_> = (drain_start..drain_end).collect();
326 assert_eq!(drained, drained_expected);
327
328 // We shouldn't have changed the capacity or made the
329 // head or tail out of bounds
330 assert_eq!(tester.capacity(), cap);
331 assert!(tester.tail < tester.cap());
332 assert!(tester.head < tester.cap());
333
334 // We should see the correct values in the VecDeque
335 let expected: VecDeque<_> = (0..drain_start).chain(drain_end..len).collect();
336 assert_eq!(expected, tester);
337 }
338 }
339 }
340 }
341 }
342
343 #[test]
344 fn test_shrink_to_fit() {
345 // This test checks that every single combination of head and tail position,
346 // is tested. Capacity 15 should be large enough to cover every case.
347
348 let mut tester = VecDeque::with_capacity(15);
349 // can't guarantee we got 15, so have to get what we got.
350 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
351 // this test isn't covering what it wants to
352 let cap = tester.capacity();
353 tester.reserve(63);
354 let max_cap = tester.capacity();
355
356 for len in 0..=cap {
357 // 0, 1, 2, .., len - 1
358 let expected = (0..).take(len).collect::<VecDeque<_>>();
359 for tail_pos in 0..=max_cap {
360 tester.tail = tail_pos;
361 tester.head = tail_pos;
362 tester.reserve(63);
363 for i in 0..len {
364 tester.push_back(i);
365 }
366 tester.shrink_to_fit();
367 assert!(tester.capacity() <= cap);
368 assert!(tester.tail < tester.cap());
369 assert!(tester.head < tester.cap());
370 assert_eq!(tester, expected);
371 }
372 }
373 }
374
375 #[test]
376 fn test_split_off() {
377 // This test checks that every single combination of tail position, length, and
378 // split position is tested. Capacity 15 should be large enough to cover every case.
379
380 let mut tester = VecDeque::with_capacity(15);
381 // can't guarantee we got 15, so have to get what we got.
382 // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
383 // this test isn't covering what it wants to
384 let cap = tester.capacity();
385
386 // len is the length *before* splitting
387 for len in 0..cap {
388 // index to split at
389 for at in 0..=len {
390 // 0, 1, 2, .., at - 1 (may be empty)
391 let expected_self = (0..).take(at).collect::<VecDeque<_>>();
392 // at, at + 1, .., len - 1 (may be empty)
393 let expected_other = (at..).take(len - at).collect::<VecDeque<_>>();
394
395 for tail_pos in 0..cap {
396 tester.tail = tail_pos;
397 tester.head = tail_pos;
398 for i in 0..len {
399 tester.push_back(i);
400 }
401 let result = tester.split_off(at);
402 assert!(tester.tail < tester.cap());
403 assert!(tester.head < tester.cap());
404 assert!(result.tail < result.cap());
405 assert!(result.head < result.cap());
406 assert_eq!(tester, expected_self);
407 assert_eq!(result, expected_other);
408 }
409 }
410 }
411 }
412
413 #[test]
414 fn test_from_vec() {
415 use crate::vec::Vec;
416 for cap in 0..35 {
417 for len in 0..=cap {
418 let mut vec = Vec::with_capacity(cap);
419 vec.extend(0..len);
420
421 let vd = VecDeque::from(vec.clone());
422 assert!(vd.cap().is_power_of_two());
423 assert_eq!(vd.len(), vec.len());
424 assert!(vd.into_iter().eq(vec));
425 }
426 }
427 }
428
429 #[test]
430 fn test_vec_from_vecdeque() {
431 use crate::vec::Vec;
432
433 fn create_vec_and_test_convert(capacity: usize, offset: usize, len: usize) {
434 let mut vd = VecDeque::with_capacity(capacity);
435 for _ in 0..offset {
436 vd.push_back(0);
437 vd.pop_front();
438 }
439 vd.extend(0..len);
440
441 let vec: Vec<_> = Vec::from(vd.clone());
442 assert_eq!(vec.len(), vd.len());
443 assert!(vec.into_iter().eq(vd));
444 }
445
446 // Miri is too slow
447 let max_pwr = if cfg!(miri) { 5 } else { 7 };
448
449 for cap_pwr in 0..max_pwr {
450 // Make capacity as a (2^x)-1, so that the ring size is 2^x
451 let cap = (2i32.pow(cap_pwr) - 1) as usize;
452
453 // In these cases there is enough free space to solve it with copies
454 for len in 0..((cap + 1) / 2) {
455 // Test contiguous cases
456 for offset in 0..(cap - len) {
457 create_vec_and_test_convert(cap, offset, len)
458 }
459
460 // Test cases where block at end of buffer is bigger than block at start
461 for offset in (cap - len)..(cap - (len / 2)) {
462 create_vec_and_test_convert(cap, offset, len)
463 }
464
465 // Test cases where block at start of buffer is bigger than block at end
466 for offset in (cap - (len / 2))..cap {
467 create_vec_and_test_convert(cap, offset, len)
468 }
469 }
470
471 // Now there's not (necessarily) space to straighten the ring with simple copies,
472 // the ring will use swapping when:
473 // (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len))
474 // right block size > free space && left block size > free space
475 for len in ((cap + 1) / 2)..cap {
476 // Test contiguous cases
477 for offset in 0..(cap - len) {
478 create_vec_and_test_convert(cap, offset, len)
479 }
480
481 // Test cases where block at end of buffer is bigger than block at start
482 for offset in (cap - len)..(cap - (len / 2)) {
483 create_vec_and_test_convert(cap, offset, len)
484 }
485
486 // Test cases where block at start of buffer is bigger than block at end
487 for offset in (cap - (len / 2))..cap {
488 create_vec_and_test_convert(cap, offset, len)
489 }
490 }
491 }
492 }
493
494 #[test]
495 fn test_clone_from() {
496 let m = vec![1; 8];
497 let n = vec![2; 12];
498 for pfv in 0..8 {
499 for pfu in 0..8 {
500 for longer in 0..2 {
501 let (vr, ur) = if longer == 0 { (&m, &n) } else { (&n, &m) };
502 let mut v = VecDeque::from(vr.clone());
503 for _ in 0..pfv {
504 v.push_front(1);
505 }
506 let mut u = VecDeque::from(ur.clone());
507 for _ in 0..pfu {
508 u.push_front(2);
509 }
510 v.clone_from(&u);
511 assert_eq!(&v, &u);
512 }
513 }
514 }
515 }
516
517 #[test]
518 fn test_vec_deque_truncate_drop() {
519 static mut DROPS: u32 = 0;
520 #[derive(Clone)]
521 struct Elem(i32);
522 impl Drop for Elem {
523 fn drop(&mut self) {
524 unsafe {
525 DROPS += 1;
526 }
527 }
528 }
529
530 let v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
531 for push_front in 0..=v.len() {
532 let v = v.clone();
533 let mut tester = VecDeque::with_capacity(5);
534 for (index, elem) in v.into_iter().enumerate() {
535 if index < push_front {
536 tester.push_front(elem);
537 } else {
538 tester.push_back(elem);
539 }
540 }
541 assert_eq!(unsafe { DROPS }, 0);
542 tester.truncate(3);
543 assert_eq!(unsafe { DROPS }, 2);
544 tester.truncate(0);
545 assert_eq!(unsafe { DROPS }, 5);
546 unsafe {
547 DROPS = 0;
548 }
549 }
550 }
551
552 #[test]
553 fn issue_53529() {
554 use crate::boxed::Box;
555
556 let mut dst = VecDeque::new();
557 dst.push_front(Box::new(1));
558 dst.push_front(Box::new(2));
559 assert_eq!(*dst.pop_back().unwrap(), 1);
560
561 let mut src = VecDeque::new();
562 src.push_front(Box::new(2));
563 dst.append(&mut src);
564 for a in dst {
565 assert_eq!(*a, 2);
566 }
567 }