]> git.lizzy.rs Git - rust.git/blob - library/alloc/src/collections/vec_deque/tests.rs
Rollup merge of #90851 - ibraheemdev:downcast-unchecked, r=scottmcm
[rust.git] / library / alloc / src / 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_retain_whole_10000(b: &mut test::Bencher) {
46     let v = (1..100000).collect::<VecDeque<u32>>();
47
48     b.iter(|| {
49         let mut v = v.clone();
50         v.retain(|x| *x > 0)
51     })
52 }
53
54 #[bench]
55 #[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
56 fn bench_retain_odd_10000(b: &mut test::Bencher) {
57     let v = (1..100000).collect::<VecDeque<u32>>();
58
59     b.iter(|| {
60         let mut v = v.clone();
61         v.retain(|x| x & 1 == 0)
62     })
63 }
64
65 #[bench]
66 #[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
67 fn bench_retain_half_10000(b: &mut test::Bencher) {
68     let v = (1..100000).collect::<VecDeque<u32>>();
69
70     b.iter(|| {
71         let mut v = v.clone();
72         v.retain(|x| *x > 50000)
73     })
74 }
75
76 #[bench]
77 #[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
78 fn bench_pop_front_100(b: &mut test::Bencher) {
79     let mut deq = VecDeque::<i32>::with_capacity(101);
80
81     b.iter(|| {
82         deq.head = 100;
83         deq.tail = 0;
84         while !deq.is_empty() {
85             test::black_box(deq.pop_front());
86         }
87     })
88 }
89
90 #[test]
91 fn test_swap_front_back_remove() {
92     fn test(back: bool) {
93         // This test checks that every single combination of tail position and length is tested.
94         // Capacity 15 should be large enough to cover every case.
95         let mut tester = VecDeque::with_capacity(15);
96         let usable_cap = tester.capacity();
97         let final_len = usable_cap / 2;
98
99         for len in 0..final_len {
100             let expected: VecDeque<_> =
101                 if back { (0..len).collect() } else { (0..len).rev().collect() };
102             for tail_pos in 0..usable_cap {
103                 tester.tail = tail_pos;
104                 tester.head = tail_pos;
105                 if back {
106                     for i in 0..len * 2 {
107                         tester.push_front(i);
108                     }
109                     for i in 0..len {
110                         assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i));
111                     }
112                 } else {
113                     for i in 0..len * 2 {
114                         tester.push_back(i);
115                     }
116                     for i in 0..len {
117                         let idx = tester.len() - 1 - i;
118                         assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i));
119                     }
120                 }
121                 assert!(tester.tail < tester.cap());
122                 assert!(tester.head < tester.cap());
123                 assert_eq!(tester, expected);
124             }
125         }
126     }
127     test(true);
128     test(false);
129 }
130
131 #[test]
132 fn test_insert() {
133     // This test checks that every single combination of tail position, length, and
134     // insertion position is tested. Capacity 15 should be large enough to cover every case.
135
136     let mut tester = VecDeque::with_capacity(15);
137     // can't guarantee we got 15, so have to get what we got.
138     // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
139     // this test isn't covering what it wants to
140     let cap = tester.capacity();
141
142     // len is the length *after* insertion
143     let minlen = if cfg!(miri) { cap - 1 } else { 1 }; // Miri is too slow
144     for len in minlen..cap {
145         // 0, 1, 2, .., len - 1
146         let expected = (0..).take(len).collect::<VecDeque<_>>();
147         for tail_pos in 0..cap {
148             for to_insert in 0..len {
149                 tester.tail = tail_pos;
150                 tester.head = tail_pos;
151                 for i in 0..len {
152                     if i != to_insert {
153                         tester.push_back(i);
154                     }
155                 }
156                 tester.insert(to_insert, to_insert);
157                 assert!(tester.tail < tester.cap());
158                 assert!(tester.head < tester.cap());
159                 assert_eq!(tester, expected);
160             }
161         }
162     }
163 }
164
165 #[test]
166 fn make_contiguous_big_tail() {
167     let mut tester = VecDeque::with_capacity(15);
168
169     for i in 0..3 {
170         tester.push_back(i);
171     }
172
173     for i in 3..10 {
174         tester.push_front(i);
175     }
176
177     // 012......9876543
178     assert_eq!(tester.capacity(), 15);
179     assert_eq!((&[9, 8, 7, 6, 5, 4, 3] as &[_], &[0, 1, 2] as &[_]), tester.as_slices());
180
181     let expected_start = tester.head;
182     tester.make_contiguous();
183     assert_eq!(tester.tail, expected_start);
184     assert_eq!((&[9, 8, 7, 6, 5, 4, 3, 0, 1, 2] as &[_], &[] as &[_]), tester.as_slices());
185 }
186
187 #[test]
188 fn make_contiguous_big_head() {
189     let mut tester = VecDeque::with_capacity(15);
190
191     for i in 0..8 {
192         tester.push_back(i);
193     }
194
195     for i in 8..10 {
196         tester.push_front(i);
197     }
198
199     // 01234567......98
200     let expected_start = 0;
201     tester.make_contiguous();
202     assert_eq!(tester.tail, expected_start);
203     assert_eq!((&[9, 8, 0, 1, 2, 3, 4, 5, 6, 7] as &[_], &[] as &[_]), tester.as_slices());
204 }
205
206 #[test]
207 fn make_contiguous_small_free() {
208     let mut tester = VecDeque::with_capacity(15);
209
210     for i in 'A' as u8..'I' as u8 {
211         tester.push_back(i as char);
212     }
213
214     for i in 'I' as u8..'N' as u8 {
215         tester.push_front(i as char);
216     }
217
218     // ABCDEFGH...MLKJI
219     let expected_start = 0;
220     tester.make_contiguous();
221     assert_eq!(tester.tail, expected_start);
222     assert_eq!(
223         (&['M', 'L', 'K', 'J', 'I', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] as &[_], &[] as &[_]),
224         tester.as_slices()
225     );
226
227     tester.clear();
228     for i in 'I' as u8..'N' as u8 {
229         tester.push_back(i as char);
230     }
231
232     for i in 'A' as u8..'I' as u8 {
233         tester.push_front(i as char);
234     }
235
236     // IJKLM...HGFEDCBA
237     let expected_start = 0;
238     tester.make_contiguous();
239     assert_eq!(tester.tail, expected_start);
240     assert_eq!(
241         (&['H', 'G', 'F', 'E', 'D', 'C', 'B', 'A', 'I', 'J', 'K', 'L', 'M'] as &[_], &[] as &[_]),
242         tester.as_slices()
243     );
244 }
245
246 #[test]
247 fn make_contiguous_head_to_end() {
248     let mut dq = VecDeque::with_capacity(3);
249     dq.push_front('B');
250     dq.push_front('A');
251     dq.push_back('C');
252     dq.make_contiguous();
253     let expected_tail = 0;
254     let expected_head = 3;
255     assert_eq!(expected_tail, dq.tail);
256     assert_eq!(expected_head, dq.head);
257     assert_eq!((&['A', 'B', 'C'] as &[_], &[] as &[_]), dq.as_slices());
258 }
259
260 #[test]
261 fn make_contiguous_head_to_end_2() {
262     // Another test case for #79808, taken from #80293.
263
264     let mut dq = VecDeque::from_iter(0..6);
265     dq.pop_front();
266     dq.pop_front();
267     dq.push_back(6);
268     dq.push_back(7);
269     dq.push_back(8);
270     dq.make_contiguous();
271     let collected: Vec<_> = dq.iter().copied().collect();
272     assert_eq!(dq.as_slices(), (&collected[..], &[] as &[_]));
273 }
274
275 #[test]
276 fn test_remove() {
277     // This test checks that every single combination of tail position, length, and
278     // removal position is tested. Capacity 15 should be large enough to cover every case.
279
280     let mut tester = VecDeque::with_capacity(15);
281     // can't guarantee we got 15, so have to get what we got.
282     // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
283     // this test isn't covering what it wants to
284     let cap = tester.capacity();
285
286     // len is the length *after* removal
287     let minlen = if cfg!(miri) { cap - 2 } else { 0 }; // Miri is too slow
288     for len in minlen..cap - 1 {
289         // 0, 1, 2, .., len - 1
290         let expected = (0..).take(len).collect::<VecDeque<_>>();
291         for tail_pos in 0..cap {
292             for to_remove in 0..=len {
293                 tester.tail = tail_pos;
294                 tester.head = tail_pos;
295                 for i in 0..len {
296                     if i == to_remove {
297                         tester.push_back(1234);
298                     }
299                     tester.push_back(i);
300                 }
301                 if to_remove == len {
302                     tester.push_back(1234);
303                 }
304                 tester.remove(to_remove);
305                 assert!(tester.tail < tester.cap());
306                 assert!(tester.head < tester.cap());
307                 assert_eq!(tester, expected);
308             }
309         }
310     }
311 }
312
313 #[test]
314 fn test_range() {
315     let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
316
317     let cap = tester.capacity();
318     let minlen = if cfg!(miri) { cap - 1 } else { 0 }; // Miri is too slow
319     for len in minlen..=cap {
320         for tail in 0..=cap {
321             for start in 0..=len {
322                 for end in start..=len {
323                     tester.tail = tail;
324                     tester.head = tail;
325                     for i in 0..len {
326                         tester.push_back(i);
327                     }
328
329                     // Check that we iterate over the correct values
330                     let range: VecDeque<_> = tester.range(start..end).copied().collect();
331                     let expected: VecDeque<_> = (start..end).collect();
332                     assert_eq!(range, expected);
333                 }
334             }
335         }
336     }
337 }
338
339 #[test]
340 fn test_range_mut() {
341     let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
342
343     let cap = tester.capacity();
344     for len in 0..=cap {
345         for tail in 0..=cap {
346             for start in 0..=len {
347                 for end in start..=len {
348                     tester.tail = tail;
349                     tester.head = tail;
350                     for i in 0..len {
351                         tester.push_back(i);
352                     }
353
354                     let head_was = tester.head;
355                     let tail_was = tester.tail;
356
357                     // Check that we iterate over the correct values
358                     let range: VecDeque<_> = tester.range_mut(start..end).map(|v| *v).collect();
359                     let expected: VecDeque<_> = (start..end).collect();
360                     assert_eq!(range, expected);
361
362                     // We shouldn't have changed the capacity or made the
363                     // head or tail out of bounds
364                     assert_eq!(tester.capacity(), cap);
365                     assert_eq!(tester.tail, tail_was);
366                     assert_eq!(tester.head, head_was);
367                 }
368             }
369         }
370     }
371 }
372
373 #[test]
374 fn test_drain() {
375     let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
376
377     let cap = tester.capacity();
378     for len in 0..=cap {
379         for tail in 0..=cap {
380             for drain_start in 0..=len {
381                 for drain_end in drain_start..=len {
382                     tester.tail = tail;
383                     tester.head = tail;
384                     for i in 0..len {
385                         tester.push_back(i);
386                     }
387
388                     // Check that we drain the correct values
389                     let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect();
390                     let drained_expected: VecDeque<_> = (drain_start..drain_end).collect();
391                     assert_eq!(drained, drained_expected);
392
393                     // We shouldn't have changed the capacity or made the
394                     // head or tail out of bounds
395                     assert_eq!(tester.capacity(), cap);
396                     assert!(tester.tail < tester.cap());
397                     assert!(tester.head < tester.cap());
398
399                     // We should see the correct values in the VecDeque
400                     let expected: VecDeque<_> = (0..drain_start).chain(drain_end..len).collect();
401                     assert_eq!(expected, tester);
402                 }
403             }
404         }
405     }
406 }
407
408 #[test]
409 fn test_shrink_to_fit() {
410     // This test checks that every single combination of head and tail position,
411     // is tested. Capacity 15 should be large enough to cover every case.
412
413     let mut tester = VecDeque::with_capacity(15);
414     // can't guarantee we got 15, so have to get what we got.
415     // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
416     // this test isn't covering what it wants to
417     let cap = tester.capacity();
418     tester.reserve(63);
419     let max_cap = tester.capacity();
420
421     for len in 0..=cap {
422         // 0, 1, 2, .., len - 1
423         let expected = (0..).take(len).collect::<VecDeque<_>>();
424         for tail_pos in 0..=max_cap {
425             tester.tail = tail_pos;
426             tester.head = tail_pos;
427             tester.reserve(63);
428             for i in 0..len {
429                 tester.push_back(i);
430             }
431             tester.shrink_to_fit();
432             assert!(tester.capacity() <= cap);
433             assert!(tester.tail < tester.cap());
434             assert!(tester.head < tester.cap());
435             assert_eq!(tester, expected);
436         }
437     }
438 }
439
440 #[test]
441 fn test_split_off() {
442     // This test checks that every single combination of tail position, length, and
443     // split position is tested. Capacity 15 should be large enough to cover every case.
444
445     let mut tester = VecDeque::with_capacity(15);
446     // can't guarantee we got 15, so have to get what we got.
447     // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
448     // this test isn't covering what it wants to
449     let cap = tester.capacity();
450
451     // len is the length *before* splitting
452     let minlen = if cfg!(miri) { cap - 1 } else { 0 }; // Miri is too slow
453     for len in minlen..cap {
454         // index to split at
455         for at in 0..=len {
456             // 0, 1, 2, .., at - 1 (may be empty)
457             let expected_self = (0..).take(at).collect::<VecDeque<_>>();
458             // at, at + 1, .., len - 1 (may be empty)
459             let expected_other = (at..).take(len - at).collect::<VecDeque<_>>();
460
461             for tail_pos in 0..cap {
462                 tester.tail = tail_pos;
463                 tester.head = tail_pos;
464                 for i in 0..len {
465                     tester.push_back(i);
466                 }
467                 let result = tester.split_off(at);
468                 assert!(tester.tail < tester.cap());
469                 assert!(tester.head < tester.cap());
470                 assert!(result.tail < result.cap());
471                 assert!(result.head < result.cap());
472                 assert_eq!(tester, expected_self);
473                 assert_eq!(result, expected_other);
474             }
475         }
476     }
477 }
478
479 #[test]
480 fn test_from_vec() {
481     use crate::vec::Vec;
482     for cap in 0..35 {
483         for len in 0..=cap {
484             let mut vec = Vec::with_capacity(cap);
485             vec.extend(0..len);
486
487             let vd = VecDeque::from(vec.clone());
488             assert!(vd.cap().is_power_of_two());
489             assert_eq!(vd.len(), vec.len());
490             assert!(vd.into_iter().eq(vec));
491         }
492     }
493
494     let vec = Vec::from([(); MAXIMUM_ZST_CAPACITY - 1]);
495     let vd = VecDeque::from(vec.clone());
496     assert!(vd.cap().is_power_of_two());
497     assert_eq!(vd.len(), vec.len());
498 }
499
500 #[test]
501 #[should_panic = "capacity overflow"]
502 fn test_from_vec_zst_overflow() {
503     use crate::vec::Vec;
504     let vec = Vec::from([(); MAXIMUM_ZST_CAPACITY]);
505     let vd = VecDeque::from(vec.clone()); // no room for +1
506     assert!(vd.cap().is_power_of_two());
507     assert_eq!(vd.len(), vec.len());
508 }
509
510 #[test]
511 fn test_from_array() {
512     fn test<const N: usize>() {
513         let mut array: [usize; N] = [0; N];
514
515         for i in 0..N {
516             array[i] = i;
517         }
518
519         let deq: VecDeque<_> = array.into();
520
521         for i in 0..N {
522             assert_eq!(deq[i], i);
523         }
524
525         assert!(deq.cap().is_power_of_two());
526         assert_eq!(deq.len(), N);
527     }
528     test::<0>();
529     test::<1>();
530     test::<2>();
531     test::<32>();
532     test::<35>();
533
534     let array = [(); MAXIMUM_ZST_CAPACITY - 1];
535     let deq = VecDeque::from(array);
536     assert!(deq.cap().is_power_of_two());
537     assert_eq!(deq.len(), MAXIMUM_ZST_CAPACITY - 1);
538 }
539
540 #[test]
541 fn test_vec_from_vecdeque() {
542     use crate::vec::Vec;
543
544     fn create_vec_and_test_convert(capacity: usize, offset: usize, len: usize) {
545         let mut vd = VecDeque::with_capacity(capacity);
546         for _ in 0..offset {
547             vd.push_back(0);
548             vd.pop_front();
549         }
550         vd.extend(0..len);
551
552         let vec: Vec<_> = Vec::from(vd.clone());
553         assert_eq!(vec.len(), vd.len());
554         assert!(vec.into_iter().eq(vd));
555     }
556
557     // Miri is too slow
558     let max_pwr = if cfg!(miri) { 5 } else { 7 };
559
560     for cap_pwr in 0..max_pwr {
561         // Make capacity as a (2^x)-1, so that the ring size is 2^x
562         let cap = (2i32.pow(cap_pwr) - 1) as usize;
563
564         // In these cases there is enough free space to solve it with copies
565         for len in 0..((cap + 1) / 2) {
566             // Test contiguous cases
567             for offset in 0..(cap - len) {
568                 create_vec_and_test_convert(cap, offset, len)
569             }
570
571             // Test cases where block at end of buffer is bigger than block at start
572             for offset in (cap - len)..(cap - (len / 2)) {
573                 create_vec_and_test_convert(cap, offset, len)
574             }
575
576             // Test cases where block at start of buffer is bigger than block at end
577             for offset in (cap - (len / 2))..cap {
578                 create_vec_and_test_convert(cap, offset, len)
579             }
580         }
581
582         // Now there's not (necessarily) space to straighten the ring with simple copies,
583         // the ring will use swapping when:
584         // (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len))
585         //  right block size  >   free space    &&      left block size       >    free space
586         for len in ((cap + 1) / 2)..cap {
587             // Test contiguous cases
588             for offset in 0..(cap - len) {
589                 create_vec_and_test_convert(cap, offset, len)
590             }
591
592             // Test cases where block at end of buffer is bigger than block at start
593             for offset in (cap - len)..(cap - (len / 2)) {
594                 create_vec_and_test_convert(cap, offset, len)
595             }
596
597             // Test cases where block at start of buffer is bigger than block at end
598             for offset in (cap - (len / 2))..cap {
599                 create_vec_and_test_convert(cap, offset, len)
600             }
601         }
602     }
603 }
604
605 #[test]
606 fn test_clone_from() {
607     let m = vec![1; 8];
608     let n = vec![2; 12];
609     let limit = if cfg!(miri) { 4 } else { 8 }; // Miri is too slow
610     for pfv in 0..limit {
611         for pfu in 0..limit {
612             for longer in 0..2 {
613                 let (vr, ur) = if longer == 0 { (&m, &n) } else { (&n, &m) };
614                 let mut v = VecDeque::from(vr.clone());
615                 for _ in 0..pfv {
616                     v.push_front(1);
617                 }
618                 let mut u = VecDeque::from(ur.clone());
619                 for _ in 0..pfu {
620                     u.push_front(2);
621                 }
622                 v.clone_from(&u);
623                 assert_eq!(&v, &u);
624             }
625         }
626     }
627 }
628
629 #[test]
630 fn test_vec_deque_truncate_drop() {
631     static mut DROPS: u32 = 0;
632     #[derive(Clone)]
633     struct Elem(i32);
634     impl Drop for Elem {
635         fn drop(&mut self) {
636             unsafe {
637                 DROPS += 1;
638             }
639         }
640     }
641
642     let v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
643     for push_front in 0..=v.len() {
644         let v = v.clone();
645         let mut tester = VecDeque::with_capacity(5);
646         for (index, elem) in v.into_iter().enumerate() {
647             if index < push_front {
648                 tester.push_front(elem);
649             } else {
650                 tester.push_back(elem);
651             }
652         }
653         assert_eq!(unsafe { DROPS }, 0);
654         tester.truncate(3);
655         assert_eq!(unsafe { DROPS }, 2);
656         tester.truncate(0);
657         assert_eq!(unsafe { DROPS }, 5);
658         unsafe {
659             DROPS = 0;
660         }
661     }
662 }
663
664 #[test]
665 fn issue_53529() {
666     use crate::boxed::Box;
667
668     let mut dst = VecDeque::new();
669     dst.push_front(Box::new(1));
670     dst.push_front(Box::new(2));
671     assert_eq!(*dst.pop_back().unwrap(), 1);
672
673     let mut src = VecDeque::new();
674     src.push_front(Box::new(2));
675     dst.append(&mut src);
676     for a in dst {
677         assert_eq!(*a, 2);
678     }
679 }
680
681 #[test]
682 fn issue_80303() {
683     use core::iter;
684     use core::num::Wrapping;
685
686     // This is a valid, albeit rather bad hash function implementation.
687     struct SimpleHasher(Wrapping<u64>);
688
689     impl Hasher for SimpleHasher {
690         fn finish(&self) -> u64 {
691             self.0.0
692         }
693
694         fn write(&mut self, bytes: &[u8]) {
695             // This particular implementation hashes value 24 in addition to bytes.
696             // Such an implementation is valid as Hasher only guarantees equivalence
697             // for the exact same set of calls to its methods.
698             for &v in iter::once(&24).chain(bytes) {
699                 self.0 = Wrapping(31) * self.0 + Wrapping(u64::from(v));
700             }
701         }
702     }
703
704     fn hash_code(value: impl Hash) -> u64 {
705         let mut hasher = SimpleHasher(Wrapping(1));
706         value.hash(&mut hasher);
707         hasher.finish()
708     }
709
710     // This creates two deques for which values returned by as_slices
711     // method differ.
712     let vda: VecDeque<u8> = (0..10).collect();
713     let mut vdb = VecDeque::with_capacity(10);
714     vdb.extend(5..10);
715     (0..5).rev().for_each(|elem| vdb.push_front(elem));
716     assert_ne!(vda.as_slices(), vdb.as_slices());
717     assert_eq!(vda, vdb);
718     assert_eq!(hash_code(vda), hash_code(vdb));
719 }