#![allow(clippy::assertions_on_constants, clippy::eq_op)] use index_vec::{index_vec, IndexSlice, IndexVec}; index_vec::define_index_type! { pub struct USize16 = usize; MAX_INDEX = u16::MAX as usize; DEFAULT = USize16::from_raw_unchecked(usize::MAX); } index_vec::define_index_type! { pub struct ZeroMaxIgnore = u16; MAX_INDEX = 0; DISABLE_MAX_INDEX_CHECK = true; } index_vec::define_index_type! { pub struct ZeroMax = u16; MAX_INDEX = 0; } index_vec::define_index_type! { pub struct IdxSz = usize; } index_vec::define_index_type! { pub struct Idx32 = u32; DEBUG_FORMAT = "Test({:?})"; DISPLAY_FORMAT = "foo {}"; IMPL_RAW_CONVERSIONS = true; } index_vec::define_index_type! { pub struct Idx16 = u16; } index_vec::define_index_type! { pub struct Idx8 = u8; } index_vec::define_index_type! { pub struct SmallCheckedEarly = u8; MAX_INDEX = 0x7f; } index_vec::define_index_type! { pub struct SmallChecked = u8; } index_vec::define_index_type! { pub struct SmallUnchecked = u8; DISABLE_MAX_INDEX_CHECK = true; } index_vec::define_index_type! { pub struct SmallUncheckedEarly = u8; DISABLE_MAX_INDEX_CHECK = true; MAX_INDEX = 0x7f; } #[test] fn test_idx_default_max() { assert_eq!(Idx32::MAX_INDEX, u32::MAX as usize); assert_eq!(IdxSz::MAX_INDEX, usize::MAX); assert_eq!(Idx16::MAX_INDEX, u16::MAX as usize); assert_eq!(Idx8::MAX_INDEX, u8::MAX as usize); assert!(Idx32::CHECKS_MAX_INDEX); assert!(IdxSz::CHECKS_MAX_INDEX); assert!(Idx16::CHECKS_MAX_INDEX); assert!(Idx8::CHECKS_MAX_INDEX); assert!(!ZeroMaxIgnore::CHECKS_MAX_INDEX); assert_eq!(ZeroMaxIgnore::MAX_INDEX, 0); } #[test] fn test_idx_arith() { assert_eq!(Idx32::new(0), 0usize); assert_eq!(Idx32::new(0) + 1, 1usize); assert_eq!(1 + Idx32::new(0), 1usize); assert_eq!(Idx32::new(1) - 1, 0usize); assert_eq!(Idx32::new(5) % 4, 1usize); let mut m = Idx32::new(5); m += 1; assert_eq!(m, 6); assert!(Idx32::new(5) < Idx32::new(6)); assert!(Idx32::new(5) < 6usize); assert!(Idx32::new(5) < Idx32::new(6)); assert!(Idx32::new(5) < 6usize); assert!(5usize < Idx32::new(6)); } #[test] fn test_idx_checks1() { let v: u32 = Idx32::new(4).raw(); assert_eq!(v, 4); let u: usize = Idx32::new(4).index(); assert_eq!(u, 4); assert_eq!(SmallCheckedEarly::from_raw_unchecked(0xff).raw(), 0xff); assert!(SmallChecked::CHECKS_MAX_INDEX); assert!(SmallCheckedEarly::CHECKS_MAX_INDEX); assert_eq!(SmallChecked::MAX_INDEX, 255); assert_eq!(SmallCheckedEarly::MAX_INDEX, 0x7f); assert!(!SmallUnchecked::CHECKS_MAX_INDEX); assert!(!SmallUncheckedEarly::CHECKS_MAX_INDEX); assert_eq!(SmallUnchecked::MAX_INDEX, 255); assert_eq!(SmallUncheckedEarly::MAX_INDEX, 0x7f); } #[test] fn test_idx_checks2() { // all shouldn't panic let v = SmallChecked::from_raw(150); assert_eq!(v, 150); let v = SmallChecked::from_usize(150); assert_eq!(v, 150); let v = SmallChecked::from_usize(255); assert_eq!(v, 255); let v = SmallChecked::from_usize(0); assert_eq!(v, 0); let v = SmallCheckedEarly::from_usize(0x7f); assert_eq!(v, 0x7f); let v = SmallCheckedEarly::from_usize(0); assert_eq!(v, 0); let v = SmallUncheckedEarly::from_raw(0xff); assert_eq!(v, 0xff); let v = SmallUncheckedEarly::from_usize(150); assert_eq!(v, 150); let v = SmallUncheckedEarly::from_usize(300); assert_eq!(v.raw(), 300usize as u8); let v = SmallUnchecked::from_usize(150); assert_eq!(v, 150); let v = SmallUnchecked::from_usize(300); assert_eq!(v.raw(), 300usize as u8); let v = SmallCheckedEarly::from_raw_unchecked(0xff); assert_eq!(v, 0xff); let v = SmallCheckedEarly::from_usize_unchecked(150); assert_eq!(v, 150); let v = SmallCheckedEarly::from_usize_unchecked(300); assert_eq!(v.raw(), 300usize as u8); let v = SmallChecked::from_usize_unchecked(300); assert_eq!(v.raw(), 300usize as u8); assert_eq!(::default().index(), usize::MAX); let v = ZeroMaxIgnore::new((u16::MAX as usize) + 1); assert_eq!(v, 0); let v = ZeroMaxIgnore::new(0) + 1; assert_eq!(v, 1); // let _ = ZeroMaxIgnore::new(0) - 1; let v = ZeroMaxIgnore::new(2); assert_eq!(v, 2); let v = ZeroMaxIgnore::new((u16::MAX as usize) + 1); assert_eq!(v, 0); } #[test] #[should_panic] fn test_idx_sc_cf_raw() { let _ = SmallCheckedEarly::from_raw(0xff); } #[test] #[should_panic] fn test_idx_sc_cf_idx0() { let _ = SmallCheckedEarly::from_usize(150); } #[test] #[should_panic] fn test_idx_sc_cf_idx1() { let _ = SmallCheckedEarly::from_usize(300); } #[test] #[should_panic] fn test_idx_sc_cf_idx2() { let _ = SmallChecked::from_usize(300); } #[test] #[should_panic] fn test_idx_sc_of_add() { let _ = SmallChecked::from_usize(255) + 1; } #[test] #[should_panic] fn test_idx_sc_of_addassign() { let mut e2 = SmallChecked::from_usize(255); e2 += 1; } #[test] #[should_panic] fn test_idx_sc_of_sub() { let _ = SmallChecked::from_usize(0) - 1; } #[test] #[should_panic] fn test_idx_sc_of_subassign() { let mut z2 = SmallChecked::from_usize(0); z2 -= 1; } #[test] #[should_panic] fn test_idx_zm_cf_idx() { let _ = ZeroMax::new(2); } #[test] #[should_panic] fn test_idx_zm_cf_raw() { let _ = ZeroMax::from_raw(2); } #[test] #[should_panic] fn test_idx_zm_of_add0() { let _ = ZeroMax::new(0) + 1; } #[test] #[should_panic] fn test_idx_zm_of_sub0() { let _ = ZeroMax::new(0) - 1; } #[test] #[should_panic] fn test_idx_zm_of_nowrap() { let _ = ZeroMax::new((u16::MAX as usize) + 1); } #[test] #[should_panic] fn test_idx_sce_adde() { let _ = SmallCheckedEarly::from_usize(0x7f) + 1; } #[test] #[should_panic] fn test_idx_sce_addassign() { let mut e3 = SmallCheckedEarly::from_usize(0x7f); e3 += 1; } #[test] #[should_panic] fn test_idx_sce_sub() { let _ = SmallCheckedEarly::from_usize(0) - 1; } #[test] #[should_panic] fn test_idx_sce_subassign() { let mut z3 = SmallCheckedEarly::from_usize(0); z3 -= 1; } #[test] fn test_vec() { let mut strs: IndexVec = index_vec!["strs", "bar", "baz"]; let l = strs.last_idx(); assert_eq!(strs[l], "baz"); let new_i = strs.push("quux"); assert_eq!(strs[new_i], "quux"); } #[test] fn test_idx() { let mut e = Idx32::new(0); let one = Idx32::new(1); e += 1; assert_eq!(e, 1); e -= 1; assert_eq!(e, 0); e += one; assert_eq!(e, 1); e -= one; assert_eq!(e, 0); let e2 = e + one; assert_eq!(e2, 1); let e2 = e2 - one; assert_eq!(e2, 0); let e2 = e + 1; assert_eq!(e2, 1); let e2 = e2 - 1; assert_eq!(0, e2); assert_eq!(40usize - Idx32::new(10), 30); assert_eq!(u32::from(Idx32::new(500)), 500); assert_eq!(Idx32::from(500u32), 500); } #[test] fn test_fmt() { let i = format!("{:?}", Idx32::new(30)); assert_eq!(i, "Test(30)"); let i = format!("{}", Idx32::new(30)); assert_eq!(i, "foo 30"); let v: IndexVec = index_vec![3, 4, 5]; assert_eq!(format!("{:?}", v), format!("{:?}", vec![3, 4, 5])); assert_eq!(format!("{:#?}", v), format!("{:#?}", vec![3, 4, 5])); assert_eq!(format!("{:?}", &v[..]), format!("{:?}", &[3, 4, 5])); } #[test] fn test_partial_eq() { let i0: IndexVec = index_vec![0]; let i1: IndexVec = index_vec![1]; let i123: IndexVec = index_vec![1, 2, 3]; assert_eq!(i0, i0); assert_ne!(i0, i1); assert_eq!(i123, vec![1, 2, 3]); assert_eq!(i123, &[1, 2, 3]); assert_eq!(i123, [1, 2, 3]); assert_eq!(i123[..], [1, 2, 3]); assert_eq!(i123[..Idx32::new(1)], [1usize]); assert_eq!(i123[..Idx32::new(1)], i1.as_slice()); assert_eq!(i123[..Idx32::new(1)], i1.as_raw_slice()); } #[test] fn test_drain() { let mut vec: IndexVec = index_vec![1, 2, 3]; let mut vec2: IndexVec = index_vec![]; for i in vec.drain(..) { vec2.push(i); } assert!(vec.is_empty()); assert_eq!(vec2, [1, 2, 3]); let mut vec: IndexVec = index_vec![1, 2, 3]; let mut vec2: IndexVec = index_vec![]; for i in vec.drain(Idx32::from_raw(1)..) { vec2.push(i); } assert_eq!(vec, [1]); assert_eq!(vec2, [2, 3]); let mut vec: IndexVec = index_vec![(), (), ()]; let mut vec2: IndexVec = index_vec![]; for _i in vec.drain(..) { vec2.push(()); } assert_eq!(vec, []); assert_eq!(vec2, [(), (), ()]); } #[test] fn test_drain_enumerated() { let mut vec: IndexVec = index_vec![1, 2, 3]; let mut vec2: IndexVec = index_vec![]; for (i, j) in vec.drain_enumerated(..) { assert_eq!(i.index() + 1, j); vec2.push(j); } assert!(vec.is_empty()); assert_eq!(vec2, [1, 2, 3]); } #[test] fn test_position() { let b: &IndexSlice = IndexSlice::new(&[1, 2, 3, 5, 5]); assert_eq!(b.position(|&v| v == 9), None); assert_eq!(b.position(|&v| v == 5), Some(IdxSz::from_raw(3))); assert_eq!(b.position(|&v| v == 3), Some(IdxSz::from_raw(2))); assert_eq!(b.position(|&v| v == 0), None); } #[test] fn test_rposition() { let b: &IndexSlice = IndexSlice::new(&[1, 2, 3, 5, 5]); assert_eq!(b.rposition(|&v| v == 9), None); assert_eq!(b.rposition(|&v| v == 5), Some(IdxSz::from_raw(4))); assert_eq!(b.rposition(|&v| v == 3), Some(IdxSz::from_raw(2))); assert_eq!(b.rposition(|&v| v == 0), None); } #[test] fn test_binary_search() { let b: &IndexSlice = IndexSlice::new(&[]); assert_eq!(b.binary_search(&5), Err(IdxSz::new(0))); let b: &IndexSlice = IndexSlice::new(&[4]); assert_eq!(b.binary_search(&3), Err(IdxSz::new(0))); assert_eq!(b.binary_search(&4), Ok(IdxSz::new(0))); assert_eq!(b.binary_search(&5), Err(IdxSz::new(1))); } #[test] fn test_chunk_iters() { let mut v: IndexVec = index_vec![0, 1, 2, 3, 4]; assert_eq!( v.chunks(3).collect::>(), &[IndexSlice::new(&[0, 1, 2]), IndexSlice::new(&[3, 4])] ); assert_eq!( v.chunks_mut(3).collect::>(), &[ IndexSlice::new_mut(&mut [0, 1, 2]), IndexSlice::new_mut(&mut [3, 4]) ] ); assert_eq!( v.chunks_exact(3).collect::>(), &[IndexSlice::new(&[0, 1, 2])] ); assert_eq!( v.chunks_exact_mut(3).collect::>(), &[IndexSlice::new_mut(&mut [0, 1, 2])] ); assert_eq!( v.rchunks(3).collect::>(), &[IndexSlice::new(&[2, 3, 4]), IndexSlice::new(&[0, 1])] ); assert_eq!( v.rchunks_mut(3).collect::>(), &[ IndexSlice::new_mut(&mut [2, 3, 4]), IndexSlice::new_mut(&mut [0, 1]) ] ); assert_eq!( v.rchunks_exact(3).collect::>(), &[IndexSlice::new(&[2, 3, 4])] ); assert_eq!( v.rchunks_exact_mut(3).collect::>(), &[IndexSlice::new_mut(&mut [2, 3, 4])] ); assert_eq!( v.windows(2).collect::>(), &[ IndexSlice::new(&[0, 1]), IndexSlice::new(&[1, 2]), IndexSlice::new(&[2, 3]), IndexSlice::new(&[3, 4]) ] ); } #[test] fn test_indexing() { let v: IndexVec = index_vec![0, 1, 2, 3, 4]; assert_eq!(v[..], &[0, 1, 2, 3, 4]); assert_eq!(v[IdxSz::new(1)..], &[1, 2, 3, 4]); assert_eq!(v[IdxSz::new(1)..IdxSz::new(3)], &[1, 2]); assert_eq!(v[IdxSz::new(1)..=IdxSz::new(3)], &[1, 2, 3]); assert_eq!(v[..=IdxSz::new(3)], &[0, 1, 2, 3]); assert_eq!(v[IdxSz::new(3)], 3); assert_eq!(v[3], 3); // usize is allowed. // Make sure the types are as expected let s: &IndexSlice = &v[..]; assert_eq!(s, &[0, 1, 2, 3, 4]); let s: &IndexSlice = &v[IdxSz::new(1)..]; assert_eq!(s, &[1, 2, 3, 4]); let s: &IndexSlice = &v[IdxSz::new(1)..IdxSz::new(3)]; assert_eq!(s, &[1, 2]); let s: &IndexSlice = &v[IdxSz::new(1)..=IdxSz::new(3)]; assert_eq!(s, &[1, 2, 3]); let s: &IndexSlice = &v[..=IdxSz::new(3)]; assert_eq!(s, &[0, 1, 2, 3]); let mut v: IndexVec = index_vec![0, 1, 2, 3, 4]; // check `IndexMut` { let s: &mut IndexSlice = &mut v[..]; assert_eq!(s, &[0, 1, 2, 3, 4]); } { let s: &mut IndexSlice = &mut v[IdxSz::new(1)..]; assert_eq!(s, &[1, 2, 3, 4]); } { let s: &mut IndexSlice = &mut v[IdxSz::new(1)..IdxSz::new(3)]; assert_eq!(s, &[1, 2]); } { let s: &mut IndexSlice = &mut v[IdxSz::new(1)..=IdxSz::new(3)]; assert_eq!(s, &[1, 2, 3]); } { let s: &mut IndexSlice = &mut v[..=IdxSz::new(3)]; assert_eq!(s, &[0, 1, 2, 3]); } assert_eq!(&mut v[IdxSz::new(3)], &mut 3); assert_eq!(&mut v[3], &mut 3); // usize is allowed. } #[test] fn test_get() { let v: IndexVec = index_vec![0, 1, 2, 3, 4]; let s: Option<&IndexSlice> = v.get(..); assert_eq!(s.unwrap(), &[0, 1, 2, 3, 4]); let s: Option<&IndexSlice> = v.get(IdxSz::new(1)..); assert_eq!(s.unwrap(), &[1, 2, 3, 4]); let s: Option<&IndexSlice> = v.get(IdxSz::new(1)..IdxSz::new(3)); assert_eq!(s.unwrap(), &[1, 2]); let s: Option<&IndexSlice> = v.get(IdxSz::new(1)..=IdxSz::new(3)); assert_eq!(s.unwrap(), &[1, 2, 3]); let s: Option<&IndexSlice> = v.get(..=IdxSz::new(3)); assert_eq!(s.unwrap(), &[0, 1, 2, 3]); assert_eq!(v.get(IdxSz::new(3)), Some(&3)); assert_eq!(v.get(3), Some(&3)); } #[test] fn test_get_mut() { let mut v: IndexVec = index_vec![0, 1, 2, 3, 4]; let s: Option<&mut IndexSlice> = v.get_mut(..); assert_eq!(s.unwrap(), &[0, 1, 2, 3, 4]); let s: Option<&mut IndexSlice> = v.get_mut(IdxSz::new(1)..); assert_eq!(s.unwrap(), &[1, 2, 3, 4]); let s: Option<&mut IndexSlice> = v.get_mut(IdxSz::new(1)..IdxSz::new(3)); assert_eq!(s.unwrap(), &[1, 2]); let s: Option<&mut IndexSlice> = v.get_mut(IdxSz::new(1)..=IdxSz::new(3)); assert_eq!(s.unwrap(), &[1, 2, 3]); let s: Option<&mut IndexSlice> = v.get_mut(..=IdxSz::new(3)); assert_eq!(s.unwrap(), &[0, 1, 2, 3]); assert_eq!(v.get_mut(IdxSz::new(3)), Some(&mut 3)); assert_eq!(v.get_mut(3), Some(&mut 3)); } #[test] fn test_splits() { let v: IndexVec = index_vec![0, 1, 2, 3, 4]; let (a, b): (&i32, &IndexSlice) = v.split_first().unwrap(); assert_eq!(a, &0); assert_eq!(b, &[1, 2, 3, 4]); let (a, b): (&i32, &IndexSlice) = v.split_last().unwrap(); assert_eq!(a, &4); assert_eq!(b, &[0, 1, 2, 3]); let mut v: IndexVec = index_vec![0, 1, 2, 3, 4]; let (a, b): (&mut i32, &mut IndexSlice) = v.split_first_mut().unwrap(); assert_eq!(a, &0); assert_eq!(b, &[1, 2, 3, 4]); let (a, b): (&mut i32, &mut IndexSlice) = v.split_last_mut().unwrap(); assert_eq!(a, &4); assert_eq!(b, &[0, 1, 2, 3]); let mut v: IndexVec = index_vec![]; assert!(v.split_first().is_none()); assert!(v.split_last().is_none()); assert!(v.split_first_mut().is_none()); assert!(v.split_last_mut().is_none()); }