| use std::cmp::Ordering::{Equal, Greater, Less}; |
| use std::convert::identity; |
| use std::rc::Rc; |
| use std::{fmt, mem, panic}; |
| |
| fn square(n: usize) -> usize { |
| n * n |
| } |
| |
| fn is_odd(n: &usize) -> bool { |
| *n % 2 == 1 |
| } |
| |
| #[test] |
| fn test_from_fn() { |
| // Test on-stack from_fn. |
| let mut v: Vec<_> = (0..3).map(square).collect(); |
| { |
| let v = v; |
| assert_eq!(v.len(), 3); |
| assert_eq!(v[0], 0); |
| assert_eq!(v[1], 1); |
| assert_eq!(v[2], 4); |
| } |
| |
| // Test on-heap from_fn. |
| v = (0..5).map(square).collect(); |
| { |
| let v = v; |
| assert_eq!(v.len(), 5); |
| assert_eq!(v[0], 0); |
| assert_eq!(v[1], 1); |
| assert_eq!(v[2], 4); |
| assert_eq!(v[3], 9); |
| assert_eq!(v[4], 16); |
| } |
| } |
| |
| #[test] |
| fn test_from_elem() { |
| // Test on-stack from_elem. |
| let mut v = vec![10, 10]; |
| { |
| let v = v; |
| assert_eq!(v.len(), 2); |
| assert_eq!(v[0], 10); |
| assert_eq!(v[1], 10); |
| } |
| |
| // Test on-heap from_elem. |
| v = vec![20; 6]; |
| { |
| let v = &v[..]; |
| assert_eq!(v[0], 20); |
| assert_eq!(v[1], 20); |
| assert_eq!(v[2], 20); |
| assert_eq!(v[3], 20); |
| assert_eq!(v[4], 20); |
| assert_eq!(v[5], 20); |
| } |
| } |
| |
| #[test] |
| fn test_is_empty() { |
| let xs: [i32; 0] = []; |
| assert!(xs.is_empty()); |
| assert!(![0].is_empty()); |
| } |
| |
| #[test] |
| fn test_len_divzero() { |
| type Z = [i8; 0]; |
| let v0: &[Z] = &[]; |
| let v1: &[Z] = &[[]]; |
| let v2: &[Z] = &[[], []]; |
| assert_eq!(mem::size_of::<Z>(), 0); |
| assert_eq!(v0.len(), 0); |
| assert_eq!(v1.len(), 1); |
| assert_eq!(v2.len(), 2); |
| } |
| |
| #[test] |
| fn test_get() { |
| let mut a = vec![11]; |
| assert_eq!(a.get(1), None); |
| a = vec![11, 12]; |
| assert_eq!(a.get(1).unwrap(), &12); |
| a = vec![11, 12, 13]; |
| assert_eq!(a.get(1).unwrap(), &12); |
| } |
| |
| #[test] |
| fn test_first() { |
| let mut a = vec![]; |
| assert_eq!(a.first(), None); |
| a = vec![11]; |
| assert_eq!(a.first().unwrap(), &11); |
| a = vec![11, 12]; |
| assert_eq!(a.first().unwrap(), &11); |
| } |
| |
| #[test] |
| fn test_first_mut() { |
| let mut a = vec![]; |
| assert_eq!(a.first_mut(), None); |
| a = vec![11]; |
| assert_eq!(*a.first_mut().unwrap(), 11); |
| a = vec![11, 12]; |
| assert_eq!(*a.first_mut().unwrap(), 11); |
| } |
| |
| #[test] |
| fn test_split_first() { |
| let mut a = vec![11]; |
| let b: &[i32] = &[]; |
| assert!(b.split_first().is_none()); |
| assert_eq!(a.split_first(), Some((&11, b))); |
| a = vec![11, 12]; |
| let b: &[i32] = &[12]; |
| assert_eq!(a.split_first(), Some((&11, b))); |
| } |
| |
| #[test] |
| fn test_split_first_mut() { |
| let mut a = vec![11]; |
| let b: &mut [i32] = &mut []; |
| assert!(b.split_first_mut().is_none()); |
| assert!(a.split_first_mut() == Some((&mut 11, b))); |
| a = vec![11, 12]; |
| let b: &mut [_] = &mut [12]; |
| assert!(a.split_first_mut() == Some((&mut 11, b))); |
| } |
| |
| #[test] |
| fn test_split_last() { |
| let mut a = vec![11]; |
| let b: &[i32] = &[]; |
| assert!(b.split_last().is_none()); |
| assert_eq!(a.split_last(), Some((&11, b))); |
| a = vec![11, 12]; |
| let b: &[_] = &[11]; |
| assert_eq!(a.split_last(), Some((&12, b))); |
| } |
| |
| #[test] |
| fn test_split_last_mut() { |
| let mut a = vec![11]; |
| let b: &mut [i32] = &mut []; |
| assert!(b.split_last_mut().is_none()); |
| assert!(a.split_last_mut() == Some((&mut 11, b))); |
| |
| a = vec![11, 12]; |
| let b: &mut [_] = &mut [11]; |
| assert!(a.split_last_mut() == Some((&mut 12, b))); |
| } |
| |
| #[test] |
| fn test_last() { |
| let mut a = vec![]; |
| assert_eq!(a.last(), None); |
| a = vec![11]; |
| assert_eq!(a.last().unwrap(), &11); |
| a = vec![11, 12]; |
| assert_eq!(a.last().unwrap(), &12); |
| } |
| |
| #[test] |
| fn test_last_mut() { |
| let mut a = vec![]; |
| assert_eq!(a.last_mut(), None); |
| a = vec![11]; |
| assert_eq!(*a.last_mut().unwrap(), 11); |
| a = vec![11, 12]; |
| assert_eq!(*a.last_mut().unwrap(), 12); |
| } |
| |
| #[test] |
| fn test_slice() { |
| // Test fixed length vector. |
| let vec_fixed = [1, 2, 3, 4]; |
| let v_a = vec_fixed[1..vec_fixed.len()].to_vec(); |
| assert_eq!(v_a.len(), 3); |
| |
| assert_eq!(v_a[0], 2); |
| assert_eq!(v_a[1], 3); |
| assert_eq!(v_a[2], 4); |
| |
| // Test on stack. |
| let vec_stack: &[_] = &[1, 2, 3]; |
| let v_b = vec_stack[1..3].to_vec(); |
| assert_eq!(v_b.len(), 2); |
| |
| assert_eq!(v_b[0], 2); |
| assert_eq!(v_b[1], 3); |
| |
| // Test `Box<[T]>` |
| let vec_unique = vec![1, 2, 3, 4, 5, 6]; |
| let v_d = vec_unique[1..6].to_vec(); |
| assert_eq!(v_d.len(), 5); |
| |
| assert_eq!(v_d[0], 2); |
| assert_eq!(v_d[1], 3); |
| assert_eq!(v_d[2], 4); |
| assert_eq!(v_d[3], 5); |
| assert_eq!(v_d[4], 6); |
| } |
| |
| #[test] |
| fn test_slice_from() { |
| let vec: &[_] = &[1, 2, 3, 4]; |
| assert_eq!(&vec[..], vec); |
| let b: &[_] = &[3, 4]; |
| assert_eq!(&vec[2..], b); |
| let b: &[_] = &[]; |
| assert_eq!(&vec[4..], b); |
| } |
| |
| #[test] |
| fn test_slice_to() { |
| let vec: &[_] = &[1, 2, 3, 4]; |
| assert_eq!(&vec[..4], vec); |
| let b: &[_] = &[1, 2]; |
| assert_eq!(&vec[..2], b); |
| let b: &[_] = &[]; |
| assert_eq!(&vec[..0], b); |
| } |
| |
| #[test] |
| fn test_pop() { |
| let mut v = vec![5]; |
| let e = v.pop(); |
| assert_eq!(v.len(), 0); |
| assert_eq!(e, Some(5)); |
| let f = v.pop(); |
| assert_eq!(f, None); |
| let g = v.pop(); |
| assert_eq!(g, None); |
| } |
| |
| #[test] |
| fn test_swap_remove() { |
| let mut v = vec![1, 2, 3, 4, 5]; |
| let mut e = v.swap_remove(0); |
| assert_eq!(e, 1); |
| assert_eq!(v, [5, 2, 3, 4]); |
| e = v.swap_remove(3); |
| assert_eq!(e, 4); |
| assert_eq!(v, [5, 2, 3]); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_swap_remove_fail() { |
| let mut v = vec![1]; |
| let _ = v.swap_remove(0); |
| let _ = v.swap_remove(0); |
| } |
| |
| #[test] |
| fn test_swap_remove_noncopyable() { |
| // Tests that we don't accidentally run destructors twice. |
| let mut v: Vec<Box<_>> = Vec::new(); |
| v.push(Box::new(0)); |
| v.push(Box::new(0)); |
| v.push(Box::new(0)); |
| let mut _e = v.swap_remove(0); |
| assert_eq!(v.len(), 2); |
| _e = v.swap_remove(1); |
| assert_eq!(v.len(), 1); |
| _e = v.swap_remove(0); |
| assert_eq!(v.len(), 0); |
| } |
| |
| #[test] |
| fn test_push() { |
| // Test on-stack push(). |
| let mut v = vec![]; |
| v.push(1); |
| assert_eq!(v.len(), 1); |
| assert_eq!(v[0], 1); |
| |
| // Test on-heap push(). |
| v.push(2); |
| assert_eq!(v.len(), 2); |
| assert_eq!(v[0], 1); |
| assert_eq!(v[1], 2); |
| } |
| |
| #[test] |
| fn test_truncate() { |
| let mut v: Vec<Box<_>> = vec![Box::new(6), Box::new(5), Box::new(4)]; |
| v.truncate(1); |
| let v = v; |
| assert_eq!(v.len(), 1); |
| assert_eq!(*(v[0]), 6); |
| // If the unsafe block didn't drop things properly, we blow up here. |
| } |
| |
| #[test] |
| fn test_clear() { |
| let mut v: Vec<Box<_>> = vec![Box::new(6), Box::new(5), Box::new(4)]; |
| v.clear(); |
| assert_eq!(v.len(), 0); |
| // If the unsafe block didn't drop things properly, we blow up here. |
| } |
| |
| #[test] |
| fn test_retain() { |
| let mut v = vec![1, 2, 3, 4, 5]; |
| v.retain(is_odd); |
| assert_eq!(v, [1, 3, 5]); |
| } |
| |
| #[test] |
| fn test_binary_search() { |
| assert_eq!([1, 2, 3, 4, 5].binary_search(&5).ok(), Some(4)); |
| assert_eq!([1, 2, 3, 4, 5].binary_search(&4).ok(), Some(3)); |
| assert_eq!([1, 2, 3, 4, 5].binary_search(&3).ok(), Some(2)); |
| assert_eq!([1, 2, 3, 4, 5].binary_search(&2).ok(), Some(1)); |
| assert_eq!([1, 2, 3, 4, 5].binary_search(&1).ok(), Some(0)); |
| |
| assert_eq!([2, 4, 6, 8, 10].binary_search(&1).ok(), None); |
| assert_eq!([2, 4, 6, 8, 10].binary_search(&5).ok(), None); |
| assert_eq!([2, 4, 6, 8, 10].binary_search(&4).ok(), Some(1)); |
| assert_eq!([2, 4, 6, 8, 10].binary_search(&10).ok(), Some(4)); |
| |
| assert_eq!([2, 4, 6, 8].binary_search(&1).ok(), None); |
| assert_eq!([2, 4, 6, 8].binary_search(&5).ok(), None); |
| assert_eq!([2, 4, 6, 8].binary_search(&4).ok(), Some(1)); |
| assert_eq!([2, 4, 6, 8].binary_search(&8).ok(), Some(3)); |
| |
| assert_eq!([2, 4, 6].binary_search(&1).ok(), None); |
| assert_eq!([2, 4, 6].binary_search(&5).ok(), None); |
| assert_eq!([2, 4, 6].binary_search(&4).ok(), Some(1)); |
| assert_eq!([2, 4, 6].binary_search(&6).ok(), Some(2)); |
| |
| assert_eq!([2, 4].binary_search(&1).ok(), None); |
| assert_eq!([2, 4].binary_search(&5).ok(), None); |
| assert_eq!([2, 4].binary_search(&2).ok(), Some(0)); |
| assert_eq!([2, 4].binary_search(&4).ok(), Some(1)); |
| |
| assert_eq!([2].binary_search(&1).ok(), None); |
| assert_eq!([2].binary_search(&5).ok(), None); |
| assert_eq!([2].binary_search(&2).ok(), Some(0)); |
| |
| assert_eq!([].binary_search(&1).ok(), None); |
| assert_eq!([].binary_search(&5).ok(), None); |
| |
| assert!([1, 1, 1, 1, 1].binary_search(&1).ok() != None); |
| assert!([1, 1, 1, 1, 2].binary_search(&1).ok() != None); |
| assert!([1, 1, 1, 2, 2].binary_search(&1).ok() != None); |
| assert!([1, 1, 2, 2, 2].binary_search(&1).ok() != None); |
| assert_eq!([1, 2, 2, 2, 2].binary_search(&1).ok(), Some(0)); |
| |
| assert_eq!([1, 2, 3, 4, 5].binary_search(&6).ok(), None); |
| assert_eq!([1, 2, 3, 4, 5].binary_search(&0).ok(), None); |
| } |
| |
| #[test] |
| fn test_reverse() { |
| let mut v = vec![10, 20]; |
| assert_eq!(v[0], 10); |
| assert_eq!(v[1], 20); |
| v.reverse(); |
| assert_eq!(v[0], 20); |
| assert_eq!(v[1], 10); |
| |
| let mut v3 = Vec::<i32>::new(); |
| v3.reverse(); |
| assert!(v3.is_empty()); |
| |
| // check the 1-byte-types path |
| let mut v = (-50..51i8).collect::<Vec<_>>(); |
| v.reverse(); |
| assert_eq!(v, (-50..51i8).rev().collect::<Vec<_>>()); |
| |
| // check the 2-byte-types path |
| let mut v = (-50..51i16).collect::<Vec<_>>(); |
| v.reverse(); |
| assert_eq!(v, (-50..51i16).rev().collect::<Vec<_>>()); |
| } |
| |
| #[test] |
| fn test_rotate_left() { |
| let expected: Vec<_> = (0..13).collect(); |
| let mut v = Vec::new(); |
| |
| // no-ops |
| v.clone_from(&expected); |
| v.rotate_left(0); |
| assert_eq!(v, expected); |
| v.rotate_left(expected.len()); |
| assert_eq!(v, expected); |
| let mut zst_array = [(), (), ()]; |
| zst_array.rotate_left(2); |
| |
| // happy path |
| v = (5..13).chain(0..5).collect(); |
| v.rotate_left(8); |
| assert_eq!(v, expected); |
| |
| let expected: Vec<_> = (0..1000).collect(); |
| |
| // small rotations in large slice, uses ptr::copy |
| v = (2..1000).chain(0..2).collect(); |
| v.rotate_left(998); |
| assert_eq!(v, expected); |
| v = (998..1000).chain(0..998).collect(); |
| v.rotate_left(2); |
| assert_eq!(v, expected); |
| |
| // non-small prime rotation, has a few rounds of swapping |
| v = (389..1000).chain(0..389).collect(); |
| v.rotate_left(1000 - 389); |
| assert_eq!(v, expected); |
| } |
| |
| #[test] |
| fn test_rotate_right() { |
| let expected: Vec<_> = (0..13).collect(); |
| let mut v = Vec::new(); |
| |
| // no-ops |
| v.clone_from(&expected); |
| v.rotate_right(0); |
| assert_eq!(v, expected); |
| v.rotate_right(expected.len()); |
| assert_eq!(v, expected); |
| let mut zst_array = [(), (), ()]; |
| zst_array.rotate_right(2); |
| |
| // happy path |
| v = (5..13).chain(0..5).collect(); |
| v.rotate_right(5); |
| assert_eq!(v, expected); |
| |
| let expected: Vec<_> = (0..1000).collect(); |
| |
| // small rotations in large slice, uses ptr::copy |
| v = (2..1000).chain(0..2).collect(); |
| v.rotate_right(2); |
| assert_eq!(v, expected); |
| v = (998..1000).chain(0..998).collect(); |
| v.rotate_right(998); |
| assert_eq!(v, expected); |
| |
| // non-small prime rotation, has a few rounds of swapping |
| v = (389..1000).chain(0..389).collect(); |
| v.rotate_right(389); |
| assert_eq!(v, expected); |
| } |
| |
| #[test] |
| fn test_concat() { |
| let v: [Vec<i32>; 0] = []; |
| let c = v.concat(); |
| assert_eq!(c, []); |
| let d = [vec![1], vec![2, 3]].concat(); |
| assert_eq!(d, [1, 2, 3]); |
| |
| let v: &[&[_]] = &[&[1], &[2, 3]]; |
| assert_eq!(v.join(&0), [1, 0, 2, 3]); |
| let v: &[&[_]] = &[&[1], &[2], &[3]]; |
| assert_eq!(v.join(&0), [1, 0, 2, 0, 3]); |
| } |
| |
| #[test] |
| fn test_join() { |
| let v: [Vec<i32>; 0] = []; |
| assert_eq!(v.join(&0), []); |
| assert_eq!([vec![1], vec![2, 3]].join(&0), [1, 0, 2, 3]); |
| assert_eq!([vec![1], vec![2], vec![3]].join(&0), [1, 0, 2, 0, 3]); |
| |
| let v: [&[_]; 2] = [&[1], &[2, 3]]; |
| assert_eq!(v.join(&0), [1, 0, 2, 3]); |
| let v: [&[_]; 3] = [&[1], &[2], &[3]]; |
| assert_eq!(v.join(&0), [1, 0, 2, 0, 3]); |
| } |
| |
| #[test] |
| fn test_join_nocopy() { |
| let v: [String; 0] = []; |
| assert_eq!(v.join(","), ""); |
| assert_eq!(["a".to_string(), "ab".into()].join(","), "a,ab"); |
| assert_eq!(["a".to_string(), "ab".into(), "abc".into()].join(","), "a,ab,abc"); |
| assert_eq!(["a".to_string(), "ab".into(), "".into()].join(","), "a,ab,"); |
| } |
| |
| #[test] |
| fn test_insert() { |
| let mut a = vec![1, 2, 4]; |
| a.insert(2, 3); |
| assert_eq!(a, [1, 2, 3, 4]); |
| |
| let mut a = vec![1, 2, 3]; |
| a.insert(0, 0); |
| assert_eq!(a, [0, 1, 2, 3]); |
| |
| let mut a = vec![1, 2, 3]; |
| a.insert(3, 4); |
| assert_eq!(a, [1, 2, 3, 4]); |
| |
| let mut a = vec![]; |
| a.insert(0, 1); |
| assert_eq!(a, [1]); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_insert_oob() { |
| let mut a = vec![1, 2, 3]; |
| a.insert(4, 5); |
| } |
| |
| #[test] |
| fn test_remove() { |
| let mut a = vec![1, 2, 3, 4]; |
| |
| assert_eq!(a.remove(2), 3); |
| assert_eq!(a, [1, 2, 4]); |
| |
| assert_eq!(a.remove(2), 4); |
| assert_eq!(a, [1, 2]); |
| |
| assert_eq!(a.remove(0), 1); |
| assert_eq!(a, [2]); |
| |
| assert_eq!(a.remove(0), 2); |
| assert_eq!(a, []); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_remove_fail() { |
| let mut a = vec![1]; |
| let _ = a.remove(0); |
| let _ = a.remove(0); |
| } |
| |
| #[test] |
| fn test_capacity() { |
| let mut v = vec![0]; |
| v.reserve_exact(10); |
| assert!(v.capacity() >= 11); |
| } |
| |
| #[test] |
| fn test_slice_2() { |
| let v = vec![1, 2, 3, 4, 5]; |
| let v = &v[1..3]; |
| assert_eq!(v.len(), 2); |
| assert_eq!(v[0], 2); |
| assert_eq!(v[1], 3); |
| } |
| |
| macro_rules! assert_order { |
| (Greater, $a:expr, $b:expr) => { |
| assert_eq!($a.cmp($b), Greater); |
| assert!($a > $b); |
| }; |
| (Less, $a:expr, $b:expr) => { |
| assert_eq!($a.cmp($b), Less); |
| assert!($a < $b); |
| }; |
| (Equal, $a:expr, $b:expr) => { |
| assert_eq!($a.cmp($b), Equal); |
| assert_eq!($a, $b); |
| }; |
| } |
| |
| #[test] |
| fn test_total_ord_u8() { |
| let c = &[1u8, 2, 3]; |
| assert_order!(Greater, &[1u8, 2, 3, 4][..], &c[..]); |
| let c = &[1u8, 2, 3, 4]; |
| assert_order!(Less, &[1u8, 2, 3][..], &c[..]); |
| let c = &[1u8, 2, 3, 6]; |
| assert_order!(Equal, &[1u8, 2, 3, 6][..], &c[..]); |
| let c = &[1u8, 2, 3, 4, 5, 6]; |
| assert_order!(Less, &[1u8, 2, 3, 4, 5, 5, 5, 5][..], &c[..]); |
| let c = &[1u8, 2, 3, 4]; |
| assert_order!(Greater, &[2u8, 2][..], &c[..]); |
| } |
| |
| #[test] |
| fn test_total_ord_i32() { |
| let c = &[1, 2, 3]; |
| assert_order!(Greater, &[1, 2, 3, 4][..], &c[..]); |
| let c = &[1, 2, 3, 4]; |
| assert_order!(Less, &[1, 2, 3][..], &c[..]); |
| let c = &[1, 2, 3, 6]; |
| assert_order!(Equal, &[1, 2, 3, 6][..], &c[..]); |
| let c = &[1, 2, 3, 4, 5, 6]; |
| assert_order!(Less, &[1, 2, 3, 4, 5, 5, 5, 5][..], &c[..]); |
| let c = &[1, 2, 3, 4]; |
| assert_order!(Greater, &[2, 2][..], &c[..]); |
| } |
| |
| #[test] |
| fn test_iterator() { |
| let xs = [1, 2, 5, 10, 11]; |
| let mut it = xs.iter(); |
| assert_eq!(it.size_hint(), (5, Some(5))); |
| assert_eq!(it.next().unwrap(), &1); |
| assert_eq!(it.size_hint(), (4, Some(4))); |
| assert_eq!(it.next().unwrap(), &2); |
| assert_eq!(it.size_hint(), (3, Some(3))); |
| assert_eq!(it.next().unwrap(), &5); |
| assert_eq!(it.size_hint(), (2, Some(2))); |
| assert_eq!(it.next().unwrap(), &10); |
| assert_eq!(it.size_hint(), (1, Some(1))); |
| assert_eq!(it.next().unwrap(), &11); |
| assert_eq!(it.size_hint(), (0, Some(0))); |
| assert!(it.next().is_none()); |
| } |
| |
| #[test] |
| fn test_iter_size_hints() { |
| let mut xs = [1, 2, 5, 10, 11]; |
| assert_eq!(xs.iter().size_hint(), (5, Some(5))); |
| assert_eq!(xs.iter_mut().size_hint(), (5, Some(5))); |
| } |
| |
| #[test] |
| fn test_iter_as_slice() { |
| let xs = [1, 2, 5, 10, 11]; |
| let mut iter = xs.iter(); |
| assert_eq!(iter.as_slice(), &[1, 2, 5, 10, 11]); |
| iter.next(); |
| assert_eq!(iter.as_slice(), &[2, 5, 10, 11]); |
| } |
| |
| #[test] |
| fn test_iter_as_ref() { |
| let xs = [1, 2, 5, 10, 11]; |
| let mut iter = xs.iter(); |
| assert_eq!(iter.as_ref(), &[1, 2, 5, 10, 11]); |
| iter.next(); |
| assert_eq!(iter.as_ref(), &[2, 5, 10, 11]); |
| } |
| |
| #[test] |
| fn test_iter_clone() { |
| let xs = [1, 2, 5]; |
| let mut it = xs.iter(); |
| it.next(); |
| let mut jt = it.clone(); |
| assert_eq!(it.next(), jt.next()); |
| assert_eq!(it.next(), jt.next()); |
| assert_eq!(it.next(), jt.next()); |
| } |
| |
| #[test] |
| fn test_iter_is_empty() { |
| let xs = [1, 2, 5, 10, 11]; |
| for i in 0..xs.len() { |
| for j in i..xs.len() { |
| assert_eq!(xs[i..j].iter().is_empty(), xs[i..j].is_empty()); |
| } |
| } |
| } |
| |
| #[test] |
| fn test_mut_iterator() { |
| let mut xs = [1, 2, 3, 4, 5]; |
| for x in &mut xs { |
| *x += 1; |
| } |
| assert!(xs == [2, 3, 4, 5, 6]) |
| } |
| |
| #[test] |
| fn test_rev_iterator() { |
| let xs = [1, 2, 5, 10, 11]; |
| let ys = [11, 10, 5, 2, 1]; |
| let mut i = 0; |
| for &x in xs.iter().rev() { |
| assert_eq!(x, ys[i]); |
| i += 1; |
| } |
| assert_eq!(i, 5); |
| } |
| |
| #[test] |
| fn test_mut_rev_iterator() { |
| let mut xs = [1, 2, 3, 4, 5]; |
| for (i, x) in xs.iter_mut().rev().enumerate() { |
| *x += i; |
| } |
| assert!(xs == [5, 5, 5, 5, 5]) |
| } |
| |
| #[test] |
| fn test_move_iterator() { |
| let xs = vec![1, 2, 3, 4, 5]; |
| assert_eq!(xs.into_iter().fold(0, |a: usize, b: usize| 10 * a + b), 12345); |
| } |
| |
| #[test] |
| fn test_move_rev_iterator() { |
| let xs = vec![1, 2, 3, 4, 5]; |
| assert_eq!(xs.into_iter().rev().fold(0, |a: usize, b: usize| 10 * a + b), 54321); |
| } |
| |
| #[test] |
| fn test_split_iterator() { |
| let xs = &[1, 2, 3, 4, 5]; |
| |
| let splits: &[&[_]] = &[&[1], &[3], &[5]]; |
| assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[], &[2, 3, 4, 5]]; |
| assert_eq!(xs.split(|x| *x == 1).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4], &[]]; |
| assert_eq!(xs.split(|x| *x == 5).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.split(|x| *x == 10).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[], &[], &[], &[], &[], &[]]; |
| assert_eq!(xs.split(|_| true).collect::<Vec<&[i32]>>(), splits); |
| |
| let xs: &[i32] = &[]; |
| let splits: &[&[i32]] = &[&[]]; |
| assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[i32]>>(), splits); |
| } |
| |
| #[test] |
| fn test_split_iterator_inclusive() { |
| let xs = &[1, 2, 3, 4, 5]; |
| |
| let splits: &[&[_]] = &[&[1, 2], &[3, 4], &[5]]; |
| assert_eq!(xs.split_inclusive(|x| *x % 2 == 0).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1], &[2, 3, 4, 5]]; |
| assert_eq!(xs.split_inclusive(|x| *x == 1).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.split_inclusive(|x| *x == 5).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.split_inclusive(|x| *x == 10).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1], &[2], &[3], &[4], &[5]]; |
| assert_eq!(xs.split_inclusive(|_| true).collect::<Vec<&[i32]>>(), splits); |
| |
| let xs: &[i32] = &[]; |
| let splits: &[&[i32]] = &[]; |
| assert_eq!(xs.split_inclusive(|x| *x == 5).collect::<Vec<&[i32]>>(), splits); |
| } |
| |
| #[test] |
| fn test_split_iterator_inclusive_reverse() { |
| let xs = &[1, 2, 3, 4, 5]; |
| |
| let splits: &[&[_]] = &[&[5], &[3, 4], &[1, 2]]; |
| assert_eq!(xs.split_inclusive(|x| *x % 2 == 0).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[2, 3, 4, 5], &[1]]; |
| assert_eq!(xs.split_inclusive(|x| *x == 1).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.split_inclusive(|x| *x == 5).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.split_inclusive(|x| *x == 10).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[5], &[4], &[3], &[2], &[1]]; |
| assert_eq!(xs.split_inclusive(|_| true).rev().collect::<Vec<_>>(), splits); |
| |
| let xs: &[i32] = &[]; |
| let splits: &[&[i32]] = &[]; |
| assert_eq!(xs.split_inclusive(|x| *x == 5).rev().collect::<Vec<_>>(), splits); |
| } |
| |
| #[test] |
| fn test_split_iterator_mut_inclusive() { |
| let xs = &mut [1, 2, 3, 4, 5]; |
| |
| let splits: &[&[_]] = &[&[1, 2], &[3, 4], &[5]]; |
| assert_eq!(xs.split_inclusive_mut(|x| *x % 2 == 0).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1], &[2, 3, 4, 5]]; |
| assert_eq!(xs.split_inclusive_mut(|x| *x == 1).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.split_inclusive_mut(|x| *x == 5).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.split_inclusive_mut(|x| *x == 10).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1], &[2], &[3], &[4], &[5]]; |
| assert_eq!(xs.split_inclusive_mut(|_| true).collect::<Vec<_>>(), splits); |
| |
| let xs: &mut [i32] = &mut []; |
| let splits: &[&[i32]] = &[]; |
| assert_eq!(xs.split_inclusive_mut(|x| *x == 5).collect::<Vec<_>>(), splits); |
| } |
| |
| #[test] |
| fn test_split_iterator_mut_inclusive_reverse() { |
| let xs = &mut [1, 2, 3, 4, 5]; |
| |
| let splits: &[&[_]] = &[&[5], &[3, 4], &[1, 2]]; |
| assert_eq!(xs.split_inclusive_mut(|x| *x % 2 == 0).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[2, 3, 4, 5], &[1]]; |
| assert_eq!(xs.split_inclusive_mut(|x| *x == 1).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.split_inclusive_mut(|x| *x == 5).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.split_inclusive_mut(|x| *x == 10).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[5], &[4], &[3], &[2], &[1]]; |
| assert_eq!(xs.split_inclusive_mut(|_| true).rev().collect::<Vec<_>>(), splits); |
| |
| let xs: &mut [i32] = &mut []; |
| let splits: &[&[i32]] = &[]; |
| assert_eq!(xs.split_inclusive_mut(|x| *x == 5).rev().collect::<Vec<_>>(), splits); |
| } |
| |
| #[test] |
| fn test_splitn_iterator() { |
| let xs = &[1, 2, 3, 4, 5]; |
| |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1], &[3, 4, 5]]; |
| assert_eq!(xs.splitn(2, |x| *x % 2 == 0).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[], &[], &[], &[4, 5]]; |
| assert_eq!(xs.splitn(4, |_| true).collect::<Vec<_>>(), splits); |
| |
| let xs: &[i32] = &[]; |
| let splits: &[&[i32]] = &[&[]]; |
| assert_eq!(xs.splitn(2, |x| *x == 5).collect::<Vec<_>>(), splits); |
| } |
| |
| #[test] |
| fn test_splitn_iterator_mut() { |
| let xs = &mut [1, 2, 3, 4, 5]; |
| |
| let splits: &[&mut [_]] = &[&mut [1, 2, 3, 4, 5]]; |
| assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::<Vec<_>>(), splits); |
| let splits: &[&mut [_]] = &[&mut [1], &mut [3, 4, 5]]; |
| assert_eq!(xs.splitn_mut(2, |x| *x % 2 == 0).collect::<Vec<_>>(), splits); |
| let splits: &[&mut [_]] = &[&mut [], &mut [], &mut [], &mut [4, 5]]; |
| assert_eq!(xs.splitn_mut(4, |_| true).collect::<Vec<_>>(), splits); |
| |
| let xs: &mut [i32] = &mut []; |
| let splits: &[&mut [i32]] = &[&mut []]; |
| assert_eq!(xs.splitn_mut(2, |x| *x == 5).collect::<Vec<_>>(), splits); |
| } |
| |
| #[test] |
| fn test_rsplit_iterator() { |
| let xs = &[1, 2, 3, 4, 5]; |
| |
| let splits: &[&[_]] = &[&[5], &[3], &[1]]; |
| assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[2, 3, 4, 5], &[]]; |
| assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[], &[1, 2, 3, 4]]; |
| assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<_>>(), splits); |
| |
| let xs: &[i32] = &[]; |
| let splits: &[&[i32]] = &[&[]]; |
| assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[i32]>>(), splits); |
| } |
| |
| #[test] |
| fn test_rsplitn_iterator() { |
| let xs = &[1, 2, 3, 4, 5]; |
| |
| let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[5], &[1, 2, 3]]; |
| assert_eq!(xs.rsplitn(2, |x| *x % 2 == 0).collect::<Vec<_>>(), splits); |
| let splits: &[&[_]] = &[&[], &[], &[], &[1, 2]]; |
| assert_eq!(xs.rsplitn(4, |_| true).collect::<Vec<_>>(), splits); |
| |
| let xs: &[i32] = &[]; |
| let splits: &[&[i32]] = &[&[]]; |
| assert_eq!(xs.rsplitn(2, |x| *x == 5).collect::<Vec<&[i32]>>(), splits); |
| assert!(xs.rsplitn(0, |x| *x % 2 == 0).next().is_none()); |
| } |
| |
| #[test] |
| fn test_split_iterators_size_hint() { |
| #[derive(Copy, Clone)] |
| enum Bounds { |
| Lower, |
| Upper, |
| } |
| fn assert_tight_size_hints(mut it: impl Iterator, which: Bounds, ctx: impl fmt::Display) { |
| match which { |
| Bounds::Lower => { |
| let mut lower_bounds = vec![it.size_hint().0]; |
| while let Some(_) = it.next() { |
| lower_bounds.push(it.size_hint().0); |
| } |
| let target: Vec<_> = (0..lower_bounds.len()).rev().collect(); |
| assert_eq!(lower_bounds, target, "lower bounds incorrect or not tight: {}", ctx); |
| } |
| Bounds::Upper => { |
| let mut upper_bounds = vec![it.size_hint().1]; |
| while let Some(_) = it.next() { |
| upper_bounds.push(it.size_hint().1); |
| } |
| let target: Vec<_> = (0..upper_bounds.len()).map(Some).rev().collect(); |
| assert_eq!(upper_bounds, target, "upper bounds incorrect or not tight: {}", ctx); |
| } |
| } |
| } |
| |
| for len in 0..=2 { |
| let mut v: Vec<u8> = (0..len).collect(); |
| |
| // p: predicate, b: bound selection |
| for (p, b) in [ |
| // with a predicate always returning false, the split*-iterators |
| // become maximally short, so the size_hint lower bounds are tight |
| ((|_| false) as fn(&_) -> _, Bounds::Lower), |
| // with a predicate always returning true, the split*-iterators |
| // become maximally long, so the size_hint upper bounds are tight |
| ((|_| true) as fn(&_) -> _, Bounds::Upper), |
| ] { |
| use {assert_tight_size_hints as a, format_args as f}; |
| |
| a(v.split(p), b, "split"); |
| a(v.split_mut(p), b, "split_mut"); |
| a(v.split_inclusive(p), b, "split_inclusive"); |
| a(v.split_inclusive_mut(p), b, "split_inclusive_mut"); |
| a(v.rsplit(p), b, "rsplit"); |
| a(v.rsplit_mut(p), b, "rsplit_mut"); |
| |
| for n in 0..=3 { |
| a(v.splitn(n, p), b, f!("splitn, n = {n}")); |
| a(v.splitn_mut(n, p), b, f!("splitn_mut, n = {n}")); |
| a(v.rsplitn(n, p), b, f!("rsplitn, n = {n}")); |
| a(v.rsplitn_mut(n, p), b, f!("rsplitn_mut, n = {n}")); |
| } |
| } |
| } |
| } |
| |
| #[test] |
| fn test_windows_iterator() { |
| let v = &[1, 2, 3, 4]; |
| |
| let wins: &[&[_]] = &[&[1, 2], &[2, 3], &[3, 4]]; |
| assert_eq!(v.windows(2).collect::<Vec<_>>(), wins); |
| |
| let wins: &[&[_]] = &[&[1, 2, 3], &[2, 3, 4]]; |
| assert_eq!(v.windows(3).collect::<Vec<_>>(), wins); |
| assert!(v.windows(6).next().is_none()); |
| |
| let wins: &[&[_]] = &[&[3, 4], &[2, 3], &[1, 2]]; |
| assert_eq!(v.windows(2).rev().collect::<Vec<&[_]>>(), wins); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_windows_iterator_0() { |
| let v = &[1, 2, 3, 4]; |
| let _it = v.windows(0); |
| } |
| |
| #[test] |
| fn test_chunks_iterator() { |
| let v = &[1, 2, 3, 4, 5]; |
| |
| assert_eq!(v.chunks(2).len(), 3); |
| |
| let chunks: &[&[_]] = &[&[1, 2], &[3, 4], &[5]]; |
| assert_eq!(v.chunks(2).collect::<Vec<_>>(), chunks); |
| let chunks: &[&[_]] = &[&[1, 2, 3], &[4, 5]]; |
| assert_eq!(v.chunks(3).collect::<Vec<_>>(), chunks); |
| let chunks: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(v.chunks(6).collect::<Vec<_>>(), chunks); |
| |
| let chunks: &[&[_]] = &[&[5], &[3, 4], &[1, 2]]; |
| assert_eq!(v.chunks(2).rev().collect::<Vec<_>>(), chunks); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_chunks_iterator_0() { |
| let v = &[1, 2, 3, 4]; |
| let _it = v.chunks(0); |
| } |
| |
| #[test] |
| fn test_chunks_exact_iterator() { |
| let v = &[1, 2, 3, 4, 5]; |
| |
| assert_eq!(v.chunks_exact(2).len(), 2); |
| |
| let chunks: &[&[_]] = &[&[1, 2], &[3, 4]]; |
| assert_eq!(v.chunks_exact(2).collect::<Vec<_>>(), chunks); |
| let chunks: &[&[_]] = &[&[1, 2, 3]]; |
| assert_eq!(v.chunks_exact(3).collect::<Vec<_>>(), chunks); |
| let chunks: &[&[_]] = &[]; |
| assert_eq!(v.chunks_exact(6).collect::<Vec<_>>(), chunks); |
| |
| let chunks: &[&[_]] = &[&[3, 4], &[1, 2]]; |
| assert_eq!(v.chunks_exact(2).rev().collect::<Vec<_>>(), chunks); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_chunks_exact_iterator_0() { |
| let v = &[1, 2, 3, 4]; |
| let _it = v.chunks_exact(0); |
| } |
| |
| #[test] |
| fn test_rchunks_iterator() { |
| let v = &[1, 2, 3, 4, 5]; |
| |
| assert_eq!(v.rchunks(2).len(), 3); |
| |
| let chunks: &[&[_]] = &[&[4, 5], &[2, 3], &[1]]; |
| assert_eq!(v.rchunks(2).collect::<Vec<_>>(), chunks); |
| let chunks: &[&[_]] = &[&[3, 4, 5], &[1, 2]]; |
| assert_eq!(v.rchunks(3).collect::<Vec<_>>(), chunks); |
| let chunks: &[&[_]] = &[&[1, 2, 3, 4, 5]]; |
| assert_eq!(v.rchunks(6).collect::<Vec<_>>(), chunks); |
| |
| let chunks: &[&[_]] = &[&[1], &[2, 3], &[4, 5]]; |
| assert_eq!(v.rchunks(2).rev().collect::<Vec<_>>(), chunks); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_rchunks_iterator_0() { |
| let v = &[1, 2, 3, 4]; |
| let _it = v.rchunks(0); |
| } |
| |
| #[test] |
| fn test_rchunks_exact_iterator() { |
| let v = &[1, 2, 3, 4, 5]; |
| |
| assert_eq!(v.rchunks_exact(2).len(), 2); |
| |
| let chunks: &[&[_]] = &[&[4, 5], &[2, 3]]; |
| assert_eq!(v.rchunks_exact(2).collect::<Vec<_>>(), chunks); |
| let chunks: &[&[_]] = &[&[3, 4, 5]]; |
| assert_eq!(v.rchunks_exact(3).collect::<Vec<_>>(), chunks); |
| let chunks: &[&[_]] = &[]; |
| assert_eq!(v.rchunks_exact(6).collect::<Vec<_>>(), chunks); |
| |
| let chunks: &[&[_]] = &[&[2, 3], &[4, 5]]; |
| assert_eq!(v.rchunks_exact(2).rev().collect::<Vec<_>>(), chunks); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_rchunks_exact_iterator_0() { |
| let v = &[1, 2, 3, 4]; |
| let _it = v.rchunks_exact(0); |
| } |
| |
| #[test] |
| fn test_reverse_part() { |
| let mut values = [1, 2, 3, 4, 5]; |
| values[1..4].reverse(); |
| assert!(values == [1, 4, 3, 2, 5]); |
| } |
| |
| #[test] |
| fn test_show() { |
| macro_rules! test_show_vec { |
| ($x:expr, $x_str:expr) => {{ |
| let (x, x_str) = ($x, $x_str); |
| assert_eq!(format!("{x:?}"), x_str); |
| assert_eq!(format!("{x:?}"), x_str); |
| }}; |
| } |
| let empty = Vec::<i32>::new(); |
| test_show_vec!(empty, "[]"); |
| test_show_vec!(vec![1], "[1]"); |
| test_show_vec!(vec![1, 2, 3], "[1, 2, 3]"); |
| test_show_vec!(vec![vec![], vec![1], vec![1, 1]], "[[], [1], [1, 1]]"); |
| |
| let empty_mut: &mut [i32] = &mut []; |
| test_show_vec!(empty_mut, "[]"); |
| let v = &mut [1]; |
| test_show_vec!(v, "[1]"); |
| let v = &mut [1, 2, 3]; |
| test_show_vec!(v, "[1, 2, 3]"); |
| let v: &mut [&mut [_]] = &mut [&mut [], &mut [1], &mut [1, 1]]; |
| test_show_vec!(v, "[[], [1], [1, 1]]"); |
| } |
| |
| #[test] |
| fn test_vec_default() { |
| macro_rules! t { |
| ($ty:ty) => {{ |
| let v: $ty = Default::default(); |
| assert!(v.is_empty()); |
| }}; |
| } |
| |
| t!(&[i32]); |
| t!(Vec<i32>); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_overflow_does_not_cause_segfault() { |
| let mut v = vec![]; |
| v.reserve_exact(!0); |
| v.push(1); |
| v.push(2); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_overflow_does_not_cause_segfault_managed() { |
| let mut v = vec![Rc::new(1)]; |
| v.reserve_exact(!0); |
| v.push(Rc::new(2)); |
| } |
| |
| #[test] |
| fn test_mut_split_at() { |
| let mut values = [1, 2, 3, 4, 5]; |
| { |
| let (left, right) = values.split_at_mut(2); |
| { |
| let left: &[_] = left; |
| assert!(left[..left.len()] == [1, 2]); |
| } |
| for p in left { |
| *p += 1; |
| } |
| |
| { |
| let right: &[_] = right; |
| assert!(right[..right.len()] == [3, 4, 5]); |
| } |
| for p in right { |
| *p += 2; |
| } |
| } |
| |
| assert!(values == [2, 3, 5, 6, 7]); |
| } |
| |
| #[derive(Clone, PartialEq)] |
| struct Foo; |
| |
| #[test] |
| fn test_iter_zero_sized() { |
| let mut v = vec![Foo, Foo, Foo]; |
| assert_eq!(v.len(), 3); |
| let mut cnt = 0; |
| |
| for f in &v { |
| assert!(*f == Foo); |
| cnt += 1; |
| } |
| assert_eq!(cnt, 3); |
| |
| for f in &v[1..3] { |
| assert!(*f == Foo); |
| cnt += 1; |
| } |
| assert_eq!(cnt, 5); |
| |
| for f in &mut v { |
| assert!(*f == Foo); |
| cnt += 1; |
| } |
| assert_eq!(cnt, 8); |
| |
| for f in v { |
| assert!(f == Foo); |
| cnt += 1; |
| } |
| assert_eq!(cnt, 11); |
| |
| let xs: [Foo; 3] = [Foo, Foo, Foo]; |
| cnt = 0; |
| for f in &xs { |
| assert!(*f == Foo); |
| cnt += 1; |
| } |
| assert!(cnt == 3); |
| } |
| |
| #[test] |
| fn test_shrink_to_fit() { |
| let mut xs = vec![0, 1, 2, 3]; |
| for i in 4..100 { |
| xs.push(i) |
| } |
| assert_eq!(xs.capacity(), 128); |
| xs.shrink_to_fit(); |
| assert_eq!(xs.capacity(), 100); |
| assert_eq!(xs, (0..100).collect::<Vec<_>>()); |
| } |
| |
| #[test] |
| fn test_starts_with() { |
| assert!(b"foobar".starts_with(b"foo")); |
| assert!(!b"foobar".starts_with(b"oob")); |
| assert!(!b"foobar".starts_with(b"bar")); |
| assert!(!b"foo".starts_with(b"foobar")); |
| assert!(!b"bar".starts_with(b"foobar")); |
| assert!(b"foobar".starts_with(b"foobar")); |
| let empty: &[u8] = &[]; |
| assert!(empty.starts_with(empty)); |
| assert!(!empty.starts_with(b"foo")); |
| assert!(b"foobar".starts_with(empty)); |
| } |
| |
| #[test] |
| fn test_ends_with() { |
| assert!(b"foobar".ends_with(b"bar")); |
| assert!(!b"foobar".ends_with(b"oba")); |
| assert!(!b"foobar".ends_with(b"foo")); |
| assert!(!b"foo".ends_with(b"foobar")); |
| assert!(!b"bar".ends_with(b"foobar")); |
| assert!(b"foobar".ends_with(b"foobar")); |
| let empty: &[u8] = &[]; |
| assert!(empty.ends_with(empty)); |
| assert!(!empty.ends_with(b"foo")); |
| assert!(b"foobar".ends_with(empty)); |
| } |
| |
| #[test] |
| fn test_mut_split_iterator() { |
| let mut xs = [0, 1, 0, 2, 3, 0, 0, 4, 5, 0]; |
| assert_eq!(xs.split_mut(|x| *x == 0).count(), 6); |
| for slice in xs.split_mut(|x| *x == 0) { |
| slice.reverse(); |
| } |
| assert!(xs == [0, 1, 0, 3, 2, 0, 0, 5, 4, 0]); |
| |
| let mut xs = [0, 1, 0, 2, 3, 0, 0, 4, 5, 0, 6, 7]; |
| for slice in xs.split_mut(|x| *x == 0).take(5) { |
| slice.reverse(); |
| } |
| assert!(xs == [0, 1, 0, 3, 2, 0, 0, 5, 4, 0, 6, 7]); |
| } |
| |
| #[test] |
| fn test_mut_split_iterator_rev() { |
| let mut xs = [1, 2, 0, 3, 4, 0, 0, 5, 6, 0]; |
| for slice in xs.split_mut(|x| *x == 0).rev().take(4) { |
| slice.reverse(); |
| } |
| assert!(xs == [1, 2, 0, 4, 3, 0, 0, 6, 5, 0]); |
| } |
| |
| #[test] |
| fn test_get_mut() { |
| let mut v = [0, 1, 2]; |
| assert_eq!(v.get_mut(3), None); |
| v.get_mut(1).map(|e| *e = 7); |
| assert_eq!(v[1], 7); |
| let mut x = 2; |
| assert_eq!(v.get_mut(2), Some(&mut x)); |
| } |
| |
| #[test] |
| fn test_mut_chunks() { |
| let mut v = [0, 1, 2, 3, 4, 5, 6]; |
| assert_eq!(v.chunks_mut(3).len(), 3); |
| for (i, chunk) in v.chunks_mut(3).enumerate() { |
| for x in chunk { |
| *x = i as u8; |
| } |
| } |
| let result = [0, 0, 0, 1, 1, 1, 2]; |
| assert_eq!(v, result); |
| } |
| |
| #[test] |
| fn test_mut_chunks_rev() { |
| let mut v = [0, 1, 2, 3, 4, 5, 6]; |
| for (i, chunk) in v.chunks_mut(3).rev().enumerate() { |
| for x in chunk { |
| *x = i as u8; |
| } |
| } |
| let result = [2, 2, 2, 1, 1, 1, 0]; |
| assert_eq!(v, result); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_mut_chunks_0() { |
| let mut v = [1, 2, 3, 4]; |
| let _it = v.chunks_mut(0); |
| } |
| |
| #[test] |
| fn test_mut_chunks_exact() { |
| let mut v = [0, 1, 2, 3, 4, 5, 6]; |
| assert_eq!(v.chunks_exact_mut(3).len(), 2); |
| for (i, chunk) in v.chunks_exact_mut(3).enumerate() { |
| for x in chunk { |
| *x = i as u8; |
| } |
| } |
| let result = [0, 0, 0, 1, 1, 1, 6]; |
| assert_eq!(v, result); |
| } |
| |
| #[test] |
| fn test_mut_chunks_exact_rev() { |
| let mut v = [0, 1, 2, 3, 4, 5, 6]; |
| for (i, chunk) in v.chunks_exact_mut(3).rev().enumerate() { |
| for x in chunk { |
| *x = i as u8; |
| } |
| } |
| let result = [1, 1, 1, 0, 0, 0, 6]; |
| assert_eq!(v, result); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_mut_chunks_exact_0() { |
| let mut v = [1, 2, 3, 4]; |
| let _it = v.chunks_exact_mut(0); |
| } |
| |
| #[test] |
| fn test_mut_rchunks() { |
| let mut v = [0, 1, 2, 3, 4, 5, 6]; |
| assert_eq!(v.rchunks_mut(3).len(), 3); |
| for (i, chunk) in v.rchunks_mut(3).enumerate() { |
| for x in chunk { |
| *x = i as u8; |
| } |
| } |
| let result = [2, 1, 1, 1, 0, 0, 0]; |
| assert_eq!(v, result); |
| } |
| |
| #[test] |
| fn test_mut_rchunks_rev() { |
| let mut v = [0, 1, 2, 3, 4, 5, 6]; |
| for (i, chunk) in v.rchunks_mut(3).rev().enumerate() { |
| for x in chunk { |
| *x = i as u8; |
| } |
| } |
| let result = [0, 1, 1, 1, 2, 2, 2]; |
| assert_eq!(v, result); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_mut_rchunks_0() { |
| let mut v = [1, 2, 3, 4]; |
| let _it = v.rchunks_mut(0); |
| } |
| |
| #[test] |
| fn test_mut_rchunks_exact() { |
| let mut v = [0, 1, 2, 3, 4, 5, 6]; |
| assert_eq!(v.rchunks_exact_mut(3).len(), 2); |
| for (i, chunk) in v.rchunks_exact_mut(3).enumerate() { |
| for x in chunk { |
| *x = i as u8; |
| } |
| } |
| let result = [0, 1, 1, 1, 0, 0, 0]; |
| assert_eq!(v, result); |
| } |
| |
| #[test] |
| fn test_mut_rchunks_exact_rev() { |
| let mut v = [0, 1, 2, 3, 4, 5, 6]; |
| for (i, chunk) in v.rchunks_exact_mut(3).rev().enumerate() { |
| for x in chunk { |
| *x = i as u8; |
| } |
| } |
| let result = [0, 0, 0, 0, 1, 1, 1]; |
| assert_eq!(v, result); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_mut_rchunks_exact_0() { |
| let mut v = [1, 2, 3, 4]; |
| let _it = v.rchunks_exact_mut(0); |
| } |
| |
| #[test] |
| fn test_mut_last() { |
| let mut x = [1, 2, 3, 4, 5]; |
| let h = x.last_mut(); |
| assert_eq!(*h.unwrap(), 5); |
| |
| let y: &mut [i32] = &mut []; |
| assert!(y.last_mut().is_none()); |
| } |
| |
| #[test] |
| fn test_to_vec() { |
| let xs: Box<_> = Box::new([1, 2, 3]); |
| let ys = xs.to_vec(); |
| assert_eq!(ys, [1, 2, 3]); |
| } |
| |
| #[test] |
| fn test_in_place_iterator_specialization() { |
| let src: Box<[usize]> = Box::new([1, 2, 3]); |
| let src_ptr = src.as_ptr(); |
| let sink: Box<_> = src.into_vec().into_iter().map(std::convert::identity).collect(); |
| let sink_ptr = sink.as_ptr(); |
| assert_eq!(src_ptr, sink_ptr); |
| } |
| |
| #[test] |
| fn test_box_slice_clone() { |
| let data = vec![vec![0, 1], vec![0], vec![1]]; |
| let data2 = data.clone().into_boxed_slice().clone().to_vec(); |
| |
| assert_eq!(data, data2); |
| } |
| |
| #[test] |
| #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` |
| #[cfg_attr(target_os = "emscripten", ignore)] |
| #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] |
| fn test_box_slice_clone_panics() { |
| use std::sync::Arc; |
| use std::sync::atomic::{AtomicUsize, Ordering}; |
| |
| struct Canary { |
| count: Arc<AtomicUsize>, |
| panics: bool, |
| } |
| |
| impl Drop for Canary { |
| fn drop(&mut self) { |
| self.count.fetch_add(1, Ordering::SeqCst); |
| } |
| } |
| |
| impl Clone for Canary { |
| fn clone(&self) -> Self { |
| if self.panics { |
| panic!() |
| } |
| |
| Canary { count: self.count.clone(), panics: self.panics } |
| } |
| } |
| |
| let drop_count = Arc::new(AtomicUsize::new(0)); |
| let canary = Canary { count: drop_count.clone(), panics: false }; |
| let panic = Canary { count: drop_count.clone(), panics: true }; |
| |
| std::panic::catch_unwind(move || { |
| // When xs is dropped, +5. |
| let xs = |
| vec![canary.clone(), canary.clone(), canary.clone(), panic, canary].into_boxed_slice(); |
| |
| // When panic is cloned, +3. |
| xs.clone(); |
| }) |
| .unwrap_err(); |
| |
| // Total = 8 |
| assert_eq!(drop_count.load(Ordering::SeqCst), 8); |
| } |
| |
| #[test] |
| fn test_copy_from_slice() { |
| let src = [0, 1, 2, 3, 4, 5]; |
| let mut dst = [0; 6]; |
| dst.copy_from_slice(&src); |
| assert_eq!(src, dst) |
| } |
| |
| #[test] |
| #[should_panic(expected = "source slice length (4) does not match destination slice length (5)")] |
| fn test_copy_from_slice_dst_longer() { |
| let src = [0, 1, 2, 3]; |
| let mut dst = [0; 5]; |
| dst.copy_from_slice(&src); |
| } |
| |
| #[test] |
| #[should_panic(expected = "source slice length (4) does not match destination slice length (3)")] |
| fn test_copy_from_slice_dst_shorter() { |
| let src = [0, 1, 2, 3]; |
| let mut dst = [0; 3]; |
| dst.copy_from_slice(&src); |
| } |
| |
| #[test] |
| fn repeat_generic_slice() { |
| assert_eq!([1, 2].repeat(2), vec![1, 2, 1, 2]); |
| assert_eq!([1, 2, 3, 4].repeat(0), vec![]); |
| assert_eq!([1, 2, 3, 4].repeat(1), vec![1, 2, 3, 4]); |
| assert_eq!([1, 2, 3, 4].repeat(3), vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]); |
| } |
| |
| #[test] |
| #[allow(unreachable_patterns)] |
| fn subslice_patterns() { |
| // This test comprehensively checks the passing static and dynamic semantics |
| // of subslice patterns `..`, `x @ ..`, `ref x @ ..`, and `ref mut @ ..` |
| // in slice patterns `[$($pat), $(,)?]` . |
| |
| #[derive(PartialEq, Debug, Clone)] |
| struct N(u8); |
| |
| macro_rules! n { |
| ($($e:expr),* $(,)?) => { |
| [$(N($e)),*] |
| } |
| } |
| |
| macro_rules! c { |
| ($inp:expr, $typ:ty, $out:expr $(,)?) => { |
| assert_eq!($out, identity::<$typ>($inp)) |
| }; |
| } |
| |
| macro_rules! m { |
| ($e:expr, $p:pat => $b:expr) => { |
| match $e { |
| $p => $b, |
| _ => panic!(), |
| } |
| }; |
| } |
| |
| // == Slices == |
| |
| // Matching slices using `ref` patterns: |
| let mut v = vec![N(0), N(1), N(2), N(3), N(4)]; |
| let mut vc = (0..=4).collect::<Vec<u8>>(); |
| |
| let [..] = v[..]; // Always matches. |
| m!(v[..], [N(0), ref sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); |
| m!(v[..], [N(0), ref sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); |
| m!(v[..], [ref sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); |
| m!(v[..], [ref sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); |
| m!(v[..], [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N], &n![] as &[N])); |
| m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); |
| |
| // Matching slices using `ref mut` patterns: |
| let [..] = v[..]; // Always matches. |
| m!(v[..], [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); |
| m!(v[..], [N(0), ref mut sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); |
| m!(v[..], [ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); |
| m!(v[..], [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); |
| m!(v[..], [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); |
| m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); |
| |
| // Matching slices using default binding modes (&): |
| let [..] = &v[..]; // Always matches. |
| m!(&v[..], [N(0), sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); |
| m!(&v[..], [N(0), sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); |
| m!(&v[..], [sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); |
| m!(&v[..], [sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); |
| m!(&v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &[N], &n![] as &[N])); |
| m!(&vc[..], [x, .., y] => c!((x, y), (&u8, &u8), (&0, &4))); |
| |
| // Matching slices using default binding modes (&mut): |
| let [..] = &mut v[..]; // Always matches. |
| m!(&mut v[..], [N(0), sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); |
| m!(&mut v[..], [N(0), sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); |
| m!(&mut v[..], [sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); |
| m!(&mut v[..], [sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); |
| m!(&mut v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); |
| m!(&mut vc[..], [x, .., y] => c!((x, y), (&mut u8, &mut u8), (&mut 0, &mut 4))); |
| |
| // == Arrays == |
| let mut v = n![0, 1, 2, 3, 4]; |
| let vc = [0, 1, 2, 3, 4]; |
| |
| // Matching arrays by value: |
| m!(v.clone(), [N(0), sub @ .., N(4)] => c!(sub, [N; 3], n![1, 2, 3])); |
| m!(v.clone(), [N(0), sub @ ..] => c!(sub, [N; 4], n![1, 2, 3, 4])); |
| m!(v.clone(), [sub @ .., N(4)] => c!(sub, [N; 4], n![0, 1, 2, 3])); |
| m!(v.clone(), [sub @ .., _, _, _, _, _] => c!(sub, [N; 0], n![] as [N; 0])); |
| m!(v.clone(), [_, _, _, _, _, sub @ ..] => c!(sub, [N; 0], n![] as [N; 0])); |
| m!(v.clone(), [x, .., y] => c!((x, y), (N, N), (N(0), N(4)))); |
| m!(v.clone(), [..] => ()); |
| |
| // Matching arrays by ref patterns: |
| m!(v, [N(0), ref sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); |
| m!(v, [N(0), ref sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); |
| m!(v, [ref sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); |
| m!(v, [ref sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); |
| m!(v, [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); |
| m!(vc, [x, .., y] => c!((x, y), (u8, u8), (0, 4))); |
| |
| // Matching arrays by ref mut patterns: |
| m!(v, [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); |
| m!(v, [N(0), ref mut sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); |
| m!(v, [ref mut sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); |
| m!(v, [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); |
| m!(v, [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); |
| |
| // Matching arrays by default binding modes (&): |
| m!(&v, [N(0), sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); |
| m!(&v, [N(0), sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); |
| m!(&v, [sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); |
| m!(&v, [sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); |
| m!(&v, [_, _, _, _, _, sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); |
| m!(&v, [..] => ()); |
| m!(&v, [x, .., y] => c!((x, y), (&N, &N), (&N(0), &N(4)))); |
| |
| // Matching arrays by default binding modes (&mut): |
| m!(&mut v, [N(0), sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); |
| m!(&mut v, [N(0), sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); |
| m!(&mut v, [sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); |
| m!(&mut v, [sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); |
| m!(&mut v, [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); |
| m!(&mut v, [..] => ()); |
| m!(&mut v, [x, .., y] => c!((x, y), (&mut N, &mut N), (&mut N(0), &mut N(4)))); |
| } |
| |
| #[test] |
| fn test_chunk_by() { |
| let slice = &[1, 1, 1, 3, 3, 2, 2, 2, 1, 0]; |
| |
| let mut iter = slice.chunk_by(|a, b| a == b); |
| assert_eq!(iter.next(), Some(&[1, 1, 1][..])); |
| assert_eq!(iter.next(), Some(&[3, 3][..])); |
| assert_eq!(iter.next(), Some(&[2, 2, 2][..])); |
| assert_eq!(iter.next(), Some(&[1][..])); |
| assert_eq!(iter.next(), Some(&[0][..])); |
| assert_eq!(iter.next(), None); |
| |
| let mut iter = slice.chunk_by(|a, b| a == b); |
| assert_eq!(iter.next_back(), Some(&[0][..])); |
| assert_eq!(iter.next_back(), Some(&[1][..])); |
| assert_eq!(iter.next_back(), Some(&[2, 2, 2][..])); |
| assert_eq!(iter.next_back(), Some(&[3, 3][..])); |
| assert_eq!(iter.next_back(), Some(&[1, 1, 1][..])); |
| assert_eq!(iter.next_back(), None); |
| |
| let mut iter = slice.chunk_by(|a, b| a == b); |
| assert_eq!(iter.next(), Some(&[1, 1, 1][..])); |
| assert_eq!(iter.next_back(), Some(&[0][..])); |
| assert_eq!(iter.next(), Some(&[3, 3][..])); |
| assert_eq!(iter.next_back(), Some(&[1][..])); |
| assert_eq!(iter.next(), Some(&[2, 2, 2][..])); |
| assert_eq!(iter.next_back(), None); |
| } |
| |
| #[test] |
| fn test_chunk_by_mut() { |
| let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2, 1, 0]; |
| |
| let mut iter = slice.chunk_by_mut(|a, b| a == b); |
| assert_eq!(iter.next(), Some(&mut [1, 1, 1][..])); |
| assert_eq!(iter.next(), Some(&mut [3, 3][..])); |
| assert_eq!(iter.next(), Some(&mut [2, 2, 2][..])); |
| assert_eq!(iter.next(), Some(&mut [1][..])); |
| assert_eq!(iter.next(), Some(&mut [0][..])); |
| assert_eq!(iter.next(), None); |
| |
| let mut iter = slice.chunk_by_mut(|a, b| a == b); |
| assert_eq!(iter.next_back(), Some(&mut [0][..])); |
| assert_eq!(iter.next_back(), Some(&mut [1][..])); |
| assert_eq!(iter.next_back(), Some(&mut [2, 2, 2][..])); |
| assert_eq!(iter.next_back(), Some(&mut [3, 3][..])); |
| assert_eq!(iter.next_back(), Some(&mut [1, 1, 1][..])); |
| assert_eq!(iter.next_back(), None); |
| |
| let mut iter = slice.chunk_by_mut(|a, b| a == b); |
| assert_eq!(iter.next(), Some(&mut [1, 1, 1][..])); |
| assert_eq!(iter.next_back(), Some(&mut [0][..])); |
| assert_eq!(iter.next(), Some(&mut [3, 3][..])); |
| assert_eq!(iter.next_back(), Some(&mut [1][..])); |
| assert_eq!(iter.next(), Some(&mut [2, 2, 2][..])); |
| assert_eq!(iter.next_back(), None); |
| } |