diff --git a/src/arrayvec.rs b/src/arrayvec.rs index d5de521..a71523a 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -1,4 +1,5 @@ use super::*; +use core::convert::TryInto; /// Helper to make an `ArrayVec`. /// @@ -91,7 +92,7 @@ macro_rules! array_vec { #[repr(C)] #[derive(Clone, Copy, Default)] pub struct ArrayVec { - len: usize, + len: u16, pub(crate) data: A, } @@ -100,7 +101,7 @@ impl Deref for ArrayVec { #[inline(always)] #[must_use] fn deref(&self) -> &Self::Target { - &self.data.as_slice()[..self.len] + &self.data.as_slice()[..self.len as usize] } } @@ -108,7 +109,7 @@ impl DerefMut for ArrayVec { #[inline(always)] #[must_use] fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.data.as_slice_mut()[..self.len] + &mut self.data.as_slice_mut()[..self.len as usize] } } @@ -284,7 +285,7 @@ impl ArrayVec { return; } - let new_len = self.len + sli.len(); + let new_len = self.len as usize + sli.len(); assert!( new_len <= A::CAPACITY, "ArrayVec::extend_from_slice> total length {} exceeds capacity {}!", @@ -292,7 +293,7 @@ impl ArrayVec { A::CAPACITY ); - let target = &mut self.data.as_slice_mut()[self.len..new_len]; + let target = &mut self.data.as_slice_mut()[self.len as usize..new_len]; target.clone_from_slice(sli); self.set_len(new_len); } @@ -397,7 +398,7 @@ impl ArrayVec { #[inline] pub fn try_insert(&mut self, index: usize, item: A::Item) -> Option { assert!( - index <= self.len, + index <= self.len as usize, "ArrayVec::try_insert> index {} is out of bounds {}", index, self.len @@ -422,7 +423,7 @@ impl ArrayVec { #[inline(always)] #[must_use] pub fn len(&self) -> usize { - self.len + self.len as usize } /// Makes a new, empty `ArrayVec`. @@ -452,7 +453,7 @@ impl ArrayVec { pub fn pop(&mut self) -> Option { if self.len > 0 { self.len -= 1; - let out = take(&mut self.data.as_slice_mut()[self.len]); + let out = take(&mut self.data.as_slice_mut()[self.len as usize]); Some(out) } else { None @@ -496,9 +497,9 @@ impl ArrayVec { /// ``` #[inline(always)] pub fn try_push(&mut self, val: A::Item) -> Option { - debug_assert!(self.len <= A::CAPACITY); + debug_assert!(self.len as usize <= A::CAPACITY); - let itemref = match self.data.as_slice_mut().get_mut(self.len) { + let itemref = match self.data.as_slice_mut().get_mut(self.len as usize) { None => return Some(val), Some(x) => x, }; @@ -585,7 +586,7 @@ impl ArrayVec { new_len: usize, mut f: F, ) { - match new_len.checked_sub(self.len) { + match new_len.checked_sub(self.len as usize) { None => self.truncate(new_len), Some(new_elements) => { for _ in 0..new_elements { @@ -624,12 +625,13 @@ impl ArrayVec { } let mut rest = JoinOnDrop { - items: &mut self.data.as_slice_mut()[..self.len], + items: &mut self.data.as_slice_mut()[..self.len as usize], done_end: 0, tail_start: 0, }; - for idx in 0..self.len { + let len = self.len as usize; + for idx in 0..len { // Loop start invariant: idx = rest.done_end + rest.tail_start if !acceptable(&rest.items[idx]) { let _ = take(&mut rest.items[idx]); @@ -664,9 +666,12 @@ impl ArrayVec { new_len, A::CAPACITY ) - } else { - self.len = new_len; } + + let new_len: u16 = new_len + .try_into() + .expect("ArrayVec::set_len> new length is not in range 0..=u16::MAX"); + self.len = new_len; } /// Splits the collection at the point given. @@ -692,7 +697,7 @@ impl ArrayVec { Self: Default, { // FIXME: should this just use drain into the output? - if at > self.len { + if at > self.len() { panic!( "ArrayVec::split_off> at value {} exceeds length of {}", at, self.len @@ -703,8 +708,10 @@ impl ArrayVec { let split_len = moves.len(); let targets = &mut new.data.as_slice_mut()[..split_len]; moves.swap_with_slice(targets); - new.len = split_len; - self.len = at; + + /* moves.len() <= u16::MAX, so these are surely in u16 range */ + new.len = split_len as u16; + self.len = at as u16; new } @@ -795,12 +802,12 @@ impl ArrayVec { #[inline] pub fn swap_remove(&mut self, index: usize) -> A::Item { assert!( - index < self.len, + index < self.len(), "ArrayVec::swap_remove> index {} is out of bounds {}", index, self.len ); - if index == self.len - 1 { + if index == self.len() - 1 { self.pop().unwrap() } else { let i = self.pop().unwrap(); @@ -813,13 +820,20 @@ impl ArrayVec { /// If the vec is already shorter than the input, nothing happens. #[inline] pub fn truncate(&mut self, new_len: usize) { - if needs_drop::() { - while self.len > new_len { - self.pop(); - } - } else { - self.len = self.len.min(new_len); + if new_len >= self.len as usize { + return; } + + if needs_drop::() { + let len = self.len as usize; + self.data.as_slice_mut()[new_len..len] + .iter_mut() + .map(take) + .for_each(drop); + } + + /* new_len is less than self.len */ + self.len = new_len as u16; } /// Wraps an array, using the given length as the starting length. @@ -833,8 +847,9 @@ impl ArrayVec { /// error, and you'll get the array back in the `Err`. #[inline] pub fn try_from_array_len(data: A, len: usize) -> Result { + /* Note(Soveu): Should we allow A::CAPACITY > u16::MAX for now? */ if len <= A::CAPACITY { - Ok(Self { data, len }) + Ok(Self { data, len: len as u16 }) } else { Err(data) } @@ -858,7 +873,7 @@ impl ArrayVec { /// ``` #[inline(always)] pub fn grab_spare_slice(&self) -> &[A::Item] { - &self.data.as_slice()[self.len..] + &self.data.as_slice()[self.len as usize..] } /// Obtain the mutable slice of the array _after_ the active memory. @@ -874,7 +889,7 @@ impl ArrayVec { /// ``` #[inline(always)] pub fn grab_spare_slice_mut(&mut self) -> &mut [A::Item] { - &mut self.data.as_slice_mut()[self.len..] + &mut self.data.as_slice_mut()[self.len as usize..] } } @@ -1066,7 +1081,12 @@ impl From for ArrayVec { /// If you want to select a length, use /// [`from_array_len`](ArrayVec::from_array_len) fn from(data: A) -> Self { - Self { len: data.as_slice().len(), data } + let len: u16 = data + .as_slice() + .len() + .try_into() + .expect("ArrayVec::from> lenght must be in range 0..=u16::MAX"); + Self { len, data } } } @@ -1084,8 +1104,8 @@ impl FromIterator for ArrayVec { /// Iterator for consuming an `ArrayVec` and returning owned elements. pub struct ArrayVecIterator { - base: usize, - len: usize, + base: u16, + tail: u16, data: A, } @@ -1094,7 +1114,7 @@ impl ArrayVecIterator { #[inline] #[must_use] pub fn as_slice(&self) -> &[A::Item] { - &self.data.as_slice()[self.base..self.len] + &self.data.as_slice()[self.base as usize..self.tail as usize] } } impl FusedIterator for ArrayVecIterator {} @@ -1102,7 +1122,8 @@ impl Iterator for ArrayVecIterator { type Item = A::Item; #[inline] fn next(&mut self) -> Option { - let slice = &mut self.data.as_slice_mut()[self.base..self.len]; + let slice = + &mut self.data.as_slice_mut()[self.base as usize..self.tail as usize]; let itemref = slice.first_mut()?; self.base += 1; return Some(take(itemref)); @@ -1110,12 +1131,13 @@ impl Iterator for ArrayVecIterator { #[inline(always)] #[must_use] fn size_hint(&self) -> (usize, Option) { - let s = self.len - self.base; + let s = self.tail - self.base; + let s = s as usize; (s, Some(s)) } #[inline(always)] fn count(self) -> usize { - self.len - self.base + self.size_hint().0 } #[inline] fn last(mut self) -> Option { @@ -1123,14 +1145,16 @@ impl Iterator for ArrayVecIterator { } #[inline] fn nth(&mut self, n: usize) -> Option { - let slice = &mut self.data.as_slice_mut()[self.base..self.len]; + let slice = &mut self.data.as_slice_mut(); + let slice = &mut slice[self.base as usize..self.tail as usize]; if let Some(x) = slice.get_mut(n) { - self.base += n + 1; + /* n is in range [0 .. self.tail - self.base) so in u16 range */ + self.base += n as u16 + 1; return Some(take(x)); } - self.base = self.len; + self.base = self.tail; return None; } } @@ -1138,18 +1162,22 @@ impl Iterator for ArrayVecIterator { impl DoubleEndedIterator for ArrayVecIterator { #[inline] fn next_back(&mut self) -> Option { - let slice = &mut self.data.as_slice_mut()[self.base..self.len]; + let slice = + &mut self.data.as_slice_mut()[self.base as usize..self.tail as usize]; let item = slice.last_mut()?; - self.len -= 1; + self.tail -= 1; return Some(take(item)); } #[cfg(feature = "rustc_1_40")] #[inline] fn nth_back(&mut self, n: usize) -> Option { - let slice = &mut self.data.as_slice_mut()[self.base..self.len]; + let slice = + &mut self.data.as_slice_mut()[self.base as usize..self.tail as usize]; let n = slice.len().checked_sub(n + 1)?; let item = &mut slice[n]; - self.len = n; + + /* n is in [0..self.tail - self.base] range, so in u16 range */ + self.tail = self.base + n as u16; return Some(take(item)); } @@ -1171,7 +1199,7 @@ impl IntoIterator for ArrayVec { #[inline(always)] #[must_use] fn into_iter(self) -> Self::IntoIter { - ArrayVecIterator { base: 0, len: self.len, data: self.data } + ArrayVecIterator { base: 0, tail: self.len, data: self.data } } } diff --git a/tests/arrayvec.rs b/tests/arrayvec.rs index 68a7b7a..3d42184 100644 --- a/tests/arrayvec.rs +++ b/tests/arrayvec.rs @@ -393,16 +393,14 @@ fn reviter() { assert_eq!(iter.next(), None); assert_eq!(iter.next_back(), None); - let mut av: ArrayVec<[i32; 10]> = Default::default(); - av.push(1); - av.push(2); - av.push(3); - av.push(4); + let mut av: ArrayVec<[i32; 32]> = Default::default(); + av.extend(0..32); let mut iter = av.into_iter(); - assert_eq!(iter.nth_back(0), Some(4)); - assert_eq!(iter.nth_back(2), Some(1)); - assert_eq!(iter.nth_back(0), None); + assert_eq!(iter.nth_back(0), Some(31)); + assert_eq!(iter.nth_back(2), Some(28)); + assert_eq!(iter.nth_back(0), Some(27)); + assert_eq!(iter.nth_back(99), None); assert_eq!(iter.nth_back(99), None); }